"""Authentication routes: login page, login submit, logout.""" from fastapi import APIRouter, Form, Request, status from fastapi.responses import HTMLResponse, RedirectResponse import db from auth import ( clear_session_cookie, current_user, issue_session_cookie, rate_limit_login, verify_login, ) from common import client_ip, templates router = APIRouter() @router.get("/login", response_class=HTMLResponse) def login_form(request: Request, error: str | None = None): if current_user(request): return RedirectResponse("/", status_code=303) return templates.TemplateResponse("login.html", {"request": request, "error": error}) @router.post("/login") def login_submit(request: Request, username: str = Form(...), password: str = Form(...)): ip = client_ip(request) if not rate_limit_login(ip): db.log_audit(username or "?", "login_rate_limited", ip=ip) db.log_error(source="web", kind="rate_limit", summary=f"login throttled for {ip}", context={"username": username or ""}) return templates.TemplateResponse( "login.html", {"request": request, "error": "Zu viele Versuche. Bitte später erneut."}, status_code=status.HTTP_429_TOO_MANY_REQUESTS, ) user = verify_login(username, password) if not user: db.log_audit(username or "?", "login_failed", ip=ip) return templates.TemplateResponse( "login.html", {"request": request, "error": "Login fehlgeschlagen."}, status_code=status.HTTP_401_UNAUTHORIZED, ) response = RedirectResponse("/", status_code=303) issue_session_cookie(response, user["id"]) db.log_audit(user["username"], "login_success", user_id=user["id"], ip=ip) return response @router.post("/logout") def logout(request: Request): u = current_user(request) response = RedirectResponse("/login", status_code=303) clear_session_cookie(response) if u: db.log_audit(u["username"], "logout", user_id=u["id"], ip=client_ip(request)) return response