Repository navigation
Commit 4c62718
authored
* feat(api/auth): flip mutating-route gate to handler-level requirePermission (PR-A of #660)
Every mutating route in the plans, purchases, planned-purchases, and
ri-exchange groups was previously locked at AuthAdmin at the router
level, which meant the per-handler requirePermission(action, resource)
call was unreachable for non-admin users. This PR-A fix:
1. Router (internal/api/router.go): flips the Auth field on all
mutating routes that already have a handler-level requirePermission
call from AuthAdmin to AuthUser. The router-level gate now only
asserts "must be signed in" (401 for anonymous callers); the real
permission gate fires inside each handler.
Routes flipped:
- POST /api/plans (create:plans)
- POST /api/plans/{id}/purchases (create:plans)
- PUT /api/plans/{id}/accounts (update:plans)
- PUT /api/plans/{id} (update:plans)
- PATCH /api/plans/{id} (update:plans)
- DELETE /api/plans/{id} (delete:plans)
- POST /api/purchases/execute (execute:purchases)
- POST /api/purchases/planned/{id}/pause (update:purchases)
- POST /api/purchases/planned/{id}/resume (update:purchases)
- POST /api/purchases/planned/{id}/run (execute:purchases)
- DELETE /api/purchases/planned/{id} (delete:purchases)
- POST /api/ri-exchange/quote (view:purchases)
- POST /api/ri-exchange/execute (execute:purchases)
- PUT /api/ri-exchange/config (update:config)
2. Defaults (internal/auth/types.go): adds delete:plans and
update:purchases to DefaultUserPermissions so regular users get
the two most common operator verbs by default, per the design
comment on #660.
PR-B (execute:purchases default grant) and PR-C (frontend) are deferred
per the design comment.
Refs #660 (PR-A; PR-B and PR-C deferred per design comment)
* test(frontend/perms): update permission test fixtures for new user defaults
Refs #660 (PR-A). Updates 4 test assertions in permissions.test.ts and
plans-permissions.test.ts to reflect the 2 new entries in
DefaultUserPermissions (delete:plans and update:purchases).
- getRolePermissions user-role test: expected array 9 -> 11 entries
- canAccess user-role denied test: delete:plans now toBe(true), not false
- plans-permissions user-role card test: delete-plan button now shown
- plans-permissions user-role row test: disable button now shown
* test(api): tighten assertNotForbidden to require positive post-gate signal
Register t.Cleanup(func(){ m.AssertExpectations(t) }) in both authForUserWith
and authForAdmin so testify verifies every On() expectation was actually invoked.
This catches cases where the permission gate is bypassed before HasPermissionAPI
runs: the granted-path sub-test would have passed assertNotForbidden even if
the gate were never reached.
Also removes two incorrect GetAllowedAccountsAPI and one GetExecutionByID
expectation from admin-bypass sub-tests. Admin sessions short-circuit in
getAllowedAccounts (role == "admin" -> nil, nil) so IsUnrestrictedAccess returns
true and requirePlanAccess/requireExecutionAccess return nil immediately without
calling GetAllowedAccountsAPI or GetExecutionByID. Registering those expectations
with AssertExpectations enforced correctly surfaced them as bugs.
1 parent cb735f2 commit 4c62718
9 files changed
Lines changed: 447 additions & 50 deletions
File tree
- frontend/src
- __tests__
- internal
- api
- auth
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
40 | 40 | | |
41 | 41 | | |
42 | 42 | | |
| 43 | + | |
| 44 | + | |
43 | 45 | | |
44 | 46 | | |
45 | 47 | | |
| |||
91 | 93 | | |
92 | 94 | | |
93 | 95 | | |
94 | | - | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
95 | 99 | | |
96 | 100 | | |
97 | 101 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
140 | 140 | | |
141 | 141 | | |
142 | 142 | | |
143 | | - | |
| 143 | + | |
144 | 144 | | |
145 | 145 | | |
146 | 146 | | |
147 | 147 | | |
148 | 148 | | |
149 | 149 | | |
150 | | - | |
| 150 | + | |
151 | 151 | | |
152 | 152 | | |
153 | | - | |
| 153 | + | |
154 | 154 | | |
155 | 155 | | |
156 | 156 | | |
157 | 157 | | |
158 | 158 | | |
159 | 159 | | |
160 | | - | |
| 160 | + | |
161 | 161 | | |
162 | 162 | | |
163 | 163 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
22 | 22 | | |
23 | 23 | | |
24 | 24 | | |
| 25 | + | |
25 | 26 | | |
26 | 27 | | |
| 28 | + | |
27 | 29 | | |
28 | 30 | | |
29 | 31 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
140 | 140 | | |
141 | 141 | | |
142 | 142 | | |
143 | | - | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
144 | 149 | | |
145 | | - | |
| 150 | + | |
146 | 151 | | |
147 | | - | |
| 152 | + | |
148 | 153 | | |
149 | | - | |
| 154 | + | |
150 | 155 | | |
151 | | - | |
152 | | - | |
153 | | - | |
154 | | - | |
155 | | - | |
156 | | - | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
| 160 | + | |
| 161 | + | |
| 162 | + | |
| 163 | + | |
| 164 | + | |
157 | 165 | | |
158 | 166 | | |
159 | 167 | | |
| |||
170 | 178 | | |
171 | 179 | | |
172 | 180 | | |
173 | | - | |
174 | | - | |
175 | | - | |
| 181 | + | |
| 182 | + | |
| 183 | + | |
176 | 184 | | |
177 | | - | |
178 | | - | |
179 | | - | |
180 | | - | |
| 185 | + | |
| 186 | + | |
| 187 | + | |
| 188 | + | |
181 | 189 | | |
182 | 190 | | |
183 | 191 | | |
| |||
255 | 263 | | |
256 | 264 | | |
257 | 265 | | |
258 | | - | |
259 | | - | |
| 266 | + | |
| 267 | + | |
| 268 | + | |
| 269 | + | |
260 | 270 | | |
261 | 271 | | |
262 | 272 | | |
263 | 273 | | |
264 | 274 | | |
265 | | - | |
266 | | - | |
| 275 | + | |
| 276 | + | |
267 | 277 | | |
268 | | - | |
| 278 | + | |
269 | 279 | | |
270 | 280 | | |
271 | 281 | | |
| |||
0 commit comments