from fastapi import APIRouter, Depends, HTTPException, status, Request from fastapi.responses import HTMLResponse, RedirectResponse from fastapi.templating import Jinja2Templates from sqlalchemy import select from sqlalchemy.ext.asyncio import AsyncSession from pydantic import BaseModel from ..database import get_db from ..models import User from ..auth import verify_password, create_token, hash_password, require_admin router = APIRouter() templates = Jinja2Templates(directory="app/templates") class LoginForm(BaseModel): username: str password: str class CreateUserForm(BaseModel): username: str password: str role: str = "user" @router.get("/login", response_class=HTMLResponse) async def login_page(request: Request): return templates.TemplateResponse("login.html", {"request": request}) @router.post("/api/login") async def login(data: LoginForm, db: AsyncSession = Depends(get_db)): result = await db.execute(select(User).where(User.username == data.username)) user = result.scalar_one_or_none() if not user or not verify_password(data.password, user.password_hash): raise HTTPException(status_code=401, detail="Forkert brugernavn eller adgangskode") token = create_token(user.username, user.role) resp = RedirectResponse(url="/", status_code=302) resp.set_cookie( key="token", value=token, httponly=True, max_age=30 * 24 * 3600, samesite="lax" ) return resp @router.post("/api/logout") async def logout(): resp = RedirectResponse(url="/login", status_code=302) resp.delete_cookie("token") return resp # --- Admin-only: user management --- @router.post("/api/admin/users") async def create_user( data: CreateUserForm, db: AsyncSession = Depends(get_db), _: User = Depends(require_admin), ): exists = await db.execute(select(User).where(User.username == data.username)) if exists.scalar_one_or_none(): raise HTTPException(status_code=400, detail="Bruger findes allerede") user = User( username=data.username, password_hash=hash_password(data.password), role=data.role, ) db.add(user) await db.commit() return {"ok": True, "username": user.username, "role": user.role} @router.get("/api/admin/users") async def list_users( db: AsyncSession = Depends(get_db), _: User = Depends(require_admin), ): result = await db.execute(select(User).order_by(User.username)) users = result.scalars().all() return [ {"id": u.id, "username": u.username, "role": u.role, "created_at": str(u.created_at)} for u in users ]