You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@allura.apache.org by gc...@apache.org on 2025/01/07 18:02:37 UTC

(allura) 02/03: incomplete multifactor auth redirs back to form, instead of messing with session (problematic if you have any background requests like images, ajax etc)

This is an automated email from the ASF dual-hosted git repository.

gcruz pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/allura.git

commit 8e16eb31150b5cb489eddbc5418b6bbd56e0858b
Author: Dave Brondsema <db...@slashdotmedia.com>
AuthorDate: Mon Jan 6 16:52:05 2025 -0500

    incomplete multifactor auth redirs back to form, instead of messing with session (problematic if you have any background requests like images, ajax etc)
---
 Allura/allura/controllers/auth.py              |  4 +++-
 Allura/allura/lib/plugin.py                    |  4 ++--
 Allura/allura/templates/login_multifactor.html |  3 ++-
 Allura/allura/tests/functional/test_auth.py    | 11 +++++------
 4 files changed, 12 insertions(+), 10 deletions(-)

diff --git a/Allura/allura/controllers/auth.py b/Allura/allura/controllers/auth.py
index 8857bdaa0..6f7d3fb53 100644
--- a/Allura/allura/controllers/auth.py
+++ b/Allura/allura/controllers/auth.py
@@ -362,8 +362,10 @@ class AuthController(BaseController):
         redirect('/auth/preferences/')
 
     @expose()
-    def logout(self):
+    def logout(self, return_to=None):
         plugin.AuthenticationProvider.get(request).logout()
+        if return_to:
+            redirect(self._verify_return_to(return_to))
         redirect(config.get('auth.post_logout_url', '/'))
 
     @staticmethod
diff --git a/Allura/allura/lib/plugin.py b/Allura/allura/lib/plugin.py
index 437357be2..dba9bc438 100644
--- a/Allura/allura/lib/plugin.py
+++ b/Allura/allura/lib/plugin.py
@@ -95,6 +95,7 @@ class AuthenticationProvider:
     multifactor_allowed_urls = [
         '/auth/multifactor',
         '/auth/do_multifactor',
+        '/auth/logout',
     ]
     cfg_prefix_pwds = 'auth.password.'
     default_pwd_algo = 'scrypt'  # noqa: S105
@@ -129,8 +130,7 @@ class AuthenticationProvider:
 
         if 'multifactor-username' in self.session and request.path not in self.multifactor_allowed_urls:
             # ensure any partially completed multifactor login is not left open, if user goes to any other pages
-            del self.session['multifactor-username']
-            self.session.save()
+            redirect(h.url_return_to(self.multifactor_allowed_urls[0], self.request))
         if user is None:
             return M.User.anonymous()
         if user.disabled or user.pending:
diff --git a/Allura/allura/templates/login_multifactor.html b/Allura/allura/templates/login_multifactor.html
index 749b74b34..061f87469 100644
--- a/Allura/allura/templates/login_multifactor.html
+++ b/Allura/allura/templates/login_multifactor.html
@@ -45,6 +45,7 @@
             or <a href="#" class="show-totp">use an authenticator app code</a>
         </span>
     </span>
+        or <a href="/auth/logout?return_to=/auth/">Cancel</a>
     <input type="hidden" name="mode" value="{{ mode }}"/>
     {{ lib.csrf_token() }}
     </p>
@@ -84,4 +85,4 @@
       });
   });
 </script>
-{% endblock %}
\ No newline at end of file
+{% endblock %}
diff --git a/Allura/allura/tests/functional/test_auth.py b/Allura/allura/tests/functional/test_auth.py
index 3ca7741d0..1b9cafaf7 100644
--- a/Allura/allura/tests/functional/test_auth.py
+++ b/Allura/allura/tests/functional/test_auth.py
@@ -3163,19 +3163,18 @@ class TestTwoFactor(TestController):
         r = r.follow()
 
         # go to some other page instead of filling out the 2FA code
-        other_r = self.app.get('/')
+        r = self.app.get('/')
+        assert r.location.endswith('/auth/multifactor?return_to=%2F')
 
         # then try to complete the 2FA form
+        r = r.follow()
         totp = TotpService().Totp(self.sample_key)
         code = totp.generate(time_time())
         r.form['code'] = code
         r = r.form.submit()
 
-        # sent back to regular login
-        assert ('Your multifactor login was disrupted, please start over.' ==
-                json.loads(self.webflash(r))['message']), self.webflash(r)
-        r = r.follow()
-        assert 'Password Login' in r
+        # login worked
+        assert r.session['username'] == 'test-admin'
 
     def test_login_recovery_code(self):
         self._init_totp()