This is an automated email from the ASF dual-hosted git repository. asf-gitbox-commits pushed a commit to branch db/8607d in repository https://gitbox.apache.org/repos/asf/allura.git
commit 909c17c2bc6ecbf0ebf7b945ed14ce6e45118e92 Author: Dave Brondsema <[email protected]> AuthorDate: Fri Jun 12 15:32:23 2026 -0400 [#8607] require post for phone verification endpoints --- Allura/allura/controllers/project.py | 2 + .../allura/tests/functional/test_neighborhood.py | 48 +++++++++++++++++----- 2 files changed, 39 insertions(+), 11 deletions(-) diff --git a/Allura/allura/controllers/project.py b/Allura/allura/controllers/project.py index cf521e59c..cf46f7705 100644 --- a/Allura/allura/controllers/project.py +++ b/Allura/allura/controllers/project.py @@ -164,6 +164,7 @@ def phone_verification_fragment(self, *args, **kw): return {} @expose('json:') + @require_post() def verify_phone(self, number, **kw): require_access(self.neighborhood, 'register') p = plugin.ProjectRegistrationProvider.get() @@ -180,6 +181,7 @@ def verify_phone(self, number, **kw): return result @expose('json:') + @require_post() def check_phone_verification(self, pin, **kw): require_access(self.neighborhood, 'register') p = plugin.ProjectRegistrationProvider.get() diff --git a/Allura/allura/tests/functional/test_neighborhood.py b/Allura/allura/tests/functional/test_neighborhood.py index f6f43c54c..87dcf3954 100644 --- a/Allura/allura/tests/functional/test_neighborhood.py +++ b/Allura/allura/tests/functional/test_neighborhood.py @@ -975,17 +975,25 @@ def test_nav_json(self): class TestPhoneVerificationOnProjectRegistration(TestController): + def setup_method(self, method): + super().setup_method(method) + self.app.get('/p/phone_verification_fragment') # establish _csrf_token cookie + def test_phone_verification_fragment_renders(self): self.app.get('/p/phone_verification_fragment', status=200) self.app.get('/adobe/phone_verification_fragment', status=200) def test_verify_phone_no_params(self): with h.push_config(config, **{'project.verify_phone': 'true'}): - self.app.get('/p/verify_phone', status=404) + self.app.post('/p/verify_phone', + params={'_csrf_token': self.app.cookies['_csrf_token']}, + status=404) def test_verify_phone_error(self): with h.push_config(config, **{'project.verify_phone': 'true'}): - r = self.app.get('/p/verify_phone', {'number': '1234567890'}) + r = self.app.post('/p/verify_phone', + params={'number': '1234567890', + '_csrf_token': self.app.cookies['_csrf_token']}) expected = {'status': 'error', 'error': 'Phone service is not configured'} assert r.json == expected @@ -999,7 +1007,9 @@ def test_verify_phone(self, phone_service): with h.push_config(config, **{'project.verify_phone': 'true'}): phone_service.verify.return_value = { 'request_id': 'request-id', 'status': 'ok'} - r = self.app.get('/p/verify_phone', {'number': '1-555-444-3333'}) + r = self.app.post('/p/verify_phone', + params={'number': '1-555-444-3333', + '_csrf_token': self.app.cookies['_csrf_token']}) phone_service.verify.assert_called_once_with('15554443333') assert r.json == {'status': 'ok'} rid = r.session.get('phone_verification.request_id') @@ -1014,7 +1024,9 @@ def test_verify_phone_escapes_error(self, phone_service): 'error': '<script>alert("hacked");</script>', } with h.push_config(config, **{'project.verify_phone': 'true'}): - r = self.app.get('/p/verify_phone', {'number': '555-444-3333'}) + r = self.app.post('/p/verify_phone', + params={'number': '555-444-3333', + '_csrf_token': self.app.cookies['_csrf_token']}) expected = { 'status': 'error', 'error': '<script>alert("hacked");</script>', @@ -1028,7 +1040,9 @@ def test_verify_phone_already_used(self, phone_service): u.set_tool_data('phone_verification', number_hash=utils.phone_number_hash('1-555-444-9999')) session(u).flush(u) phone_service.verify.return_value = {'request_id': 'request-id', 'status': 'ok'} - r = self.app.get('/p/verify_phone', {'number': '1-555-444-9999'}) + r = self.app.post('/p/verify_phone', + params={'number': '1-555-444-9999', + '_csrf_token': self.app.cookies['_csrf_token']}) assert r.json == { 'status': 'error', 'error': 'That phone number has already been used.' @@ -1036,7 +1050,9 @@ def test_verify_phone_already_used(self, phone_service): def test_check_phone_verification_no_params(self): with h.push_config(config, **{'project.verify_phone': 'true'}): - self.app.get('/p/check_phone_verification', status=404) + self.app.post('/p/check_phone_verification', + params={'_csrf_token': self.app.cookies['_csrf_token']}, + status=404) @patch.object(g, 'phone_service', autospec=True) def test_check_phone_verification_error(self, phone_service): @@ -1047,9 +1063,13 @@ def test_check_phone_verification_error(self, phone_service): # make request to verify first to initialize session phone_service.verify.return_value = { 'request_id': req_id, 'status': 'ok'} - r = self.app.get('/p/verify_phone', {'number': '1234567890'}) + r = self.app.post('/p/verify_phone', + params={'number': '1234567890', + '_csrf_token': self.app.cookies['_csrf_token']}) - r = self.app.get('/p/check_phone_verification', {'pin': '1234'}) + r = self.app.post('/p/check_phone_verification', + params={'pin': '1234', + '_csrf_token': self.app.cookies['_csrf_token']}) assert r.json == {'status': 'error'} phone_service.check.assert_called_once_with(req_id, '1234') @@ -1066,9 +1086,13 @@ def test_check_phone_verification_ok(self, phone_service): # make request to verify first to initialize session phone_service.verify.return_value = { 'request_id': req_id, 'status': 'ok'} - r = self.app.get('/p/verify_phone', {'number': '11234567890'}) + r = self.app.post('/p/verify_phone', + params={'number': '11234567890', + '_csrf_token': self.app.cookies['_csrf_token']}) - r = self.app.get('/p/check_phone_verification', {'pin': '1234'}) + r = self.app.post('/p/check_phone_verification', + params={'pin': '1234', + '_csrf_token': self.app.cookies['_csrf_token']}) assert r.json == {'status': 'ok'} phone_service.check.assert_called_once_with(req_id, '1234') @@ -1083,7 +1107,9 @@ def test_check_phone_verification_escapes_error(self, phone_service): 'error': '<script>alert("hacked");</script>', } with h.push_config(config, **{'project.verify_phone': 'true'}): - r = self.app.get('/p/check_phone_verification', {'pin': '1234'}) + r = self.app.post('/p/check_phone_verification', + params={'pin': '1234', + '_csrf_token': self.app.cookies['_csrf_token']}) expected = { 'status': 'error', 'error': '<script>alert("hacked");</script>',
