"""GET /me — отдаёт текущего пользователя и его RBAC-scope. Caddy basic_auth пропускает `X-Authenticated-User: ` через `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