from __future__ import annotations from datetime import UTC, datetime from fastapi import APIRouter, Depends, HTTPException, Response from sqlalchemy.orm import Session from .. import models from ..auth import ( clear_session_cookie, create_local_session, get_optional_local_session, set_session_cookie, ) from ..db import get_session from ..schemas import AuthSessionRead, HouseholdRead, LocalLoginRequest, LocalSessionRead, UserRead router = APIRouter(tags=["auth"]) def _auth_session_read( session: Session, local_session: models.LocalSession, ) -> AuthSessionRead: user = session.get(models.User, local_session.user_id) household = session.get(models.Household, local_session.household_id) if not user or not household: raise HTTPException(status_code=404, detail="Session user or household not found") return AuthSessionRead( session=LocalSessionRead.model_validate(local_session), user=UserRead.model_validate(user), household=HouseholdRead.model_validate(household), ) @router.post("/auth/login", response_model=AuthSessionRead) def local_login( payload: LocalLoginRequest, response: Response, session: Session = Depends(get_session), ) -> AuthSessionRead: user = session.get(models.User, payload.user_id) if not user: raise HTTPException(status_code=404, detail="User not found") local_session, token = create_local_session(session, user) session.commit() session.refresh(local_session) set_session_cookie(response, token) return _auth_session_read(session, local_session) @router.get("/auth/me", response_model=AuthSessionRead | None) def current_local_session( local_session: models.LocalSession | None = Depends(get_optional_local_session), session: Session = Depends(get_session), ) -> AuthSessionRead | None: if not local_session: return None return _auth_session_read(session, local_session) @router.post("/auth/logout") def logout( response: Response, local_session: models.LocalSession | None = Depends(get_optional_local_session), session: Session = Depends(get_session), ) -> dict[str, bool]: if local_session: local_session.revoked_at = datetime.now(UTC) session.add(local_session) session.commit() clear_session_cookie(response) return {"logged_out": True}