## Summary - Add `is_admin` column to users table with Alembic migration and a `require_admin` FastAPI dependency that protects all admin-facing write endpoints (games, pokemon, evolutions, bosses, routes CRUD) - Expose admin status to frontend via user API and update AuthContext to fetch/store `isAdmin` after login - Make navigation menu auth-aware (different links for logged-out, logged-in, and admin users) and protect frontend routes with `ProtectedRoute` and `AdminRoute` components, preserving deep-linking through redirects - Fix test reliability: `drop_all` before `create_all` to clear stale PostgreSQL enums from interrupted test runs - Fix test auth: add `admin_client` fixture and use valid UUID for mock user so tests pass with new admin-protected endpoints ## Test plan - [x] All 252 backend tests pass - [ ] Verify non-admin users cannot access admin write endpoints (games, pokemon, evolutions, bosses CRUD) - [ ] Verify admin users can access admin endpoints normally - [ ] Verify navigation shows correct links for logged-out, logged-in, and admin states - [ ] Verify `/admin/*` routes redirect non-admin users with a toast - [ ] Verify `/runs/new` and `/genlockes/new` redirect unauthenticated users to login, then back after auth 🤖 Generated with [Claude Code](https://claude.com/claude-code) Reviewed-on: #67 Co-authored-by: Julian Tabel <juliantabel.jt@gmail.com> Co-committed-by: Julian Tabel <juliantabel.jt@gmail.com>
2.1 KiB
2.1 KiB
title, status, type, priority, created_at, updated_at, parent, blocked_by
| title | status | type | priority | created_at | updated_at | parent | blocked_by | |
|---|---|---|---|---|---|---|---|---|
| Add require_admin dependency and protect admin endpoints | completed | task | normal | 2026-03-21T10:06:19Z | 2026-03-21T10:15:14Z | nuzlocke-tracker-ce4o |
|
Add a require_admin FastAPI dependency that checks the is_admin column on the users table. Apply it to all admin-facing API endpoints (games CRUD, pokemon CRUD, evolutions CRUD, bosses CRUD, route CRUD).
Checklist
- Add
require_admindependency inbackend/src/app/core/auth.pythat:- Requires authentication (reuses
require_auth) - Looks up the user in the
userstable byAuthUser.id - Returns 403 if
is_adminis notTrue
- Requires authentication (reuses
- Apply
require_adminto write endpoints in:games.py,pokemon.py,evolutions.py,bosses.py(all POST/PUT/PATCH/DELETE) - Keep read endpoints (GET) accessible to all authenticated users
- Add tests for 403 response when non-admin user hits admin endpoints
Files to change
backend/src/app/core/auth.py— addrequire_adminbackend/src/app/api/games.py— replacerequire_authwithrequire_adminon mutationsbackend/src/app/api/pokemon.py— samebackend/src/app/api/evolutions.py— samebackend/src/app/api/bosses.py— same
Summary of Changes
Added require_admin FastAPI dependency to backend/src/app/core/auth.py:
- Depends on
require_auth(returns 401 if not authenticated) - Looks up user in
userstable by UUID - Returns 403 if user not found or
is_adminis not True
Applied require_admin to all admin-facing write endpoints:
games.py: POST/PUT/DELETE for games and routespokemon.py: POST/PUT/DELETE for pokemon and route encountersevolutions.py: POST/PUT/DELETE for evolutionsbosses.py: POST/PUT/DELETE for game-scoped boss operations (run-scoped endpoints kept withrequire_auth)
Added tests in test_auth.py:
- Unit tests for
require_admin(admin user, non-admin user, user not in DB) - Integration tests for admin endpoint access (403 for non-admin, 201 for admin)