This commit is contained in:
2026-03-27 17:52:41 +01:00
parent 3cf8233054
commit 8320738acb
32 changed files with 5113 additions and 1385 deletions
+181
View File
@@ -0,0 +1,181 @@
"""
DragonBank - Validateurs
=========================
Centralise toutes les fonctions de validation des donnees
recues depuis les requetes HTTP.
Principe : chaque validateur retourne soit la valeur nettoyee,
soit leve une ValueError avec un message explicite.
Les routes n'ont ainsi pas a contenir de logique de validation.
Version : 3.0
"""
import re
import decimal
from config import (
MONTANT_MINIMUM_VIREMENT,
MONTANT_MAXIMUM_VIREMENT,
SIMULATION_DUREE_MIN,
SIMULATION_DUREE_MAX
)
# ============================================================
# EXPRESSIONS REGULIERES
# ============================================================
# Valide le format d'une adresse email (RFC 5322 simplifie).
REGEX_EMAIL = re.compile(
r'^[a-zA-Z0-9._%+\-]+@[a-zA-Z0-9.\-]+\.[a-zA-Z]{2,}$'
)
# ============================================================
# VALIDATEURS
# ============================================================
def valider_email(email):
"""
Valide le format d'une adresse email.
Args:
email (str): L'adresse email a valider.
Returns:
str: L'email normalise (strip + lowercase).
Raises:
ValueError: Si le format est invalide ou si l'email est vide.
"""
if not email or not email.strip():
raise ValueError("L'adresse email est obligatoire")
email_normalise = email.strip().lower()
if not REGEX_EMAIL.match(email_normalise):
raise ValueError("Le format de l'adresse email est invalide")
return email_normalise
def valider_mot_de_passe(mot_de_passe):
"""
Valide la complexite d'un mot de passe.
Regles appliquees :
- Au moins 8 caracteres.
- Au moins une lettre majuscule (A-Z).
- Au moins une lettre minuscule (a-z).
- Au moins un chiffre (0-9).
Args:
mot_de_passe (str): Le mot de passe en clair a verifier.
Returns:
str: Le mot de passe inchange si valide.
Raises:
ValueError: Si une regle n'est pas respectee.
"""
if not mot_de_passe or len(mot_de_passe) < 8:
raise ValueError("Le mot de passe doit contenir au moins 8 caracteres")
if not re.search(r'[A-Z]', mot_de_passe):
raise ValueError("Le mot de passe doit contenir au moins une majuscule")
if not re.search(r'[a-z]', mot_de_passe):
raise ValueError("Le mot de passe doit contenir au moins une minuscule")
if not re.search(r'\d', mot_de_passe):
raise ValueError("Le mot de passe doit contenir au moins un chiffre")
return mot_de_passe
def valider_montant(montant_brut):
"""
Valide et convertit un montant en Decimal de maniere securisee.
Utilise Decimal (et non float) pour eviter les erreurs d'arrondi
inherentes aux nombres a virgule flottante (ex: 0.1 + 0.2 != 0.3).
Args:
montant_brut: Le montant brut a valider (str, int ou float).
Returns:
Decimal: Le montant valide et converti.
Raises:
ValueError: Si le montant est non numerique ou hors limites.
"""
try:
montant = decimal.Decimal(str(montant_brut))
except (decimal.InvalidOperation, TypeError):
raise ValueError("Le montant doit etre un nombre valide")
if montant < MONTANT_MINIMUM_VIREMENT:
raise ValueError(
"Le montant minimum est de " + str(MONTANT_MINIMUM_VIREMENT) + " euros"
)
if montant > MONTANT_MAXIMUM_VIREMENT:
raise ValueError(
"Le montant maximum par virement est de " + str(MONTANT_MAXIMUM_VIREMENT) + " euros"
)
return montant
def valider_champs_obligatoires(donnees, champs):
"""
Verifie que tous les champs obligatoires sont presents et non vides.
Args:
donnees (dict): Dictionnaire des donnees recues.
champs (list) : Liste des noms de champs obligatoires.
Returns:
None
Raises:
ValueError: Liste des champs manquants si au moins un est absent.
"""
if not donnees:
raise ValueError("Le corps de la requete JSON est manquant")
manquants = []
for champ in champs:
valeur = donnees.get(champ, '')
if not valeur or (isinstance(valeur, str) and not valeur.strip()):
manquants.append(champ)
if manquants:
raise ValueError("Champs obligatoires manquants : " + ", ".join(manquants))
def valider_parametres_simulateur(capital, taux, duree, versement):
"""
Valide les parametres d'entree du simulateur d'epargne.
Args:
capital (float): Capital initial en euros.
taux (float): Taux annuel en pourcentage.
duree (int) : Duree en annees.
versement (float): Versement mensuel en euros.
Returns:
None
Raises:
ValueError: Si un parametre est invalide.
"""
if capital < 0:
raise ValueError("Le capital initial ne peut pas etre negatif")
if taux < 0 or taux > 100:
raise ValueError("Le taux annuel doit etre compris entre 0 et 100 %")
if duree < SIMULATION_DUREE_MIN or duree > SIMULATION_DUREE_MAX:
raise ValueError(
"La duree doit etre comprise entre "
+ str(SIMULATION_DUREE_MIN) + " et "
+ str(SIMULATION_DUREE_MAX) + " ans"
)
if versement < 0:
raise ValueError("Le versement mensuel ne peut pas etre negatif")