"""Dashboard login — minimal cookie-session auth. Credentials come from `core_config.json` → `auth.{username,password}`. The session is signed by Starlette's SessionMiddleware (stateless cookie). """ from __future__ import annotations from fastapi import APIRouter, HTTPException, Request from fastapi.responses import HTMLResponse, RedirectResponse from pydantic import BaseModel from Project.Sanad.config import BASE_DIR from Project.Sanad.core.config_loader import section as _cfg_section from Project.Sanad.core.logger import get_logger router = APIRouter() log = get_logger("dashboard.auth") _AUTH_CFG = _cfg_section("core", "auth") or {} USERNAME = _AUTH_CFG.get("username", "admin") PASSWORD = _AUTH_CFG.get("password", "admin") LOGIN_PAGE = BASE_DIR / "dashboard" / "static" / "login.html" def is_authed(request: Request) -> bool: return bool(request.session.get("user")) class LoginPayload(BaseModel): username: str password: str @router.get("/login", include_in_schema=False) async def login_page(request: Request): if is_authed(request): return RedirectResponse("/", status_code=303) if LOGIN_PAGE.exists(): return HTMLResponse(LOGIN_PAGE.read_text(encoding="utf-8")) return HTMLResponse("

Login page missing

", status_code=500) @router.post("/api/auth/login") async def login(request: Request, payload: LoginPayload): if payload.username == USERNAME and payload.password == PASSWORD: request.session["user"] = payload.username log.info("login OK: %s", payload.username) return {"ok": True, "user": payload.username} log.warning("login FAILED: %s", payload.username) raise HTTPException(401, "Invalid username or password") @router.post("/api/auth/logout") async def logout(request: Request): user = request.session.pop("user", None) log.info("logout: %s", user) return {"ok": True} @router.get("/api/auth/me") async def whoami(request: Request): return {"authenticated": is_authed(request), "user": request.session.get("user")}