This is an automated email from the ASF dual-hosted git repository. asf-gitbox-commits pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/allura.git
commit bb89bba9f370db183c4d9aaa78b4929981a2fdb4 Author: Dave Brondsema <[email protected]> AuthorDate: Mon May 18 13:27:01 2026 -0400 [#8607] perm checks in markdown_to_html and fix wiki tool check --- Allura/allura/controllers/newforge.py | 14 +++++++--- Allura/allura/tests/functional/test_newforge.py | 34 ++++++++++++++++++++++--- Allura/allura/tests/functional/test_root.py | 3 ++- 3 files changed, 44 insertions(+), 7 deletions(-) diff --git a/Allura/allura/controllers/newforge.py b/Allura/allura/controllers/newforge.py index 68351fd3f..ef93940ae 100644 --- a/Allura/allura/controllers/newforge.py +++ b/Allura/allura/controllers/newforge.py @@ -23,9 +23,11 @@ from webob import exc from tg import app_globals as g +from tg import tmpl_context as c from allura.lib import helpers as h from allura.lib import utils from allura.lib.exceptions import ForgeError +from allura.lib.security import require_access class NewForgeController: @@ -35,16 +37,22 @@ class NewForgeController: @expose() @without_trailing_slash - def markdown_to_html(self, markdown, neighborhood=None, project=None, app=None): + def markdown_to_html(self, markdown, neighborhood, project, app): """Convert markdown to html.""" if neighborhood is None or project is None: raise exc.HTTPBadRequest() try: h.set_context(project, app, neighborhood=neighborhood) - except ForgeError: + except ForgeError: # no project or nbhd found raise exc.HTTPBadRequest() - if app == 'wiki': + if c.app is None: + raise exc.HTTPBadRequest() + + require_access(c.project, 'read') + require_access(c.app, 'read') + + if c.app.tool_label.lower() == 'wiki': html = g.markdown_wiki.convert(markdown) else: html = g.markdown.convert(markdown) diff --git a/Allura/allura/tests/functional/test_newforge.py b/Allura/allura/tests/functional/test_newforge.py index de5432585..c52fbf37d 100644 --- a/Allura/allura/tests/functional/test_newforge.py +++ b/Allura/allura/tests/functional/test_newforge.py @@ -17,6 +17,7 @@ import logging from urllib.parse import quote +from ming.odm import ThreadLocalODMSession from testfixtures import LogCapture from allura.tests import TestController @@ -30,19 +31,46 @@ class TestNewForgeController(TestController): def test_markdown_to_html(self): n = M.Neighborhood.query.get(name='Projects') r = self.app.get( - '/nf/markdown_to_html?markdown=*aaa*bb[wiki:Home]&project=test&app=bugs&neighborhood=%s' % n._id, validate_chunk=True) + '/nf/markdown_to_html?markdown=*aaa*bb[wiki:Home]&project=test&app=wiki&neighborhood=%s' % n._id, validate_chunk=True) assert '<p><em>aaa</em>bb<a class="alink" href="/p/test/wiki/Home/">[wiki:Home]</a></p>' in r, r # this happens to trigger an error bad_markdown = '<foo {bar}>' - r = self.app.get('/nf/markdown_to_html?markdown=%s&project=test&app=bugs&neighborhood=%s' % + r = self.app.get('/nf/markdown_to_html?markdown=%s&project=test&app=wiki&neighborhood=%s' % (quote(bad_markdown), n._id)) r.mustcontain('The markdown supplied could not be parsed correctly.') r.mustcontain('<pre><foo {bar}></pre>') - r = self.app.get('/nf/markdown_to_html?markdown=*aaa*bb[wiki:Home]&project=test&app=bugs&neighborhood=bogus', + r = self.app.get('/nf/markdown_to_html?markdown=*aaa*bb[wiki:Home]&project=test&app=wiki&neighborhood=bogus', status=400) + @td.with_wiki + def test_markdown_to_html_private_project(self): + # Make the test project private by removing anonymous read access + p = M.Project.query.get(shortname='test') + p.acl = [ace for ace in p.acl + if not (ace.access == M.ACE.ALLOW + and ace.permission == 'read' + and ace.role_id == M.ProjectRole.anonymous(p)._id)] + ThreadLocalODMSession.flush_all() + + n = M.Neighborhood.query.get(name='Projects') + # Authenticated user with access should still work + r = self.app.get( + '/nf/markdown_to_html?markdown=*hello*&project=test&app=wiki&neighborhood=%s' % n._id, + extra_environ=dict(username='test-admin')) + assert '<p><em>hello</em></p>' in r, r + + # test-user and *anonymous get different errors, but that's ok, neither work: + self.app.get( + '/nf/markdown_to_html?markdown=*hello*&project=test&app=wiki&neighborhood=%s' % n._id, + extra_environ=dict(username='test-user'), + status=403) + self.app.get( + '/nf/markdown_to_html?markdown=*hello*&project=test&app=wiki&neighborhood=%s' % n._id, + extra_environ=dict(username='*anonymous'), + status=302) + def test_markdown_syntax(self): with LogCapture(level=logging.INFO) as logs: r = self.app.get('/nf/markdown_syntax') diff --git a/Allura/allura/tests/functional/test_root.py b/Allura/allura/tests/functional/test_root.py index 1c0b8c8f7..b3ca1139b 100644 --- a/Allura/allura/tests/functional/test_root.py +++ b/Allura/allura/tests/functional/test_root.py @@ -91,11 +91,12 @@ def test_neighborhood(self): assert cat_links[0].find('a').get('href') == '/browse/clustering' assert cat_links[0].find('a').find('span').string == 'Clustering' + @td.with_wiki def test_validation(self): # this is not configured ON currently, so adding an individual test to get coverage of the validator itself with mock.patch.dict(os.environ, ALLURA_VALIDATION='all'): self.app.get('/neighborhood') - self.app.get('/nf/markdown_to_html?markdown=aaa&project=test&app=bugs&neighborhood=%s' + self.app.get('/nf/markdown_to_html?markdown=aaa&project=test&app=wiki&neighborhood=%s' % M.Neighborhood.query.get(name='Projects')._id, validate_chunk=True)
