Initial commit
This commit is contained in:
@@ -0,0 +1,100 @@
|
||||
# Capability Sets
|
||||
|
||||
Capability sets are the tenant-scoped bundles of REST and WebDAV permissions. Every user membership and API token now references one of these sets, and the capability guard middleware enforces the scopes on every route.
|
||||
|
||||
## Enumerated Capabilities
|
||||
|
||||
All capabilities live in the `ApiCapability` enum. The current list is:
|
||||
|
||||
- `documents:read`
|
||||
- `documents:edit`
|
||||
- `documents:write`
|
||||
- `documents:upload`
|
||||
- `folders:read`
|
||||
- `folders:edit`
|
||||
- `folders:write`
|
||||
- `tags:read`
|
||||
- `tags:edit`
|
||||
- `tags:write`
|
||||
- `correspondents:read`
|
||||
- `correspondents:edit`
|
||||
- `correspondents:write`
|
||||
- `profile:read`
|
||||
- `profile:write`
|
||||
- `webdav:read`
|
||||
- `webdav:write`
|
||||
- `capability_sets:read`
|
||||
- `capability_sets:write`
|
||||
|
||||
## Default Sets
|
||||
|
||||
Provisioning (and the test harness) seed four system capability sets per tenant:
|
||||
|
||||
- `owner` — contains the full set above. Tenant owners, admin users, and freshly minted API tokens effectively get unrestricted access.
|
||||
- `user` — the default interactive role: full document/tag/correspondent/profile access, but no capability-set or WebDAV write privileges.
|
||||
- `readonly` — interactive but read-only: document/folder/tag/correspondent reads plus WebDAV downloads, but no modifying routes.
|
||||
- `webdav` — contains only `webdav:read`. WebDAV backup scripts can bind to this set for read-only access.
|
||||
|
||||
System sets are flagged with `is_system = true` and cannot be modified or deleted via the API.
|
||||
|
||||
## REST API
|
||||
|
||||
The capability-set endpoints live at `/api/capability-sets` and require the new admin capabilities:
|
||||
|
||||
| Method & Path | Capability | Description |
|
||||
|----------------------------------------|-------------------------|-----------------------------------------|
|
||||
| `GET /api/capability-sets` | `capability_sets:read` | List all sets for the tenant |
|
||||
| `POST /api/capability-sets` | `capability_sets:write` | Create a new set |
|
||||
| `GET /api/capability-sets/{id}` | `capability_sets:read` | Fetch details of a specific set |
|
||||
| `PATCH /api/capability-sets/{id}` | `capability_sets:write` | Replace capabilities / rename the set |
|
||||
| `DELETE /api/capability-sets/{id}` | `capability_sets:write` | Remove a custom set (must be unused) |
|
||||
|
||||
### Examples
|
||||
|
||||
Create a read-only set:
|
||||
|
||||
```bash
|
||||
curl -X POST \
|
||||
-H "Authorization: Bearer $TOKEN" \
|
||||
-H "Content-Type: application/json" \
|
||||
https://app.papercrate.org/api/capability-sets \
|
||||
-d '{
|
||||
"slug": "api_readonly",
|
||||
"capabilities": [
|
||||
"documents:read",
|
||||
"folders:read",
|
||||
"tags:read"
|
||||
]
|
||||
}'
|
||||
```
|
||||
|
||||
Update an existing set:
|
||||
|
||||
```bash
|
||||
curl -X PATCH \
|
||||
-H "Authorization: Bearer $TOKEN" \
|
||||
-H "Content-Type: application/json" \
|
||||
https://app.papercrate.org/api/capability-sets/$SET_ID \
|
||||
-d '{
|
||||
"capabilities": ["documents:read", "documents:edit"]
|
||||
}'
|
||||
```
|
||||
|
||||
Delete (fails if still referenced by memberships or tokens):
|
||||
|
||||
```bash
|
||||
curl -X DELETE \
|
||||
-H "Authorization: Bearer $TOKEN" \
|
||||
https://app.papercrate.org/api/capability-sets/$SET_ID
|
||||
```
|
||||
|
||||
## Assigning Sets
|
||||
|
||||
- **User memberships**: change the `capability_set_id` column (via future admin APIs or direct SQL) to reassign a user. The authentication pipeline will enforce the new capabilities automatically.
|
||||
- **API tokens**: `POST /api/profile/api-tokens` requires a `capability_set_id`. Tokens are bound to the selected set; raw capability arrays are no longer accepted.
|
||||
|
||||
## Guard Coverage
|
||||
|
||||
The `RequireCapabilitiesLayer` middleware wraps all protected routers (documents, folders, tags, correspondents, profile, capability sets, assets). Requests missing the necessary capability now terminate with a 403 containing `missing_capability` details.
|
||||
|
||||
Integration tests in `backend/tests/capability_guards_flow.rs` ensure read-only users cannot upload or manage capability sets, and WebDAV tokens without `webdav:read` are rejected (`backend/tests/api_tokens_flow.rs`).
|
||||
Reference in New Issue
Block a user