Deux protections etaient configurees sans avoir d'effet. Expiration de session app.py:73 definit PERMANENT_SESSION_LIFETIME = 3600, mais Flask n'applique cette duree qu'aux sessions marquees permanentes. Aucune occurrence de session.permanent n'existait dans app/. Le cookie emis etait donc un cookie de session navigateur, sans expiration, et le serveur ne verifiait aucune anciennete. Ajout de session.permanent juste avant login_user, apres la rotation anti-fixation. Desactivation de compte is_active_account n'etait consulte qu'au moment du login (auth.py:141). User n'ayant pas surcharge is_active, UserMixin renvoyait True en permanence. Desactiver un compte empechait donc la reconnexion mais laissait vivre la session en cours. La propriete is_active seule ne suffit pas : Flask-Login ne la consulte qu'a l'appel de login_user, jamais lors de la restauration d'une session depuis le cookie. Le verrou effectif est donc dans load_user, qui renvoie desormais None pour un compte desactive. La propriete est ajoutee malgre tout pour que login_user soit coherent avec le chargeur. load_user passe au passage de Query.get() (API heritee, avertie en SQLAlchemy 2.0) a db.session.get(), et tolere un identifiant non entier sans lever. Co-Authored-By: Claude Opus 5 <[email protected]>
30 lines
957 B
Python
30 lines
957 B
Python
"""Flask-Login user loader — registered with login_manager in models.py."""
|
|
|
|
from app.extensions import login_manager
|
|
|
|
|
|
@login_manager.user_loader
|
|
def load_user(user_id):
|
|
"""Load a user by ID for Flask-Login session management.
|
|
|
|
Returns the correct polymorphic subclass (Admin, Coach, Player, etc.)
|
|
automatically because SQLAlchemy resolves the identity column.
|
|
|
|
Returns None for deactivated accounts so that disabling a user also
|
|
invalidates the sessions they already hold. Flask-Login only consults
|
|
is_active when login_user() is called, never when restoring a session
|
|
from the cookie, so the check has to happen here.
|
|
"""
|
|
from app.extensions import db
|
|
from app.models.user_model.user import User
|
|
|
|
try:
|
|
pk = int(user_id)
|
|
except (TypeError, ValueError):
|
|
return None
|
|
|
|
user = db.session.get(User, pk)
|
|
if user is None or not user.is_active_account:
|
|
return None
|
|
return user
|