from fastapi import APIRouter, Depends, Form, Request from sqlalchemy import select from sqlalchemy.orm import Session from app.auth import require_auth from app.db import get_session from app.models.tables import Category from app.routers.gui import gui_session, templates from app.services.admin import apply_rules_retroactively, change_password router = APIRouter() @router.get("/admin", dependencies=[Depends(gui_session)]) def admin_page(request: Request, session: Session = Depends(get_session)): return templates.TemplateResponse(request, "admin.html", { "error": None, "success": None, "categories": session.execute(select(Category)).scalars().all(), }) @router.post("/admin/passwort", dependencies=[Depends(gui_session)]) def admin_change_password( request: Request, alt: str = Form(...), neu: str = Form(...), neu2: str = Form(...), session: Session = Depends(get_session), ): categories = session.execute(select(Category)).scalars().all() # UX-Regel: das Formular selbst bleibt immer sichtbar/bedienbar; Fehler # werden inline auf derselben Seite gemeldet statt still zu verwerfen. # Der Kategorien-Abschnitt bleibt aus demselben Grund in JEDEM Render-Pfad # (Fehler wie Erfolg) im Kontext, statt nur bei der GET-Route. if len(neu) < 8: return templates.TemplateResponse(request, "admin.html", { "error": "Das neue Passwort muss mindestens 8 Zeichen lang sein.", "success": None, "categories": categories, }, status_code=400) if neu != neu2: return templates.TemplateResponse(request, "admin.html", { "error": "Die Wiederholung stimmt nicht mit dem neuen Passwort überein.", "success": None, "categories": categories, }, status_code=400) try: change_password(alt, neu) except (ValueError, RuntimeError) as exc: return templates.TemplateResponse(request, "admin.html", { "error": str(exc), "success": None, "categories": categories, }, status_code=400) return templates.TemplateResponse(request, "admin.html", { "error": None, "success": "Passwort erfolgreich geändert (gilt für GUI und Grafana). " "Bestehende Sitzungen bleiben angemeldet.", "categories": categories, }) @router.post("/api/category-rules/apply", dependencies=[Depends(require_auth)]) def apply_category_rules(session: Session = Depends(get_session)): return {"categorized": apply_rules_retroactively(session)}