import uuid from typing import Annotated from fastapi import Cookie, Depends, HTTPException, status from sqlalchemy.ext.asyncio import AsyncSession from src.auth.session import decode_session_cookie from src.config import Settings from src.database import SessionLocal from src.models.project import Project from src.models.user import User async def get_db_session(): async with SessionLocal() as session: yield session async def get_current_user_id( session_cookie: Annotated[str | None, Cookie(alias="session")] = None, ) -> uuid.UUID: if not session_cookie: raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="missing session") settings = Settings() try: payload = decode_session_cookie(settings=settings, cookie_value=session_cookie) return uuid.UUID(str(payload["user_id"])) except ValueError: raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="invalid session") async def get_current_user( session_cookie: Annotated[str | None, Cookie(alias="session")] = None, db_session: AsyncSession = Depends(get_db_session), ) -> User: if not session_cookie: raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="missing session") settings = Settings() try: payload = decode_session_cookie(settings=settings, cookie_value=session_cookie) user_id = uuid.UUID(str(payload["user_id"])) except ValueError: raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="invalid session") user = await db_session.get(User, user_id) if user is None: raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="user not found") return user async def _get_user(session: AsyncSession, user_id: uuid.UUID) -> User: """Fetch a user by ID or raise 401 if not found.""" user = await session.get(User, user_id) if user is None: raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="user not found") return user async def _get_owned_project( project_id: uuid.UUID, user_id: uuid.UUID, session: AsyncSession, ) -> "Project": """Fetch a project and verify ownership. Args: project_id: UUID of the project. user_id: ID of the authenticated user. session: Database session. Returns: The project if found and owned by the user. Raises: HTTPException: 404 if project not found, 403 if user is not the owner. """ from src.models.project import Project project = await session.get(Project, project_id) if project is None: raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="project not found") if project.owner_id != user_id: raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail="not project owner") return project