diff --git a/backend/auth.py b/backend/auth.py index e69de29..1e521b5 100644 --- a/backend/auth.py +++ b/backend/auth.py @@ -0,0 +1,26 @@ +from passlib.context import CryptContext +import pyotp + +# Configuration du hachage (bcrypt) +pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto") + +def verify_password(plain_password: str, hashed_password: str) -> bool: + """Vérifie si le mot de passe en clair correspond au hash.""" + return pwd_context.verify(plain_password, hashed_password) + +def get_password_hash(password: str) -> str: + """Génère le hash d'un mot de passe.""" + return pwd_context.hash(password) + +def generate_totp_secret() -> str: + """Génère un secret aléatoire pour l'application 2FA (Authenticator, Keepassium).""" + return pyotp.random_base32() + +def get_totp_uri(secret: str, username: str) -> str: + """Génère l'URI pour créer le QR Code.""" + return pyotp.totp.TOTP(secret).provisioning_uri(name=username, issuer_name="AETHAS38") + +def verify_totp(secret: str, code: str) -> bool: + """Vérifie le code à 6 chiffres soumis par l'utilisateur.""" + totp = pyotp.TOTP(secret) + return totp.verify(code) \ No newline at end of file diff --git a/backend/database.py b/backend/database.py index e69de29..fe0f5ec 100644 --- a/backend/database.py +++ b/backend/database.py @@ -0,0 +1,23 @@ +import os +from sqlalchemy import create_engine +from sqlalchemy.orm import sessionmaker, declarative_base + +# Récupération de l'URL de connexion injectée par Docker via le .env +SQLALCHEMY_DATABASE_URL = os.getenv("DATABASE_URL") + +# Création du moteur de connexion (engine) +engine = create_engine(SQLALCHEMY_DATABASE_URL) + +# Création de la fabrique de sessions +SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine) + +# Classe de base pour définir nos futures tables (modèles) +Base = declarative_base() + +# Dépendance FastAPI pour ouvrir et fermer proprement les sessions BDD +def get_db(): + db = SessionLocal() + try: + yield db + finally: + db.close() \ No newline at end of file diff --git a/backend/models.py b/backend/models.py new file mode 100644 index 0000000..4d2a925 --- /dev/null +++ b/backend/models.py @@ -0,0 +1,16 @@ +from sqlalchemy import Column, Integer, String, Boolean, DateTime +from datetime import datetime, timezone +from .database import Base + +class User(Base): + __tablename__ = "users" + + id = Column(Integer, primary_key=True, index=True) + email = Column(String, unique=True, index=True, nullable=False) + username = Column(String, unique=True, index=True, nullable=False) + hashed_password = Column(String, nullable=False) + totp_secret = Column(String, nullable=True) # Secret pour Keepassium/Authenticator + is_admin = Column(Boolean, default=False) + is_active = Column(Boolean, default=True) + created_at = Column(DateTime, default=lambda: datetime.now(timezone.utc)) + last_activity = Column(DateTime, nullable=True) # Servira pour la déconnexion après 60 min \ No newline at end of file