Refactor privilege management to support hierarchical privilege keys
- Updated privilege key structure to use a 3- or 4-part dotted hierarchy (e.g., `GROUP.PARENT.MODULE`). - Modified the `RequirePrivilege` decorator to accept multiple keys, allowing for OR logic in privilege checks. - Enhanced `PrivilegesGuard` to validate against multiple privilege keys, improving access control logic. - Created migration scripts to update existing privilege keys in the database to the new format. - Updated related services, controllers, and tests to accommodate the new privilege key structure and validation logic.
This commit is contained in:
@@ -11,7 +11,7 @@ alwaysApply: false
|
||||
Every **non-public** controller handler on a primary (CRUD) resource MUST use:
|
||||
|
||||
```typescript
|
||||
@RequirePrivilege('MODULE.RESOURCE', 'view' | 'create' | 'update' | 'delete' | 'import')
|
||||
@RequirePrivilege('GROUP.PARENT.MODULE' | ['ADMIN.SALES.ACTIVITIES.PLAN', 'MOBILE.SALES.PLAN'], 'view' | 'create' | 'update' | 'delete' | 'import')
|
||||
```
|
||||
|
||||
Map HTTP verbs to actions:
|
||||
@@ -24,13 +24,13 @@ Map HTTP verbs to actions:
|
||||
| `DELETE /:id`, bulk-delete | `delete` |
|
||||
| `POST /import` | `import` |
|
||||
|
||||
Key codes use dotted uppercase module levels (`PRIVILEGES`, `SALES.INVOICE`). New modules add a `privilege_keys` seed row via migration — do not invent a parallel permission helper.
|
||||
Key codes use 3- or 4-part dotted uppercase hierarchy: `Group.Parent.Module` or `Group.Parent.Module.Submodule` (e.g. `ADMIN.SALES.ACTIVITIES.INVOICE`, `MOBILE.SALES.PLAN`). Pass a string or string array to `@RequirePrivilege`; arrays use OR semantics. New modules add `privilege_keys` rows via migration — do not invent a parallel permission helper.
|
||||
|
||||
Seed an Administrator privilege only via SQL/ops after the first user exists (`created_by` requires a user). Documented bootstrap: insert privilege + details, then `UPDATE users SET privilege_id = …`. Do not auto-grant on register.
|
||||
|
||||
## Guard behavior
|
||||
|
||||
`PrivilegesGuard` (global) allows when there is no metadata. When metadata is present, `users.is_superadmin === true` skips the matrix check. Otherwise the user’s assigned privilege must be **status `active`** and the matrix cell must be `value === true`, or the request is `403 Forbidden`. Missing privilege / draft / archived / missing cell / `false` → deny.
|
||||
`PrivilegesGuard` (global) allows when there is no metadata. When metadata is present, `users.is_superadmin === true` skips the matrix check. Otherwise the user’s assigned privilege must be **status `active`** and at least one matrix cell in the required key list must be `value === true`, or the request is `403 Forbidden`. Missing privilege / draft / archived / missing cell / `false` → deny.
|
||||
|
||||
Do not set `is_superadmin` via register/login. Default is `false`; promote via SQL/ops (`UPDATE users SET is_superadmin = true`). The flag is loaded from the database on each JWT validation (not from JWT claims).
|
||||
|
||||
|
||||
Reference in New Issue
Block a user