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 = [];
|
||||
foreach ($raw as $permission) {
|
||||
$permission = is_string($permission) ? strtoupper(trim($permission)) : $permission;
|
||||
if (!is_string($permission) || subusers_permission_node_key::tryFrom($permission) === null) {
|
||||
$response->error('Unknown permission key: ' . (string)$permission, 400);
|
||||
}
|
||||
$permissions[] = strtoupper(trim($permission));
|
||||
$permissions[] = $permission;
|
||||
}
|
||||
|
||||
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/subusers/SelfservePermissionInitTest.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'],
|
||||
];
|
||||
|
||||
@@ -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