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
This commit is contained in:
@@ -24,6 +24,9 @@ use objects\products_o;
|
||||
use objects\users_o;
|
||||
use traits\route_t;
|
||||
|
||||
use app\auth\Scope;
|
||||
use app\auth\ScopeMiddleware;
|
||||
|
||||
class InvoicingPeriodRoute
|
||||
{
|
||||
use route_t;
|
||||
@@ -1412,6 +1415,7 @@ class InvoicingPeriodRoute
|
||||
public function run(): void
|
||||
{
|
||||
$this->post('/superuser/invoicing/period/object-tree/canary', function () {
|
||||
ScopeMiddleware::requireScope(Scope::SUPERUSER_WRITE, '/superuser/invoicing/period/object-tree/canary');
|
||||
global $response;
|
||||
$this->requirePermission('superuser');
|
||||
self::requireParameters(['enabled']);
|
||||
@@ -1463,6 +1467,7 @@ class InvoicingPeriodRoute
|
||||
]);
|
||||
|
||||
$this->get('/superuser/invoicing/period', function () {
|
||||
ScopeMiddleware::requireScope(Scope::SUPERUSER_READ, '/superuser/invoicing/period');
|
||||
// Require the user to be logged in
|
||||
global $response;
|
||||
$this->requirePermission('superuser_invoicing_period');
|
||||
@@ -1507,6 +1512,7 @@ class InvoicingPeriodRoute
|
||||
);
|
||||
|
||||
$this->get('/superuser/invoicing/period/tree', function () {
|
||||
ScopeMiddleware::requireScope(Scope::SUPERUSER_READ, '/superuser/invoicing/period/tree');
|
||||
global $response;
|
||||
$this->requirePermission('superuser_invoicing_period');
|
||||
$user = (new authentication())->get_user();
|
||||
@@ -1546,6 +1552,7 @@ class InvoicingPeriodRoute
|
||||
);
|
||||
|
||||
$this->post('/superuser/invoicing/period/flags', function () {
|
||||
ScopeMiddleware::requireScope(Scope::SUPERUSER_WRITE, '/superuser/invoicing/period/flags');
|
||||
global $response;
|
||||
$this->requirePermission('add_invoice_period_flag');
|
||||
$user = (new authentication())->get_user();
|
||||
@@ -1571,6 +1578,7 @@ class InvoicingPeriodRoute
|
||||
);
|
||||
|
||||
$this->patch('/superuser/invoicing/period/flags/{id}/status', function () {
|
||||
ScopeMiddleware::requireScope(Scope::SUPERUSER_WRITE, '/superuser/invoicing/period/flags/{id}/status');
|
||||
global $response;
|
||||
$this->requirePermission('update_invoice_period_flag_status');
|
||||
$user = (new authentication())->get_user();
|
||||
@@ -1599,6 +1607,7 @@ class InvoicingPeriodRoute
|
||||
);
|
||||
|
||||
$this->post('/superuser/invoicing/period/flags/automatic/status', function () {
|
||||
ScopeMiddleware::requireScope(Scope::SUPERUSER_WRITE, '/superuser/invoicing/period/flags/automatic/status');
|
||||
global $response;
|
||||
$this->requirePermission('update_invoice_period_flag_status');
|
||||
$user = (new authentication())->get_user();
|
||||
@@ -1625,6 +1634,7 @@ class InvoicingPeriodRoute
|
||||
|
||||
|
||||
$this->get('/superuser/invoicing/period/distribution/all', function () {
|
||||
ScopeMiddleware::requireScope(Scope::SUPERUSER_READ, '/superuser/invoicing/period/distribution/all');
|
||||
// Require the user to be logged in
|
||||
global $response;
|
||||
$this->requirePermission('superuser_invoicing_period');
|
||||
@@ -1647,6 +1657,7 @@ class InvoicingPeriodRoute
|
||||
);
|
||||
|
||||
$this->get('/superuser/invoicing/period/distribution/fixed-pricing', function () {
|
||||
ScopeMiddleware::requireScope(Scope::SUPERUSER_READ, '/superuser/invoicing/period/distribution/fixed-pricing');
|
||||
// Require the user to be logged in
|
||||
global $response;
|
||||
$this->requirePermission('superuser_invoicing_period');
|
||||
@@ -1664,6 +1675,7 @@ class InvoicingPeriodRoute
|
||||
);
|
||||
|
||||
$this->get('/superuser/invoicing/period/distribution/wash-subscriptions', function () {
|
||||
ScopeMiddleware::requireScope(Scope::SUPERUSER_READ, '/superuser/invoicing/period/distribution/wash-subscriptions');
|
||||
// Require the user to be logged in
|
||||
global $response;
|
||||
$this->requirePermission('superuser_invoicing_period');
|
||||
@@ -1681,6 +1693,7 @@ class InvoicingPeriodRoute
|
||||
);
|
||||
|
||||
$this->get('/superuser/invoicing/period/distribution/v2/all', function () {
|
||||
ScopeMiddleware::requireScope(Scope::SUPERUSER_READ, '/superuser/invoicing/period/distribution/v2/all');
|
||||
global $response;
|
||||
$this->requirePermission('superuser_invoicing_period_distribution_v2');
|
||||
$dateRange = $this->requireAndNormalizeDateRange();
|
||||
@@ -1699,6 +1712,7 @@ class InvoicingPeriodRoute
|
||||
);
|
||||
|
||||
$this->get('/superuser/invoicing/period/distribution/v2/fixed-pricing', function () {
|
||||
ScopeMiddleware::requireScope(Scope::SUPERUSER_READ, '/superuser/invoicing/period/distribution/v2/fixed-pricing');
|
||||
global $response;
|
||||
$this->requirePermission('superuser_invoicing_period_distribution_v2');
|
||||
$dateRange = $this->requireAndNormalizeDateRange();
|
||||
@@ -1717,6 +1731,7 @@ class InvoicingPeriodRoute
|
||||
);
|
||||
|
||||
$this->get('/superuser/invoicing/period/distribution/v2/wash-subscriptions', function () {
|
||||
ScopeMiddleware::requireScope(Scope::SUPERUSER_READ, '/superuser/invoicing/period/distribution/v2/wash-subscriptions');
|
||||
global $response;
|
||||
$this->requirePermission('superuser_invoicing_period_distribution_v2');
|
||||
$dateRange = $this->requireAndNormalizeDateRange();
|
||||
@@ -1735,6 +1750,7 @@ class InvoicingPeriodRoute
|
||||
);
|
||||
|
||||
$this->get('/superuser/invoicing/period/distribution/v2/customer-prices', function () {
|
||||
ScopeMiddleware::requireScope(Scope::SUPERUSER_READ, '/superuser/invoicing/period/distribution/v2/customer-prices');
|
||||
global $response;
|
||||
$this->requirePermission('superuser_invoicing_period_distribution_v2');
|
||||
$dateRange = $this->requireAndNormalizeDateRange();
|
||||
@@ -1753,6 +1769,7 @@ class InvoicingPeriodRoute
|
||||
);
|
||||
|
||||
$this->get('/superuser/invoicing/period/distribution/v2/booked-department-75', function () {
|
||||
ScopeMiddleware::requireScope(Scope::SUPERUSER_READ, '/superuser/invoicing/period/distribution/v2/booked-department-75');
|
||||
global $response;
|
||||
$this->requirePermission('superuser_invoicing_period_distribution_v2');
|
||||
$dateRange = $this->requireAndNormalizeDateRange();
|
||||
@@ -1771,6 +1788,7 @@ class InvoicingPeriodRoute
|
||||
);
|
||||
|
||||
$this->get('/superuser/customers/pricing-history', function () {
|
||||
ScopeMiddleware::requireScope(Scope::SUPERUSER_READ, '/superuser/customers/pricing-history');
|
||||
global $response;
|
||||
$this->requirePermission('superuser_customer_pricing_history_v2');
|
||||
self::requireParameters(['customer_number']);
|
||||
@@ -1832,6 +1850,7 @@ class InvoicingPeriodRoute
|
||||
);
|
||||
|
||||
$this->get('/superuser/invoicing/period/distribution/wash-subscriptions/historical', function () {
|
||||
ScopeMiddleware::requireScope(Scope::SUPERUSER_READ, '/superuser/invoicing/period/distribution/wash-subscriptions/historical');
|
||||
// Require the user to be logged in
|
||||
global $response;
|
||||
$this->requirePermission('superuser_invoicing_period');
|
||||
|
||||
Reference in New Issue
Block a user