forked from seb_vallee/BillManager
163 lines
5.2 KiB
Python
163 lines
5.2 KiB
Python
from template_helper import render
|
|
from fastapi import APIRouter, Depends, Request, Form, HTTPException
|
|
from fastapi.responses import HTMLResponse, RedirectResponse, Response
|
|
from fastapi.templating import Jinja2Templates
|
|
from sqlalchemy.orm import Session
|
|
|
|
from database import get_db
|
|
from models import User
|
|
from auth import (
|
|
hasher_mot_de_passe, verifier_mot_de_passe,
|
|
creer_session, get_current_admin, COOKIE_NAME
|
|
)
|
|
from config import settings
|
|
|
|
router = APIRouter(tags=["auth"])
|
|
templates = Jinja2Templates(directory="templates")
|
|
|
|
|
|
# ── Login / Logout ─────────────────────────────────────────────────────────────
|
|
|
|
@router.get("/login", response_class=HTMLResponse)
|
|
def login_form(request: Request):
|
|
return render(templates, "auth/login.html", request, {
|
|
"erreur": None
|
|
})
|
|
|
|
|
|
@router.post("/login")
|
|
def login(
|
|
request: Request,
|
|
username: str = Form(...),
|
|
password: str = Form(...),
|
|
db: Session = Depends(get_db)
|
|
):
|
|
user = db.query(User).filter(
|
|
User.username == username, User.actif == True
|
|
).first()
|
|
|
|
if not user or not verifier_mot_de_passe(password, user.hashed_password):
|
|
return render(templates, "auth/login.html", request, {
|
|
"erreur": "Identifiants incorrects."
|
|
}, status_code=401)
|
|
|
|
token = creer_session(user.id)
|
|
response = RedirectResponse("/factures/", status_code=303)
|
|
response.set_cookie(
|
|
key=COOKIE_NAME,
|
|
value=token,
|
|
max_age=settings.session_max_age,
|
|
httponly=True,
|
|
samesite="lax",
|
|
secure=False # Passer à True si HTTPS (recommandé en prod)
|
|
)
|
|
return response
|
|
|
|
|
|
@router.post("/logout")
|
|
def logout():
|
|
response = RedirectResponse("/login", status_code=303)
|
|
response.delete_cookie(COOKIE_NAME)
|
|
return response
|
|
|
|
|
|
# ── Gestion utilisateurs (admin) ───────────────────────────────────────────────
|
|
|
|
@router.get("/admin/utilisateurs", response_class=HTMLResponse)
|
|
def liste_utilisateurs(
|
|
request: Request,
|
|
db: Session = Depends(get_db),
|
|
current_user=Depends(get_current_admin)
|
|
):
|
|
users = db.query(User).order_by(User.username).all()
|
|
return render(templates, "auth/utilisateurs.html", request, {
|
|
"users": users, "current_user": current_user
|
|
})
|
|
|
|
|
|
@router.get("/admin/utilisateurs/nouveau", response_class=HTMLResponse)
|
|
def nouveau_user_form(request: Request, current_user=Depends(get_current_admin)):
|
|
return render(templates, "auth/user_form.html", request, {
|
|
"user": None,
|
|
"titre": "Nouvel utilisateur", "current_user": current_user
|
|
})
|
|
|
|
|
|
@router.post("/admin/utilisateurs/nouveau")
|
|
def creer_user(
|
|
username: str = Form(...),
|
|
email: str = Form(""),
|
|
password: str = Form(...),
|
|
is_admin: bool = Form(False),
|
|
db: Session = Depends(get_db),
|
|
current_user=Depends(get_current_admin)
|
|
):
|
|
if db.query(User).filter(User.username == username).first():
|
|
raise HTTPException(status_code=400, detail="Ce nom d'utilisateur existe déjà.")
|
|
user = User(
|
|
username=username,
|
|
email=email,
|
|
hashed_password=hasher_mot_de_passe(password),
|
|
is_admin=is_admin
|
|
)
|
|
db.add(user)
|
|
db.commit()
|
|
return RedirectResponse("/admin/utilisateurs", status_code=303)
|
|
|
|
|
|
@router.get("/admin/utilisateurs/{user_id}/modifier", response_class=HTMLResponse)
|
|
def modifier_user_form(
|
|
request: Request,
|
|
user_id: int,
|
|
db: Session = Depends(get_db),
|
|
current_user=Depends(get_current_admin)
|
|
):
|
|
user = db.query(User).get(user_id)
|
|
if not user:
|
|
raise HTTPException(status_code=404)
|
|
return render(templates, "auth/user_form.html", request, {
|
|
"user": user,
|
|
"titre": "Modifier l'utilisateur", "current_user": current_user
|
|
})
|
|
|
|
|
|
@router.post("/admin/utilisateurs/{user_id}/modifier")
|
|
def modifier_user(
|
|
user_id: int,
|
|
username: str = Form(...),
|
|
email: str = Form(""),
|
|
password: str = Form(""),
|
|
is_admin: bool = Form(False),
|
|
db: Session = Depends(get_db),
|
|
current_user=Depends(get_current_admin)
|
|
):
|
|
user = db.query(User).get(user_id)
|
|
if not user:
|
|
raise HTTPException(status_code=404)
|
|
# Empêcher de se retirer les droits admin à soi-même
|
|
if user.id == current_user.id and not is_admin:
|
|
raise HTTPException(status_code=400, detail="Vous ne pouvez pas retirer vos propres droits admin.")
|
|
user.username = username
|
|
user.email = email
|
|
user.is_admin = is_admin
|
|
if password:
|
|
user.hashed_password = hasher_mot_de_passe(password)
|
|
db.commit()
|
|
return RedirectResponse("/admin/utilisateurs", status_code=303)
|
|
|
|
|
|
@router.post("/admin/utilisateurs/{user_id}/desactiver")
|
|
def desactiver_user(
|
|
user_id: int,
|
|
db: Session = Depends(get_db),
|
|
current_user=Depends(get_current_admin)
|
|
):
|
|
user = db.query(User).get(user_id)
|
|
if not user:
|
|
raise HTTPException(status_code=404)
|
|
if user.id == current_user.id:
|
|
raise HTTPException(status_code=400, detail="Impossible de se désactiver soi-même.")
|
|
user.actif = not user.actif
|
|
db.commit()
|
|
return RedirectResponse("/admin/utilisateurs", status_code=303)
|