All checks were successful
Deploy Trade-In / changes (push) Successful in 5s
Deploy / changes (push) Successful in 6s
Deploy Trade-In / build-frontend (push) Successful in 27s
Deploy / build-frontend (push) Successful in 30s
Deploy Trade-In / build-backend (push) Successful in 1m8s
Deploy Trade-In / deploy (push) Successful in 45s
Deploy / build-backend (push) Successful in 2m40s
Deploy / build-worker (push) Successful in 3m20s
Deploy / deploy (push) Successful in 1m16s
Backend RBAC + Caddy header_up. Closes part of #fixes-rbac-pra.
48 lines
1.7 KiB
Python
48 lines
1.7 KiB
Python
"""GET /me — отдаёт текущего пользователя и его RBAC-scope.
|
||
|
||
Caddy basic_auth пропускает `X-Authenticated-User: <username>` через
|
||
`header_up` в каждом reverse_proxy. Frontend дёргает /api/v1/me чтобы
|
||
понять кому что показывать (admin-only кнопки, etc).
|
||
|
||
Failure modes:
|
||
- header отсутствует → 401 (некорректная Caddy-конфигурация или прямой
|
||
запрос мимо basic_auth, не должно происходить в проде)
|
||
- header есть, но username не в roles.yaml → 403 (Caddy basic_auth знает
|
||
юзера, а RBAC config — нет; конфигурации рассинхронизированы)
|
||
"""
|
||
|
||
from __future__ import annotations
|
||
|
||
import logging
|
||
from typing import Annotated
|
||
|
||
from fastapi import APIRouter, Header, HTTPException
|
||
|
||
from app.core.auth import UserScope, get_user_scope
|
||
|
||
logger = logging.getLogger(__name__)
|
||
|
||
router = APIRouter()
|
||
|
||
|
||
@router.get("/me")
|
||
async def me(
|
||
x_authenticated_user: Annotated[str | None, Header(alias="X-Authenticated-User")] = None,
|
||
) -> UserScope:
|
||
"""Return the current user's RBAC scope (role + allowed/deny paths)."""
|
||
if not x_authenticated_user:
|
||
raise HTTPException(
|
||
status_code=401,
|
||
detail="no authenticated user (Caddy basic_auth required)",
|
||
)
|
||
try:
|
||
return get_user_scope(x_authenticated_user)
|
||
except KeyError:
|
||
logger.warning(
|
||
"user %r authenticated via Caddy but missing from roles.yaml",
|
||
x_authenticated_user,
|
||
)
|
||
raise HTTPException(
|
||
status_code=403,
|
||
detail="user not in roles config",
|
||
) from None
|