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

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

commit 68d0a31e9b5155b722a2a93662f66a85069aa2ed
Author: Dave Brondsema <[email protected]>
AuthorDate: Tue Jun 2 11:38:07 2026 -0400

    [#8607] add explicit perm check on project rest controller
---
 Allura/allura/controllers/rest.py           |  3 +++
 Allura/allura/tests/functional/test_rest.py | 16 ++++++++++++++++
 2 files changed, 19 insertions(+)

diff --git a/Allura/allura/controllers/rest.py 
b/Allura/allura/controllers/rest.py
index 7613ac4fb..267855329 100644
--- a/Allura/allura/controllers/rest.py
+++ b/Allura/allura/controllers/rest.py
@@ -708,6 +708,9 @@ def add_project(self, **kw):
 
 class ProjectRestController:
 
+    def _check_security(self):
+        security.require_access(c.project, 'read')
+
     @expose()
     def _lookup(self, name, *remainder):
         if not name:
diff --git a/Allura/allura/tests/functional/test_rest.py 
b/Allura/allura/tests/functional/test_rest.py
index becb5684b..b0c8b3918 100644
--- a/Allura/allura/tests/functional/test_rest.py
+++ b/Allura/allura/tests/functional/test_rest.py
@@ -26,6 +26,7 @@
 import webtest
 from ming.odm import ThreadLocalODMSession
 from tg import config
+from tg import tmpl_context as c
 
 from allura.tests import decorators as td
 from alluratest.controller import TestRestApiBase
@@ -222,6 +223,21 @@ def test_project_data_tools(self):
         assert 'bugs' in tool_mounts
         assert 'private-bugs' not in tool_mounts
 
+    def test_project_metadata_private_denied_to_anon(self):
+        # public project: anonymous can read project metadata + DOAP via REST
+        assert self.app.get('/rest/p/test/', extra_environ={'username': 
'*anonymous'}, status=200)
+        # make the project itself private
+        with h.push_context('test', neighborhood='Projects'):
+            role = M.ProjectRole.by_name('*anonymous')._id
+            read_permission = M.ACE.allow(role, 'read')
+            c.project.acl.remove(read_permission)
+        ThreadLocalODMSession.flush_all()
+        # anonymous is now denied the project metadata and member roster 
(index + doap)
+        self.app.get('/rest/p/test/', extra_environ={'username': 
'*anonymous'}, status=401)
+        self.app.get('/rest/p/test/?doap', extra_environ={'username': 
'*anonymous'}, status=401)
+        # an authorized admin can still read it
+        r = self.api_get('/rest/p/test/', status=200)
+
     def test_neighborhood_has_access_no_params(self):
         r = self.api_get('/rest/p/has_access', status=404)
         r = self.api_get('/rest/p/has_access?user=test-admin', status=404)

Reply via email to