Harden subuser permission payloads (#328)
## Summary - Normalize subuser grant permission payload keys before enum validation so mixed-case customer-facing writes are accepted and deduped consistently. - Add a focused subuser route static check for permission payload normalization. ## Verification - `php services/nginx/app/tests/subusers/SubusersRoutePermissionLinkTest.php && php services/nginx/app/tests/subusers/SubusersRoutePermissionsPayloadTest.php` - `php -l services/nginx/app/routes/subusersRoute.php && php -l services/nginx/app/tests/subusers/SubusersRoutePermissionsPayloadTest.php` --------- Co-authored-by: Jeppe Bundgaard <jb@truckwash.dk>
This commit is contained in:
co-authored by
Jeppe Bundgaard
parent
30d860fdef
commit
3c13892366
@@ -119,10 +119,11 @@ class subusersRoute
|
|||||||
|
|
||||||
$permissions = [];
|
$permissions = [];
|
||||||
foreach ($raw as $permission) {
|
foreach ($raw as $permission) {
|
||||||
|
$permission = is_string($permission) ? strtoupper(trim($permission)) : $permission;
|
||||||
if (!is_string($permission) || subusers_permission_node_key::tryFrom($permission) === null) {
|
if (!is_string($permission) || subusers_permission_node_key::tryFrom($permission) === null) {
|
||||||
$response->error('Unknown permission key: ' . (string)$permission, 400);
|
$response->error('Unknown permission key: ' . (string)$permission, 400);
|
||||||
}
|
}
|
||||||
$permissions[] = strtoupper(trim($permission));
|
$permissions[] = $permission;
|
||||||
}
|
}
|
||||||
|
|
||||||
return array_values(array_unique($permissions));
|
return array_values(array_unique($permissions));
|
||||||
|
|||||||
@@ -30,5 +30,6 @@ return [
|
|||||||
['path' => 'tests/slackModule/SlackModuleTest.php', 'classification' => 'manual-external', 'type' => 'script', 'reason' => 'Requires a configured Slack webhook and department webhook cache state.'],
|
['path' => 'tests/slackModule/SlackModuleTest.php', 'classification' => 'manual-external', 'type' => 'script', 'reason' => 'Requires a configured Slack webhook and department webhook cache state.'],
|
||||||
['path' => 'tests/subusers/SelfservePermissionInitTest.php', 'classification' => 'unit', 'type' => 'script'],
|
['path' => 'tests/subusers/SelfservePermissionInitTest.php', 'classification' => 'unit', 'type' => 'script'],
|
||||||
['path' => 'tests/subusers/SubusersRoutePermissionLinkTest.php', 'classification' => 'unit', 'type' => 'script'],
|
['path' => 'tests/subusers/SubusersRoutePermissionLinkTest.php', 'classification' => 'unit', 'type' => 'script'],
|
||||||
|
['path' => 'tests/subusers/SubusersRoutePermissionsPayloadTest.php', 'classification' => 'unit', 'type' => 'script'],
|
||||||
['path' => 'tests/subusers/SubuserUserGrantInitTest.php', 'classification' => 'unit', 'type' => 'script'],
|
['path' => 'tests/subusers/SubuserUserGrantInitTest.php', 'classification' => 'unit', 'type' => 'script'],
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -0,0 +1,33 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
if (!defined('WD')) {
|
||||||
|
define('WD', dirname(__DIR__, 2));
|
||||||
|
}
|
||||||
|
|
||||||
|
function ok($message): void { echo "\n\033[32m✔ $message\033[0m\n"; }
|
||||||
|
function fail($message): void { echo "\n\033[31m✖ $message\033[0m\n"; exit(1); }
|
||||||
|
|
||||||
|
$routeFile = WD . '/routes/subusersRoute.php';
|
||||||
|
if (!file_exists($routeFile)) {
|
||||||
|
fail('subusersRoute.php not found');
|
||||||
|
}
|
||||||
|
|
||||||
|
$code = file_get_contents($routeFile);
|
||||||
|
if ($code === false) {
|
||||||
|
fail('Unable to read subusersRoute.php');
|
||||||
|
}
|
||||||
|
|
||||||
|
$normalized = preg_replace('/\s+/', ' ', $code);
|
||||||
|
|
||||||
|
$normalizesBeforeEnumLookup = 'permission = is_string($permission) ? strtoupper(trim($permission)) : $permission; if (!is_string($permission) || subusers_permission_node_key::tryFrom($permission) === null)';
|
||||||
|
if (strpos($normalized, $normalizesBeforeEnumLookup) === false) {
|
||||||
|
fail('Expected permissions payload parser to normalize permission keys before enum validation');
|
||||||
|
}
|
||||||
|
|
||||||
|
$dedupesNormalizedPermissions = 'return array_values(array_unique($permissions));';
|
||||||
|
if (strpos($normalized, $dedupesNormalizedPermissions) === false) {
|
||||||
|
fail('Expected permissions payload parser to deduplicate normalized permission keys');
|
||||||
|
}
|
||||||
|
|
||||||
|
ok('Subusers route normalizes mixed-case permission payloads before validation and dedupe');
|
||||||
|
echo "\nSubusersRoutePermissionsPayloadTest completed.\n";
|
||||||
Reference in New Issue
Block a user