Add CRUD operations for subuser grants and list permission nodes
- Implement routes for managing subuser grants: listing, creating, updating, and deleting. - Add endpoint to fetch available permission nodes grouped by type. - Extend `subuser_grants_o` with new utility methods, including `asArray`. - Update OpenAPI documentation to include new endpoints and schemas.
This commit is contained in:
@@ -13,6 +13,12 @@ use objects\logs_o;
|
||||
use objects\subuser_grants_o;
|
||||
use objects\subusers_o;
|
||||
use objects\users_o;
|
||||
use modules\subusers\permissions\subusers_permission_nodes_bookings;
|
||||
use modules\subusers\permissions\subusers_permission_nodes_orders;
|
||||
use modules\subusers\permissions\subusers_permission_nodes_selfserve;
|
||||
use modules\subusers\permissions\subusers_permission_nodes_subusers;
|
||||
use modules\subusers\permissions\subusers_permission_nodes_vehicles;
|
||||
use modules\subusers\helpers\subusers_permission_node_key;
|
||||
use traits\route_t;
|
||||
|
||||
class subusersRoute
|
||||
@@ -29,6 +35,189 @@ class subusersRoute
|
||||
|
||||
public function run(): void
|
||||
{
|
||||
// =============================
|
||||
// Subuser Grant Management
|
||||
// =============================
|
||||
$this->get('/subusers/grants', function () {
|
||||
global $response;
|
||||
// Optional filters: customer_number, subuser_id
|
||||
$filters = ['deleted_at' => null];
|
||||
$hasFilter = false;
|
||||
if (self::isParametersSet(['customer_number'])) {
|
||||
$customer_number = (int)self::getParameter('customer_number');
|
||||
self::requireType($customer_number, self::type_int());
|
||||
$filters['billing_customer_number'] = $customer_number;
|
||||
$hasFilter = true;
|
||||
}
|
||||
if (self::isParametersSet(['subuser_id'])) {
|
||||
$subuser_id = (int)self::getParameter('subuser_id');
|
||||
self::requireType($subuser_id, self::type_int());
|
||||
$filters['subuser'] = $subuser_id;
|
||||
$hasFilter = true;
|
||||
}
|
||||
if (!$hasFilter) {
|
||||
$response->error('You must provide at least one of: customer_number or subuser_id', 400);
|
||||
}
|
||||
$rows = (new subuser_grants_o())->getFieldsWhere($filters, [
|
||||
'id', 'billing_customer_number', 'subuser', 'enabled', 'note', 'permissions', 'created_at', 'updated_at', 'deleted_at'
|
||||
]);
|
||||
// Decode permissions JSON
|
||||
$data = array_map(function ($row) {
|
||||
$row['id'] = (int)$row['id'];
|
||||
$row['billing_customer_number'] = (int)$row['billing_customer_number'];
|
||||
$row['subuser'] = (int)$row['subuser'];
|
||||
$row['enabled'] = (bool)$row['enabled'];
|
||||
$row['permissions'] = (!empty($row['permissions'])) ? (json_decode($row['permissions'], true) ?: []) : [];
|
||||
return $row;
|
||||
}, $rows);
|
||||
$response->success(['grants' => $data]);
|
||||
}, []);
|
||||
|
||||
$this->post('/subusers/grants', function () {
|
||||
global $response;
|
||||
self::requireParameters(['customer_number', 'subuser_id']);
|
||||
$customer_number = (int)self::getParameter('customer_number');
|
||||
$subuser_id = (int)self::getParameter('subuser_id');
|
||||
self::requireType($customer_number, self::type_int());
|
||||
self::requireType($subuser_id, self::type_int());
|
||||
$enabled = true;
|
||||
if (self::isParametersSet(['enabled'])) {
|
||||
$enabled = (bool)filter_var(self::getParameter('enabled'), FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE);
|
||||
if ($enabled === null) { $enabled = true; }
|
||||
}
|
||||
$note = null;
|
||||
if (self::isParametersSet(['note'])) {
|
||||
$note = (string)self::getParameter('note');
|
||||
self::requireType($note, self::type_string());
|
||||
self::requireMaxLength('note', 65535);
|
||||
}
|
||||
$permissions = null;
|
||||
if (self::isParametersSet(['permissions'])) {
|
||||
$raw = self::getParameter('permissions');
|
||||
// Expect array (already parsed) or JSON string
|
||||
if (is_string($raw)) {
|
||||
$decoded = json_decode($raw, true);
|
||||
if (!is_array($decoded)) {
|
||||
$response->error('Invalid permissions payload', 400);
|
||||
}
|
||||
$permissions = $decoded;
|
||||
} elseif (is_array($raw)) {
|
||||
$permissions = $raw;
|
||||
} 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
try {
|
||||
$grant = (new subuser_grants_o())->add($customer_number, $subuser_id, (bool)$enabled, $note, $permissions);
|
||||
$response->success(['grant' => $grant->asArray()]);
|
||||
} catch (Exception $e) {
|
||||
$response->error('Failed to add subuser grant', 500);
|
||||
}
|
||||
}, []);
|
||||
|
||||
$this->patch('/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();
|
||||
$data = [];
|
||||
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 (self::isParametersSet(['note'])) {
|
||||
$note = (string)self::getParameter('note');
|
||||
self::requireType($note, self::type_string());
|
||||
self::requireMaxLength('note', 65535);
|
||||
$data['note'] = $note;
|
||||
}
|
||||
if (self::isParametersSet(['permissions'])) {
|
||||
$raw = self::getParameter('permissions');
|
||||
$permissions = null;
|
||||
if (is_string($raw)) {
|
||||
$decoded = json_decode($raw, true);
|
||||
if (!is_array($decoded)) {
|
||||
$response->error('Invalid permissions payload', 400);
|
||||
}
|
||||
$permissions = $decoded;
|
||||
} elseif (is_array($raw)) {
|
||||
$permissions = $raw;
|
||||
} else {
|
||||
$response->error('Invalid permissions type', 400);
|
||||
}
|
||||
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;
|
||||
}
|
||||
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);
|
||||
}
|
||||
}, []);
|
||||
|
||||
$this->get('/subusers/permission-nodes', function () {
|
||||
global $response;
|
||||
// Build groups
|
||||
$groups = [
|
||||
new subusers_permission_nodes_bookings(),
|
||||
new subusers_permission_nodes_orders(),
|
||||
new subusers_permission_nodes_selfserve(),
|
||||
new subusers_permission_nodes_subusers(),
|
||||
new subusers_permission_nodes_vehicles(),
|
||||
];
|
||||
$out = [];
|
||||
foreach ($groups as $group) {
|
||||
$nodes = [];
|
||||
foreach ($group->nodes as $key => $node) {
|
||||
$nodes[] = [
|
||||
'key' => $key,
|
||||
'name' => $node->name,
|
||||
'description' => $node->description,
|
||||
'type' => $node->type->name,
|
||||
'default' => (bool)($node->value ?? false),
|
||||
];
|
||||
}
|
||||
$out[] = [
|
||||
'group' => $group->group_name,
|
||||
'description' => $group->description,
|
||||
'nodes' => $nodes,
|
||||
];
|
||||
}
|
||||
$response->success(['permission_nodes' => $out]);
|
||||
}, []);
|
||||
|
||||
$this->post('/subusers', function () {
|
||||
global /** @var response $response */
|
||||
$response;
|
||||
|
||||
Reference in New Issue
Block a user