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 3fd079342e324e4b518dda650006be15e22b5910 Author: Dave Brondsema <[email protected]> AuthorDate: Mon Jan 6 18:06:03 2025 -0500 if you end up on /auth/ or /auth/multifactor already fully logged in, skip that form --- Allura/allura/controllers/auth.py | 11 ++++++ Allura/allura/tests/functional/test_auth.py | 46 ++++++++++++++++++---- Allura/allura/tests/functional/test_site_admin.py | 22 +++++------ AlluraTest/alluratest/validation.py | 4 +- .../forgegit/tests/functional/test_controllers.py | 2 +- 5 files changed, 63 insertions(+), 22 deletions(-) diff --git a/Allura/allura/controllers/auth.py b/Allura/allura/controllers/auth.py index 6f7d3fb53..a40e434c3 100644 --- a/Allura/allura/controllers/auth.py +++ b/Allura/allura/controllers/auth.py @@ -153,6 +153,13 @@ class AuthController(BaseController): return_to = six.ensure_text(request.referer) else: return_to = None + + if return_to and return_to.endswith('/auth/'): + return_to = None + + if not c.user.is_anonymous(): # already logged in + redirect(self._verify_return_to(return_to)) + c.form = F.login_form return dict(return_to=return_to) @@ -404,6 +411,10 @@ class AuthController(BaseController): if not asbool(config.get('auth.multifactor.totp', False)): raise wexc.HTTPNotFound + if not c.user.is_anonymous(): + # already logged in, no need to do this form + redirect(self._verify_return_to(return_to)) + return dict( return_to=return_to, mode=mode, diff --git a/Allura/allura/tests/functional/test_auth.py b/Allura/allura/tests/functional/test_auth.py index 1b9cafaf7..2f6a76af4 100644 --- a/Allura/allura/tests/functional/test_auth.py +++ b/Allura/allura/tests/functional/test_auth.py @@ -53,19 +53,18 @@ def unentity(s): class TestAuth(TestController): def test_login(self): - self.app.get('/auth/') - r = self.app.post('/auth/send_verification_link', params=dict(a='[email protected]', - _session_id=self.app.cookies['_session_id'])) + self.app.get('/auth/preferences/') # establish session_id cookie email = M.User.query.get(username='test-admin').email_addresses[0] r = self.app.post('/auth/send_verification_link', params=dict(a=email, _session_id=self.app.cookies['_session_id'])) + assert json.loads(self.webflash(r))['status'] == 'ok', self.webflash(r) + ThreadLocalODMSession.flush_all() r = self.app.get('/auth/verify_addr', params=dict(a='foo')) assert json.loads(self.webflash(r))['status'] == 'error', self.webflash(r) ea = M.EmailAddress.find({'email': email}).first() r = self.app.get('/auth/verify_addr', params=dict(a=ea.nonce)) assert json.loads(self.webflash(r))['status'] == 'ok', self.webflash(r) - r = self.app.get('/auth/logout') with audits('Successful login', user=True): r = self.app.post('/auth/do_login', params=dict( @@ -84,12 +83,12 @@ class TestAuth(TestController): assert wf['message'] == 'Spambot protection engaged' with audits('Failed login', user=True): - r = self.app.post('/auth/do_login', antispam=True, params=dict( + r = self.app.post('/auth/do_login', antispam=True, extra_environ=dict(username='*anonymous'), params=dict( username='test-user', password='food', _session_id=self.app.cookies['_session_id'])) assert 'Invalid login' in str(r), r.showbrowser() - r = self.app.post('/auth/do_login', antispam=True, params=dict( + r = self.app.post('/auth/do_login', antispam=True, extra_environ=dict(username='*anonymous'), params=dict( username='test-usera', password='foo', _session_id=self.app.cookies['_session_id'])) assert 'Invalid login' in str(r), r.showbrowser() @@ -225,6 +224,32 @@ class TestAuth(TestController): with audits('Successful login', 'Rehashed password automatically', user=True): r = f.submit(extra_environ={'username': '*anonymous'}) + def test_login_redirect(self): + # show page + r = self.app.get('/auth/', extra_environ={'username': '*anonymous'}, + status=200) + + # already logged in, so redir + r = self.app.get('/auth/', extra_environ={'username': 'test-admin'}, + status=302) + assert r.location == 'http://localhost/' + + # redir to requested location + r = self.app.get('/auth/', extra_environ={'username': 'test-admin'}, params={'return_to': '/p/test/?a=b'}, + status=302) + assert r.location == 'http://localhost/p/test/?a=b' + + # no redirect loop on /auth/ + r = self.app.get('/auth/', extra_environ={'username': 'test-admin'}, params={'return_to': '/auth/'}, + status=302) + assert r.location == 'http://localhost/' + + # no external redirect + r = self.app.get('/auth/', extra_environ={'username': 'test-admin'}, params={'return_to': 'http://example.com/x'}, + status=302) + assert r.location == 'http://localhost/' + + def test_login_overlay(self): r = self.app.get('/auth/login_fragment/', extra_environ={'username': '*anonymous'}) f = r.forms[0] @@ -2878,12 +2903,12 @@ class TestCSRFProtection(TestController): assert r.location == 'http://localhost/auth/' def test_blocks_invalid_on_login(self): - r = self.app.get('/auth/') + r = self.app.get('/auth/', extra_environ=dict(username='*anonymous')) r.form['_session_id'] = 'bogus' r.form.submit(status=403) def test_token_present_on_first_request(self): - r = self.app.get('/auth/') + r = self.app.get('/auth/', extra_environ=dict(username='*anonymous')) assert r.form['_session_id'].value @@ -3117,6 +3142,11 @@ class TestTwoFactor(TestController): assert r.session['username'] == 'test-admin' assert r.location.endswith('/p/foo'), r + # if you end up on multifactor page again somehow, redir + r = self.app.get('/auth/multifactor?return_to=/p/foo', status=302) + assert r.location == 'http://localhost/p/foo' + + def test_login_rate_limit(self): self._init_totp() diff --git a/Allura/allura/tests/functional/test_site_admin.py b/Allura/allura/tests/functional/test_site_admin.py index 78e775904..a6e955072 100644 --- a/Allura/allura/tests/functional/test_site_admin.py +++ b/Allura/allura/tests/functional/test_site_admin.py @@ -36,12 +36,10 @@ from allura.lib.plugin import LocalAuthenticationProvider class TestSiteAdmin(TestController): def test_access(self): - r = self.app.get('/nf/admin/', extra_environ=dict( - username='test-user'), status=403) + r = self.app.get('/nf/admin/', extra_environ=dict(username='test-user'), status=403) - r = self.app.get('/nf/admin/', extra_environ=dict( - username='*anonymous'), status=302) - r = r.follow() + r = self.app.get('/nf/admin/', extra_environ=dict(username='*anonymous'), status=302) + r = r.follow(extra_environ=dict(username='*anonymous')) assert 'Login' in r def test_home(self): @@ -65,8 +63,9 @@ class TestSiteAdmin(TestController): def test_new_projects_access(self): self.app.get('/nf/admin/new_projects', extra_environ=dict( username='test_user'), status=403) - r = self.app.get('/nf/admin/new_projects', extra_environ=dict( - username='*anonymous'), status=302).follow() + + self.app.extra_environ = {'username': '*anonymous'} + r = self.app.get('/nf/admin/new_projects', status=302).follow() assert 'Login' in r def test_new_projects(self): @@ -107,8 +106,8 @@ class TestSiteAdmin(TestController): assert count == 1 # only row with headers - no results def test_reclone_repo_access(self): - r = self.app.get('/nf/admin/reclone_repo', extra_environ=dict( - username='*anonymous'), status=302).follow() + self.app.extra_environ = dict(username='*anonymous') + r = self.app.get('/nf/admin/reclone_repo', status=302).follow() assert 'Login' in r def test_reclone_repo(self): @@ -187,8 +186,9 @@ class TestSiteAdminNotifications(TestController): def test_site_notifications_access(self): self.app.get('/nf/admin/site_notifications', extra_environ=dict( username='test_user'), status=403) - r = self.app.get('/nf/admin/site_notifications', extra_environ=dict( - username='*anonymous'), status=302).follow() + + self.app.extra_environ = dict(username='*anonymous') + r = self.app.get('/nf/admin/site_notifications', status=302).follow() assert 'Login' in r def test_site_notifications(self): diff --git a/AlluraTest/alluratest/validation.py b/AlluraTest/alluratest/validation.py index 434b1a140..ee3c7ce48 100644 --- a/AlluraTest/alluratest/validation.py +++ b/AlluraTest/alluratest/validation.py @@ -266,8 +266,8 @@ class PostParamCheckingTestApp(AntiSpamTestApp): self._validate_val(k, vv, method) elif not isinstance(v, (str, bytes, webtest.forms.File, webtest.forms.Upload)): raise TypeError( - '%s key %s has value %s of type %s, not str. ' % - (method, k, v, type(v))) + '%s key %r has value %s of type %s, not str. ' % + (method.upper(), k, v, type(v))) def get(self, *args, **kwargs) -> TestResponse: params = None diff --git a/ForgeGit/forgegit/tests/functional/test_controllers.py b/ForgeGit/forgegit/tests/functional/test_controllers.py index b071af922..f9edeaf6d 100644 --- a/ForgeGit/forgegit/tests/functional/test_controllers.py +++ b/ForgeGit/forgegit/tests/functional/test_controllers.py @@ -879,7 +879,7 @@ class TestFork(_TestCase): }, extra_environ=dict(username='*anonymous'), status=302, - ).follow() + ).follow(extra_environ=dict(username='*anonymous')) assert 'Login' in r r = self.app.post('/p/test/src-git/merge-requests/1/do_request_merge_edit',
