"""Shared API dependencies: DB session, the authenticated user, and the mailer.""" from typing import Annotated from fastapi import Depends, HTTPException, Request, status from sqlalchemy.ext.asyncio import AsyncSession from app.core.config import get_settings from app.core.db import get_session from app.integrations.mailer.base import Mailer from app.integrations.mailer.console import ConsoleMailer from app.integrations.mailer.smtp import SMTPMailer from app.integrations.objectstore.base import ObjectStore from app.integrations.objectstore.s3 import S3ObjectStore from app.models.user import User from app.services import auth_service SessionDep = Annotated[AsyncSession, Depends(get_session)] def extract_session_token(request: Request) -> str | None: """Bearer header (API clients) takes precedence over the session cookie (browser).""" authorization = request.headers.get("authorization") if authorization and authorization.lower().startswith("bearer "): return authorization[7:].strip() return request.cookies.get(get_settings().cookie_name) async def get_current_user(request: Request, session: SessionDep) -> User: raw_token = extract_session_token(request) if raw_token is None: raise HTTPException(status.HTTP_401_UNAUTHORIZED, "authentication required") user = await auth_service.resolve_session_user(session, raw_token=raw_token) if user is None: raise HTTPException(status.HTTP_401_UNAUTHORIZED, "invalid or expired session") return user CurrentUser = Annotated[User, Depends(get_current_user)] def get_mailer() -> Mailer: settings = get_settings() if settings.mailer == "smtp" and settings.smtp_host: return SMTPMailer(settings) return ConsoleMailer() MailerDep = Annotated[Mailer, Depends(get_mailer)] def get_objectstore() -> ObjectStore: return S3ObjectStore(get_settings()) ObjectStoreDep = Annotated[ObjectStore, Depends(get_objectstore)]