from functools import lru_cache from fastapi import Depends, HTTPException, Request, status from fastapi.security import HTTPAuthorizationCredentials, HTTPBearer from app.core.config import get_settings from app.core.contracts import RequestContext from app.core.security import JwtAuthenticator from app.service.identity_service import IdentityService _bearer = HTTPBearer(auto_error=False) @lru_cache(maxsize=1) def _authenticator() -> JwtAuthenticator: return JwtAuthenticator(get_settings()) async def build_request_context( request: Request, credentials: HTTPAuthorizationCredentials | None = Depends(_bearer), # noqa: B008 ) -> RequestContext: if credentials is None or credentials.scheme.lower() != "bearer": raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Unauthorized") try: context = _authenticator().authenticate(credentials.credentials) context = await IdentityService().resolve(context) except Exception as exc: from app.core.errors import UnauthorizedAgentError if isinstance(exc, UnauthorizedAgentError): raise HTTPException(status_code=401, detail="Unauthorized") from exc raise request.state.request_context = context return context