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

asf-gitbox-commits pushed a commit to branch db/8607
in repository https://gitbox.apache.org/repos/asf/allura.git

commit 9a32ca3312f437a5d93d4e66a54c75d5deac6de1
Author: Dave Brondsema <[email protected]>
AuthorDate: Mon May 18 15:10:49 2026 -0400

    [#8607] check client_id when making bearer token
---
 Allura/allura/controllers/auth.py           |  5 +++++
 Allura/allura/tests/functional/test_auth.py | 33 +++++++++++++++++++++++++++++
 2 files changed, 38 insertions(+)

diff --git a/Allura/allura/controllers/auth.py 
b/Allura/allura/controllers/auth.py
index 385cc6c08..0917f19df 100644
--- a/Allura/allura/controllers/auth.py
+++ b/Allura/allura/controllers/auth.py
@@ -1577,6 +1577,11 @@ def generate_bearer_token(self, client_id):
         """
         Manually generates an OAuth2 access token without needing to go 
through the OAuth2 flow.
         """
+        client = M.OAuth2ClientApp.query.get(client_id=client_id)
+        if client is None or client.user_id != c.user._id:
+            flash('Invalid client ID', 'error')
+            redirect('.')
+
         M.OAuth2AccessToken(
             client_id=client_id,
             user_id=c.user._id,
diff --git a/Allura/allura/tests/functional/test_auth.py 
b/Allura/allura/tests/functional/test_auth.py
index 31cb3e413..8338a2ecc 100644
--- a/Allura/allura/tests/functional/test_auth.py
+++ b/Allura/allura/tests/functional/test_auth.py
@@ -2586,6 +2586,39 @@ def test_authorization_code_no_duplicates(self, 
mock_client):
         ac = 
M.OAuth2AuthorizationCode.query.find(dict(client_id=c.client_id)).all()
         assert len(ac) == 1
 
+    @mock.patch.dict(config, {'auth.oauth2.enabled': True})
+    def test_generate_bearer_token_ownership_check(self):
+        user = M.User.by_username('test-admin')
+        M.OAuth2ClientApp(
+            client_id='client_12345',
+            client_secret='98765',
+            user_id=user._id,
+            name='testoauth2',
+            description='test client',
+            response_type='code',
+            redirect_uris=['https://localhost/']
+        )
+        ThreadLocalODMSession.flush_all()
+
+        self.app.get('/').follow()
+
+        # As test-user (not the owner), should be rejected
+        r = self.app.get('/auth/oauth/')
+        form = [f for f in r.forms.values() if f.action == 
'generate_bearer_token'][0]
+        r = form.submit(extra_environ={'username': 'test-user'})
+        assert 'Invalid client ID' in self.webflash(r)
+        assert M.OAuth2AccessToken.query.get(client_id='client_12345') is None
+
+        # As test-admin (the owner), should succeed
+        r = self.app.get('/auth/oauth/')
+        form = [f for f in r.forms.values() if f.action == 
'generate_bearer_token'][0]
+        r = form.submit()
+        assert '' == self.webflash(r)
+        token = M.OAuth2AccessToken.query.get(client_id='client_12345')
+        assert token is not None
+        assert token.is_bearer is True
+        assert token.user_id == user._id
+
 
 class TestOAuthRequestToken(TestController):
 

Reply via email to