fix: gate admin user-management routes with adminMiddleware and add route-wiring regression tests#87
Conversation
|
Lost in the diff? Review this PR in Change Stack to follow the change map from intent to exact ranges. 📝 WalkthroughWalkthroughThe PR extracts the server's HTTP route wiring from ChangesRoute Wiring Refactoring and Middleware Testing
Estimated code review effort🎯 2 (Simple) | ⏱️ ~12 minutes Possibly related issues
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
🧹 Nitpick comments (1)
route_wiring_test.go (1)
88-106: ⚡ Quick winDeduplicate the admin route matrix to prevent coverage drift.
Both tests carry separate copies of the same 14 routes. A shared table keeps positive/negative-path coverage locked together when routes change.
♻️ Proposed refactor
+type adminRouteCase struct { + method string + path string +} + +var adminRouteCases = []adminRouteCase{ + {"GET", "/api/v1/admin/status"}, + {"GET", "/api/v1/admin/vehicles"}, + {"GET", "/api/v1/admin/vehicles/bus-1"}, + {"POST", "/api/v1/admin/vehicles"}, + {"DELETE", "/api/v1/admin/vehicles/bus-1"}, + {"GET", "/api/v1/admin/users"}, + {"GET", "/api/v1/admin/users/1"}, + {"POST", "/api/v1/admin/users"}, + {"PUT", "/api/v1/admin/users/1"}, + {"DELETE", "/api/v1/admin/users/1"}, + {"POST", "/api/v1/admin/assignments"}, + {"DELETE", "/api/v1/admin/users/1/vehicles/bus-1"}, + {"GET", "/api/v1/admin/users/1/vehicles"}, + {"GET", "/api/v1/admin/vehicles/bus-1/users"}, +} + func TestAdminRoutes_DriverTokenRejected(t *testing.T) { @@ - tests := []struct { - method string - path string - }{ - ... - } - - for _, tc := range tests { + for _, tc := range adminRouteCases { t.Run(tc.method+" "+tc.path, func(t *testing.T) { @@ func TestAdminRoutes_AdminTokenAllowed(t *testing.T) { @@ - tests := []struct { - method string - path string - }{ - ... - } - - for _, tc := range tests { + for _, tc := range adminRouteCases { t.Run(tc.method+" "+tc.path, func(t *testing.T) {Also applies to: 139-157
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@route_wiring_test.go` around lines 88 - 106, The admin route table is duplicated; extract the list into a single shared variable (e.g., adminRoutes or adminRouteMatrix) and replace both local copies (the tests variable defined around the shown block and the duplicate at lines ~139-157) to reference that single slice so coverage stays in sync when routes change; update any test functions that currently declare the local tests slice to iterate over adminRoutes instead.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@route_wiring_test.go`:
- Around line 88-106: The admin route table is duplicated; extract the list into
a single shared variable (e.g., adminRoutes or adminRouteMatrix) and replace
both local copies (the tests variable defined around the shown block and the
duplicate at lines ~139-157) to reference that single slice so coverage stays in
sync when routes change; update any test functions that currently declare the
local tests slice to iterate over adminRoutes instead.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 7c43edeb-9862-4bd4-b5fa-58b099780cef
📒 Files selected for processing (2)
main.goroute_wiring_test.go
fixes : #85
Summary
Fixes a privilege-escalation bug (#82) where the five
/api/v1/admin/users/*routes were wrapped withauthMiddlewareonly — any authenticated driver could list, create, update, and deactivate user accounts. Adds the route-wiring regression tests requested in #85 so the same gap can never silently reappear.What changed
Modified (1)
main.go— Extracted all route registration intonewMux(store, tracker, rateLimiter, jwtSecret, startTime)so tests can build the real mux without a live database. AddedadminMiddlewareto the five user-management routes that were missing it.New (1)
route_wiring_test.go— Two table-driven tests over all 14/api/v1/admin/*routes:TestAdminRoutes_DriverTokenRejected— a valid driver JWT must receive403 + "admin access required"on every admin route.TestAdminRoutes_AdminTokenAllowed— a valid admin JWT must not be blocked by either middleware layer on any admin route.Design decisions
Extract
newMuxinstead of duplicating route registration in tests. Copying the route table into the test would let the test pass even whenmain.go's wiring is wrong. By calling the samenewMuxfunction, the test exercises the actual production wiring — a missingadminMiddlewareinmain.gofails the test directly.noopStorewith zero-value stubs. The driver-rejection tests never reach handler code (middleware short-circuits first), so store methods are never called. For the admin-allowed tests, stubs return safe zero values — enough to confirm middleware passes the request through without needing a real database.Both negative and positive paths. Testing only that drivers get
403is not enough — a double-wrapped or misconfigured middleware could also block admins.TestAdminRoutes_AdminTokenAllowedguards against that.Testing
go fmt ./...— cleango vet ./...— cleango test ./...— all pass (28 new subtests across 2 test functions)Summary by CodeRabbit
Tests
Refactor