Identity — OTP / 2FA¶
Le module OTP implémente l’authentification multi-facteurs avec trois canaux : email, TOTP (RFC 6238), et codes de récupération statiques.
Module : src.module.identity.domain.otp_service
OTP par Email¶
- src.module.identity.domain.otp_service.generate_email_otp(user, device) str¶
Génère un code OTP à 6 chiffres et l’envoie par email.
Crée un
OTPChallengeavec TTL configurable (OTP_EMAIL_TOKEN_VALIDITY_SECONDS)Envoie l’email avec le code
Retourne le code (pour les tests)
- Parameters:
user – Utilisateur cible
device – OTPDevice de type
"email"
- Returns:
Code OTP généré
- src.module.identity.domain.otp_service.verify_email_otp(device, code: str) bool¶
Vérifie un code OTP email.
Cherche un
OTPChallengenon utilisé et non expiréMarque le challenge comme utilisé
Retourne
Truesi le code est valide
- Parameters:
device – OTPDevice de type
"email"code – Code à vérifier
- Returns:
Truesi valide
TOTP (Time-based One-Time Password)¶
Implémentation conforme à la RFC 6238 utilisant HMAC-SHA1 avec des pas de 30 secondes.
- src.module.identity.domain.otp_service.setup_totp(user) tuple[OTPDevice, str]¶
Initialise un dispositif TOTP.
Génère un secret aléatoire base32
Crée un
OTPDevicenon confirméRetourne le dispositif et l’URI
otpauth://pour les QR codes
- Returns:
Tuple
(device, provisioning_uri)
device, uri = setup_totp(user) # uri = "otpauth://totp/updo:user@example.com?secret=JBSWY3DPEHPK3PXP&issuer=updo" # Afficher comme QR code pour Google Authenticator / Authy
- src.module.identity.domain.otp_service.confirm_totp(device, code: str) bool¶
Confirme un dispositif TOTP en vérifiant le premier code.
Vérifie le code TOTP contre le secret stocké
Si valide, marque le dispositif comme
is_confirmed=TrueÉmet
OTPDeviceConfirmed
- Parameters:
device – OTPDevice TOTP non confirmé
code – Code TOTP à 6 chiffres
- Returns:
Truesi confirmé avec succès
- src.module.identity.domain.otp_service.verify_totp(device, code: str) bool[source]¶
Vérifie un code TOTP.
Accepte le code courant et les codes des fenêtres adjacentes (±1 pas) pour compenser le décalage d’horloge.
- Parameters:
device – OTPDevice TOTP confirmé
code – Code TOTP à 6 chiffres
- Returns:
Truesi valide
Codes de récupération statiques¶
- src.module.identity.domain.otp_service.generate_static_codes(user, count: int = 10) list[str][source]¶
Génère un ensemble de codes de récupération à usage unique.
- Parameters:
user – Utilisateur cible
count – Nombre de codes (défaut:
OTP_STATIC_TOKEN_COUNT)
- Returns:
Liste de codes alphanumériques
codes = generate_static_codes(user) # ['ABC12345', 'DEF67890', 'GHI24680', ...] # L'utilisateur doit les sauvegarder en lieu sûr
- src.module.identity.domain.otp_service.verify_static_code(device, code: str) bool[source]¶
Vérifie et consomme un code de récupération.
Cherche le code dans la liste stockée
Le supprime de la liste (usage unique)
Retourne
Truesi trouvé
- Parameters:
device – OTPDevice de type
"static"code – Code de récupération
- Returns:
Truesi valide et consommé
Fonction unifiée¶
- src.module.identity.domain.otp_service.verify_otp(user, code: str, device_type: str | None = None) bool[source]¶
Point d’entrée unifié pour la vérification OTP.
Essaie les dispositifs actifs dans l’ordre :
TOTP (si
device_typeestNoneou"totp")Email (si
device_typeestNoneou"email")Static (si
device_typeestNoneou"static")
- Parameters:
user – Utilisateur
code – Code OTP
device_type – Type spécifique à vérifier (optionnel)
- Returns:
Truesi un dispositif valide le code
Endpoints API¶
POST /api/v1/auth/otp/totp/setup/ → Initialise TOTP, retourne URI + secret
POST /api/v1/auth/otp/totp/confirm/ → Confirme le dispositif TOTP
POST /api/v1/auth/otp/email/send/ → Envoie un code OTP par email
POST /api/v1/auth/otp/static/generate/ → Génère des codes de récupération
POST /api/v1/auth/otp/verify/ → Vérifie un code OTP (tous types)
GET /api/v1/auth/otp/devices/ → Liste les dispositifs OTP
DELETE /api/v1/auth/otp/devices/<id>/ → Supprime un dispositif
Configuration¶
MULTITENANT = {
'OTP_ENABLED': True,
'OTP_EMAIL_ENABLED': True,
'OTP_TOTP_ENABLED': True,
'OTP_STATIC_ENABLED': True,
'OTP_EMAIL_TOKEN_VALIDITY_SECONDS': 300, # 5 minutes
'OTP_TOTP_ISSUER_NAME': 'updo',
'OTP_STATIC_TOKEN_COUNT': 10,
'OTP_REQUIRED_FOR_LOGIN': False,
}