ADR-010 : API canonique auth/session¶
Statut¶
Acceptée
Date¶
2026-05-16
Contexte¶
Forge dispose de deux piles parallèles pour la gestion des sessions et de l'authentification :
core.auth.session, API moderne, typée, en anglais :
| Fonction | Rôle |
|---|---|
authenticate_user(login, password, user_loader) |
Vérification identifiant + mot de passe via loader applicatif |
login_user(request, user) |
Stocke _auth_user_id dans la session |
logout_user(request) |
Retire _auth_user_id de la session |
get_authenticated_user_id(request) |
Lit l'identifiant utilisateur typé (int) |
current_user(request, user_loader) |
Retourne l'AuthUser courant |
is_authenticated(request) |
Vérifie la présence de _auth_user_id |
@login_required |
Décorateur contrôleur, 401 ou redirect |
Renommage du premier paramètre (ADR-089)
Ce paramètre s'appelait email jusqu'à l'ADR-089, qui a séparé l'identité de connexion de l'adresse de contact.
Il recevait déjà une identité quelconque : le nom disait le contraire de ce que la valeur porte.
Aucun appel nommé n'existait dans le dépôt, tous étant positionnels.
Cette pile est compatible avec AuthUser, le protocole SessionStore (Phase 3) et tous les modules opt-in (forge-mvc-mfa, forge-mvc-rbac).
core.security.session, API legacy, en français/anglais mixte :
| Fonction | Rôle |
|---|---|
create_session() |
Crée une session via le store |
get_session(session_id) |
Lit les données de session |
delete_session(session_id) |
Supprime une session |
regenerate_session(old_session_id) |
Régénère un session_id |
authenticate_session(session_id, user: dict) |
Authentifie avec un dict FR (UtilisateurId, Login…) |
get_session_id(request) |
Extrait le session_id depuis le cookie |
is_authenticated(request) |
Vérifie SESSION_KEY_AUTHENTICATED dans la session |
get_user(request) |
Retourne le dict utilisateur brut |
user_has_role(request, role) |
Vérifie un rôle dans le dict utilisateur |
set_flash(session_id, message, level) |
Stocke un message flash |
get_flash(session_id) |
Lit et supprime le message flash |
Cette pile est utilisée par mvc/controllers/auth_controller.py, mvc/controllers/mfa_challenge_controller.py, mvc/helpers/flash.py, core/security/decorators.py, core/security/middleware.py, plusieurs starters et certains modules opt-in.
Interdépendance actuelle¶
core.auth.session._resolve_request_session() appelle en interne core.security.session.get_session / get_session_id comme fallback.
forge-mvc-mfa importe les deux piles.
forge-mvc-rbac importe principalement core.auth.session.
Décision ADR-001 (historique)¶
ADR-001 a déjà établi que core.auth est l'API officielle pour les nouveaux projets Forge 1.x.
ADR-010 formalise cette décision pour la série 1.0.x (numérotation interne renommée) et pose le cadre de la transition.
Décision¶
1. core.auth.session est l'API canonique.
Tout nouveau code Forge, tout nouveau starter, tout nouveau module opt-in et toute nouvelle documentation doit référencer core.auth.session.
2. core.security.session est l'API legacy.
Elle reste fonctionnelle et non modifiée jusqu'à la livraison de AUTH-SESSION-LEGACY-DEPRECATION-001.
Elle ne doit pas être étendue.
3. core.auth.session expose les fonctions de session bas niveau via _resolve_request_session.
Les opérations HTTP bas niveau (create_session, get_session_id, set_flash, get_flash) restent dans core.security.session jusqu'à la déduplication effective.
La décision de quelles fonctions migrer appartient à AUTH-SESSION-DEDUP-001.
4. Aucun warning n'est émis à l'import de core.security.session.
L'import de core.security.session ne doit pas émettre de DeprecationWarning.
Les warnings seront ajoutés uniquement à l'appel des fonctions legacy, dans le ticket AUTH-SESSION-LEGACY-DEPRECATION-001.
5. @login_required (core.auth.session) remplace @require_auth (core.security.decorators).
@require_auth est legacy.
Les nouveaux contrôleurs utilisent @login_required.
Conséquences¶
- Le code existant (
mvc/, starters) continue de fonctionner sans modification. - Les nouveaux projets générés après cette ADR utilisent
core.auth.session. - Les modules opt-in (
forge-mvc-rbac,forge-mvc-mfa) qui importent déjàcore.auth.sessionsont conformes. - Les imports
core.security.sessiondansforge-mvc-rbac.rbacetforge-mvc-mfa.mfaseront migrés dansAUTH-SESSION-DEDUP-001.
Politique de transition¶
La transition se déroule en quatre tickets :
| Ticket | Responsabilité |
|---|---|
AUTH-SESSION-CANONICAL-DECISION-001 (ce ticket) |
Décision canonique et documentation |
AUTH-SESSION-DEDUP-001 |
Alignement et déduplication, migration des imports runtime |
AUTH-SESSION-LEGACY-DEPRECATION-001 |
Ajout des DeprecationWarning sur les fonctions legacy |
STARTER-AUTH-MODERNIZE-001 |
Modernisation du starter auth sur core.auth.session |
CORE-AUTH-NO-HARDCODED-FIELDS-001 |
Suppression des champs applicatifs codés en dur dans le core |
Règle de dépréciation¶
Aucun DeprecationWarning à l'import.
DeprecationWarning uniquement à l'appel des fonctions legacy.
Cette étape appartient exclusivement à AUTH-SESSION-LEGACY-DEPRECATION-001.
Cette règle protège les projets qui importent core.security.session sans l'utiliser directement (via des imports intermédiaires dans le core).
Amendement : Dépréciations API legacy (4.3)¶
Ticket : AUTH-SESSION-LEGACY-DEPRECATION-001
Date : 2026-05-16
Les fonctions legacy suivantes de core.security.session émettent désormais un DeprecationWarning à l'appel, avec le chemin canonique à utiliser :
| Fonction dépréciée | API canonique à utiliser |
|---|---|
create_session() |
get_session_store().create() |
authenticate_session(session_id, user) |
login_user(request, user) avec AuthUser |
is_authenticated(request) |
core.auth.session.is_authenticated(request) |
get_user(request) |
core.auth.session.current_user(request, user_loader) |
Fonctions infrastructure conservées sans warning : get_session_id, get_session, delete_session, regenerate_session, user_has_role, set_flash, get_flash, pas d'équivalent canonique direct ou utilisées en interne par le framework.
Propriétés garanties :
- L'import de core.security.session n'émet aucun DeprecationWarning.
- Les fonctions dépréciées continuent à fonctionner, la migration est progressive, non cassante.
- stacklevel=2 : le warning pointe vers le code appelant.
- user_has_role ne cascade pas le warning de get_user (refactorisé pour lire le store directement).
La suppression effective et la migration des usages applicatifs appartiennent aux tickets 4.4 (STARTER-AUTH-MODERNIZE-001) et suivants.
Amendement : Pont de compatibilité bidirectionnel (4.2b)¶
Ticket : AUTH-SESSION-COMPATIBILITY-BRIDGE-001
Date : 2026-05-16
La divergence de clés de session (_auth_user_id vs authenticated + user) rendait les deux piles mutuellement opaques.
Le ticket 4.2b a livré un pont de lecture bidirectionnel :
core.auth.session.get_authenticated_user_id reconnaît les sessions legacy : si _auth_user_id est absent mais que authenticated=True et user.id sont présents (session créée par authenticate_session), l'identifiant est retourné.
core.security.session.is_authenticated reconnaît les sessions canoniques : si les clés legacy sont absentes mais que _auth_user_id est un entier positif (session créée par login_user), la session est considérée authentifiée.
Propriétés garanties :
- Aucune écriture dans la session à la lecture, pas de pollution de clés.
- L'expiration est étendue dans les deux cas.
- Pas d'import circulaire : core.security.session utilise la clé littérale "_auth_user_id" sans importer core.auth.session.
Ce pont ferme les constats FND-AUTH-001 et FND-AUTH-002 du tracker post-audit 2026-05.
Ce que cette ADR ne fait pas¶
- N'aligne pas
mvc/controllers/surcore.auth.session. - Ne déplace aucune fonction.
- Ne supprime pas
core.security.session. - N'ajoute aucun
DeprecationWarning. - Ne modifie pas les starters.
- Ne modifie pas les modules opt-in.
- Ne modifie pas le comportement runtime (sessions, authentification, CSRF).
- Ne touche pas MFA, RBAC, CSRF.
- Ne publie aucune version.
Tickets liés¶
| Ticket | Description | Phase |
|---|---|---|
AUTH-SESSION-CANONICAL-DECISION-001 |
Ce document | Phase 4.1 |
AUTH-SESSION-DEDUP-001 |
Déduplication et migration des imports | Phase 4.2 |
AUTH-SESSION-LEGACY-DEPRECATION-001 |
Warnings legacy à l'appel | Phase 4.3 |
STARTER-AUTH-MODERNIZE-001 |
Modernisation du starter auth | Phase 4.4 |
CORE-AUTH-NO-HARDCODED-FIELDS-001 |
Suppression des champs hardcodés | Phase 4.5 |
ADR-001 |
Décision historique Forge 1.x (référence) | Forge 1.x |
AUTH-SESSION-DEDUP-001 (tracker) |
Constat FND-AUTH-001 | Audit 2026-05 |