From 13abdc68afb47218bb1c1534f1b7f7a54fbf67b1 Mon Sep 17 00:00:00 2001 From: Xavier Date: Tue, 6 Oct 2026 23:23:47 +0200 Subject: [PATCH] =?UTF-8?q?feat:=20cr=C3=A9ation=20de=20l'API=20/api/setup?= =?UTF-8?q?=20avec=20pydantic=20pour=20la=20cr=C3=A9ation=20du=20compte=20?= =?UTF-8?q?Admin?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/main.py | 45 +++++++++++++++++++++++++++++++++++++++------ backend/schemas.py | 6 ++++++ 2 files changed, 45 insertions(+), 6 deletions(-) create mode 100644 backend/schemas.py diff --git a/backend/main.py b/backend/main.py index c31c765..e76bbe7 100644 --- a/backend/main.py +++ b/backend/main.py @@ -1,12 +1,14 @@ -from fastapi import FastAPI, Depends +from fastapi import FastAPI, Depends, HTTPException, status from fastapi.responses import RedirectResponse from sqlalchemy.orm import Session # Importation de nos modules locaux from .database import engine, Base, get_db from .models import User +from .auth import get_password_hash, generate_totp_secret, get_totp_uri +from .schemas import AdminCreate -# Création des tables dans la base de données (si elles n'existent pas) +# Création des tables dans la base de données Base.metadata.create_all(bind=engine) app = FastAPI(title="AETHAS38 - Orchestrateur Multi-IA") @@ -18,21 +20,52 @@ def is_setup_required(db: Session) -> bool: @app.get("/") def read_root(db: Session = Depends(get_db)): - """Route principale : redirige selon l'état de l'installation.""" if is_setup_required(db): return RedirectResponse(url="/setup") return RedirectResponse(url="/login") @app.get("/setup") def setup_page(db: Session = Depends(get_db)): - """Affiche l'assistant d'installation (Frontend Vue.js à venir).""" if not is_setup_required(db): return RedirectResponse(url="/login") return {"message": "Assistant d'installation AETHAS38. Veuillez créer le compte Administrateur."} @app.get("/login") def login_page(db: Session = Depends(get_db)): - """Affiche la page de connexion sécurisée.""" if is_setup_required(db): return RedirectResponse(url="/setup") - return {"message": "Page de connexion (Frontend Vue.js à venir)."} \ No newline at end of file + return {"message": "Page de connexion."} + +@app.post("/api/setup") +def create_admin(admin_data: AdminCreate, db: Session = Depends(get_db)): + """Reçoit les données du frontend, crée l'admin et retourne le QR Code 2FA.""" + if not is_setup_required(db): + raise HTTPException( + status_code=status.HTTP_403_FORBIDDEN, + detail="L'installation a déjà été effectuée." + ) + + # Sécurisation des accès + hashed_pw = get_password_hash(admin_data.password) + totp_secret = generate_totp_secret() + + new_admin = User( + email=admin_data.email, + username=admin_data.username, + hashed_password=hashed_pw, + totp_secret=totp_secret, + is_admin=True + ) + + db.add(new_admin) + db.commit() + db.refresh(new_admin) + + # Génération de l'URI pour l'affichage du QR Code côté frontend + totp_uri = get_totp_uri(totp_secret, new_admin.username) + + return { + "message": "Administrateur créé avec succès.", + "totp_secret": totp_secret, + "totp_uri": totp_uri + } \ No newline at end of file diff --git a/backend/schemas.py b/backend/schemas.py new file mode 100644 index 0000000..99df7cc --- /dev/null +++ b/backend/schemas.py @@ -0,0 +1,6 @@ +from pydantic import BaseModel, EmailStr + +class AdminCreate(BaseModel): + email: EmailStr + username: str + password: str \ No newline at end of file