app.routes.auth
Auth Routing Module.
Provides routing for user authentication, registration, and user management.
Combines auto-generated routers from fastapi-users with custom admin routes.
1""" 2Auth Routing Module. 3 4Provides routing for user authentication, registration, and user management. 5Combines auto-generated routers from `fastapi-users` with custom admin routes. 6""" 7 8import uuid 9 10from fastapi import APIRouter, Depends, HTTPException, status 11from fastapi.responses import Response 12 13from app.models.user import User 14from app.schemas.user import AdminUserUpdate, UserCreate, UserRead 15from app.services import avatar_service 16from app.services.auth import ( 17 auth_backend, 18 current_active_user, 19 fastapi_users, 20 require_admin, 21) 22from app.services.user_manager import UserManager, get_user_manager 23 24router = APIRouter(prefix="/api/auth", tags=["auth"]) 25 26# Mount standard fastapi-users login/logout routes 27router.include_router(fastapi_users.get_auth_router(auth_backend)) 28 29# Mount standard fastapi-users registration route 30router.include_router(fastapi_users.get_register_router(UserRead, UserCreate)) 31 32 33@router.get("/me", response_model=UserRead) 34async def get_me(user: User = Depends(current_active_user)): 35 """ 36 Returns the current authenticated user's profile based on their token. 37 """ 38 return user 39 40 41@router.patch("/users/{id}", response_model=UserRead) 42async def update_user_admin( 43 id: uuid.UUID, 44 user_update: AdminUserUpdate, 45 admin_user: User = Depends(require_admin), 46 user_manager: UserManager = Depends(get_user_manager), 47): 48 """ 49 Admin-only route to update a user's role or deactivate their account. 50 """ 51 target_user = await user_manager.admin_update_user( 52 id, 53 role=user_update.role, 54 is_active=user_update.is_active, 55 ) 56 if not target_user: 57 raise HTTPException( 58 status_code=status.HTTP_404_NOT_FOUND, detail="User not found" 59 ) 60 61 return target_user 62 63 64@router.get("/avatar") 65async def get_avatar(user: User = Depends(current_active_user)): 66 """ 67 Returns a deterministic SVG avatar for the given user ID. 68 69 The image is generated on the fly but is identical for the same user_id, 70 so it can be aggressively cached by the browser. 71 """ 72 svg = avatar_service.generate(seed=str(user.id)) 73 return Response( 74 content=svg, 75 media_type="image/svg+xml", 76 headers={"Cache-Control": "public, max-age=31536000, immutable"}, 77 )
router =
<fastapi.routing.APIRouter object>
@router.get('/me', response_model=UserRead)
async def
get_me( user: app.models.User = Depends(dependency=<function Authenticator.current_user.<locals>.current_user_dependency>, use_cache=True, scope=None)):
34@router.get("/me", response_model=UserRead) 35async def get_me(user: User = Depends(current_active_user)): 36 """ 37 Returns the current authenticated user's profile based on their token. 38 """ 39 return user
Returns the current authenticated user's profile based on their token.
@router.patch('/users/{id}', response_model=UserRead)
async def
update_user_admin( id: uuid.UUID, user_update: app.schemas.user.AdminUserUpdate, admin_user: app.models.User = Depends(dependency=<function require_admin>, use_cache=True, scope=None), user_manager: app.services.user_manager.UserManager = Depends(dependency=<function get_user_manager>, use_cache=True, scope=None)):
42@router.patch("/users/{id}", response_model=UserRead) 43async def update_user_admin( 44 id: uuid.UUID, 45 user_update: AdminUserUpdate, 46 admin_user: User = Depends(require_admin), 47 user_manager: UserManager = Depends(get_user_manager), 48): 49 """ 50 Admin-only route to update a user's role or deactivate their account. 51 """ 52 target_user = await user_manager.admin_update_user( 53 id, 54 role=user_update.role, 55 is_active=user_update.is_active, 56 ) 57 if not target_user: 58 raise HTTPException( 59 status_code=status.HTTP_404_NOT_FOUND, detail="User not found" 60 ) 61 62 return target_user
Admin-only route to update a user's role or deactivate their account.
@router.get('/avatar')
async def
get_avatar( user: app.models.User = Depends(dependency=<function Authenticator.current_user.<locals>.current_user_dependency>, use_cache=True, scope=None)):
65@router.get("/avatar") 66async def get_avatar(user: User = Depends(current_active_user)): 67 """ 68 Returns a deterministic SVG avatar for the given user ID. 69 70 The image is generated on the fly but is identical for the same user_id, 71 so it can be aggressively cached by the browser. 72 """ 73 svg = avatar_service.generate(seed=str(user.id)) 74 return Response( 75 content=svg, 76 media_type="image/svg+xml", 77 headers={"Cache-Control": "public, max-age=31536000, immutable"}, 78 )
Returns a deterministic SVG avatar for the given user ID.
The image is generated on the fly but is identical for the same user_id, so it can be aggressively cached by the browser.