from __future__ import annotations from collections.abc import Generator from fastapi import Depends, HTTPException, Request, status from config.settings import Settings, get_settings from models import User from services.security import JWTSettings from services.session import ( AuthSession, SessionStrategy, SessionTokens, build_session_strategy, extract_session_tokens, ) from services.unit_of_work import UnitOfWork def get_unit_of_work() -> Generator[UnitOfWork, None, None]: """FastAPI dependency yielding a unit-of-work instance.""" with UnitOfWork() as uow: yield uow def get_application_settings() -> Settings: """Provide cached application settings instance.""" return get_settings() def get_jwt_settings() -> JWTSettings: """Provide JWT runtime configuration derived from settings.""" return get_settings().jwt_settings() def get_session_strategy( settings: Settings = Depends(get_application_settings), ) -> SessionStrategy: """Yield configured session transport strategy.""" return build_session_strategy(settings.session_settings()) def get_session_tokens( request: Request, strategy: SessionStrategy = Depends(get_session_strategy), ) -> SessionTokens: """Extract raw session tokens from the incoming request.""" existing = getattr(request.state, "auth_session", None) if isinstance(existing, AuthSession): return existing.tokens tokens = extract_session_tokens(request, strategy) request.state.auth_session = AuthSession(tokens=tokens) return tokens def get_auth_session( request: Request, tokens: SessionTokens = Depends(get_session_tokens), ) -> AuthSession: """Provide authentication session context for the current request.""" existing = getattr(request.state, "auth_session", None) if isinstance(existing, AuthSession): return existing if tokens.is_empty: session = AuthSession.anonymous() else: session = AuthSession(tokens=tokens) request.state.auth_session = session return session def get_current_user( session: AuthSession = Depends(get_auth_session), ) -> User | None: """Return the current authenticated user if present.""" return session.user def require_current_user( session: AuthSession = Depends(get_auth_session), ) -> User: """Ensure that a request is authenticated and return the user context.""" if session.user is None: raise HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, detail="Authentication required.", ) return session.user