Fixed an issue that cause user sessions to not be properly associated

Sessions could get duplicated, wrongly saved etc. The reason was not
persisting the actual user object to the internal session map (but the
LocalProxy instead). That could lead to multiple sessions being
created for one login, or the session user being set to an
anonymous user, or various other odd effects depending on timing.
This commit is contained in:
Gina Häußge 2015-09-09 16:13:10 +02:00
parent d5b0bd2518
commit 8aeac51124
2 changed files with 19 additions and 11 deletions

View file

@ -227,8 +227,10 @@ def passive_login():
user = flask.ext.login.current_user user = flask.ext.login.current_user
if user is not None and not user.is_anonymous(): if user is not None and not user.is_anonymous():
flask.g.user = user
flask.ext.principal.identity_changed.send(flask.current_app._get_current_object(), identity=flask.ext.principal.Identity(user.get_id())) flask.ext.principal.identity_changed.send(flask.current_app._get_current_object(), identity=flask.ext.principal.Identity(user.get_id()))
if hasattr(user, "get_session"):
flask.session["usersession.id"] = user.get_session()
flask.g.user = user
return flask.jsonify(user.asDict()) return flask.jsonify(user.asDict())
elif settings().getBoolean(["accessControl", "autologinLocal"]) \ elif settings().getBoolean(["accessControl", "autologinLocal"]) \
and settings().get(["accessControl", "autologinAs"]) is not None \ and settings().get(["accessControl", "autologinAs"]) is not None \
@ -252,7 +254,7 @@ def passive_login():
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
logger.exception("Could not autologin user %s for networks %r" % (autologinAs, localNetworks)) logger.exception("Could not autologin user %s for networks %r" % (autologinAs, localNetworks))
return ("", 204) return "", 204
#~~ cache decorator for cacheable views #~~ cache decorator for cacheable views

View file

@ -28,13 +28,18 @@ class UserManager(object):
def login_user(self, user): def login_user(self, user):
self._cleanup_sessions() self._cleanup_sessions()
if user is None \ if user is None:
or (isinstance(user, LocalProxy) and not isinstance(user._get_current_object(), User)) \ return
or (not isinstance(user, LocalProxy) and not isinstance(user, User)):
if isinstance(user, LocalProxy):
user = user._get_current_object()
if not isinstance(user, User):
return None return None
if not isinstance(user, SessionUser): if not isinstance(user, SessionUser):
user = SessionUser(user) user = SessionUser(user)
self._session_users_by_session[user.get_session()] = user self._session_users_by_session[user.get_session()] = user
if not user.get_name() in self._session_users_by_username: if not user.get_name() in self._session_users_by_username:
@ -49,6 +54,9 @@ class UserManager(object):
if user is None: if user is None:
return return
if isinstance(user, LocalProxy):
user = user._get_current_object()
if not isinstance(user, SessionUser): if not isinstance(user, SessionUser):
return return
@ -146,12 +154,10 @@ class UserManager(object):
del self._session_users_by_username[username] del self._session_users_by_username[username]
def findUser(self, username=None, session=None): def findUser(self, username=None, session=None):
if session is not None: if session is not None and session in self._session_users_by_session:
for session in self._session_users_by_session: user = self._session_users_by_session[session]
user = self._session_users_by_session[session] if username is None or username == user.get_id():
if username is None or username == user.get_id(): return user
return user
break
return None return None