You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@allura.apache.org by br...@apache.org on 2014/11/18 20:37:08 UTC

allura git commit: [#7799] invalidate all other sessions when changing your password

Repository: allura
Updated Branches:
  refs/heads/db/7799 [created] 0f13782cd


[#7799] invalidate all other sessions when changing your password


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/0f13782c
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/0f13782c
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/0f13782c

Branch: refs/heads/db/7799
Commit: 0f13782cd198c17c347b80e739bfe5829a13595a
Parents: 28cd976
Author: Dave Brondsema <db...@slashdotmedia.com>
Authored: Mon Nov 17 19:09:16 2014 +0000
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Tue Nov 18 19:16:59 2014 +0000

----------------------------------------------------------------------
 Allura/allura/controllers/auth.py                  |  3 +++
 Allura/allura/controllers/basetest_project_root.py |  3 +++
 Allura/allura/lib/plugin.py                        | 17 ++++++++++++-----
 Allura/development.ini                             |  1 -
 AlluraTest/alluratest/controller.py                |  1 -
 5 files changed, 18 insertions(+), 7 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/0f13782c/Allura/allura/controllers/auth.py
----------------------------------------------------------------------
diff --git a/Allura/allura/controllers/auth.py b/Allura/allura/controllers/auth.py
index ef7935f..f971b0a 100644
--- a/Allura/allura/controllers/auth.py
+++ b/Allura/allura/controllers/auth.py
@@ -229,6 +229,7 @@ class AuthController(BaseController):
                  display_name=display_name,
                  password=pw,
                  pending=require_email))
+        user.set_tool_data('allura', pwd_reset_preserve_session=session.id)  # else the first password set causes this session to be invalidated
         if require_email:
             em = user.claim_address(email)
             em.send_verification_link()
@@ -406,6 +407,7 @@ class AuthController(BaseController):
             expired_username = session.get('expired-username')
             expired_user = M.User.query.get(username=expired_username) if expired_username else None
             ap.set_password(expired_user or c.user, kw['oldpw'], kw['pw'])
+            expired_user.set_tool_data('allura', pwd_reset_preserve_session=session.id)
         except wexc.HTTPUnauthorized:
             flash('Incorrect password', 'error')
             redirect(tg.url('/auth/pwd_expired', dict(return_to=return_to)))
@@ -554,6 +556,7 @@ class PreferencesController(BaseController):
         ap = plugin.AuthenticationProvider.get(request)
         try:
             ap.set_password(c.user, kw['oldpw'], kw['pw'])
+            c.user.set_tool_data('allura', pwd_reset_preserve_session=session.id)
         except wexc.HTTPUnauthorized:
             flash('Incorrect password', 'error')
             redirect('.')

http://git-wip-us.apache.org/repos/asf/allura/blob/0f13782c/Allura/allura/controllers/basetest_project_root.py
----------------------------------------------------------------------
diff --git a/Allura/allura/controllers/basetest_project_root.py b/Allura/allura/controllers/basetest_project_root.py
index 91c16da..a2df7a2 100644
--- a/Allura/allura/controllers/basetest_project_root.py
+++ b/Allura/allura/controllers/basetest_project_root.py
@@ -127,6 +127,9 @@ class BasetestProjectRootController(WsgiDispatchController, ProjectController):
         if not user:
             user = M.User.anonymous()
         environ['beaker.session']['username'] = user.username
+        # save and persist, so that a creation time is set
+        environ['beaker.session'].save()
+        environ['beaker.session'].persist()
         c.user = auth.authenticate_request()
         return WsgiDispatchController.__call__(self, environ, start_response)
 

http://git-wip-us.apache.org/repos/asf/allura/blob/0f13782c/Allura/allura/lib/plugin.py
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/plugin.py b/Allura/allura/lib/plugin.py
index c0dbf51..ea66b60 100644
--- a/Allura/allura/lib/plugin.py
+++ b/Allura/allura/lib/plugin.py
@@ -106,6 +106,13 @@ class AuthenticationProvider(object):
         if user.disabled or user.pending:
             self.logout()
             return M.User.anonymous()
+        if not user.is_anonymous() and \
+                        self.get_last_password_updated(user) > datetime.utcfromtimestamp(self.session.created) and \
+                        user.get_tool_data('allura', 'pwd_reset_preserve_session') != self.session.id:
+            log.debug('Session logged out: due to user %s pwd change %s > %s', user.username,
+                      self.get_last_password_updated(user), datetime.utcfromtimestamp(self.session.created))
+            self.logout()
+            return M.User.anonymous()
 
         if self.session.get('pwd-expired') and request.path not in self.pwd_expired_allowed_urls:
             if self.request.environ['REQUEST_METHOD'] == 'GET':
@@ -130,7 +137,7 @@ class AuthenticationProvider(object):
 
     def _login(self):
         '''
-        Authorize a user, usually using self.request.params['username'] and ['password']
+        Authorize a user, usually using ``self.request.params['username']`` and ``['password']``
 
         :rtype: :class:`User <allura.model.auth.User>`
         :raises: HTTPUnauthorized if user not found, or credentials are not valid
@@ -168,10 +175,7 @@ class AuthenticationProvider(object):
             raise
 
     def logout(self):
-        self.session['login_expires'] = None
-        self.session['username'] = None
-        self.session['pwd-expired'] = False
-        self.session.save()
+        self.session.invalidate()
         response.delete_cookie('allura-loggedin')
 
     def validate_password(self, user, password):
@@ -205,6 +209,9 @@ class AuthenticationProvider(object):
         '''
         Set a user's password.
 
+        A provider implementing this method should store the timestamp of this change, either on ``user.last_password_updated`` or
+        somewhere else that a custom ``get_last_password_updated`` method uses.
+
         :param user: a :class:`User <allura.model.auth.User>`
         :rtype: None
         :raises: HTTPUnauthorized if old_password is not valid

http://git-wip-us.apache.org/repos/asf/allura/blob/0f13782c/Allura/development.ini
----------------------------------------------------------------------
diff --git a/Allura/development.ini b/Allura/development.ini
index c772e5f..0de4e80 100644
--- a/Allura/development.ini
+++ b/Allura/development.ini
@@ -311,7 +311,6 @@ full_stack = true
 cache_dir = %(here)s/data
 beaker.session.key = allura
 beaker.session.type = cookie
-beaker.session.secret = 61ece7db-ba8d-49fe-a923-ab444741708c
 beaker.session.validate_key = 714bfe3612c42390726f
 
 # Ming setup

http://git-wip-us.apache.org/repos/asf/allura/blob/0f13782c/AlluraTest/alluratest/controller.py
----------------------------------------------------------------------
diff --git a/AlluraTest/alluratest/controller.py b/AlluraTest/alluratest/controller.py
index 433431f..4237624 100644
--- a/AlluraTest/alluratest/controller.py
+++ b/AlluraTest/alluratest/controller.py
@@ -125,7 +125,6 @@ def setup_unit_test():
     REGISTRY.register(url, lambda: None)
     REGISTRY.register(request, Request.blank('/'))
     REGISTRY.register(response, Response())
-    REGISTRY.register(session, beaker.session.SessionObject({}))
     REGISTRY.register(allura.credentials, allura.lib.security.Credentials())
     c.model_cache = None
     ThreadLocalORMSession.close_all()