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.