Repository: allura
Updated Branches:
  refs/heads/db/8130 [created] 7fb402233


[#8130] invalidate other login sessions after setting up two-factor auth


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

Branch: refs/heads/db/8130
Commit: 7fb4022335055d605b571f538cff5661df509fff
Parents: e305225
Author: Dave Brondsema <d...@brondsema.net>
Authored: Tue Sep 20 16:44:01 2016 -0400
Committer: Dave Brondsema <d...@brondsema.net>
Committed: Tue Sep 20 16:44:01 2016 -0400

----------------------------------------------------------------------
 Allura/allura/controllers/auth.py           |  3 +++
 Allura/allura/lib/plugin.py                 | 16 +++++++++++-----
 Allura/allura/tests/functional/test_auth.py | 10 ++++++++++
 3 files changed, 24 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/7fb40223/Allura/allura/controllers/auth.py
----------------------------------------------------------------------
diff --git a/Allura/allura/controllers/auth.py 
b/Allura/allura/controllers/auth.py
index a5031d1..932f106 100644
--- a/Allura/allura/controllers/auth.py
+++ b/Allura/allura/controllers/auth.py
@@ -731,6 +731,8 @@ class PreferencesController(BaseController):
             h.auditlog_user('Set up multifactor TOTP')
             totp_service.set_secret_key(c.user, key)
             c.user.set_pref('multifactor', True)
+            c.user.set_tool_data('allura', multifactor_date=datetime.utcnow())
+            c.user.set_tool_data('allura', 
pwd_reset_preserve_session=session.id)  # other sessions will have to re-auth; 
preserve this one
             del session['totp_new_key']
             session.save()
             tg.flash('Two factor authentication has now been set up.')
@@ -754,6 +756,7 @@ class PreferencesController(BaseController):
         recovery = RecoveryCodeService.get()
         recovery.delete_all(c.user)
         c.user.set_pref('multifactor', False)
+        c.user.set_tool_data('allura', multifactor_date=None)
         tg.flash('Multifactor authentication has now been disabled.')
         email_body = 
g.jinja2_env.get_template('allura:templates/mail/twofactor_disabled.md').render(dict(
             user=c.user,

http://git-wip-us.apache.org/repos/asf/allura/blob/7fb40223/Allura/allura/lib/plugin.py
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/plugin.py b/Allura/allura/lib/plugin.py
index 7127120..4b2bf0a 100644
--- a/Allura/allura/lib/plugin.py
+++ b/Allura/allura/lib/plugin.py
@@ -118,11 +118,17 @@ 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))
+        session_create_date = datetime.utcfromtimestamp(self.session.created)
+        if user.is_anonymous():
+            sessions_need_reauth = False
+        elif self.get_last_password_updated(user) > session_create_date:
+            sessions_need_reauth = True
+        elif (user.get_tool_data('allura', 'multifactor_date') or 
datetime.min) > session_create_date:
+            sessions_need_reauth = True
+        else:
+            sessions_need_reauth = False
+        if sessions_need_reauth and user.get_tool_data('allura', 
'pwd_reset_preserve_session') != self.session.id:
+            log.debug('Session logged out: due to user %s pwd change or 
multifactor enabled', user.username)
             self.logout()
             return M.User.anonymous()
 

http://git-wip-us.apache.org/repos/asf/allura/blob/7fb40223/Allura/allura/tests/functional/test_auth.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/functional/test_auth.py 
b/Allura/allura/tests/functional/test_auth.py
index 4ba27e3..b7b28be 100644
--- a/Allura/allura/tests/functional/test_auth.py
+++ b/Allura/allura/tests/functional/test_auth.py
@@ -2093,6 +2093,11 @@ class TestTwoFactor(TestController):
             assert_in('Password Confirmation', r)
 
     def test_enable_totp(self):
+        # create a separate session, for later use in the test
+        other_session = TestController()
+        other_session.setUp()
+        other_session.app.get('/auth/preferences/')
+
         with out_audits(user=True):
             r = self.app.get('/auth/preferences/totp_new')
             assert_in('Password Confirmation', r)
@@ -2128,6 +2133,11 @@ class TestTwoFactor(TestController):
         r = r.follow()
         assert_in('Recovery Codes', r)
 
+        # Confirm any pre-existing sessions have to re-authenticate
+        r = other_session.app.get('/auth/preferences/')
+        assert_in('/auth/?return_to', r.headers['Location'])
+        other_session.tearDown()
+
     def test_reset_totp(self):
         self._init_totp()
 

Reply via email to