allura git commit: [#8130] invalidate other login sessions after setting up two-factor auth

2016-09-22 Thread brondsem
Repository: allura
Updated Branches:
  refs/heads/master e30522555 -> 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/master
Commit: 7fb4022335055d605b571f538cff5661df509fff
Parents: e305225
Author: Dave Brondsema 
Authored: Tue Sep 20 16:44:01 2016 -0400
Committer: Dave Brondsema 
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_n

allura git commit: [#8130] invalidate other login sessions after setting up two-factor auth

2016-09-20 Thread brondsem
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 
Authored: Tue Sep 20 16:44:01 2016 -0400
Committer: Dave Brondsema 
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_ne