Commit 80cbeec
committed
Merge torrust#856: feat!: refactor roles & permissions system (ADR-T-008)
1998ccb refactor(auth): post-review hardening for ADR-T-008 (Peer Cat)
c461db0 feat(auth): add Moderator role, exhaustive Admin grants, and hardened diagnostics (Peer Cat)
737c4c2 feat: ADR-T-008 Phase 4 — E2E tests for permissions system (Peer Cat)
44ccd66 feat: implement ADR-T-008 Phase 3 — resource-level authorization (Peer Cat)
58c23cf refactor(auth): enforce permissions at HTTP boundary with RequirePermission<A> (Peer Cat)
70701db refactor(auth)!: replace Casbin with native PermissionMatrix (ADR-T-008) (Peer Cat)
Pull request description:
## Summary
Replace the Casbin-based authorization system with a native Rust permission model built on exhaustive `Role` and `Action` enums. Adding a new role or action without deciding its permission is now a **compile error**, eliminating silent policy gaps.
### Motivation
The prior system had three intertwined authorization mechanisms (Casbin RBAC, a bare `administrator` boolean in the DB, and scattered inline ownership checks). This made the permission surface hard to audit, impossible to extend with intermediate roles, and left resource-level authorization as ad-hoc string comparisons sprinkled through service methods.
### What changed
**Phase 1 — Native `PermissionMatrix`** (`refactor(auth)!`)
- Replace `casbin` crate with a `HashSet<(Role, Action)>` table populated by exhaustive `match` arms.
- Introduce `Role` enum (`Guest`, `Registered`, `Admin`) with `Display`/`FromStr`/serde support.
- Rename `ACTION` → `Action` (Rust conventions).
- Migrate DB from `administrator: bool` to `role: String`; backfill existing rows.
- Remove the `unstable.auth.casbin` config section entirely.
**Phase 2 — `RequirePermission<A>` extractor**
- Generic Axum extractor resolves identity from the bearer token, looks up `Role` in the DB, and checks the matrix — all before the handler runs.
- `ActionMarker` trait + `action_markers!` macro bind each handler to an `Action` at the type level (compile-time enforcement).
- Remove `authorization::Service` and strip auth concerns from service methods.
- Delete the old `ExtractOptionalLoggedInUser` / `ExtractLoggedInUser` extractors.
**Phase 3 — Resource-level authorization & permissions discovery**
- `can_on_resource()` method: Admin bypasses ownership; other roles must be the resource owner.
- `GET /v1/user/me/permissions` endpoint returns the caller's resolved role and allowed actions.
- `[permissions.overrides]` TOML config — operators can grant/deny `(role, action)` tuples without touching Rust source.
- Drop the legacy `administrator` column (MySQL + SQLite migrations).
- Remove `admin: bool` from all API responses.
**Phase 4 — E2E tests**
- Five E2E tests covering permission discovery (admin / registered / guest) and TOML override propagation (grant + deny paths).
- `TestEnv::start_with()` config-mutator support for isolated test environments.
**Phase 5 — Moderator role & hardening**
- Add `Role::Moderator` with a scoped permission set (tags + `DeleteTorrent`).
- Replace `Admin => true` wildcard with exhaustive action match — new actions are a compile error until granted per-role.
- Emit `warn!` when TOML overrides grant high-risk actions to non-admin roles.
- Improved logging in registration and `grant_admin_role` paths.
### Additional cleanup
- Update all API doc examples to RS256 JWT format (post ADR-T-007).
- Fix several README typos and stale "Torrust Tracker" → "Torrust Index" references.
- AGENTS.md: add "Counts and Numbers" guideline.
### Breaking changes
- `administrator: bool` replaced by `role: String` in API responses.
- The `casbin` configuration section is removed.
- `ACTION` enum renamed to `Action`.
### Stats
~64 files changed, ~3k insertions, ~1k deletions across source, tests, migrations, docs, and the ADR.
ACKs for top commit:
peer-cat:
ACK 1998ccb
da2ce7:
ACK 1998ccb
Tree-SHA512: 8289b69bae573e150537e453d859131968d31b8117468e7f18b36d6be0cc0ae2c7fe2ec13b17f291098ec593dde5b5c75804cb3b8b68249644c350c920ae4bfb66 files changed
Lines changed: 3347 additions & 1147 deletions
File tree
- adr
- migrations
- mysql
- sqlite3
- src
- config/v2
- console/commands/seeder
- databases
- models
- services
- tests
- services
- web
- upgrades/from_v1_0_0_to_v2_0_0/databases
- web/api
- client/v1/contexts/user
- server/v1
- contexts
- about
- category
- proxy
- settings
- tag
- torrent
- user
- extractors
- tests
- common
- contexts/user
- e2e
- web/api/v1/contexts
- torrent
- user
- environments
- upgrades/from_v1_0_0_to_v2_0_0
- transferrer_testers
Some content is hidden
Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
22 | 22 | | |
23 | 23 | | |
24 | 24 | | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
25 | 31 | | |
26 | 32 | | |
27 | 33 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
9 | 9 | | |
10 | 10 | | |
11 | 11 | | |
| 12 | + | |
12 | 13 | | |
13 | 14 | | |
14 | 15 | | |
15 | 16 | | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
16 | 40 | | |
17 | 41 | | |
18 | 42 | | |
| |||
52 | 76 | | |
53 | 77 | | |
54 | 78 | | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
55 | 98 | | |
56 | 99 | | |
57 | 100 | | |
| |||
66 | 109 | | |
67 | 110 | | |
68 | 111 | | |
69 | | - | |
70 | | - | |
71 | 112 | | |
72 | 113 | | |
73 | 114 | | |
| |||
80 | 121 | | |
81 | 122 | | |
82 | 123 | | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
83 | 129 | | |
84 | 130 | | |
85 | 131 | | |
86 | 132 | | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
87 | 144 | | |
88 | 145 | | |
89 | 146 | | |
| |||
93 | 150 | | |
94 | 151 | | |
95 | 152 | | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
96 | 160 | | |
97 | 161 | | |
98 | 162 | | |
| |||
0 commit comments