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 <[email protected]>
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()

Reply via email to