from fastapi import APIRouter, Depends, Form, Request from sqlalchemy.orm import Session from app.auth import require_auth from app.db import get_session 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): return templates.TemplateResponse(request, "admin.html", {"error": None, "success": None}) @router.post("/admin/passwort", dependencies=[Depends(gui_session)]) def admin_change_password( request: Request, alt: str = Form(...), neu: str = Form(...), neu2: str = Form(...), ): # UX-Regel: das Formular selbst bleibt immer sichtbar/bedienbar; Fehler # werden inline auf derselben Seite gemeldet statt still zu verwerfen. if len(neu) < 8: return templates.TemplateResponse(request, "admin.html", { "error": "Das neue Passwort muss mindestens 8 Zeichen lang sein.", "success": None, }, status_code=400) if neu != neu2: return templates.TemplateResponse(request, "admin.html", { "error": "Die Wiederholung stimmt nicht mit dem neuen Passwort überein.", "success": None, }, status_code=400) try: change_password(alt, neu) except (ValueError, RuntimeError) as exc: return templates.TemplateResponse(request, "admin.html", { "error": str(exc), "success": None, }, 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.", }) @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)}