Files
mousehold/apps/api/mousehold_api/routers/auth.py
2026-06-28 13:48:15 +02:00

74 lines
2.3 KiB
Python

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}