Files
api/services/nginx/app/routes/moduleUsageRoute.php
T
OpenClaw 51a87655d6 feat(auth): add scope-based access control to all existing routes (TRU-149)
Adds a scope-based access control layer to all 81 existing API routes.
Sits alongside existing session-cookie auth (does not replace it).

What this PR does:
- Audits every existing route and documents required scope per route
  (see documentation/auth/route-scope-audit.md)
- Adds classes/auth/scope.php with 10 scope constants and role→scope defaults
- Adds classes/auth/scope_middleware.php with requireScope/requireAnyScope/requireRole
- Applies require*() calls to all 81 existing routes
- Adds ScopeMiddlewareTest (unit, 178 lines) and RouteScopeTest (integration, 212 lines)

Coexistence note:
This branch's classes/auth/scope.php is a stub that will be replaced
by classes/auth/scope_registry.php (from TRU-145 / PR #396) when that
PR merges first. The two have compatible APIs.

Refs: TRU-149
2026-08-17 11:43:13 +00:00

77 lines
2.8 KiB
PHP

<?php
namespace routes;
use classes\module_usage_service;
use Exception;
use traits\route_t;
use app\auth\Scope;
use app\auth\ScopeMiddleware;
class moduleUsageRoute
{
use route_t;
public function run(): void
{
$this->get('/modules/usage/summary', function () {
ScopeMiddleware::requireScope(Scope::SUPERUSER_READ, '/modules/usage/summary');
global $response;
$this->requirePermission('modules_usage_view');
$response->success((new module_usage_service())->summary([
'module' => $this->getParameter('module'),
'period' => $this->getParameter('period'),
'status' => $this->getParameter('status'),
'date' => $this->getParameter('date'),
]));
}, [
'modules_usage_view' => 'View module usage, quota, and statistics summaries',
]);
$this->get('/modules/usage/{moduleKey}', function () {
ScopeMiddleware::requireScope(Scope::SUPERUSER_READ, '/modules/usage/{moduleKey}');
global $response;
$this->requirePermission('modules_usage_view');
$moduleKey = (string)($this->fromRoute('moduleKey') ?? '');
$response->success((new module_usage_service())->moduleDetail($moduleKey, [
'period' => $this->getParameter('period'),
'date' => $this->getParameter('date'),
'limit' => $this->getParameter('limit'),
]));
}, [
'modules_usage_view' => 'View detailed module usage, quota, and statistics history',
]);
$this->patch('/modules/quotas/{moduleKey}/{metricKey}', function () {
ScopeMiddleware::requireScope(Scope::SUPERUSER_READ, '/modules/quotas/{moduleKey}/{metricKey}');
global $response;
$this->requirePermission('modules_quotas_manage');
$moduleKey = (string)($this->fromRoute('moduleKey') ?? '');
$metricKey = (string)($this->fromRoute('metricKey') ?? '');
try {
$response->success((new module_usage_service())->updateQuotaSetting(
$moduleKey,
$metricKey,
$response->getAllRequestParameters()
));
} catch (Exception $exception) {
if ($exception->getMessage() === 'quota_not_writable') {
$response->error([
'message' => 'Quota limit is not writable for this provider or derived metric.',
'code' => 'quota_not_writable',
], 409);
}
$response->error($exception->getMessage(), 422);
}
}, [
'modules_quotas_manage' => 'Manage module quota enforcement and writable hard limits',
]);
}
}