Refactor /subusers/grants update logic and require explicit autoloading for subuser module
- Replace route method for updating grants (`PATCH` to `PUT`) and streamline grant updates by directly modifying object properties instead of using manual data arrays. - Introduce parameter validation for consistency and permission checks for cross-customer grant management. - Require autoloading for all subuser module components (interfaces, traits, helpers, classes, and permissions) to improve modularity and maintainability.
This commit is contained in:
@@ -112,8 +112,23 @@ require_once 'modules/goals/classes/goals_criteria_products.php';
|
||||
require_once 'modules/goals/classes/goals_criteria.php';
|
||||
require_once 'modules/goals/classes/goals.php';
|
||||
|
||||
// Subusers module (helpers used by objects)
|
||||
require_once 'modules/subusers/helpers/subusers_permission_node_key.php';
|
||||
// Subusers module
|
||||
// Load interfaces, traits, classes, helpers and permissions to ensure autoloading for route usage
|
||||
foreach (glob(WD . '/modules/subusers/interfaces/*.php') as $interface) {
|
||||
require_once $interface;
|
||||
}
|
||||
foreach (glob(WD . '/modules/subusers/traits/*.php') as $trait) {
|
||||
require_once $trait;
|
||||
}
|
||||
foreach (glob(WD . '/modules/subusers/classes/*.php') as $classFile) {
|
||||
require_once $classFile;
|
||||
}
|
||||
foreach (glob(WD . '/modules/subusers/helpers/*.php') as $helper) {
|
||||
require_once $helper;
|
||||
}
|
||||
foreach (glob(WD . '/modules/subusers/permissions/*.php') as $permissionFile) {
|
||||
require_once $permissionFile;
|
||||
}
|
||||
|
||||
// Dynamic Images module
|
||||
foreach (glob(WD . '/modules/dynamicimages/interfaces/*.php') as $interface) {
|
||||
|
||||
@@ -128,29 +128,34 @@ class subusersRoute
|
||||
}
|
||||
}, []);
|
||||
|
||||
$this->patch('/subusers/grants/{id}', function () {
|
||||
$this->put('/subusers/grants', function () {
|
||||
global $response;
|
||||
$id = (int)self::fromRoute('id');
|
||||
self::requireType($id, self::type_int());
|
||||
$grant = (new subuser_grants_o())->select($id);
|
||||
$grant->requireSelected();
|
||||
$data = [];
|
||||
self::requireParameters(['id']);
|
||||
self::requireType(self::getParameter('id'), self::type_int());
|
||||
$grant = (new subuser_grants_o())->select((int)self::getParameter('id'));
|
||||
if (!$grant->exists()) {
|
||||
$response->error('Grant not found', 404);
|
||||
}
|
||||
$user = (new authentication())->get_user();
|
||||
// Validate permissions
|
||||
if ((int)$grant->billing_customer_number->value() !== (int)$user->customer_number->value()) {
|
||||
self::requirePermission('manage_subuser_grants_other_customer');
|
||||
}
|
||||
// Update fields provided in the request
|
||||
if (self::isParametersSet(['enabled'])) {
|
||||
$enabled = (bool)filter_var(self::getParameter('enabled'), FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE);
|
||||
if ($enabled === null) {
|
||||
$response->error('Invalid enabled flag', 400);
|
||||
}
|
||||
$data['enabled'] = (bool)$enabled;
|
||||
if ($enabled === null) { $enabled = false; }
|
||||
$grant->enabled->set($enabled);
|
||||
}
|
||||
if (self::isParametersSet(['note'])) {
|
||||
$note = (string)self::getParameter('note');
|
||||
self::requireType($note, self::type_string());
|
||||
self::requireMaxLength('note', 65535);
|
||||
$data['note'] = $note;
|
||||
$grant->note->set($note);
|
||||
}
|
||||
if (self::isParametersSet(['permissions'])) {
|
||||
$raw = self::getParameter('permissions');
|
||||
$permissions = null;
|
||||
// Expect array (already parsed) or JSON string
|
||||
if (is_string($raw)) {
|
||||
$decoded = json_decode($raw, true);
|
||||
if (!is_array($decoded)) {
|
||||
@@ -162,37 +167,20 @@ class subusersRoute
|
||||
} else {
|
||||
$response->error('Invalid permissions type', 400);
|
||||
}
|
||||
// Validate each permission is a known key
|
||||
foreach ($permissions as $perm) {
|
||||
if (!is_string($perm) || subusers_permission_node_key::tryFrom($perm) === null) {
|
||||
$response->error('Unknown permission key: ' . (string)$perm, 400);
|
||||
}
|
||||
}
|
||||
$data['permissions'] = $permissions;
|
||||
$grant->permissions->set($permissions);
|
||||
}
|
||||
if (empty($data)) {
|
||||
$response->error('No updatable fields provided', 400);
|
||||
}
|
||||
try {
|
||||
$grant->update($data);
|
||||
$response->success(['grant' => $grant->asArray()]);
|
||||
} catch (Exception $e) {
|
||||
$response->error('Failed to update grant', 500);
|
||||
}
|
||||
}, []);
|
||||
|
||||
$this->delete('/subusers/grants/{id}', function () {
|
||||
global $response;
|
||||
$id = (int)self::fromRoute('id');
|
||||
self::requireType($id, self::type_int());
|
||||
$grant = (new subuser_grants_o())->select($id);
|
||||
$grant->requireSelected();
|
||||
try {
|
||||
$grant->delete();
|
||||
$response->success(['message' => 'Grant deleted']);
|
||||
} catch (Exception $e) {
|
||||
$response->error('Failed to delete grant', 500);
|
||||
}
|
||||
}, []);
|
||||
$response->success($grant->asArray());
|
||||
},
|
||||
[
|
||||
"manage_subuser_grants_other_customer" => "Allow managing subuser grants for customers other than the one associated with the current session's user (use with caution, as this allows modifying permissions for subusers of other companies)"
|
||||
]
|
||||
);
|
||||
|
||||
$this->get('/subusers/permission-nodes', function () {
|
||||
global $response;
|
||||
@@ -222,7 +210,7 @@ class subusersRoute
|
||||
'nodes' => $nodes,
|
||||
];
|
||||
}
|
||||
$response->success(['permission_nodes' => $out]);
|
||||
$response->success($out);
|
||||
}, []);
|
||||
|
||||
$this->post('/subusers', function () {
|
||||
|
||||
Reference in New Issue
Block a user