Initial commit
This commit is contained in:
@@ -0,0 +1,46 @@
|
||||
# Permission Module
|
||||
|
||||
The Permission module provides frontend permission checks and gates. It also corresponds to the backend permission endpoint and permission discovery service used by AccessControl.
|
||||
|
||||
## Source Map
|
||||
|
||||
| Area | Path |
|
||||
| -------------------------- | -------------------------------------------------------- |
|
||||
| Frontend module | `apps/admin/src/core/Permission/` |
|
||||
| Frontend gates | `apps/admin/src/core/Permission/view/gates/` |
|
||||
| Frontend hook | `apps/admin/src/core/Permission/hooks/usePermissions.ts` |
|
||||
| Frontend types | `apps/admin/src/core/Permission/entities/permission.ts` |
|
||||
| Backend module | `backend/app/base_modules/Permission/` |
|
||||
| Backend permission service | `backend/app/services/permission_service.ts` |
|
||||
|
||||
## Documentation
|
||||
|
||||
| Page | Purpose |
|
||||
| ------------------------- | ------------------------------------------------------------------ |
|
||||
| [Frontend](./frontend.md) | Permission types, hook, gates, and usage rules. |
|
||||
| [Backend](./backend.md) | Permission endpoint, permission discovery, and permission configs. |
|
||||
|
||||
## Main Capabilities
|
||||
|
||||
- Check whether current user has required permission slugs.
|
||||
- Support `all` and `any` matching modes.
|
||||
- Render or hide UI actions through `PermissionGate`.
|
||||
- Protect full pages through `PermissionPageGate`.
|
||||
- Treat super admin as an all-permissions user.
|
||||
|
||||
## High-Level Flow
|
||||
|
||||
```txt
|
||||
AuthProvider current user
|
||||
-> AuthUser.permissions
|
||||
-> usePermissions()
|
||||
-> hasPermission()
|
||||
-> PermissionGate or PermissionPageGate
|
||||
```
|
||||
|
||||
## Ownership Rules
|
||||
|
||||
- Permission frontend owns permission checks and gate components.
|
||||
- Auth owns loading current user permissions.
|
||||
- AccessControl owns managing roles and assigning permissions.
|
||||
- Backend modules own their own permission definitions in `config/permissions.ts`.
|
||||
@@ -0,0 +1,81 @@
|
||||
# Permission Backend
|
||||
|
||||
The backend Permission module exposes available permission definitions. It is used by AccessControl when assigning permissions to roles.
|
||||
|
||||
Source root:
|
||||
|
||||
```txt
|
||||
backend/app/base_modules/Permission/
|
||||
```
|
||||
|
||||
## Route
|
||||
|
||||
| Method | Route | Controller Method | Auth Required | Purpose |
|
||||
| ------ | ------------- | ----------------- | ------------- | -------------------------------------------- |
|
||||
| `GET` | `/permission` | `index` | Yes | Return all available permission definitions. |
|
||||
|
||||
Route file:
|
||||
|
||||
```txt
|
||||
backend/app/base_modules/Permission/routes.ts
|
||||
```
|
||||
|
||||
## Request Flow
|
||||
|
||||
```txt
|
||||
GET /permission
|
||||
-> auth middleware
|
||||
-> PermissionController.index
|
||||
-> getAllPermissions()
|
||||
-> scan backend module permission configs
|
||||
-> return PermissionItem[]
|
||||
```
|
||||
|
||||
## Permission Discovery
|
||||
|
||||
Permission discovery lives in:
|
||||
|
||||
```txt
|
||||
backend/app/services/permission_service.ts
|
||||
```
|
||||
|
||||
`getAllPermissions()` scans:
|
||||
|
||||
```txt
|
||||
backend/app/base_modules/*/config/permissions.ts
|
||||
backend/app/modules/*/config/permissions.ts
|
||||
```
|
||||
|
||||
Each config exports permission items:
|
||||
|
||||
```ts
|
||||
type PermissionItem = {
|
||||
slug: string;
|
||||
name: string;
|
||||
};
|
||||
```
|
||||
|
||||
## Current Permission Configs
|
||||
|
||||
Core permission definitions currently include:
|
||||
|
||||
```txt
|
||||
backend/app/base_modules/Admin/config/permissions.ts
|
||||
backend/app/base_modules/Role/config/permissions.ts
|
||||
backend/app/base_modules/FileManager/config/permissions.ts
|
||||
```
|
||||
|
||||
When adding a feature that needs access control, add permission definitions to the owning backend module's `config/permissions.ts`.
|
||||
|
||||
## Admin Permission Slugs
|
||||
|
||||
`getAdminPermissionSlugs(admin)` loads an admin's roles and returns a set of permission slugs from `role_permissions`.
|
||||
|
||||
This function is used by backend policies to authorize operations.
|
||||
|
||||
## Ownership Rules
|
||||
|
||||
- Backend modules own their own permission definitions.
|
||||
- Permission service owns discovering all available permission definitions.
|
||||
- AccessControl owns assigning permission slugs to roles.
|
||||
- Auth owns returning the current user's permission slugs to the frontend.
|
||||
@@ -0,0 +1,102 @@
|
||||
# Permission Frontend
|
||||
|
||||
The frontend module provides reusable permission-checking primitives for the admin app.
|
||||
|
||||
Source root:
|
||||
|
||||
```txt
|
||||
apps/admin/src/core/Permission/
|
||||
```
|
||||
|
||||
## Directory Structure
|
||||
|
||||
```txt
|
||||
Permission/
|
||||
config/ Static module config and messages.
|
||||
entities/ Permission types.
|
||||
hooks/ Current-user permission hook.
|
||||
lib/ Pure permission check function.
|
||||
view/gates/ React gate components.
|
||||
```
|
||||
|
||||
## Types
|
||||
|
||||
Permission types live in:
|
||||
|
||||
```txt
|
||||
entities/permission.ts
|
||||
```
|
||||
|
||||
Key concepts:
|
||||
|
||||
```ts
|
||||
type PermissionCheckMode = "all" | "any";
|
||||
type RequiredPermissions = string | string[];
|
||||
```
|
||||
|
||||
## Hook
|
||||
|
||||
Current-user permission access:
|
||||
|
||||
```txt
|
||||
hooks/usePermissions.ts
|
||||
```
|
||||
|
||||
The hook reads auth state from AuthProvider and returns:
|
||||
|
||||
```ts
|
||||
permissions;
|
||||
isAdmin;
|
||||
loading;
|
||||
```
|
||||
|
||||
`isAdmin` is based on the configured super admin id.
|
||||
|
||||
## Pure Permission Check
|
||||
|
||||
Permission check logic:
|
||||
|
||||
```txt
|
||||
lib/hasPermission.ts
|
||||
```
|
||||
|
||||
Behavior:
|
||||
|
||||
- Super admin passes all checks.
|
||||
- `all` mode requires every permission.
|
||||
- `any` mode requires at least one permission.
|
||||
- Empty required permissions should be treated carefully at call sites.
|
||||
|
||||
## Gates
|
||||
|
||||
### `PermissionGate`
|
||||
|
||||
Use for conditional UI controls such as buttons and menu items.
|
||||
|
||||
```tsx
|
||||
<PermissionGate requiredPermissions="admins.update">
|
||||
<Button>Edit</Button>
|
||||
</PermissionGate>
|
||||
```
|
||||
|
||||
### `PermissionPageGate`
|
||||
|
||||
Use for route-level access protection.
|
||||
|
||||
```tsx
|
||||
<PermissionPageGate requiredPermissions={["admins.view", "role.view"]}>
|
||||
<AdminListPage />
|
||||
</PermissionPageGate>
|
||||
```
|
||||
|
||||
If access is denied, it renders the provided fallback or a 403 page.
|
||||
|
||||
## Translations
|
||||
|
||||
The module has a local message bundle for consistency:
|
||||
|
||||
```txt
|
||||
config/messages.ts
|
||||
config/translation/en.json
|
||||
config/translation/uk.json
|
||||
```
|
||||
Reference in New Issue
Block a user