c2b1b7b751
- new app/api/routes/api/ package with shared require_session (401) and require_csrf (presence-only X-CSRF-Token, 403) dependencies - GET /api/config returns masked config sections; PUT /api/config reuses save_config_updates (blank secret keeps old; invalid -> 422, no write) - session-protected; PUT also CSRF-protected - register router in app/main.py; regenerate openapi/ - tests/test_api_config.py
29 lines
824 B
Python
29 lines
824 B
Python
from __future__ import annotations
|
|
|
|
from fastapi import Depends, Header, HTTPException, status
|
|
|
|
from app.dependencies import get_current_auth_session
|
|
from app.services.auth import AuthenticatedSession
|
|
|
|
|
|
def require_session(
|
|
auth: AuthenticatedSession | None = Depends(get_current_auth_session),
|
|
) -> AuthenticatedSession:
|
|
if auth is None:
|
|
raise HTTPException(
|
|
status_code=status.HTTP_401_UNAUTHORIZED,
|
|
detail="authentication required",
|
|
)
|
|
return auth
|
|
|
|
|
|
def require_csrf(
|
|
_auth: AuthenticatedSession = Depends(require_session),
|
|
x_csrf_token: str | None = Header(default=None, alias="X-CSRF-Token"),
|
|
) -> None:
|
|
if not x_csrf_token:
|
|
raise HTTPException(
|
|
status_code=status.HTTP_403_FORBIDDEN,
|
|
detail="missing CSRF token",
|
|
)
|