(allura) 03/03: [#8557] update akismet version (optional)

2024-04-30 Thread brondsem
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/allura.git

commit 0aab2bd9a3ba38f4af5fcf6fcd7959087b58d81b
Author: Dave Brondsema 
AuthorDate: Tue Apr 30 18:03:41 2024 -0400

[#8557] update akismet version (optional)
---
 requirements-optional.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/requirements-optional.txt b/requirements-optional.txt
index 6b5ef0bad..f68ec31a2 100644
--- a/requirements-optional.txt
+++ b/requirements-optional.txt
@@ -8,4 +8,4 @@ html2text
 mediawiki2html  # GPL
 
 # for spam checking
-akismet>=1.0.1
+akismet>=1.3



(allura) branch master updated (0628922be -> 0aab2bd9a)

2024-04-30 Thread brondsem
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/allura.git


from 0628922be code updates to AkismetWithoutStartupVerify
 new 817891228 [#7272] Add authorization views and improve validations
 new 13cfdd535 [#7272] OAuth2 tests, renaming, improvements, config option
 new 0aab2bd9a [#8557] update akismet version (optional)

The 3 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 Allura/allura/controllers/auth.py  |  61 
 Allura/allura/controllers/rest.py  | 167 -
 Allura/allura/lib/custom_middleware.py |  11 +-
 Allura/allura/lib/widgets/__init__.py  |   6 +-
 Allura/allura/lib/widgets/oauth_widgets.py |  11 ++
 Allura/allura/model/__init__.py|   4 +-
 Allura/allura/model/oauth.py   |  58 +--
 Allura/allura/templates/oauth2_applications.html   | 127 
 ...{oauth_authorize.html => oauth2_authorize.html} |  16 +-
 ..._authorize_ok.html => oauth2_authorize_ok.html} |  12 +-
 Allura/allura/tests/functional/test_auth.py| 156 +++
 Allura/allura/tests/functional/test_rest.py|   6 +
 Allura/development.ini |   3 +
 requirements-optional.txt  |   2 +-
 14 files changed, 563 insertions(+), 77 deletions(-)
 create mode 100644 Allura/allura/templates/oauth2_applications.html
 copy Allura/allura/templates/{oauth_authorize.html => oauth2_authorize.html} 
(77%)
 copy Allura/allura/templates/{oauth_authorize_ok.html => 
oauth2_authorize_ok.html} (68%)



(allura) 01/03: [#7272] Add authorization views and improve validations

2024-04-30 Thread brondsem
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/allura.git

commit 8178912285d859c55a365f67f896e1db373c307c
Author: Carlos Cruz 
AuthorDate: Mon Apr 1 18:39:49 2024 +

[#7272] Add authorization views and improve validations
---
 Allura/allura/controllers/auth.py|  58 +++
 Allura/allura/controllers/rest.py|  98 +
 Allura/allura/lib/widgets/__init__.py|   6 +-
 Allura/allura/lib/widgets/oauth_widgets.py   |  11 ++
 Allura/allura/model/oauth.py |  24 -
 Allura/allura/templates/oauth2_applications.html | 127 +++
 Allura/allura/templates/oauth2_authorize.html|  62 +++
 Allura/allura/templates/oauth2_authorize_ok.html |  35 +++
 8 files changed, 392 insertions(+), 29 deletions(-)

diff --git a/Allura/allura/controllers/auth.py 
b/Allura/allura/controllers/auth.py
index fab1757e8..8f462def0 100644
--- a/Allura/allura/controllers/auth.py
+++ b/Allura/allura/controllers/auth.py
@@ -50,6 +50,7 @@ from allura.lib.security import HIBPClient, 
HIBPCompromisedCredentials, HIBPClie
 from allura.lib.widgets import (
 SubscriptionForm,
 OAuthApplicationForm,
+OAuth2ApplicationForm,
 OAuthRevocationForm,
 LoginForm,
 ForgottenPasswordForm,
@@ -74,6 +75,7 @@ class F:
 subscription_form = SubscriptionForm()
 registration_form = forms.RegistrationForm(action='/auth/save_new')
 oauth_application_form = OAuthApplicationForm(action='register')
+oauth2_application_form = OAuth2ApplicationForm(action='register')
 oauth_revocation_form = OAuthRevocationForm(
 action='/auth/preferences/revoke_oauth')
 change_personal_data_form = forms.PersonalDataForm()
@@ -112,6 +114,7 @@ class AuthController(BaseController):
 self.user_info = UserInfoController()
 self.subscriptions = SubscriptionsController()
 self.oauth = OAuthController()
+self.oauth2 = OAuth2Controller()
 if asbool(config.get('auth.allow_user_to_disable_account', False)):
 self.disable = DisableAccountController()
 
@@ -1404,6 +1407,61 @@ class OAuthController(BaseController):
 redirect('.')
 
 
+class OAuth2Controller(BaseController):
+def _check_security(self):
+require_authenticated()
+
+def _revoke_all(self, client_id):
+M.OAuth2AuthorizationCode.query.remove({'client_id': client_id})
+M.OAuth2Token.query.remove({'client_id': client_id})
+
+@with_trailing_slash
+@expose('jinja:allura:templates/oauth2_applications.html')
+def index(self, **kw):
+c.form = F.oauth2_application_form
+provider = plugin.AuthenticationProvider.get(request)
+clients = M.OAuth2Client.for_user(c.user)
+model = []
+
+for client in clients:
+authorization = 
M.OAuth2AuthorizationCode.query.get(client_id=client.client_id)
+token = M.OAuth2Token.query.get(client_id=client.client_id)
+model.append(dict(client=client, authorization=authorization, 
token=token))
+
+return dict(
+menu=provider.account_navigation(),
+model=model
+)
+
+@expose()
+@require_post()
+@validate(F.oauth2_application_form, error_handler=index)
+def register(self, application_name=None, application_description=None, 
redirect_url=None, **kw):
+M.OAuth2Client(name=application_name,
+   description=application_description,
+   redirect_uris=[redirect_url])
+flash('Oauth2 Client registered')
+redirect('.')
+
+@expose()
+@require_post()
+def do_client_action(self, _id=None, deregister=None, revoke=None):
+client = M.OAuth2Client.query.get(client_id=_id)
+if client is None or client.user_id != c.user._id:
+flash('Invalid client ID', 'error')
+redirect('.')
+
+if deregister:
+self._revoke_all(_id)
+client.delete()
+flash('Client deleted and access tokens revoked.')
+
+if revoke:
+self._revoke_all(_id)
+flash('Access tokens revoked.')
+redirect('.')
+
+
 class DisableAccountController(BaseController):
 
 def _check_security(self):
diff --git a/Allura/allura/controllers/rest.py 
b/Allura/allura/controllers/rest.py
index 0f29c1676..e77c8bea9 100644
--- a/Allura/allura/controllers/rest.py
+++ b/Allura/allura/controllers/rest.py
@@ -19,7 +19,7 @@
 import json
 import logging
 from datetime import datetime, timedelta
-from urllib.parse import unquote, urlparse, parse_qs
+from urllib.parse import unquote, urlparse, parse_qs, parse_qsl
 
 import oauthlib.oauth1
 import oauthlib.oauth2
@@ -261,7 +261,7 @@ class Oauth2Validator(oauthlib.oauth2.RequestValidator):
 return request.uri
 
 def

(allura) 02/03: [#7272] OAuth2 tests, renaming, improvements, config option

2024-04-30 Thread brondsem
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/allura.git

commit 13cfdd53523a4f7267e7c240456c2bc1abf581fc
Author: Carlos Cruz 
AuthorDate: Tue Apr 16 16:24:30 2024 +

[#7272] OAuth2 tests, renaming, improvements, config option
---
 Allura/allura/controllers/auth.py|  17 ++-
 Allura/allura/controllers/rest.py| 111 ++--
 Allura/allura/lib/custom_middleware.py   |  11 +-
 Allura/allura/model/__init__.py  |   4 +-
 Allura/allura/model/oauth.py |  42 +++---
 Allura/allura/templates/oauth2_applications.html |   4 +-
 Allura/allura/tests/functional/test_auth.py  | 156 +++
 Allura/allura/tests/functional/test_rest.py  |   6 +
 Allura/development.ini   |   3 +
 9 files changed, 288 insertions(+), 66 deletions(-)

diff --git a/Allura/allura/controllers/auth.py 
b/Allura/allura/controllers/auth.py
index 8f462def0..3f3f82fdb 100644
--- a/Allura/allura/controllers/auth.py
+++ b/Allura/allura/controllers/auth.py
@@ -114,7 +114,10 @@ class AuthController(BaseController):
 self.user_info = UserInfoController()
 self.subscriptions = SubscriptionsController()
 self.oauth = OAuthController()
-self.oauth2 = OAuth2Controller()
+
+if asbool(config.get('auth.oauth2.enabled', False)):
+self.oauth2 = OAuth2Controller()
+
 if asbool(config.get('auth.allow_user_to_disable_account', False)):
 self.disable = DisableAccountController()
 
@@ -1413,19 +1416,19 @@ class OAuth2Controller(BaseController):
 
 def _revoke_all(self, client_id):
 M.OAuth2AuthorizationCode.query.remove({'client_id': client_id})
-M.OAuth2Token.query.remove({'client_id': client_id})
+M.OAuth2AccessToken.query.remove({'client_id': client_id})
 
 @with_trailing_slash
 @expose('jinja:allura:templates/oauth2_applications.html')
 def index(self, **kw):
 c.form = F.oauth2_application_form
 provider = plugin.AuthenticationProvider.get(request)
-clients = M.OAuth2Client.for_user(c.user)
+clients = M.OAuth2ClientApp.for_owner(c.user)
 model = []
 
 for client in clients:
 authorization = 
M.OAuth2AuthorizationCode.query.get(client_id=client.client_id)
-token = M.OAuth2Token.query.get(client_id=client.client_id)
+token = M.OAuth2AccessToken.query.get(client_id=client.client_id)
 model.append(dict(client=client, authorization=authorization, 
token=token))
 
 return dict(
@@ -1437,7 +1440,7 @@ class OAuth2Controller(BaseController):
 @require_post()
 @validate(F.oauth2_application_form, error_handler=index)
 def register(self, application_name=None, application_description=None, 
redirect_url=None, **kw):
-M.OAuth2Client(name=application_name,
+M.OAuth2ClientApp(name=application_name,
description=application_description,
redirect_uris=[redirect_url])
 flash('Oauth2 Client registered')
@@ -1446,8 +1449,8 @@ class OAuth2Controller(BaseController):
 @expose()
 @require_post()
 def do_client_action(self, _id=None, deregister=None, revoke=None):
-client = M.OAuth2Client.query.get(client_id=_id)
-if client is None or client.user_id != c.user._id:
+client = M.OAuth2ClientApp.query.get(client_id=_id)
+if client is None or client.owner_id != c.user._id:
 flash('Invalid client ID', 'error')
 redirect('.')
 
diff --git a/Allura/allura/controllers/rest.py 
b/Allura/allura/controllers/rest.py
index e77c8bea9..b16ae0dec 100644
--- a/Allura/allura/controllers/rest.py
+++ b/Allura/allura/controllers/rest.py
@@ -16,6 +16,7 @@
 #   under the License.
 
 """REST Controller"""
+from __future__ import annotations
 import json
 import logging
 from datetime import datetime, timedelta
@@ -52,11 +53,16 @@ class RestController:
 
 def __init__(self):
 self.oauth = OAuthNegotiator()
-self.oauth2 = Oauth2Negotiator()
 self.auth = AuthRestController()
 
+if self._is_oauth2_enabled():
+self.oauth2 = Oauth2Negotiator()
+
+def _is_oauth2_enabled(self):
+return asbool(config.get('auth.oauth2.enabled', False))
+
 def _check_security(self):
-if not request.path.startswith('/rest/oauth/'):  # everything but 
OAuthNegotiator
+if not request.path.startswith(('/rest/oauth/', '/rest/oauth2/')):  # 
everything but OAuthNegotiators
 c.api_token = self._authenticate_request()
 if c.api_token:
 c.user = c.api_token.user
@@ -67,7 +73,17 @@ class RestController:
 params_auth = 'oauth_token' in request.params
 params_auth 

(allura) branch master updated (e83afa851 -> 0628922be)

2024-04-24 Thread brondsem
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/allura.git


from e83afa851 pin docutils to v0.20.1 to keep compatibility with older 
versions of Python
 add 0628922be code updates to AkismetWithoutStartupVerify

No new revisions were added by this update.

Summary of changes:
 Allura/allura/lib/spam/akismetfilter.py | 7 ++-
 1 file changed, 6 insertions(+), 1 deletion(-)



(allura) branch db/8556-breaking-removal updated (c68d64fd2 -> 5892b1699)

2024-04-03 Thread brondsem
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a change to branch db/8556-breaking-removal
in repository https://gitbox.apache.org/repos/asf/allura.git


 discard c68d64fd2 [#8556] unindent block
 discard 11902a6d3 [#8556] remove TruthyCallable and predicate stuff used by 
has_access
 discard 545732230 [#8556] simplify more calls
 discard e7a905d18 [#8556] remove unnecessary extra () on has_access calls
 discard 85c2a4a25 [#8556] avoid recursive TruthyCallable
 discard 2db77c578 [#8555] debugging option within has_access
 discard 61d406fa8 [#8555] some specific checks for blocked users, when 
creating new forum threads
 add 956c57c2f [#8555] some specific checks for blocked users, when 
creating new forum threads
 add fc4c27645 [#8555] debugging option within has_access
 add bc4676f9f [#8556] avoid recursive TruthyCallable
 add a8497a84e [#8556] remove unnecessary extra () on has_access calls
 add 5892b1699 [#8556] simplify more calls

This update added new revisions after undoing existing revisions.
That is to say, some revisions that were in the old version of the
branch are not in the new version.  This situation occurs
when a user --force pushes a change and generates a repository
containing something like this:

 * -- * -- B -- O -- O -- O   (c68d64fd2)
\
 N -- N -- N   refs/heads/db/8556-breaking-removal (5892b1699)

You should already have received notification emails for all of the O
revisions, and so the following emails describe only the N revisions
from the common base, B.

Any revisions marked "omit" are not gone; other references still
refer to them.  Any revisions marked "discard" are gone forever.

No new revisions were added by this update.

Summary of changes:
 Allura/allura/controllers/auth.py  |   6 +-
 Allura/allura/controllers/basetest_project_root.py |   8 +-
 Allura/allura/controllers/rest.py  |   2 +-
 Allura/allura/lib/security.py  | 130 +++--
 Allura/allura/lib/utils.py |  25 
 Allura/allura/tests/test_plugin.py |   1 +
 Allura/allura/tests/test_utils.py  |  21 
 .../tests/functional/test_forum_admin.py   |  17 ++-
 ForgeTracker/forgetracker/tracker_main.py  |   2 +-
 .../033-change-comment-anon-permissions.py |   2 +-
 10 files changed, 141 insertions(+), 73 deletions(-)



(allura) branch db/8556 updated (545732230 -> 5892b1699)

2024-04-03 Thread brondsem
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a change to branch db/8556
in repository https://gitbox.apache.org/repos/asf/allura.git


omit 545732230 [#8556] simplify more calls
omit e7a905d18 [#8556] remove unnecessary extra () on has_access calls
omit 85c2a4a25 [#8556] avoid recursive TruthyCallable
omit 2db77c578 [#8555] debugging option within has_access
omit 61d406fa8 [#8555] some specific checks for blocked users, when 
creating new forum threads
 add 956c57c2f [#8555] some specific checks for blocked users, when 
creating new forum threads
 add fc4c27645 [#8555] debugging option within has_access
 new bc4676f9f [#8556] avoid recursive TruthyCallable
 new a8497a84e [#8556] remove unnecessary extra () on has_access calls
 new 5892b1699 [#8556] simplify more calls

This update added new revisions after undoing existing revisions.
That is to say, some revisions that were in the old version of the
branch are not in the new version.  This situation occurs
when a user --force pushes a change and generates a repository
containing something like this:

 * -- * -- B -- O -- O -- O   (545732230)
\
 N -- N -- N   refs/heads/db/8556 (5892b1699)

You should already have received notification emails for all of the O
revisions, and so the following emails describe only the N revisions
from the common base, B.

Any revisions marked "omit" are not gone; other references still
refer to them.  Any revisions marked "discard" are gone forever.

The 3 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../tests/functional/test_forum_admin.py| 17 +++--
 1 file changed, 15 insertions(+), 2 deletions(-)



(allura) 03/03: [#8556] simplify more calls

2024-04-03 Thread brondsem
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a commit to branch db/8556
in repository https://gitbox.apache.org/repos/asf/allura.git

commit 5892b1699b114723ccef5c80770da3c5ba7666d3
Author: Dave Brondsema 
AuthorDate: Wed Apr 3 13:43:48 2024 -0400

[#8556] simplify more calls
---
 Allura/allura/app.py  | 2 +-
 Allura/allura/controllers/auth.py | 6 +++---
 Allura/allura/ext/admin/admin_main.py | 2 +-
 Allura/allura/tests/model/test_artifact.py| 6 +++---
 Allura/allura/tests/test_plugin.py| 2 +-
 ForgeBlog/forgeblog/tests/test_roles.py   | 8 ++--
 ForgeDiscussion/forgediscussion/tests/test_forum_roles.py | 8 ++--
 ForgeFeedback/forgefeedback/tests/test_feedback_roles.py  | 8 ++--
 ForgeFiles/forgefiles/tests/test_files_roles.py   | 8 ++--
 ForgeShortUrl/forgeshorturl/main.py   | 2 +-
 ForgeTracker/forgetracker/tests/test_tracker_roles.py | 8 ++--
 ForgeTracker/forgetracker/tracker_main.py | 6 +++---
 ForgeWiki/forgewiki/tests/test_wiki_roles.py  | 8 ++--
 ForgeWiki/forgewiki/wiki_main.py  | 2 +-
 14 files changed, 50 insertions(+), 26 deletions(-)

diff --git a/Allura/allura/app.py b/Allura/allura/app.py
index 518269622..55cb7d299 100644
--- a/Allura/allura/app.py
+++ b/Allura/allura/app.py
@@ -495,7 +495,7 @@ class Application(ActivityObject):
 :rtype: bool
 
 """
-return has_access(self, 'read')(user=user)
+return has_access(self, 'read', user)
 
 def subscribe_admins(self):
 """Subscribe all project Admins (for this Application's project) to the
diff --git a/Allura/allura/controllers/auth.py 
b/Allura/allura/controllers/auth.py
index d74f48445..fab1757e8 100644
--- a/Allura/allura/controllers/auth.py
+++ b/Allura/allura/controllers/auth.py
@@ -513,9 +513,9 @@ class AuthController(BaseController):
 log.info("Can't find repo at %s on repo_path %s",
  rest[0], repo_path)
 return disallow
-return dict(allow_read=has_access(c.app, 'read')(user=user),
-allow_write=has_access(c.app, 'write')(user=user),
-allow_create=has_access(c.app, 'create')(user=user))
+return dict(allow_read=bool(has_access(c.app, 'read', user)),
+allow_write=bool(has_access(c.app, 'write', user)),
+allow_create=bool(has_access(c.app, 'create', user)))
 
 @expose('jinja:allura:templates/pwd_expired.html')
 @without_trailing_slash
diff --git a/Allura/allura/ext/admin/admin_main.py 
b/Allura/allura/ext/admin/admin_main.py
index 0904c0ce8..6feecd038 100644
--- a/Allura/allura/ext/admin/admin_main.py
+++ b/Allura/allura/ext/admin/admin_main.py
@@ -97,7 +97,7 @@ class AdminApp(Application):
 
 def is_visible_to(self, user):
 '''Whether the user can view the app.'''
-return has_access(c.project, 'create')(user=user)
+return has_access(c.project, 'create', user)
 
 @staticmethod
 def installable_tools_for(project):
diff --git a/Allura/allura/tests/model/test_artifact.py 
b/Allura/allura/tests/model/test_artifact.py
index 9eb2c8b4e..d63a2041e 100644
--- a/Allura/allura/tests/model/test_artifact.py
+++ b/Allura/allura/tests/model/test_artifact.py
@@ -85,13 +85,13 @@ class TestArtifact:
 pr = M.ProjectRole.by_user(u, upsert=True)
 ThreadLocalODMSession.flush_all()
 REGISTRY.register(allura.credentials, 
allura.lib.security.Credentials())
-assert not security.has_access(pg, 'delete')(user=u)
+assert not security.has_access(pg, 'delete', u)
 pg.acl.append(M.ACE.allow(pr._id, 'delete'))
 ThreadLocalODMSession.flush_all()
-assert security.has_access(pg, 'delete')(user=u)
+assert security.has_access(pg, 'delete', u)
 pg.acl.pop()
 ThreadLocalODMSession.flush_all()
-assert not security.has_access(pg, 'delete')(user=u)
+assert not security.has_access(pg, 'delete', u)
 
 def test_artifact_index(self):
 pg = WM.Page(title='TestPage1')
diff --git a/Allura/allura/tests/test_plugin.py 
b/Allura/allura/tests/test_plugin.py
index 964502cf2..c57e9e4a4 100644
--- a/Allura/allura/tests/test_plugin.py
+++ b/Allura/allura/tests/test_plugin.py
@@ -50,7 +50,7 @@ class TestProjectRegistrationProvider:
 
 @patch('allura.lib.security.has_access')
 def test_validate_project_15char_user(self, has_access):
-has_access.return_value = TruthyCallable(lambda: True)
+has_access.return_value = True
 nbhd = M.Neighborhood()
 self.provider.validate_project(
 neighborhood=nbhd,
diff --git a/ForgeBlog/forgeblog/tests/test_roles.py 
b/ForgeBlog/forgeblog/tests/test_ro

(allura) 01/02: [#8555] some specific checks for blocked users, when creating new forum threads

2024-04-03 Thread brondsem
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a commit to branch db/8555
in repository https://gitbox.apache.org/repos/asf/allura.git

commit 956c57c2f6ee7336b5e3b98bcabf0fc88780d559
Author: Dave Brondsema 
AuthorDate: Tue Apr 2 17:44:28 2024 -0400

[#8555] some specific checks for blocked users, when creating new forum 
threads
---
 Allura/allura/lib/security.py  | 32 +++---
 Allura/allura/model/discuss.py |  6 +++-
 .../forgediscussion/controllers/root.py| 10 +--
 .../tests/functional/test_forum_admin.py   | 17 ++--
 4 files changed, 49 insertions(+), 16 deletions(-)

diff --git a/Allura/allura/lib/security.py b/Allura/allura/lib/security.py
index cc874822d..3c16d05be 100644
--- a/Allura/allura/lib/security.py
+++ b/Allura/allura/lib/security.py
@@ -19,12 +19,12 @@
 This module provides the security predicates used in decorating various models.
 """
 
-import six
-import sys
+from __future__ import annotations
 import logging
 from collections import defaultdict
 import hashlib
 import requests
+import typing
 
 from tg import tmpl_context as c
 from tg import request
@@ -35,6 +35,9 @@ import tg
 
 from allura.lib.utils import TruthyCallable
 
+if typing.TYPE_CHECKING:
+from allura.model import M
+
 log = logging.getLogger(__name__)
 
 
@@ -277,7 +280,21 @@ class RoleCache:
 return set(self.reaching_ids)
 
 
-def has_access(obj, permission, user=None, project=None):
+def is_denied(obj, permission: str, user: M.User, project: M.Project) -> bool:
+from allura import model as M
+
+if user != M.User.anonymous():
+user_roles = Credentials.get().user_roles(user_id=user._id,
+  
project_id=project.root_project._id)
+for r in user_roles:
+deny_user = M.ACE.deny(r['_id'], permission)
+if M.ACL.contains(deny_user, obj.acl):
+return True
+
+return False
+
+
+def has_access(obj, permission: str, user: M.User | None = None, project: 
M.Project | None = None):
 '''Return whether the given user has the permission name on the given 
object.
 
 - First, all the roles for a user in the given project context are 
computed.
@@ -341,13 +358,8 @@ def has_access(obj, permission, user=None, project=None):
 user_id=user._id, project_id=project._id).reaching_ids
 
 # TODO: move deny logic into loop below; see ticket [#6715]
-if user != M.User.anonymous():
-user_roles = Credentials.get().user_roles(user_id=user._id,
-  
project_id=project.root_project._id)
-for r in user_roles:
-deny_user = M.ACE.deny(r['_id'], permission)
-if M.ACL.contains(deny_user, obj.acl):
-return False
+if is_denied(obj, permission, user, project):
+return False
 
 chainable_roles = []
 for rid in roles:
diff --git a/Allura/allura/model/discuss.py b/Allura/allura/model/discuss.py
index 3ecb42907..92999e295 100644
--- a/Allura/allura/model/discuss.py
+++ b/Allura/allura/model/discuss.py
@@ -33,10 +33,11 @@ from ming.odm.property import (FieldProperty, 
RelationProperty,
ForeignIdProperty)
 from ming.utils import LazyProperty
 from bson import ObjectId
+from webob import exc
 
 from allura.lib import helpers as h
 from allura.lib import security
-from allura.lib.security import require_access, has_access
+from allura.lib.security import require_access, has_access, is_denied
 from allura.lib import utils
 from allura.model.notification import Notification, Mailbox
 from .artifact import Artifact, ArtifactReference, VersionedArtifact, 
Snapshot, Message, Feed, ReactableArtifact
@@ -335,6 +336,9 @@ class Thread(Artifact, ActivityObject):
  is_meta=False, subscribe=False, **kw):
 if not ignore_security:
 require_access(self, 'post')
+# check app-level for Blocked Users, in addition to the standard 
`self` check above
+if is_denied(self.app, 'post', c.user, self.project):
+raise exc.HTTPForbidden
 if subscribe:
 self.primary().subscribe()
 if message_id is None:
diff --git a/ForgeDiscussion/forgediscussion/controllers/root.py 
b/ForgeDiscussion/forgediscussion/controllers/root.py
index 212245f79..251d57923 100644
--- a/ForgeDiscussion/forgediscussion/controllers/root.py
+++ b/ForgeDiscussion/forgediscussion/controllers/root.py
@@ -110,9 +110,13 @@ class RootController(BaseController, DispatchIndex, 
FeedController):
 @with_trailing_slash
 
@expose('jinja:forgediscussion:templates/discussionforums/create_topic.html')
 def create_topic(self, forum_name=None, new_forum=False, **kw):
-forums = model.Forum.query.find(dict(app_config_i

(allura) branch db/8555 created (now fc4c27645)

2024-04-03 Thread brondsem
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a change to branch db/8555
in repository https://gitbox.apache.org/repos/asf/allura.git


  at fc4c27645 [#8555] debugging option within has_access

This branch includes the following new commits:

 new 956c57c2f [#8555] some specific checks for blocked users, when 
creating new forum threads
 new fc4c27645 [#8555] debugging option within has_access

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.




(allura) 02/03: [#8556] remove unnecessary extra () on has_access calls

2024-04-03 Thread brondsem
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a commit to branch db/8556
in repository https://gitbox.apache.org/repos/asf/allura.git

commit a8497a84e799521c8fb004522b186ce61a694d98
Author: Dave Brondsema 
AuthorDate: Wed Apr 3 11:08:11 2024 -0400

[#8556] remove unnecessary extra () on has_access calls
---
 Allura/allura/app.py   |  8 +--
 Allura/allura/controllers/project.py   |  2 +-
 Allura/allura/controllers/rest.py  |  4 +-
 Allura/allura/ext/admin/admin_main.py  |  4 +-
 .../ext/admin/templates/project_screenshots.html   |  4 +-
 Allura/allura/lib/macro.py | 14 +++---
 Allura/allura/lib/plugin.py|  4 +-
 Allura/allura/lib/security.py  |  4 +-
 Allura/allura/model/neighborhood.py|  2 +-
 Allura/allura/model/notification.py|  4 +-
 Allura/allura/templates/jinja_master/master.html   |  2 +-
 .../templates/jinja_master/sidebar_menu.html   |  2 +-
 Allura/allura/templates/jinja_master/top_nav.html  |  4 +-
 .../templates/neighborhood_project_list.html   |  2 +-
 Allura/allura/templates/project_list.html  |  4 +-
 Allura/allura/templates/repo/merge_request.html|  6 +--
 Allura/allura/templates/repo/repo_master.html  |  2 +-
 Allura/allura/templates/widgets/post_widget.html   |  8 +--
 .../templates/widgets/project_list_widget.html |  2 +-
 Allura/allura/templates/widgets/thread_header.html |  2 +-
 Allura/allura/templates/widgets/thread_widget.html |  4 +-
 Allura/allura/templates/widgets/vote.html  |  2 +-
 .../templates_responsive/jinja_master/master.html  |  2 +-
 .../jinja_master/sidebar_menu.html |  2 +-
 .../templates_responsive/jinja_master/top_nav.html |  4 +-
 Allura/allura/tests/model/test_notification.py | 13 ++---
 Allura/allura/tests/test_helpers.py| 24 -
 Allura/allura/tests/test_plugin.py |  6 +--
 Allura/allura/tests/test_security.py   | 38 +++---
 ForgeBlog/forgeblog/main.py| 10 ++--
 ForgeBlog/forgeblog/templates/blog/post.html   |  4 +-
 .../forgeblog/templates/blog/post_history.html |  2 +-
 .../templates/blog_widgets/preview_post.html   |  2 +-
 .../templates/blog_widgets/view_post.html  |  2 +-
 ForgeChat/forgechat/command.py |  2 +-
 .../forgediscussion/controllers/forum.py   |  8 +--
 .../forgediscussion/controllers/root.py|  6 +--
 ForgeDiscussion/forgediscussion/forum_main.py  | 12 ++---
 .../discussion_widgets/thread_header.html  |  4 +-
 .../templates/discussionforums/index.html  |  4 +-
 .../templates/discussionforums/thread.html |  2 +-
 ForgeFiles/forgefiles/templates/files.html | 10 ++--
 ForgeGit/forgegit/templates/git/index.html |  4 +-
 ForgeSVN/forgesvn/templates/svn/index.html |  4 +-
 .../forgetracker/templates/tracker/search.html |  6 +--
 .../forgetracker/templates/tracker/ticket.html |  2 +-
 .../forgetracker/tests/unit/test_ticket_model.py   | 58 +++---
 ForgeTracker/forgetracker/tracker_main.py  | 24 -
 ForgeWiki/forgewiki/templates/wiki/page_edit.html  |  6 +--
 .../forgewiki/templates/wiki/page_history.html |  2 +-
 ForgeWiki/forgewiki/templates/wiki/page_view.html  |  4 +-
 ForgeWiki/forgewiki/wiki_main.py   | 10 ++--
 52 files changed, 180 insertions(+), 187 deletions(-)

diff --git a/Allura/allura/app.py b/Allura/allura/app.py
index 23f18d1b3..518269622 100644
--- a/Allura/allura/app.py
+++ b/Allura/allura/app.py
@@ -662,7 +662,7 @@ class Application(ActivityObject):
 admin_url = c.project.url() + 'admin/' + \
 self.config.options.mount_point + '/'
 links = []
-if self.permissions and has_access(c.project, 'admin')():
+if self.permissions and has_access(c.project, 'admin'):
 links.append(
 SitemapEntry('Permissions', admin_url + 'permissions'))
 if force_options or len(self.config_options) > 3:
@@ -943,7 +943,7 @@ class DefaultAdminController(BaseController, 
AdminControllerMixin):
 block_list[ace.permission].append((role.user, ace.reason))
 return dict(
 app=self.app,
-allow_config=has_access(c.project, 'admin')(),
+allow_config=has_access(c.project, 'admin'),
 permissions=permissions,
 block_list=block_list)
 
@@ -954,7 +954,7 @@ class DefaultAdminController(BaseController, 
AdminControllerMixin):
 """
 return dict(
 app=self.app,
-allow_config=has_access(self.app, 'configure')())
+allow_config=has_access(self.app, 'configure'))
 
 @expose()
 @require_post()
@@ -979,7 +979,7 @@ class Defa

(allura) 01/03: [#8556] avoid recursive TruthyCallable

2024-04-03 Thread brondsem
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a commit to branch db/8556
in repository https://gitbox.apache.org/repos/asf/allura.git

commit bc4676f9f9a83a24697a7b85c795a5046153aebf
Author: Dave Brondsema 
AuthorDate: Wed Apr 3 11:06:22 2024 -0400

[#8556] avoid recursive TruthyCallable
---
 Allura/allura/lib/security.py | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/Allura/allura/lib/security.py b/Allura/allura/lib/security.py
index e73f6ad2b..8f59a4ba8 100644
--- a/Allura/allura/lib/security.py
+++ b/Allura/allura/lib/security.py
@@ -305,7 +305,7 @@ def debug_obj(obj) -> str:
 return str(obj)
 
 
-def has_access(obj, permission: str, user: M.User | None = None, project: 
M.Project | None = None):
+def has_access(obj, permission: str, user: M.User | None = None, project: 
M.Project | None = None) -> TruthyCallable:
 '''Return whether the given user has the permission name on the given 
object.
 
 - First, all the roles for a user in the given project context are 
computed.
@@ -348,7 +348,7 @@ def has_access(obj, permission: str, user: M.User | None = 
None, project: M.Proj
 
 DEBUG = False
 
-def predicate(obj=obj, user=user, project=project, roles=None):
+def predicate(obj=obj, user=user, project=project, roles=None) -> bool:
 if obj is None:
 if DEBUG:
 log.debug(f'{user} denied {permission} on {debug_obj(obj)} 
({debug_obj(project)})')
@@ -404,6 +404,7 @@ def has_access(obj, permission: str, user: M.User | None = 
None, project: M.Proj
 result = has_access(project, 'admin', user=user)()
 else:
 result = False
+result = bool(result)
 if DEBUG:
 log.debug(f"{user.username} '{permission}' {result} from parent(s) 
on {debug_obj(obj)} ({debug_obj(project)})")
 return result



(allura) 02/02: [#8555] debugging option within has_access

2024-04-03 Thread brondsem
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a commit to branch db/8555
in repository https://gitbox.apache.org/repos/asf/allura.git

commit fc4c2764594653740ca3ea0a05d89b87bfb3a4bb
Author: Dave Brondsema 
AuthorDate: Tue Apr 2 17:44:46 2024 -0400

[#8555] debugging option within has_access
---
 Allura/allura/lib/security.py | 36 
 1 file changed, 28 insertions(+), 8 deletions(-)

diff --git a/Allura/allura/lib/security.py b/Allura/allura/lib/security.py
index 3c16d05be..e73f6ad2b 100644
--- a/Allura/allura/lib/security.py
+++ b/Allura/allura/lib/security.py
@@ -293,6 +293,17 @@ def is_denied(obj, permission: str, user: M.User, project: 
M.Project) -> bool:
 
 return False
 
+def debug_obj(obj) -> str:
+if hasattr(obj, 'url'):
+url = obj.url
+if callable(url):
+try:
+url = url()
+except Exception:
+url = obj._id
+return f'{obj.__class__.__name__} {url}'
+return str(obj)
+
 
 def has_access(obj, permission: str, user: M.User | None = None, project: 
M.Project | None = None):
 '''Return whether the given user has the permission name on the given 
object.
@@ -335,8 +346,12 @@ def has_access(obj, permission: str, user: M.User | None = 
None, project: M.Proj
 '''
 from allura import model as M
 
+DEBUG = False
+
 def predicate(obj=obj, user=user, project=project, roles=None):
 if obj is None:
+if DEBUG:
+log.debug(f'{user} denied {permission} on {debug_obj(obj)} 
({debug_obj(project)})')
 return False
 if roles is None:
 if user is None:
@@ -354,27 +369,31 @@ def has_access(obj, permission: str, user: M.User | None 
= None, project: M.Proj
 else:
 project = getattr(obj, 'project', None) or c.project
 project = project.root_project
-roles = cred.user_roles(
-user_id=user._id, project_id=project._id).reaching_ids
+roles: RoleCache = cred.user_roles(user_id=user._id, 
project_id=project._id).reaching_roles
 
 # TODO: move deny logic into loop below; see ticket [#6715]
 if is_denied(obj, permission, user, project):
+if DEBUG:
+log.debug(f"{user.username} '{permission}' denied on 
{debug_obj(obj)} ({debug_obj(project)})")
 return False
 
 chainable_roles = []
-for rid in roles:
+for role in roles:
 for ace in obj.acl:
-if M.ACE.match(ace, rid, permission):
+if M.ACE.match(ace, role['_id'], permission):
 if ace.access == M.ACE.ALLOW:
 # access is allowed
-# log.info('%s: True', txt)
+if DEBUG:
+log.debug(f"{user.username} '{permission}' granted 
on {debug_obj(obj)} ({debug_obj(project)})")
 return True
 else:
-# access is denied for this role
+# access is denied for this particular role
+if DEBUG:
+log.debug(f"{user.username} '{permission}' denied 
for role={role['name'] or role['_id']} (BUT continuing to see if other roles 
permit) on {debug_obj(obj)} ({debug_obj(project)})")
 break
 else:
 # access neither allowed or denied, may chain to parent context
-chainable_roles.append(rid)
+chainable_roles.append(role)
 parent = obj.parent_security_context()
 if parent and chainable_roles:
 result = has_access(parent, permission, user=user, 
project=project)(
@@ -385,7 +404,8 @@ def has_access(obj, permission: str, user: M.User | None = 
None, project: M.Proj
 result = has_access(project, 'admin', user=user)()
 else:
 result = False
-# log.info('%s: %s', txt, result)
+if DEBUG:
+log.debug(f"{user.username} '{permission}' {result} from parent(s) 
on {debug_obj(obj)} ({debug_obj(project)})")
 return result
 return TruthyCallable(predicate)
 



(allura) branch db/8556 created (now 545732230)

2024-04-03 Thread brondsem
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a change to branch db/8556
in repository https://gitbox.apache.org/repos/asf/allura.git


  at 545732230 [#8556] simplify more calls

No new revisions were added by this update.



(allura) 04/07: [#8556] remove unnecessary extra () on has_access calls

2024-04-03 Thread brondsem
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a commit to branch db/8556-breaking-removal
in repository https://gitbox.apache.org/repos/asf/allura.git

commit e7a905d18ea7018064add33e9fb686f4f5663856
Author: Dave Brondsema 
AuthorDate: Wed Apr 3 11:08:11 2024 -0400

[#8556] remove unnecessary extra () on has_access calls
---
 Allura/allura/app.py   |  8 +--
 Allura/allura/controllers/project.py   |  2 +-
 Allura/allura/controllers/rest.py  |  4 +-
 Allura/allura/ext/admin/admin_main.py  |  4 +-
 .../ext/admin/templates/project_screenshots.html   |  4 +-
 Allura/allura/lib/macro.py | 14 +++---
 Allura/allura/lib/plugin.py|  4 +-
 Allura/allura/lib/security.py  |  4 +-
 Allura/allura/model/neighborhood.py|  2 +-
 Allura/allura/model/notification.py|  4 +-
 Allura/allura/templates/jinja_master/master.html   |  2 +-
 .../templates/jinja_master/sidebar_menu.html   |  2 +-
 Allura/allura/templates/jinja_master/top_nav.html  |  4 +-
 .../templates/neighborhood_project_list.html   |  2 +-
 Allura/allura/templates/project_list.html  |  4 +-
 Allura/allura/templates/repo/merge_request.html|  6 +--
 Allura/allura/templates/repo/repo_master.html  |  2 +-
 Allura/allura/templates/widgets/post_widget.html   |  8 +--
 .../templates/widgets/project_list_widget.html |  2 +-
 Allura/allura/templates/widgets/thread_header.html |  2 +-
 Allura/allura/templates/widgets/thread_widget.html |  4 +-
 Allura/allura/templates/widgets/vote.html  |  2 +-
 .../templates_responsive/jinja_master/master.html  |  2 +-
 .../jinja_master/sidebar_menu.html |  2 +-
 .../templates_responsive/jinja_master/top_nav.html |  4 +-
 Allura/allura/tests/model/test_notification.py | 13 ++---
 Allura/allura/tests/test_helpers.py| 24 -
 Allura/allura/tests/test_plugin.py |  6 +--
 Allura/allura/tests/test_security.py   | 38 +++---
 ForgeBlog/forgeblog/main.py| 10 ++--
 ForgeBlog/forgeblog/templates/blog/post.html   |  4 +-
 .../forgeblog/templates/blog/post_history.html |  2 +-
 .../templates/blog_widgets/preview_post.html   |  2 +-
 .../templates/blog_widgets/view_post.html  |  2 +-
 ForgeChat/forgechat/command.py |  2 +-
 .../forgediscussion/controllers/forum.py   |  8 +--
 .../forgediscussion/controllers/root.py|  6 +--
 ForgeDiscussion/forgediscussion/forum_main.py  | 12 ++---
 .../discussion_widgets/thread_header.html  |  4 +-
 .../templates/discussionforums/index.html  |  4 +-
 .../templates/discussionforums/thread.html |  2 +-
 ForgeFiles/forgefiles/templates/files.html | 10 ++--
 ForgeGit/forgegit/templates/git/index.html |  4 +-
 ForgeSVN/forgesvn/templates/svn/index.html |  4 +-
 .../forgetracker/templates/tracker/search.html |  6 +--
 .../forgetracker/templates/tracker/ticket.html |  2 +-
 .../forgetracker/tests/unit/test_ticket_model.py   | 58 +++---
 ForgeTracker/forgetracker/tracker_main.py  | 24 -
 ForgeWiki/forgewiki/templates/wiki/page_edit.html  |  6 +--
 .../forgewiki/templates/wiki/page_history.html |  2 +-
 ForgeWiki/forgewiki/templates/wiki/page_view.html  |  4 +-
 ForgeWiki/forgewiki/wiki_main.py   | 10 ++--
 52 files changed, 180 insertions(+), 187 deletions(-)

diff --git a/Allura/allura/app.py b/Allura/allura/app.py
index 23f18d1b3..518269622 100644
--- a/Allura/allura/app.py
+++ b/Allura/allura/app.py
@@ -662,7 +662,7 @@ class Application(ActivityObject):
 admin_url = c.project.url() + 'admin/' + \
 self.config.options.mount_point + '/'
 links = []
-if self.permissions and has_access(c.project, 'admin')():
+if self.permissions and has_access(c.project, 'admin'):
 links.append(
 SitemapEntry('Permissions', admin_url + 'permissions'))
 if force_options or len(self.config_options) > 3:
@@ -943,7 +943,7 @@ class DefaultAdminController(BaseController, 
AdminControllerMixin):
 block_list[ace.permission].append((role.user, ace.reason))
 return dict(
 app=self.app,
-allow_config=has_access(c.project, 'admin')(),
+allow_config=has_access(c.project, 'admin'),
 permissions=permissions,
 block_list=block_list)
 
@@ -954,7 +954,7 @@ class DefaultAdminController(BaseController, 
AdminControllerMixin):
 """
 return dict(
 app=self.app,
-allow_config=has_access(self.app, 'configure')())
+allow_config=has_access(self.app, 'configure'))
 
 @expose()
 @require_post()
@@ -979

(allura) 06/07: [#8556] remove TruthyCallable and predicate stuff used by has_access

2024-04-03 Thread brondsem
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a commit to branch db/8556-breaking-removal
in repository https://gitbox.apache.org/repos/asf/allura.git

commit 11902a6d366c78fbe6e7e28638293aff9bdb421f
Author: Dave Brondsema 
AuthorDate: Wed Apr 3 14:00:52 2024 -0400

[#8556] remove TruthyCallable and predicate stuff used by has_access
---
 Allura/allura/controllers/auth.py  |  6 +++---
 Allura/allura/controllers/basetest_project_root.py |  8 +++
 Allura/allura/controllers/rest.py  |  2 +-
 Allura/allura/lib/security.py  | 23 +++-
 Allura/allura/lib/utils.py | 25 --
 Allura/allura/tests/test_plugin.py |  1 -
 Allura/allura/tests/test_utils.py  | 21 --
 ForgeTracker/forgetracker/tracker_main.py  |  2 +-
 .../033-change-comment-anon-permissions.py |  2 +-
 9 files changed, 18 insertions(+), 72 deletions(-)

diff --git a/Allura/allura/controllers/auth.py 
b/Allura/allura/controllers/auth.py
index fab1757e8..628801648 100644
--- a/Allura/allura/controllers/auth.py
+++ b/Allura/allura/controllers/auth.py
@@ -513,9 +513,9 @@ class AuthController(BaseController):
 log.info("Can't find repo at %s on repo_path %s",
  rest[0], repo_path)
 return disallow
-return dict(allow_read=bool(has_access(c.app, 'read', user)),
-allow_write=bool(has_access(c.app, 'write', user)),
-allow_create=bool(has_access(c.app, 'create', user)))
+return dict(allow_read=has_access(c.app, 'read', user),
+allow_write=has_access(c.app, 'write', user),
+allow_create=has_access(c.app, 'create', user))
 
 @expose('jinja:allura:templates/pwd_expired.html')
 @without_trailing_slash
diff --git a/Allura/allura/controllers/basetest_project_root.py 
b/Allura/allura/controllers/basetest_project_root.py
index 90dc7e88c..341bb5bca 100644
--- a/Allura/allura/controllers/basetest_project_root.py
+++ b/Allura/allura/controllers/basetest_project_root.py
@@ -165,7 +165,7 @@ class SecurityTest:
 
 @expose()
 def forbidden(self):
-require(lambda: False, 'Never allowed')
+require(False, 'Never allowed')
 return ''
 
 @expose()
@@ -180,10 +180,10 @@ class SecurityTest:
 
 @expose()
 def needs_project_access_ok(self):
-pred = has_access(c.project, 'read')
-if not pred():
+ok = has_access(c.project, 'read')
+if not ok:
 log.info('Inside needs_project_access, c.user = %s' % c.user)
-require(pred)
+require(ok)
 return ''
 
 @expose()
diff --git a/Allura/allura/controllers/rest.py 
b/Allura/allura/controllers/rest.py
index 0f29c1676..d0ca8476d 100644
--- a/Allura/allura/controllers/rest.py
+++ b/Allura/allura/controllers/rest.py
@@ -481,7 +481,7 @@ def rest_has_access(obj, user, perm):
 resp = {'result': False}
 user = M.User.by_username(user)
 if user:
-resp['result'] = bool(security.has_access(obj, perm, user=user))
+resp['result'] = security.has_access(obj, perm, user=user)
 return resp
 
 
diff --git a/Allura/allura/lib/security.py b/Allura/allura/lib/security.py
index 53a675f55..a762af965 100644
--- a/Allura/allura/lib/security.py
+++ b/Allura/allura/lib/security.py
@@ -33,8 +33,6 @@ from itertools import chain
 from ming.utils import LazyProperty
 import tg
 
-from allura.lib.utils import TruthyCallable
-
 if typing.TYPE_CHECKING:
 from allura.model import M
 
@@ -305,7 +303,7 @@ def debug_obj(obj) -> str:
 return str(obj)
 
 
-def has_access(obj, permission: str, user: M.User | None = None, project: 
M.Project | None = None) -> TruthyCallable:
+def has_access(obj, permission: str, user: M.User | None = None, project: 
M.Project | None = None, roles=None) -> bool:
 '''Return whether the given user has the permission name on the given 
object.
 
 - First, all the roles for a user in the given project context are 
computed.
@@ -348,7 +346,7 @@ def has_access(obj, permission: str, user: M.User | None = 
None, project: M.Proj
 
 DEBUG = False
 
-def predicate(obj=obj, user=user, project=project, roles=None) -> bool:
+if True:
 if obj is None:
 if DEBUG:
 log.debug(f'{user} denied {permission} on {debug_obj(obj)} 
({debug_obj(project)})')
@@ -396,19 +394,16 @@ def has_access(obj, permission: str, user: M.User | None 
= None, project: M.Proj
 chainable_roles.append(role)
 parent = obj.parent_security_context()
 if parent and chainable_roles:
-result = has_access(parent, permission, user=user, 
project=project)(
-roles=tuple(chainable_roles))
+result = has_access(parent, permission, user=user, 
projec

(allura) branch db/8556-breaking-removal created (now c68d64fd2)

2024-04-03 Thread brondsem
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a change to branch db/8556-breaking-removal
in repository https://gitbox.apache.org/repos/asf/allura.git


  at c68d64fd2 [#8556] unindent block

This branch includes the following new commits:

 new 61d406fa8 [#8555] some specific checks for blocked users, when 
creating new forum threads
 new 2db77c578 [#8555] debugging option within has_access
 new 85c2a4a25 [#8556] avoid recursive TruthyCallable
 new e7a905d18 [#8556] remove unnecessary extra () on has_access calls
 new 545732230 [#8556] simplify more calls
 new 11902a6d3 [#8556] remove TruthyCallable and predicate stuff used by 
has_access
 new c68d64fd2 [#8556] unindent block

The 7 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.




(allura) 02/07: [#8555] debugging option within has_access

2024-04-03 Thread brondsem
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a commit to branch db/8556-breaking-removal
in repository https://gitbox.apache.org/repos/asf/allura.git

commit 2db77c578958a6322a0f5b512d9ab5a5dea3625a
Author: Dave Brondsema 
AuthorDate: Tue Apr 2 17:44:46 2024 -0400

[#8555] debugging option within has_access
---
 Allura/allura/lib/security.py | 36 
 1 file changed, 28 insertions(+), 8 deletions(-)

diff --git a/Allura/allura/lib/security.py b/Allura/allura/lib/security.py
index 3c16d05be..e73f6ad2b 100644
--- a/Allura/allura/lib/security.py
+++ b/Allura/allura/lib/security.py
@@ -293,6 +293,17 @@ def is_denied(obj, permission: str, user: M.User, project: 
M.Project) -> bool:
 
 return False
 
+def debug_obj(obj) -> str:
+if hasattr(obj, 'url'):
+url = obj.url
+if callable(url):
+try:
+url = url()
+except Exception:
+url = obj._id
+return f'{obj.__class__.__name__} {url}'
+return str(obj)
+
 
 def has_access(obj, permission: str, user: M.User | None = None, project: 
M.Project | None = None):
 '''Return whether the given user has the permission name on the given 
object.
@@ -335,8 +346,12 @@ def has_access(obj, permission: str, user: M.User | None = 
None, project: M.Proj
 '''
 from allura import model as M
 
+DEBUG = False
+
 def predicate(obj=obj, user=user, project=project, roles=None):
 if obj is None:
+if DEBUG:
+log.debug(f'{user} denied {permission} on {debug_obj(obj)} 
({debug_obj(project)})')
 return False
 if roles is None:
 if user is None:
@@ -354,27 +369,31 @@ def has_access(obj, permission: str, user: M.User | None 
= None, project: M.Proj
 else:
 project = getattr(obj, 'project', None) or c.project
 project = project.root_project
-roles = cred.user_roles(
-user_id=user._id, project_id=project._id).reaching_ids
+roles: RoleCache = cred.user_roles(user_id=user._id, 
project_id=project._id).reaching_roles
 
 # TODO: move deny logic into loop below; see ticket [#6715]
 if is_denied(obj, permission, user, project):
+if DEBUG:
+log.debug(f"{user.username} '{permission}' denied on 
{debug_obj(obj)} ({debug_obj(project)})")
 return False
 
 chainable_roles = []
-for rid in roles:
+for role in roles:
 for ace in obj.acl:
-if M.ACE.match(ace, rid, permission):
+if M.ACE.match(ace, role['_id'], permission):
 if ace.access == M.ACE.ALLOW:
 # access is allowed
-# log.info('%s: True', txt)
+if DEBUG:
+log.debug(f"{user.username} '{permission}' granted 
on {debug_obj(obj)} ({debug_obj(project)})")
 return True
 else:
-# access is denied for this role
+# access is denied for this particular role
+if DEBUG:
+log.debug(f"{user.username} '{permission}' denied 
for role={role['name'] or role['_id']} (BUT continuing to see if other roles 
permit) on {debug_obj(obj)} ({debug_obj(project)})")
 break
 else:
 # access neither allowed or denied, may chain to parent context
-chainable_roles.append(rid)
+chainable_roles.append(role)
 parent = obj.parent_security_context()
 if parent and chainable_roles:
 result = has_access(parent, permission, user=user, 
project=project)(
@@ -385,7 +404,8 @@ def has_access(obj, permission: str, user: M.User | None = 
None, project: M.Proj
 result = has_access(project, 'admin', user=user)()
 else:
 result = False
-# log.info('%s: %s', txt, result)
+if DEBUG:
+log.debug(f"{user.username} '{permission}' {result} from parent(s) 
on {debug_obj(obj)} ({debug_obj(project)})")
 return result
 return TruthyCallable(predicate)
 



(allura) 03/07: [#8556] avoid recursive TruthyCallable

2024-04-03 Thread brondsem
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a commit to branch db/8556-breaking-removal
in repository https://gitbox.apache.org/repos/asf/allura.git

commit 85c2a4a25599c00775137aa96f303ceeec2cb0d1
Author: Dave Brondsema 
AuthorDate: Wed Apr 3 11:06:22 2024 -0400

[#8556] avoid recursive TruthyCallable
---
 Allura/allura/lib/security.py | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/Allura/allura/lib/security.py b/Allura/allura/lib/security.py
index e73f6ad2b..8f59a4ba8 100644
--- a/Allura/allura/lib/security.py
+++ b/Allura/allura/lib/security.py
@@ -305,7 +305,7 @@ def debug_obj(obj) -> str:
 return str(obj)
 
 
-def has_access(obj, permission: str, user: M.User | None = None, project: 
M.Project | None = None):
+def has_access(obj, permission: str, user: M.User | None = None, project: 
M.Project | None = None) -> TruthyCallable:
 '''Return whether the given user has the permission name on the given 
object.
 
 - First, all the roles for a user in the given project context are 
computed.
@@ -348,7 +348,7 @@ def has_access(obj, permission: str, user: M.User | None = 
None, project: M.Proj
 
 DEBUG = False
 
-def predicate(obj=obj, user=user, project=project, roles=None):
+def predicate(obj=obj, user=user, project=project, roles=None) -> bool:
 if obj is None:
 if DEBUG:
 log.debug(f'{user} denied {permission} on {debug_obj(obj)} 
({debug_obj(project)})')
@@ -404,6 +404,7 @@ def has_access(obj, permission: str, user: M.User | None = 
None, project: M.Proj
 result = has_access(project, 'admin', user=user)()
 else:
 result = False
+result = bool(result)
 if DEBUG:
 log.debug(f"{user.username} '{permission}' {result} from parent(s) 
on {debug_obj(obj)} ({debug_obj(project)})")
 return result



(allura) 07/07: [#8556] unindent block

2024-04-03 Thread brondsem
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a commit to branch db/8556-breaking-removal
in repository https://gitbox.apache.org/repos/asf/allura.git

commit c68d64fd2146099937b9ec0bb9c6f4c4388f2dc3
Author: Dave Brondsema 
AuthorDate: Wed Apr 3 14:01:41 2024 -0400

[#8556] unindent block
---
 Allura/allura/lib/security.py | 111 +-
 1 file changed, 55 insertions(+), 56 deletions(-)

diff --git a/Allura/allura/lib/security.py b/Allura/allura/lib/security.py
index a762af965..4547b8dd5 100644
--- a/Allura/allura/lib/security.py
+++ b/Allura/allura/lib/security.py
@@ -346,64 +346,63 @@ def has_access(obj, permission: str, user: M.User | None 
= None, project: M.Proj
 
 DEBUG = False
 
-if True:
-if obj is None:
-if DEBUG:
-log.debug(f'{user} denied {permission} on {debug_obj(obj)} 
({debug_obj(project)})')
-return False
-if roles is None:
-if user is None:
-user = c.user
-assert user, 'c.user should always be at least M.User.anonymous()'
-cred = Credentials.get()
-if project is None:
-if isinstance(obj, M.Neighborhood):
-project = obj.neighborhood_project
-if project is None:
-log.error('Neighborhood project missing for %s', obj)
-return False
-elif isinstance(obj, M.Project):
-project = obj.root_project
-else:
-project = getattr(obj, 'project', None) or c.project
-project = project.root_project
-roles: RoleCache = cred.user_roles(user_id=user._id, 
project_id=project._id).reaching_roles
-
-# TODO: move deny logic into loop below; see ticket [#6715]
-if is_denied(obj, permission, user, project):
-if DEBUG:
-log.debug(f"{user.username} '{permission}' denied on 
{debug_obj(obj)} ({debug_obj(project)})")
-return False
-
-chainable_roles = []
-for role in roles:
-for ace in obj.acl:
-if M.ACE.match(ace, role['_id'], permission):
-if ace.access == M.ACE.ALLOW:
-# access is allowed
-if DEBUG:
-log.debug(f"{user.username} '{permission}' granted 
on {debug_obj(obj)} ({debug_obj(project)})")
-return True
-else:
-# access is denied for this particular role
-if DEBUG:
-log.debug(f"{user.username} '{permission}' denied 
for role={role['name'] or role['_id']} (BUT continuing to see if other roles 
permit) on {debug_obj(obj)} ({debug_obj(project)})")
-break
+if obj is None:
+if DEBUG:
+log.debug(f'{user} denied {permission} on {debug_obj(obj)} 
({debug_obj(project)})')
+return False
+if roles is None:
+if user is None:
+user = c.user
+assert user, 'c.user should always be at least M.User.anonymous()'
+cred = Credentials.get()
+if project is None:
+if isinstance(obj, M.Neighborhood):
+project = obj.neighborhood_project
+if project is None:
+log.error('Neighborhood project missing for %s', obj)
+return False
+elif isinstance(obj, M.Project):
+project = obj.root_project
 else:
-# access neither allowed or denied, may chain to parent context
-chainable_roles.append(role)
-parent = obj.parent_security_context()
-if parent and chainable_roles:
-result = has_access(parent, permission, user=user, 
project=project, roles=tuple(chainable_roles))
-elif not isinstance(obj, M.Neighborhood):
-result = has_access(project.neighborhood, 'admin', user=user)
-if not (result or isinstance(obj, M.Project)):
-result = has_access(project, 'admin', user=user)
-else:
-result = False
+project = getattr(obj, 'project', None) or c.project
+project = project.root_project
+roles: RoleCache = cred.user_roles(user_id=user._id, 
project_id=project._id).reaching_roles
+
+# TODO: move deny logic into loop below; see ticket [#6715]
+if is_denied(obj, permission, user, project):
 if DEBUG:
-log.debug(f"{user.username} '{permission}' {result} from parent(s) 
on {debug_obj(obj)} ({debug_obj(project)})")
-return result
+log.debug(f"{user.username} '{permission}' denied on 
{debug_obj(obj)} ({debug_obj(project)})")
+return False
+
+chainable_r

(allura) 01/07: [#8555] some specific checks for blocked users, when creating new forum threads

2024-04-03 Thread brondsem
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a commit to branch db/8556-breaking-removal
in repository https://gitbox.apache.org/repos/asf/allura.git

commit 61d406fa8afea467efbb6478ba4e8e52d6506696
Author: Dave Brondsema 
AuthorDate: Tue Apr 2 17:44:28 2024 -0400

[#8555] some specific checks for blocked users, when creating new forum 
threads
---
 Allura/allura/lib/security.py  | 32 +++---
 Allura/allura/model/discuss.py |  6 +++-
 .../forgediscussion/controllers/root.py| 10 +--
 3 files changed, 34 insertions(+), 14 deletions(-)

diff --git a/Allura/allura/lib/security.py b/Allura/allura/lib/security.py
index cc874822d..3c16d05be 100644
--- a/Allura/allura/lib/security.py
+++ b/Allura/allura/lib/security.py
@@ -19,12 +19,12 @@
 This module provides the security predicates used in decorating various models.
 """
 
-import six
-import sys
+from __future__ import annotations
 import logging
 from collections import defaultdict
 import hashlib
 import requests
+import typing
 
 from tg import tmpl_context as c
 from tg import request
@@ -35,6 +35,9 @@ import tg
 
 from allura.lib.utils import TruthyCallable
 
+if typing.TYPE_CHECKING:
+from allura.model import M
+
 log = logging.getLogger(__name__)
 
 
@@ -277,7 +280,21 @@ class RoleCache:
 return set(self.reaching_ids)
 
 
-def has_access(obj, permission, user=None, project=None):
+def is_denied(obj, permission: str, user: M.User, project: M.Project) -> bool:
+from allura import model as M
+
+if user != M.User.anonymous():
+user_roles = Credentials.get().user_roles(user_id=user._id,
+  
project_id=project.root_project._id)
+for r in user_roles:
+deny_user = M.ACE.deny(r['_id'], permission)
+if M.ACL.contains(deny_user, obj.acl):
+return True
+
+return False
+
+
+def has_access(obj, permission: str, user: M.User | None = None, project: 
M.Project | None = None):
 '''Return whether the given user has the permission name on the given 
object.
 
 - First, all the roles for a user in the given project context are 
computed.
@@ -341,13 +358,8 @@ def has_access(obj, permission, user=None, project=None):
 user_id=user._id, project_id=project._id).reaching_ids
 
 # TODO: move deny logic into loop below; see ticket [#6715]
-if user != M.User.anonymous():
-user_roles = Credentials.get().user_roles(user_id=user._id,
-  
project_id=project.root_project._id)
-for r in user_roles:
-deny_user = M.ACE.deny(r['_id'], permission)
-if M.ACL.contains(deny_user, obj.acl):
-return False
+if is_denied(obj, permission, user, project):
+return False
 
 chainable_roles = []
 for rid in roles:
diff --git a/Allura/allura/model/discuss.py b/Allura/allura/model/discuss.py
index 3ecb42907..92999e295 100644
--- a/Allura/allura/model/discuss.py
+++ b/Allura/allura/model/discuss.py
@@ -33,10 +33,11 @@ from ming.odm.property import (FieldProperty, 
RelationProperty,
ForeignIdProperty)
 from ming.utils import LazyProperty
 from bson import ObjectId
+from webob import exc
 
 from allura.lib import helpers as h
 from allura.lib import security
-from allura.lib.security import require_access, has_access
+from allura.lib.security import require_access, has_access, is_denied
 from allura.lib import utils
 from allura.model.notification import Notification, Mailbox
 from .artifact import Artifact, ArtifactReference, VersionedArtifact, 
Snapshot, Message, Feed, ReactableArtifact
@@ -335,6 +336,9 @@ class Thread(Artifact, ActivityObject):
  is_meta=False, subscribe=False, **kw):
 if not ignore_security:
 require_access(self, 'post')
+# check app-level for Blocked Users, in addition to the standard 
`self` check above
+if is_denied(self.app, 'post', c.user, self.project):
+raise exc.HTTPForbidden
 if subscribe:
 self.primary().subscribe()
 if message_id is None:
diff --git a/ForgeDiscussion/forgediscussion/controllers/root.py 
b/ForgeDiscussion/forgediscussion/controllers/root.py
index 212245f79..251d57923 100644
--- a/ForgeDiscussion/forgediscussion/controllers/root.py
+++ b/ForgeDiscussion/forgediscussion/controllers/root.py
@@ -110,9 +110,13 @@ class RootController(BaseController, DispatchIndex, 
FeedController):
 @with_trailing_slash
 
@expose('jinja:forgediscussion:templates/discussionforums/create_topic.html')
 def create_topic(self, forum_name=None, new_forum=False, **kw):
-forums = model.Forum.query.find(dict(app_config_id=c.app.config._id,
- 

(allura) 05/07: [#8556] simplify more calls

2024-04-03 Thread brondsem
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a commit to branch db/8556-breaking-removal
in repository https://gitbox.apache.org/repos/asf/allura.git

commit 54573223031f45e2df820bc90dda57fe92721713
Author: Dave Brondsema 
AuthorDate: Wed Apr 3 13:43:48 2024 -0400

[#8556] simplify more calls
---
 Allura/allura/app.py  | 2 +-
 Allura/allura/controllers/auth.py | 6 +++---
 Allura/allura/ext/admin/admin_main.py | 2 +-
 Allura/allura/tests/model/test_artifact.py| 6 +++---
 Allura/allura/tests/test_plugin.py| 2 +-
 ForgeBlog/forgeblog/tests/test_roles.py   | 8 ++--
 ForgeDiscussion/forgediscussion/tests/test_forum_roles.py | 8 ++--
 ForgeFeedback/forgefeedback/tests/test_feedback_roles.py  | 8 ++--
 ForgeFiles/forgefiles/tests/test_files_roles.py   | 8 ++--
 ForgeShortUrl/forgeshorturl/main.py   | 2 +-
 ForgeTracker/forgetracker/tests/test_tracker_roles.py | 8 ++--
 ForgeTracker/forgetracker/tracker_main.py | 6 +++---
 ForgeWiki/forgewiki/tests/test_wiki_roles.py  | 8 ++--
 ForgeWiki/forgewiki/wiki_main.py  | 2 +-
 14 files changed, 50 insertions(+), 26 deletions(-)

diff --git a/Allura/allura/app.py b/Allura/allura/app.py
index 518269622..55cb7d299 100644
--- a/Allura/allura/app.py
+++ b/Allura/allura/app.py
@@ -495,7 +495,7 @@ class Application(ActivityObject):
 :rtype: bool
 
 """
-return has_access(self, 'read')(user=user)
+return has_access(self, 'read', user)
 
 def subscribe_admins(self):
 """Subscribe all project Admins (for this Application's project) to the
diff --git a/Allura/allura/controllers/auth.py 
b/Allura/allura/controllers/auth.py
index d74f48445..fab1757e8 100644
--- a/Allura/allura/controllers/auth.py
+++ b/Allura/allura/controllers/auth.py
@@ -513,9 +513,9 @@ class AuthController(BaseController):
 log.info("Can't find repo at %s on repo_path %s",
  rest[0], repo_path)
 return disallow
-return dict(allow_read=has_access(c.app, 'read')(user=user),
-allow_write=has_access(c.app, 'write')(user=user),
-allow_create=has_access(c.app, 'create')(user=user))
+return dict(allow_read=bool(has_access(c.app, 'read', user)),
+allow_write=bool(has_access(c.app, 'write', user)),
+allow_create=bool(has_access(c.app, 'create', user)))
 
 @expose('jinja:allura:templates/pwd_expired.html')
 @without_trailing_slash
diff --git a/Allura/allura/ext/admin/admin_main.py 
b/Allura/allura/ext/admin/admin_main.py
index 0904c0ce8..6feecd038 100644
--- a/Allura/allura/ext/admin/admin_main.py
+++ b/Allura/allura/ext/admin/admin_main.py
@@ -97,7 +97,7 @@ class AdminApp(Application):
 
 def is_visible_to(self, user):
 '''Whether the user can view the app.'''
-return has_access(c.project, 'create')(user=user)
+return has_access(c.project, 'create', user)
 
 @staticmethod
 def installable_tools_for(project):
diff --git a/Allura/allura/tests/model/test_artifact.py 
b/Allura/allura/tests/model/test_artifact.py
index 9eb2c8b4e..d63a2041e 100644
--- a/Allura/allura/tests/model/test_artifact.py
+++ b/Allura/allura/tests/model/test_artifact.py
@@ -85,13 +85,13 @@ class TestArtifact:
 pr = M.ProjectRole.by_user(u, upsert=True)
 ThreadLocalODMSession.flush_all()
 REGISTRY.register(allura.credentials, 
allura.lib.security.Credentials())
-assert not security.has_access(pg, 'delete')(user=u)
+assert not security.has_access(pg, 'delete', u)
 pg.acl.append(M.ACE.allow(pr._id, 'delete'))
 ThreadLocalODMSession.flush_all()
-assert security.has_access(pg, 'delete')(user=u)
+assert security.has_access(pg, 'delete', u)
 pg.acl.pop()
 ThreadLocalODMSession.flush_all()
-assert not security.has_access(pg, 'delete')(user=u)
+assert not security.has_access(pg, 'delete', u)
 
 def test_artifact_index(self):
 pg = WM.Page(title='TestPage1')
diff --git a/Allura/allura/tests/test_plugin.py 
b/Allura/allura/tests/test_plugin.py
index 964502cf2..c57e9e4a4 100644
--- a/Allura/allura/tests/test_plugin.py
+++ b/Allura/allura/tests/test_plugin.py
@@ -50,7 +50,7 @@ class TestProjectRegistrationProvider:
 
 @patch('allura.lib.security.has_access')
 def test_validate_project_15char_user(self, has_access):
-has_access.return_value = TruthyCallable(lambda: True)
+has_access.return_value = True
 nbhd = M.Neighborhood()
 self.provider.validate_project(
 neighborhood=nbhd,
diff --git a/ForgeBlog/forgeblog/tests/test_roles.py 
b/ForgeBlog/forge

(allura) branch db/8540 created (now 114c7bea1)

2024-03-28 Thread brondsem
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a change to branch db/8540
in repository https://gitbox.apache.org/repos/asf/allura.git


  at 114c7bea1 [#8540] wiki pages' recent sort by mod_date; simplify code

This branch includes the following new commits:

 new 114c7bea1 [#8540] wiki pages' recent sort by mod_date; simplify code

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.




(allura) 01/01: [#8540] wiki pages' recent sort by mod_date; simplify code

2024-03-28 Thread brondsem
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a commit to branch db/8540
in repository https://gitbox.apache.org/repos/asf/allura.git

commit 114c7bea111a2caf5151143a2ffa72698fedf472
Author: Dave Brondsema 
AuthorDate: Thu Mar 28 14:22:54 2024 -0400

[#8540] wiki pages' recent sort by mod_date; simplify code
---
 ForgeWiki/forgewiki/templates/wiki/browse.html |  6 +-
 ForgeWiki/forgewiki/wiki_main.py   | 16 
 2 files changed, 5 insertions(+), 17 deletions(-)

diff --git a/ForgeWiki/forgewiki/templates/wiki/browse.html 
b/ForgeWiki/forgewiki/templates/wiki/browse.html
index c384f0f1c..1bb776d92 100644
--- a/ForgeWiki/forgewiki/templates/wiki/browse.html
+++ b/ForgeWiki/forgewiki/templates/wiki/browse.html
@@ -52,11 +52,7 @@
 {% else %}
   
 {% endif %}
-{% if 'updated' in page %}
-  {{abbr_date(page['updated'])}}
-{% else %}
-  
-{% endif %}
+{{abbr_date(page['mod_date'])}}
   
 {% endfor %}
   
diff --git a/ForgeWiki/forgewiki/wiki_main.py b/ForgeWiki/forgewiki/wiki_main.py
index bac4d36da..8876cd8eb 100644
--- a/ForgeWiki/forgewiki/wiki_main.py
+++ b/ForgeWiki/forgewiki/wiki_main.py
@@ -477,24 +477,16 @@ class RootController(BaseController, DispatchIndex, 
FeedController):
 q = WM.Page.query.find(criteria)
 if sort == 'alpha':
 q = q.sort('title')
+elif sort == 'recent':
+q = q.sort('mod_date', -1)
 count = q.count()
 q = q.skip(start).limit(int(limit))
 for page in q:
 recent_edit = page.history().first()
-p = dict(title=page.title, url=page.url(), deleted=page.deleted)
+p = dict(title=page.title, url=page.url(), deleted=page.deleted, 
mod_date=page.mod_date)
 if recent_edit:
-p['updated'] = recent_edit.timestamp
-p['user_label'] = recent_edit.author.display_name
 p['user_name'] = recent_edit.author.username
-pages.append(p)
-else:
-if sort == 'recent':
-uv_pages.append(p)
-else:
-pages.append(p)
-if sort == 'recent':
-pages.sort(reverse=True, key=lambda x: (x['updated']))
-pages = pages + uv_pages
+pages.append(p)
 h1_text = f"{c.project.name} {c.app.config.options.mount_label} - 
Browse Pages"
 return dict(
 pages=pages, can_delete=can_delete, show_deleted=show_deleted,



(allura) branch master updated: [#8538] add new get_object_from_id timeline helper method which tries to find an object from an allura_id

2024-03-21 Thread brondsem
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/allura.git


The following commit(s) were added to refs/heads/master by this push:
 new 9ebd2cba3 [#8538] add new get_object_from_id timeline helper method 
which tries to find an object from an allura_id
9ebd2cba3 is described below

commit 9ebd2cba32e5badafe1678c6ddad9816024f16b3
Author: Dillon Walls 
AuthorDate: Wed Mar 13 19:38:02 2024 +

[#8538] add new get_object_from_id timeline helper method which tries to 
find an object from an allura_id
---
 Allura/allura/model/timeline.py | 6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/Allura/allura/model/timeline.py b/Allura/allura/model/timeline.py
index 9048b6c1e..6c343bd6f 100644
--- a/Allura/allura/model/timeline.py
+++ b/Allura/allura/model/timeline.py
@@ -138,7 +138,11 @@ def get_activity_object(activity_object_dict):
 allura_id = get_allura_id(activity_object_dict)
 if not allura_id:
 return None
-classname, _id = allura_id.split(':', 1)
+return get_object_from_id(allura_id)
+
+
+def get_object_from_id(node_id):
+classname, _id = node_id.split(':', 1)
 cls = Mapper.by_classname(classname).mapped_class
 try:
 _id = bson.ObjectId(_id)



(allura) 04/05: [#8539] add some pylint checks

2024-03-20 Thread brondsem
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a commit to branch db/8539
in repository https://gitbox.apache.org/repos/asf/allura.git

commit 5c76a8524570698a5bc6b1e91ee0319ef33b5c41
Author: Dave Brondsema 
AuthorDate: Wed Mar 20 17:10:45 2024 -0400

[#8539] add some pylint checks
---
 Allura/allura/command/base.py  | 2 +-
 Allura/allura/lib/helpers.py   | 2 +-
 Allura/allura/lib/patches.py   | 2 +-
 Allura/allura/tests/functional/test_discuss.py | 3 +--
 Allura/allura/websetup/bootstrap.py| 2 +-
 ruff.toml  | 4 
 scripts/ApacheAccessHandler.py | 2 +-
 7 files changed, 10 insertions(+), 7 deletions(-)

diff --git a/Allura/allura/command/base.py b/Allura/allura/command/base.py
index 65b7c758e..de09018c9 100644
--- a/Allura/allura/command/base.py
+++ b/Allura/allura/command/base.py
@@ -87,7 +87,7 @@ class Command(command.Command, metaclass=MetaParserDocstring):
 return tg.config
 
 def basic_setup(self):
-global log, M
+global log, M  # noqa: PLW0603
 if self.args[0]:
 # Probably being called from the command line - load the config
 # file
diff --git a/Allura/allura/lib/helpers.py b/Allura/allura/lib/helpers.py
index 5f5c41bdf..26d031446 100644
--- a/Allura/allura/lib/helpers.py
+++ b/Allura/allura/lib/helpers.py
@@ -32,7 +32,7 @@ import json
 import logging
 import string
 import random
-import pickle as pickle
+import pickle
 from hashlib import sha1
 from datetime import datetime, timedelta
 from collections import defaultdict, OrderedDict
diff --git a/Allura/allura/lib/patches.py b/Allura/allura/lib/patches.py
index 7c6e416eb..964624d0b 100644
--- a/Allura/allura/lib/patches.py
+++ b/Allura/allura/lib/patches.py
@@ -29,7 +29,7 @@ import six
 
 _patched = False
 def apply():
-global _patched
+global _patched  # noqa: PLW0603
 if _patched:
 return
 _patched = True
diff --git a/Allura/allura/tests/functional/test_discuss.py 
b/Allura/allura/tests/functional/test_discuss.py
index f87f4352d..100f9b276 100644
--- a/Allura/allura/tests/functional/test_discuss.py
+++ b/Allura/allura/tests/functional/test_discuss.py
@@ -426,8 +426,7 @@ class TestAttachment(TestDiscussBase):
 if 'attachment' in alink['href']:
 alink = str(alink['href'])
 return alink
-else:
-assert False, 'attachment link not found'
+assert False, 'attachment link not found'
 
 def test_attach(self):
 r = self.app.post(self.post_link + 'attach',
diff --git a/Allura/allura/websetup/bootstrap.py 
b/Allura/allura/websetup/bootstrap.py
index eadd141e9..21cfa6781 100644
--- a/Allura/allura/websetup/bootstrap.py
+++ b/Allura/allura/websetup/bootstrap.py
@@ -56,7 +56,7 @@ def bootstrap(command, conf, vars):
 REGISTRY.register(ew.widget_context,
   ew.core.WidgetContext('http', ew.ResourceManager()))
 
-create_test_data = asbool(os.getenv('ALLURA_TEST_DATA', True))
+create_test_data = asbool(os.getenv('ALLURA_TEST_DATA', 'true'))
 
 # if this is a test_run, skip user project creation to save time
 make_user_projects = not test_run
diff --git a/ruff.toml b/ruff.toml
index 7da944339..4337590c5 100644
--- a/ruff.toml
+++ b/ruff.toml
@@ -33,6 +33,9 @@ lint.select = [
 "G010", # logging.warn
 "T10",  # debugger breakpoints
 "T20",  # print()
+"PLC",
+"PLE",
+"PLW",
 "FA",   # future annotations (to ensure compatibility with 
`target-version`)
 ]
 
@@ -57,6 +60,7 @@ lint.ignore = [
 'S324', # md5 & sha1
 'S603', # subprocess
 'S607', # partial path
+'PLW2901', # loop var overwritten
 ]
 
 [lint.per-file-ignores]
diff --git a/scripts/ApacheAccessHandler.py b/scripts/ApacheAccessHandler.py
index 217e4ecf6..fc10499a1 100644
--- a/scripts/ApacheAccessHandler.py
+++ b/scripts/ApacheAccessHandler.py
@@ -52,7 +52,7 @@ def load_requests_lib(req):
 exec(compile(open(activate_this, "rb").read(), activate_this, 
'exec'), {'__file__': activate_this})  # noqa: S102
 except Exception as e:
 log(req, "Couldn't activate venv via {}: {}".format(activate_this, 
repr(e)))
-global requests
+global requests  # noqa: PLW0603
 import requests as requests_lib
 requests = requests_lib
 



(allura) branch db/8539 created (now a7c783e6d)

2024-03-20 Thread brondsem
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a change to branch db/8539
in repository https://gitbox.apache.org/repos/asf/allura.git


  at a7c783e6d [#8539] code simplifications

This branch includes the following new commits:

 new c5a60409d [#8539] upgrade ruff
 new 2dc7b9fbd [#8539] remove old teamforge import script, which had lots 
of hardcoded specifics
 new 99daa1fdf [#8539] add bandit checks
 new 5c76a8524 [#8539] add some pylint checks
 new a7c783e6d [#8539] code simplifications

The 5 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.




(allura) 05/05: [#8539] code simplifications

2024-03-20 Thread brondsem
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a commit to branch db/8539
in repository https://gitbox.apache.org/repos/asf/allura.git

commit a7c783e6d18be9881311bd124c7842679bad3ae0
Author: Dave Brondsema 
AuthorDate: Wed Mar 20 17:16:19 2024 -0400

[#8539] code simplifications
---
 Allura/allura/command/taskd_cleanup.py |  4 +--
 Allura/allura/controllers/project.py   |  2 +-
 Allura/allura/controllers/rest.py  |  2 +-
 Allura/allura/controllers/site_admin.py|  2 +-
 Allura/allura/lib/utils.py |  2 +-
 Allura/allura/tests/decorators.py  |  8 ++
 .../allura/tests/functional/test_neighborhood.py   |  4 +--
 .../tests/functional/test_personal_dashboard.py| 29 +++---
 .../allura/tests/functional/test_user_profile.py   | 17 ++---
 Allura/allura/tests/model/test_project.py  | 11 
 Allura/allura/tests/test_commands.py   |  4 +--
 Allura/allura/tests/test_helpers.py|  5 ++--
 Allura/allura/tests/test_tasks.py  | 10 
 Allura/allura/tests/test_webhooks.py   |  5 ++--
 Allura/allura/tests/unit/test_session.py   | 28 ++---
 ForgeActivity/forgeactivity/main.py|  2 +-
 .../tests/unit/test_root_controller.py |  4 +--
 ForgeImporters/forgeimporters/github/__init__.py   |  2 +-
 ForgeTracker/forgetracker/tracker_main.py  |  2 +-
 ruff.toml  |  5 
 20 files changed, 71 insertions(+), 77 deletions(-)

diff --git a/Allura/allura/command/taskd_cleanup.py 
b/Allura/allura/command/taskd_cleanup.py
index 0f4ec913e..232773f93 100644
--- a/Allura/allura/command/taskd_cleanup.py
+++ b/Allura/allura/command/taskd_cleanup.py
@@ -154,7 +154,7 @@ class TaskdCleanupCommand(base.Command):
 
 def _check_taskd_status(self, pid):
 for i in range(self.options.num_retry):
-retry = False if i == 0 else True
+retry = i != 0
 status = self._taskd_status(pid, retry)
 if ('taskd pid %s' % pid) in status:
 return 'OK'
@@ -164,7 +164,7 @@ class TaskdCleanupCommand(base.Command):
 
 def _check_task(self, taskd_pid, task):
 for i in range(self.options.num_retry):
-retry = False if i == 0 else True
+retry = i != 0
 status = self._taskd_status(taskd_pid, retry)
 line = 'taskd pid {} is currently handling task {}'.format(
 taskd_pid, task)
diff --git a/Allura/allura/controllers/project.py 
b/Allura/allura/controllers/project.py
index f4d8c9865..f04fa5b62 100644
--- a/Allura/allura/controllers/project.py
+++ b/Allura/allura/controllers/project.py
@@ -564,7 +564,7 @@ class NeighborhoodAdminController:
 set_nav(self.neighborhood)
 c.overview_form = W.neighborhood_overview_form
 allow_undelete = asbool(config.get('allow_project_undelete', True))
-allow_wiki_as_root = True if get_default_wiki_page() else False
+allow_wiki_as_root = bool(get_default_wiki_page())
 
 return dict(
 neighborhood=self.neighborhood,
diff --git a/Allura/allura/controllers/rest.py 
b/Allura/allura/controllers/rest.py
index f077b3d40..255348208 100644
--- a/Allura/allura/controllers/rest.py
+++ b/Allura/allura/controllers/rest.py
@@ -189,7 +189,7 @@ class Oauth1Validator(oauthlib.oauth1.RequestValidator):
 if request.environ.get('paste.testing'):
 # test suite is running
 return False
-elif asbool(config.get('debug')) and 
config['base_url'].startswith('http://'):
+elif asbool(config.get('debug')) and 
config['base_url'].startswith('http://'):  # noqa: SIM103
 # development w/o https
 return False
 else:
diff --git a/Allura/allura/controllers/site_admin.py 
b/Allura/allura/controllers/site_admin.py
index 07009028b..252aea353 100644
--- a/Allura/allura/controllers/site_admin.py
+++ b/Allura/allura/controllers/site_admin.py
@@ -184,7 +184,7 @@ class SiteAdminController:
 try:
 end_dt = datetime.strptime(end_dt, '%Y/%m/%d %H:%M:%S')
 except ValueError:
-end_dt = start_dt - timedelta(days=3) if not end_dt else end_dt
+end_dt = end_dt if end_dt else start_dt - timedelta(days=3)
 start = bson.ObjectId.from_datetime(start_dt)
 end = bson.ObjectId.from_datetime(end_dt)
 nb = M.Neighborhood.query.get(name='Users')
diff --git a/Allura/allura/lib/utils.py b/Allura/allura/lib/utils.py
index 0cf6b8c3c..de33f559b 100644
--- a/Allura/allura/lib/utils.py
+++ b/Allura/allura/lib/utils.py
@@ -337,7 +337,7 @@ class AntiSpam:
 if params is None:
 params = request.params
 new_params = dict(params)
-if not request.method == 'GET':
+if request.method != 'GET

(allura) 02/05: [#8539] remove old teamforge import script, which had lots of hardcoded specifics

2024-03-20 Thread brondsem
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a commit to branch db/8539
in repository https://gitbox.apache.org/repos/asf/allura.git

commit 2dc7b9fbdf79cae0cbd43fbc72a169724997ca47
Author: Dave Brondsema 
AuthorDate: Wed Mar 20 16:20:08 2024 -0400

[#8539] remove old teamforge import script, which had lots of hardcoded 
specifics
---
 .gitignore |1 -
 .pre-commit-config.yaml|1 -
 Allura/docs/getting_started/administration.rst |   11 -
 scripts/teamforge-import.py| 1126 
 4 files changed, 1139 deletions(-)

diff --git a/.gitignore b/.gitignore
index c620e794e..97d6ae99e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -34,7 +34,6 @@ Allura/allura/templates/home
 Allura/allura/templates/var
 Allura/production.ini
 Allura/forced_upgrade.ini
-scripts/teamforge-export/
 /node_modules
 report.clonedigger
 .ropeproject
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 7d3eea1f2..bfda2f671 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -33,7 +33,6 @@ repos:
 (?x)^(
 Allura/allura/eventslistener.py|
 Allura/allura/lib/.*|
-scripts/teamforge-import.py
 )$
 
 
diff --git a/Allura/docs/getting_started/administration.rst 
b/Allura/docs/getting_started/administration.rst
index 03b413f21..5d9bff267 100644
--- a/Allura/docs/getting_started/administration.rst
+++ b/Allura/docs/getting_started/administration.rst
@@ -314,17 +314,6 @@ scrub-allura-data.py
 :prog: paster script development.ini ../scripts/scrub-allura-data.py --
 
 
-teamforge-import.py

-
-*Cannot currently be run as a background task.*
-
-Extract data from a TeamForge site (via its web API), and import directly into 
Allura.  There are some hard-coded
-and extra functions in this script, which should be removed or updated before 
being used again.
-Requires running: :command:`pip install suds` first. ::
-
-usage: paster script development.ini ../scripts/teamforge-import.py -- 
--help
-
 .. _site-notifications:
 
 Site Notifications
diff --git a/scripts/teamforge-import.py b/scripts/teamforge-import.py
deleted file mode 100644
index 15b669d38..0
--- a/scripts/teamforge-import.py
+++ /dev/null
@@ -1,1126 +0,0 @@
-#   Licensed to the Apache Software Foundation (ASF) under one
-#   or more contributor license agreements.  See the NOTICE file
-#   distributed with this work for additional information
-#   regarding copyright ownership.  The ASF licenses this file
-#   to you under the Apache License, Version 2.0 (the
-#   "License"); you may not use this file except in compliance
-#   with the License.  You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-#   Unless required by applicable law or agreed to in writing,
-#   software distributed under the License is distributed on an
-#   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-#   KIND, either express or implied.  See the License for the
-#   specific language governing permissions and limitations
-#   under the License.
-
-import logging
-from ast import literal_eval
-from getpass import getpass
-from optparse import OptionParser
-from tg import tmpl_context as c
-import re
-import os
-from time import mktime
-import time
-import json
-from urllib.parse import urlparse
-import six.moves.urllib.request
-import six.moves.urllib.parse
-import six.moves.urllib.error
-from http.cookiejar import CookieJar
-from datetime import datetime
-from configparser import ConfigParser
-import random
-import string
-
-import sqlalchemy
-from suds.client import Client
-from ming.odm.odmsession import ThreadLocalODMSession
-from ming.base import Object
-
-from allura import model as M
-from allura.lib import helpers as h
-from allura.lib import utils
-import six
-
-log = logging.getLogger('teamforge-import')
-
-'''
-
-http://help.collab.net/index.jsp?topic=/teamforge520/reference/api-services.html
-
-http://www.open.collab.net/nonav/community/cif/csfe/50/javadoc/index.html?com/collabnet/ce/soap50/webservices/page/package-summary.html
-
-'''
-
-options = None
-s = None  # security token
-client = None  # main api client
-users = {}
-
-cj = CookieJar()
-loggedInOpener = 
six.moves.urllib.request.build_opener(six.moves.urllib.request.HTTPCookieProcessor(cj))
-
-
-def make_client(api_url, app):
-return Client(api_url + app + '?wsdl', location=api_url + app)
-
-
-def main():
-global options, s, client, users
-defaults = dict(
-api_url=None,
-attachment_url='/sf/%s/do/%s/',
-default_wiki_text='PRODUCT NAME HERE',
-username=None,
-password=None,
-output_dir='teamforge-export/',
-list_project_ids=False,
-neighborhood=None,
-ne

(allura) 01/05: [#8539] upgrade ruff

2024-03-20 Thread brondsem
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a commit to branch db/8539
in repository https://gitbox.apache.org/repos/asf/allura.git

commit c5a60409d0cf6ea1f184bb8069b8ea8075187763
Author: Dave Brondsema 
AuthorDate: Tue Mar 19 18:08:38 2024 -0400

[#8539] upgrade ruff
---
 .pre-commit-config.yaml |  2 +-
 requirements.txt|  2 +-
 ruff.toml   | 10 ++
 3 files changed, 8 insertions(+), 6 deletions(-)

diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 0e3a5168f..7d3eea1f2 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -80,7 +80,7 @@ repos:
 
 - repo: https://github.com/astral-sh/ruff-pre-commit
   # Ruff version.
-  rev: v0.1.11
+  rev: v0.3.3
   hooks:
 - id: ruff
   types: [python]
diff --git a/requirements.txt b/requirements.txt
index 471b477ba..656376a0e 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -201,7 +201,7 @@ requests==2.31.0
 #   requests-oauthlib
 requests-oauthlib==1.3.1
 # via -r requirements.in
-ruff==0.1.13
+ruff==0.3.2
 # via -r requirements.in
 setproctitle==1.3.3
 # via -r requirements.in
diff --git a/ruff.toml b/ruff.toml
index b2e7c55cb..2bfa1ec9e 100644
--- a/ruff.toml
+++ b/ruff.toml
@@ -16,10 +16,10 @@
 #   under the License.
 
 line-length = 119
-show-source = true
+output-format = "full"
 target-version = "py38"
 
-select = [
+lint.select = [
 # all flake8 & pep8 (except 'ignore' below)
 "F",
 "E",
@@ -29,12 +29,14 @@ select = [
 "ISC001",  # NIC001 in flake8 codes
 "B",
 "PGH",  # https://github.com/pre-commit/pygrep-hooks
+"S307", # eval
+"G010", # logging.warn
 "T10",  # debugger breakpoints
 "T20",  # print()
 "FA",   # future annotations (to ensure compatibility with 
`target-version`)
 ]
 
-ignore = [
+lint.ignore = [
 'F401', # Imported but unused,
 'F811', # Redefinition of unused
 'F841', # Assigned to but never used
@@ -47,7 +49,7 @@ ignore = [
 'B905', # zip(strict=True) would be good, but need to closely evaluate all 
existing cases first
 ]
 
-[per-file-ignores]
+[lint.per-file-ignores]
 '__init__.py' = ['F403']  # import *
 '**/{alluratest,tests}/*' = [
 'B011',  # assert False



(allura) 03/05: [#8539] add bandit checks

2024-03-20 Thread brondsem
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a commit to branch db/8539
in repository https://gitbox.apache.org/repos/asf/allura.git

commit 99daa1fdfc121810da84be60ad75c7256f386949
Author: Dave Brondsema 
AuthorDate: Wed Mar 20 16:37:16 2024 -0400

[#8539] add bandit checks
---
 Allura/allura/command/script.py|  2 +-
 Allura/allura/command/taskd.py |  2 +-
 Allura/allura/config/middleware.py |  2 +-
 Allura/allura/controllers/rest.py  |  2 +-
 Allura/allura/lib/decorators.py|  2 +-
 Allura/allura/lib/helpers.py   |  2 +-
 Allura/allura/lib/import_api.py|  2 +-
 Allura/allura/lib/phone/nexmo.py   |  4 ++--
 Allura/allura/lib/plugin.py|  5 +++--
 Allura/allura/lib/project_create_helpers.py|  2 +-
 Allura/allura/model/index.py   |  2 +-
 Allura/allura/model/notification.py|  4 ++--
 Allura/allura/scripts/trac_export.py   |  6 +++---
 .../allura/tests/functional/test_neighborhood.py   |  7 ++-
 Allura/allura/tests/unit/phone/test_nexmo.py   | 16 
 Allura/allura/websetup/bootstrap.py|  2 +-
 Allura/ldap-setup.py   |  2 +-
 Allura/setup.py|  2 +-
 ForgeImporters/forgeimporters/base.py  |  2 +-
 .../forgetracker/tests/unit/test_ticket_model.py   |  2 +-
 fuse/accessfs.py   |  2 +-
 ruff.toml  | 22 +++---
 scripts/ApacheAccessHandler.py |  2 +-
 scripts/changelog.py   |  2 +-
 scripts/new_ticket.py  |  2 +-
 scripts/wiki-copy.py   |  4 ++--
 26 files changed, 63 insertions(+), 41 deletions(-)

diff --git a/Allura/allura/command/script.py b/Allura/allura/command/script.py
index 52e58b2fb..78edd8746 100644
--- a/Allura/allura/command/script.py
+++ b/Allura/allura/command/script.py
@@ -73,7 +73,7 @@ class ScriptCommand(base.Command):
 pr = cProfile.Profile()
 pr.enable()
 
-exec(code, ns)
+exec(code, ns)  # noqa: S102
 
 if self.options.profile:
 pr.disable()
diff --git a/Allura/allura/command/taskd.py b/Allura/allura/command/taskd.py
index 9d6c42c67..782c216cd 100644
--- a/Allura/allura/command/taskd.py
+++ b/Allura/allura/command/taskd.py
@@ -160,7 +160,7 @@ class TaskdCommand(base.Command):
 
 if self.restart_when_done:
 base.log.info('taskd pid %s restarting itself' % os.getpid())
-os.execv(sys.argv[0], sys.argv)
+os.execv(sys.argv[0], sys.argv)  # noqa: S606
 
 
 class TaskCommand(base.Command):
diff --git a/Allura/allura/config/middleware.py 
b/Allura/allura/config/middleware.py
index e481a1621..edf28a968 100644
--- a/Allura/allura/config/middleware.py
+++ b/Allura/allura/config/middleware.py
@@ -91,7 +91,7 @@ def make_app(global_conf: dict, **app_conf):
 class BeakerPickleSerializerWithLatin1(PickleSerializer):
 def loads(self, data_string):
 # need latin1 to decode py2 timestamps in py  
https://docs.python.org/3/library/pickle.html#pickle.Unpickler
-return pickle.loads(data_string, encoding='latin1')
+return pickle.loads(data_string, encoding='latin1')  # noqa: S301
 
 
 def _make_core_app(root, global_conf: dict, **app_conf):
diff --git a/Allura/allura/controllers/rest.py 
b/Allura/allura/controllers/rest.py
index ef4ae4ca5..f077b3d40 100644
--- a/Allura/allura/controllers/rest.py
+++ b/Allura/allura/controllers/rest.py
@@ -251,7 +251,7 @@ class OAuthNegotiator:
 return AlluraOauth1Server(Oauth1Validator())
 
 def _authenticate(self):
-bearer_token_prefix = 'Bearer '
+bearer_token_prefix = 'Bearer '  # noqa: S105
 auth = request.headers.get('Authorization')
 if auth and auth.startswith(bearer_token_prefix):
 access_token = auth[len(bearer_token_prefix):]
diff --git a/Allura/allura/lib/decorators.py b/Allura/allura/lib/decorators.py
index eaf8016f8..a0fecc1f4 100644
--- a/Allura/allura/lib/decorators.py
+++ b/Allura/allura/lib/decorators.py
@@ -142,7 +142,7 @@ def reconfirm_auth(func, *args, **kwargs):
 session.save()
 kwargs.pop('password', None)
 else:
-request.validation.errors['password'] = 'Invalid password.'
+request.validation.errors['password'] = 'Invalid password.'  # 
noqa: S105
 
 allowed_timedelta = 
timedelta(seconds=asint(config.get('auth.reconfirm.seconds', 60)))
 last_reconfirm = session.get('auth-reconfirmed', datetime.min)
diff --git a/Allura/allura/lib/helpers.py b/Allura/allura/lib/helpers.py
index f0675e443..5f5c41bdf

(allura) branch master updated: support overlapping admin urls, if a tool is installed with "groups" mount point

2024-03-12 Thread brondsem
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/allura.git


The following commit(s) were added to refs/heads/master by this push:
 new 7ff944374 support overlapping admin urls, if a tool is installed with 
"groups" mount point
7ff944374 is described below

commit 7ff9443742f751009b4f6bf0d33f76cb4efae868
Author: Dave Brondsema 
AuthorDate: Tue Mar 12 11:40:18 2024 -0400

support overlapping admin urls, if a tool is installed with "groups" mount 
point
---
 Allura/allura/ext/admin/admin_main.py| 13 -
 Allura/allura/tests/functional/test_admin.py |  6 ++
 2 files changed, 14 insertions(+), 5 deletions(-)

diff --git a/Allura/allura/ext/admin/admin_main.py 
b/Allura/allura/ext/admin/admin_main.py
index d250a70fe..78563f2cb 100644
--- a/Allura/allura/ext/admin/admin_main.py
+++ b/Allura/allura/ext/admin/admin_main.py
@@ -300,11 +300,6 @@ class ProjectAdminController(BaseController):
 raise exc.HTTPNotFound(name)
 return app.admin, remainder
 
-@without_trailing_slash
-@expose('jinja:allura.ext.admin:templates/project_permissions.html')
-def groups(self, **kw):
-return dict()
-
 @expose()
 @require_post()
 @validate(W.metadata_admin, error_handler=overview)
@@ -1089,6 +1084,14 @@ class GroupsController(BaseController):
 def _check_security(self):
 require_access(c.project, 'admin')
 
+@expose()
+def _lookup(self, *remainder):
+# if a forum/wiki/etc is installed at mount_point 'groups', this 
allows its tool admin pages to still work
+# could expand this to other ProjectAdminController paths too.
+app = c.project.app_instance('groups')
+if app:
+return app.admin, remainder
+
 def _index_permissions(self):
 permissions = {
 p: [] for p in c.project.permissions}
diff --git a/Allura/allura/tests/functional/test_admin.py 
b/Allura/allura/tests/functional/test_admin.py
index 485f26b9b..62d7111d8 100644
--- a/Allura/allura/tests/functional/test_admin.py
+++ b/Allura/allura/tests/functional/test_admin.py
@@ -999,6 +999,12 @@ class TestProjectAdmin(TestController):
 resp = self.app.post('/admin/update', params={'fediverse_address': 
'https://indieweb.social/@test'})
 assert resp.status_int == 302
 
+@td.with_tool('test', 'Wiki', 'groups')
+def test_overlapping_url_paths(self):
+# the wiki installed at "groups" overlaps its admin pages with normal 
/admin/groups but is still usable
+r = self.app.get('/p/test/admin/groups/edit_label')
+r.mustcontain('')
+
 
 class TestExport(TestController):
 



(allura) branch master updated: future annotations in a few files, so it works fine on python 3.8 still

2024-03-08 Thread brondsem
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/allura.git


The following commit(s) were added to refs/heads/master by this push:
 new 2f38593f4 future annotations in a few files, so it works fine on 
python 3.8 still
2f38593f4 is described below

commit 2f38593f46ac00b67115ed5d09f17edffbb4a1c7
Author: Dave Brondsema 
AuthorDate: Fri Mar 8 17:45:01 2024 -0500

future annotations in a few files, so it works fine on python 3.8 still
---
 Allura/allura/lib/markdown_extensions.py | 1 +
 Allura/allura/lib/plugin.py  | 1 +
 Allura/allura/lib/widgets/discuss.py | 1 +
 ruff.toml| 1 +
 4 files changed, 4 insertions(+)

diff --git a/Allura/allura/lib/markdown_extensions.py 
b/Allura/allura/lib/markdown_extensions.py
index 9bcc7f892..b6d423d58 100644
--- a/Allura/allura/lib/markdown_extensions.py
+++ b/Allura/allura/lib/markdown_extensions.py
@@ -15,6 +15,7 @@
 #   specific language governing permissions and limitations
 #   under the License.
 
+from __future__ import annotations
 import re
 import logging
 from typing import List
diff --git a/Allura/allura/lib/plugin.py b/Allura/allura/lib/plugin.py
index 3bb389d15..03b6d61f2 100644
--- a/Allura/allura/lib/plugin.py
+++ b/Allura/allura/lib/plugin.py
@@ -18,6 +18,7 @@
 '''
 Allura plugins for authentication and project registration
 '''
+from __future__ import annotations
 import re
 import os
 import logging
diff --git a/Allura/allura/lib/widgets/discuss.py 
b/Allura/allura/lib/widgets/discuss.py
index db5cf0ac4..feef86db8 100644
--- a/Allura/allura/lib/widgets/discuss.py
+++ b/Allura/allura/lib/widgets/discuss.py
@@ -14,6 +14,7 @@
 #   KIND, either express or implied.  See the License for the
 #   specific language governing permissions and limitations
 #   under the License.
+from __future__ import annotations
 
 from formencode import validators as fev
 
diff --git a/ruff.toml b/ruff.toml
index e1cf41377..b2e7c55cb 100644
--- a/ruff.toml
+++ b/ruff.toml
@@ -31,6 +31,7 @@ select = [
 "PGH",  # https://github.com/pre-commit/pygrep-hooks
 "T10",  # debugger breakpoints
 "T20",  # print()
+"FA",   # future annotations (to ensure compatibility with 
`target-version`)
 ]
 
 ignore = [



(allura) branch master updated: make it easier to change order of sidebar items w/ the AdminExtension

2024-03-08 Thread brondsem
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/allura.git


The following commit(s) were added to refs/heads/master by this push:
 new 1ced11479 make it easier to change order of sidebar items w/ the 
AdminExtension
1ced11479 is described below

commit 1ced1147925c5b90edb507c3aa81d04d13375374
Author: Dillon Walls 
AuthorDate: Wed Mar 6 16:24:01 2024 +

make it easier to change order of sidebar items w/ the AdminExtension
---
 Allura/allura/ext/admin/admin_main.py | 2 +-
 Allura/allura/lib/plugin.py   | 8 ++--
 ForgeImporters/forgeimporters/base.py | 1 +
 3 files changed, 8 insertions(+), 3 deletions(-)

diff --git a/Allura/allura/ext/admin/admin_main.py 
b/Allura/allura/ext/admin/admin_main.py
index 6e8232fc6..d250a70fe 100644
--- a/Allura/allura/ext/admin/admin_main.py
+++ b/Allura/allura/ext/admin/admin_main.py
@@ -172,7 +172,7 @@ class AdminApp(Application):
 
 for ep_name in sorted(g.entry_points['admin'].keys()):
 admin_extension = g.entry_points['admin'][ep_name]
-admin_extension().update_project_sidebar_menu(links)
+links = (admin_extension().update_project_sidebar_menu(links) or 
links)
 
 return links
 
diff --git a/Allura/allura/lib/plugin.py b/Allura/allura/lib/plugin.py
index d88163284..3bb389d15 100644
--- a/Allura/allura/lib/plugin.py
+++ b/Allura/allura/lib/plugin.py
@@ -33,6 +33,7 @@ from random import randint
 from hashlib import sha256
 from base64 import b64encode
 from datetime import datetime, timedelta
+import typing
 import calendar
 import six
 
@@ -60,6 +61,9 @@ from allura.lib import utils
 from allura.tasks import activity_tasks
 from allura.tasks.index_tasks import solr_del_project_artifacts
 
+if typing.TYPE_CHECKING:
+from allura.app import SitemapEntry
+
 log = logging.getLogger(__name__)
 
 
@@ -1800,7 +1804,7 @@ class AdminExtension:
 
 project_admin_controllers = {}
 
-def update_project_sidebar_menu(self, sidebar_links):
+def update_project_sidebar_menu(self, sidebar_links: list['SitemapEntry']) 
-> list['SitemapEntry']:
 """
 Implement this function to modify the project sidebar.
 Check `c.project` if you want to limit when this displays
@@ -1811,7 +1815,7 @@ class AdminExtension:
 
 :rtype: ``None``
 """
-pass
+return sidebar_links
 
 
 class SiteAdminExtension:
diff --git a/ForgeImporters/forgeimporters/base.py 
b/ForgeImporters/forgeimporters/base.py
index bd07200c5..e66cce270 100644
--- a/ForgeImporters/forgeimporters/base.py
+++ b/ForgeImporters/forgeimporters/base.py
@@ -611,6 +611,7 @@ class ImportAdminExtension(AdminExtension):
 base_url = c.project.url() + 'admin/ext/'
 link = SitemapEntry('Import', base_url + 'import/')
 sidebar_links.append(link)
+return sidebar_links
 
 
 def bytesio_parser(page):



(allura) 03/03: [#8537] do not run scanMessages forever

2024-03-08 Thread brondsem
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/allura.git

commit 9871bd9b3375b6ba19585f5b79dfdff3f01626e9
Author: Dave Brondsema 
AuthorDate: Fri Mar 8 12:38:16 2024 -0500

[#8537] do not run scanMessages forever
---
 Allura/allura/public/nf/js/jquery.notify.js | 56 ++---
 1 file changed, 18 insertions(+), 38 deletions(-)

diff --git a/Allura/allura/public/nf/js/jquery.notify.js 
b/Allura/allura/public/nf/js/jquery.notify.js
index 7e81ff58f..9ad8b8916 100644
--- a/Allura/allura/public/nf/js/jquery.notify.js
+++ b/Allura/allura/public/nf/js/jquery.notify.js
@@ -55,47 +55,21 @@
 $(message).animate({ opacity: 0 }, { duration: 250, queue: false, 
complete: fadeComplete });
 }
 
-function scanMessages(container, o) {
-function helper() {
-var selector = '.' + o.newClass + '.' + o.messageClass,
-$msg;
-// Special support for persistent messages, such as sitewide
-// notifications; note that this requires the cookie plugin.
-// Persistent messages are assumed sticky.
-if ($.cookie && $.cookie(o.persistentCookie)){
-$msg = $(selector, container).not(o.persistentClass);
-} else {
-$msg = $(selector, container);
-}
-if ($msg.length) {
-$msg.prepend(o.closeIcon);
-$msg.click(function(e) {
-if ($.cookie && $msg.hasClass(o.persistentClass)) {
-$.cookie(o.persistentCookie, 1, { path: '/' });
-}
-closer(this, o);
-});
-$msg.removeClass(o.newClass).addClass(o.activeClass);
-$msg.each(function() {
-var self = this;
-if (!$(self).hasClass(o.stickyClass) && 
!$(self).hasClass(o.persistentClass)) {
-var timer = $(self).attr('data-timer') || o.timer;
-setTimeout(function() {
-closer($(self), o);
-}, timer);
-}
-$(self).fadeIn(500);
-});
-}
-setTimeout(helper, o.interval);
-}
-helper();
-}
-
 function sanitize(str) {
 return str.replace(//g, '');
 }
 
+function displayNotification(el, o){
+var selector = '.' + o.newClass + '.' + o.messageClass;
+$(selector).fadeIn(500);
+if (!$(selector).hasClass(o.persistentClass)) {
+var timer = $(selector).attr('data-timer') || o.timer;
+setTimeout(function() {
+closer(el, o);
+}, timer);
+}
+}
+
 $.fn.notifier = function(options){
 var opts = $.extend({}, $.fn.notify.defaults, options);
 return $(this).each(function() {
@@ -107,7 +81,11 @@
 });
 }
 $('.' + o.messageClass, self).addClass(o.newClass);
-scanMessages(self, o);
+var selector = '.' + o.newClass + '.' + o.messageClass;
+$('body').on("click", selector, function(e) {
+  closer(this, o);
+});
+displayNotification($(selector).get(0), o);
 });
 };
 
@@ -136,6 +114,8 @@
 }
 var html = tmpl(o.tmpl, o);
 $(this).append(html);
+var newMsgEl = $('.message:last-child', this).get(0);
+displayNotification(newMsgEl, o);
 } else {
 if (window.console) {
 //#JSCOVERAGE_IF window.console



(allura) 01/03: [#8537] moved g analytics further down the page

2024-03-08 Thread brondsem
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/allura.git

commit 4bed769841e8981cb4fa4ae3803b6fe3dab3282e
Author: Guillermo Cruz 
AuthorDate: Thu Feb 22 16:59:44 2024 -0700

[#8537] moved g analytics further down the page
---
 Allura/allura/templates/jinja_master/master.html| 2 +-
 Allura/allura/templates_responsive/jinja_master/master.html | 3 ++-
 2 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/Allura/allura/templates/jinja_master/master.html 
b/Allura/allura/templates/jinja_master/master.html
index 19cb43ca1..95ee01e16 100644
--- a/Allura/allura/templates/jinja_master/master.html
+++ b/Allura/allura/templates/jinja_master/master.html
@@ -72,7 +72,6 @@
 {% endblock %}
 {% block head_bottom -%}
 {% endblock %}
-{{ g.analytics.display() }}
 
 
 
@@ -197,5 +196,6 @@
 });
 });
 
+{{ g.analytics.display() }}
 
 
diff --git a/Allura/allura/templates_responsive/jinja_master/master.html 
b/Allura/allura/templates_responsive/jinja_master/master.html
index 5d28d00dc..76c470f92 100644
--- a/Allura/allura/templates_responsive/jinja_master/master.html
+++ b/Allura/allura/templates_responsive/jinja_master/master.html
@@ -72,7 +72,6 @@
 
 {% block head %}
 {% endblock %}
-{{ g.analytics.display() }}
 {% block head_bottom -%}
 {% endblock %}
 
@@ -163,5 +162,7 @@
 {% if flash %}
 {{ flash | safe }}{# comes from 
flash.static_template in root.py and escaped by tg.flash allow_html setting #}
 {% endif %}
+{{ g.analytics.display() }}
+
 
 



(allura) branch master updated (b3827038c -> 9871bd9b3)

2024-03-08 Thread brondsem
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/allura.git


from b3827038c bump cryptography 42.0.4 -> 42.0.5
 new 4bed76984 [#8537] moved g analytics further down the page
 new e832a13f7 [#8537] allow 'this' in JS functions, a common jquery 
pattern we use
 new 9871bd9b3 [#8537] do not run scanMessages forever

The 3 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .eslintrc-es5  |  2 +-
 Allura/allura/public/nf/js/jquery.notify.js| 56 +++---
 Allura/allura/templates/jinja_master/master.html   |  2 +-
 .../templates_responsive/jinja_master/master.html  |  3 +-
 4 files changed, 22 insertions(+), 41 deletions(-)



(allura) 02/03: [#8537] allow 'this' in JS functions, a common jquery pattern we use

2024-03-08 Thread brondsem
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/allura.git

commit e832a13f72eb67e6d4e06f5163b88b3d269d339a
Author: Guillermo Cruz 
AuthorDate: Mon Mar 4 10:27:19 2024 -0700

[#8537] allow 'this' in JS functions, a common jquery pattern we use
---
 .eslintrc-es5 | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/.eslintrc-es5 b/.eslintrc-es5
index 493b774e1..880f708b3 100644
--- a/.eslintrc-es5
+++ b/.eslintrc-es5
@@ -18,7 +18,7 @@
 // disallow use of eval()-like methods
 "no-implied-eval": 2,
 // disallow this keywords outside of classes or class-like objects
-"no-invalid-this": 2,
+"no-invalid-this": 0,
 // disallow creation of functions within loops
 "no-loop-func": 2,
 // disallow declaring the same variable more then once



(allura) branch master updated: [#8446] update inline username mentions (missed in original work on this ticket)

2024-02-21 Thread brondsem
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/allura.git


The following commit(s) were added to refs/heads/master by this push:
 new 094aba957 [#8446] update inline username mentions (missed in original 
work on this ticket)
094aba957 is described below

commit 094aba95792d56349d3ab54f2fdb24b5ca0ebf7e
Author: Dave Brondsema 
AuthorDate: Wed Feb 21 16:56:57 2024 -0500

[#8446] update inline username mentions (missed in original work on this 
ticket)
---
 Allura/allura/lib/markdown_extensions.py | 2 +-
 Allura/allura/tests/test_globals.py  | 4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/Allura/allura/lib/markdown_extensions.py 
b/Allura/allura/lib/markdown_extensions.py
index 576f5e737..9bcc7f892 100644
--- a/Allura/allura/lib/markdown_extensions.py
+++ b/Allura/allura/lib/markdown_extensions.py
@@ -343,7 +343,7 @@ class 
UserMentionInlinePattern(markdown.inlinepatterns.Pattern):
 if user and not user.pending and not user.disabled:
 result = etree.Element('a')
 result.text = "@%s" % user_name
-result.set('href', user.url())
+result.set('href', h.username_project_url(user))
 result.set('class', 'user-mention')
 else:
 result = "@%s" % user_name
diff --git a/Allura/allura/tests/test_globals.py 
b/Allura/allura/tests/test_globals.py
index 627c633e6..472c1f3a1 100644
--- a/Allura/allura/tests/test_globals.py
+++ b/Allura/allura/tests/test_globals.py
@@ -919,13 +919,13 @@ class TestUserMentions(unittest.TestCase):
 ThreadLocalODMSession.flush_all()
 output = g.markdown.convert('Hello.. @admin1, how are you?')
 assert 'class="user-mention"' in output
-assert ('href="%s"' % u1.url()) in output
+assert 'href="/u/admin1/profile/"' in output
 u2 = M.User.register(dict(username='admin-2'), make_project=True)
 ThreadLocalODMSession.flush_all()
 output = g.markdown.convert('Do you know @ab? @admin-2 has solved it!')
 assert 'Do you know @ab?' in output
 assert 'class="user-mention"' in output
-assert ('href="%s"' % u2.url()) in output
+assert 'href="/u/admin-2/profile/"' in output
 output = g.markdown.convert('t...@admin1.com Hey!')
 assert 't...@admin1.com Hey!' in output
 



(allura) branch master updated: use $regex instead of re.compile in mongo queries, so it uses indexes properly. Maybe fixed in current mongo versions https://jira.mongodb.org/browse/SERVER-26991

2024-02-21 Thread brondsem
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/allura.git


The following commit(s) were added to refs/heads/master by this push:
 new 430baa37a use $regex instead of re.compile in mongo queries, so it 
uses indexes properly.  Maybe fixed in current mongo versions 
https://jira.mongodb.org/browse/SERVER-26991
430baa37a is described below

commit 430baa37a5ea8cd263bb9b3cee331e636e61438a
Author: Dave Brondsema 
AuthorDate: Wed Feb 21 12:06:19 2024 -0500

use $regex instead of re.compile in mongo queries, so it uses indexes 
properly.  Maybe fixed in current mongo versions 
https://jira.mongodb.org/browse/SERVER-26991
---
 Allura/allura/controllers/project.py   | 2 +-
 Allura/allura/controllers/site_admin.py| 4 ++--
 Allura/allura/controllers/trovecategories.py   | 6 +++---
 Allura/allura/ext/admin/admin_main.py  | 4 ++--
 Allura/allura/lib/plugin.py| 4 ++--
 Allura/allura/model/project.py | 2 +-
 ForgeDiscussion/forgediscussion/controllers/forum.py   | 2 +-
 ForgeUserStats/forgeuserstats/controllers/userstats.py | 2 +-
 8 files changed, 13 insertions(+), 13 deletions(-)

diff --git a/Allura/allura/controllers/project.py 
b/Allura/allura/controllers/project.py
index 8ddb21da8..f4d8c9865 100644
--- a/Allura/allura/controllers/project.py
+++ b/Allura/allura/controllers/project.py
@@ -687,7 +687,7 @@ class NeighborhoodAdminController:
 if icon is not None and icon != b'':
 if self.neighborhood.icon:
 self.neighborhood.icon.delete()
-M.ProjectFile.query.remove(dict(project_id=c.project._id, 
category=re.compile(r'^icon')))
+M.ProjectFile.query.remove(dict(project_id=c.project._id, 
category={'$regex': r'^icon'}))
 save_icon = c.project.save_icon(icon.filename, icon.file, 
content_type=icon.type)
 if save_icon:
 M.AuditLog.log('update neighborhood icon')
diff --git a/Allura/allura/controllers/site_admin.py 
b/Allura/allura/controllers/site_admin.py
index 5b41bc94a..07009028b 100644
--- a/Allura/allura/controllers/site_admin.py
+++ b/Allura/allura/controllers/site_admin.py
@@ -542,9 +542,9 @@ class TaskManagerController:
 if state:
 query['state'] = state
 if task_name:
-query['task_name'] = re.compile(re.escape(task_name))
+query['task_name'] = {'$regex': re.escape(task_name)}
 if host:
-query['process'] = re.compile(re.escape(host))
+query['process'] = {'$regex': re.escape(host)}
 
 tasks = list(M.monq_model.MonQTask.query.find(query).sort('_id', -1))
 for task in tasks:
diff --git a/Allura/allura/controllers/trovecategories.py 
b/Allura/allura/controllers/trovecategories.py
index 1c0c14a89..d94d60e42 100644
--- a/Allura/allura/controllers/trovecategories.py
+++ b/Allura/allura/controllers/trovecategories.py
@@ -131,11 +131,11 @@ class TroveCategoryController(BaseController):
 
 if upper:
 trove_type = upper.fullpath.split(' :: ')[0]
-fullpath_re = re.compile(fr'^{re.escape(trove_type)} :: ')  # e.g. 
scope within "Topic :: "
+fullpath_re = fr'^{re.escape(trove_type)} :: '  # e.g. scope 
within "Topic :: "
 else:
 # no parent, so making a top-level.  Don't limit fullpath_re, so 
enforcing global uniqueness
-fullpath_re = re.compile(r'')
-oldcat = M.TroveCategory.query.get(shortname=shortname, 
fullpath=fullpath_re)
+fullpath_re = r''
+oldcat = M.TroveCategory.query.get(shortname=shortname, 
fullpath={'$regex': fullpath_re})
 
 if oldcat:
 raise TroveAdminException(
diff --git a/Allura/allura/ext/admin/admin_main.py 
b/Allura/allura/ext/admin/admin_main.py
index fc2f2ac53..6e8232fc6 100644
--- a/Allura/allura/ext/admin/admin_main.py
+++ b/Allura/allura/ext/admin/admin_main.py
@@ -336,7 +336,7 @@ class ProjectAdminController(BaseController):
 c.project.removal = removal
 c.project.removal_changed_date = datetime.utcnow()
 if 'delete_icon' in kw:
-M.ProjectFile.query.remove(dict(project_id=c.project._id, 
category=re.compile(r'^icon')))
+M.ProjectFile.query.remove(dict(project_id=c.project._id, 
category={'$regex': r'^icon'}))
 c.project.set_tool_data('allura', icon_original_size=None, 
icon_sha256=None)
 M.AuditLog.log('remove project icon')
 g.post_event('project_updated')
@@ -415,7 +415,7 @@ class ProjectAdminController(BaseController):
 
 if icon is not None and icon != b'':
 if c.project.icon:
-M.ProjectFile.query.remove(dict(project_id=c.project._id, 
category=re.compile(r'^icon')))
+M.ProjectFi

(allura) 03/08: [#8536] move/improve |safe usage

2024-02-15 Thread brondsem
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a commit to branch db/8536
in repository https://gitbox.apache.org/repos/asf/allura.git

commit 2869dfdf58eefdf3c564e56953bc7cacd6192e89
Author: Dave Brondsema 
AuthorDate: Fri Feb 9 16:12:37 2024 -0500

[#8536] move/improve |safe usage
---
 Allura/allura/app.py  | 7 ---
 Allura/allura/ext/admin/templates/project_groups.html | 2 +-
 Allura/allura/lib/diff.py | 3 ++-
 Allura/allura/templates/jinja_master/sidebar_menu.html| 2 +-
 Allura/allura/templates/repo/barediff.html| 2 +-
 Allura/allura/templates/repo/diff.html| 2 +-
 Allura/allura/templates_responsive/jinja_master/sidebar_menu.html | 2 +-
 ForgeTracker/forgetracker/tracker_main.py | 6 --
 ForgeWiki/forgewiki/wiki_main.py  | 5 +++--
 9 files changed, 18 insertions(+), 13 deletions(-)

diff --git a/Allura/allura/app.py b/Allura/allura/app.py
index 1beddf562..23f18d1b3 100644
--- a/Allura/allura/app.py
+++ b/Allura/allura/app.py
@@ -24,6 +24,7 @@ from xml.etree import ElementTree as ET
 from copy import copy
 
 import pkg_resources
+from markupsafe import Markup
 from tg import expose, redirect, flash, validate
 from tg.decorators import without_trailing_slash
 from tg import config as tg_config
@@ -619,13 +620,13 @@ class Application(ActivityObject):
 """
 return []
 
-def sidebar_menu_js(self):
+def sidebar_menu_js(self) -> Markup:
 """Return Javascript needed by the sidebar menu of this Application.
 
-:return: a string of Javascript code
+:return: Markup string of Javascript code
 
 """
-return ""
+return Markup("")
 
 @LazyProperty
 def _webhooks(self):
diff --git a/Allura/allura/ext/admin/templates/project_groups.html 
b/Allura/allura/ext/admin/templates/project_groups.html
index bb5571010..ed941dd9d 100644
--- a/Allura/allura/ext/admin/templates/project_groups.html
+++ b/Allura/allura/ext/admin/templates/project_groups.html
@@ -76,7 +76,7 @@
   {% for r in role.users_with_role() %}
   
 {{ g.icons['perm_delete'].render(
-title=('%s (%s)' % (r.user.display_name | escape, 
r.user.username | escape)) | safe,
+title=('%s (%s)'|safe) % (r.user.display_name, 
r.user.username),
 show_title=True,
 extra_css='deleter',
 **{'data-user': r.user.username}) }}
diff --git a/Allura/allura/lib/diff.py b/Allura/allura/lib/diff.py
index 000ecce01..ee9087253 100644
--- a/Allura/allura/lib/diff.py
+++ b/Allura/allura/lib/diff.py
@@ -24,6 +24,7 @@ from collections.abc import Iterable, Generator
 import sxsdiff
 from diff_match_patch import diff_match_patch
 import six
+from markupsafe import Markup
 from sxsdiff.calculator import LineChange, ElementsHolder, PlainElement, 
AdditionElement, DeletionElement
 
 log = logging.getLogger(__name__)
@@ -67,7 +68,7 @@ class SxsOutputGenerator(sxsdiff.BaseGenerator):
 def run(self, diff_result: Iterable[LineChange | None]):
 self.out = ''
 super().run(diff_result)
-return self.out
+return Markup(self.out)  # "safe" because we use html.escape in a few 
key places below
 
 def visit_row(self, line_change: LineChange | None):
 if line_change is None:
diff --git a/Allura/allura/templates/jinja_master/sidebar_menu.html 
b/Allura/allura/templates/jinja_master/sidebar_menu.html
index 6097e7132..d9db22f24 100644
--- a/Allura/allura/templates/jinja_master/sidebar_menu.html
+++ b/Allura/allura/templates/jinja_master/sidebar_menu.html
@@ -95,7 +95,7 @@
 {% endif %}
 {% if c.app and c.app.sidebar_menu_js() %}
   
-{{c.app.sidebar_menu_js()|safe}}
+{{c.app.sidebar_menu_js()}}
   
 {% endif %}
 
diff --git a/Allura/allura/templates/repo/barediff.html 
b/Allura/allura/templates/repo/barediff.html
index babccfa61..84085149f 100644
--- a/Allura/allura/templates/repo/barediff.html
+++ b/Allura/allura/templates/repo/barediff.html
@@ -25,7 +25,7 @@
title="{{h.text.truncate(b.commit._id, 10)}}"/>
 {% else %}
   {% if session.diformat == 'sidebyside' %}
-{{diff|safe}}
+{{diff}}
   {% else %}
 {{g.highlight(diff, lexer='diff')}}
   {% endif%}
diff --git a/Allura/allura/templates/repo/diff.html 
b/Allura/allura/templates/repo/diff.html
index df74c6c66..fdbec5663 100644
--- a/Allura/allura/templates/repo/diff.html
+++ b/Allura/allura/templates/repo/diff.html
@@ -63,7 +63,7 @@
 Switch to {{ switch_text }} 
view
   
 {% if session.diformat == 'sidebyside' %}
-  {{diff|safe}}
+  {{diff}}
 {% else %}
   {{g.highlight(diff, le

(allura) 01/08: [#8536] use Markup's own interpolation

2024-02-15 Thread brondsem
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a commit to branch db/8536
in repository https://gitbox.apache.org/repos/asf/allura.git

commit 8fb39f641df098feef390709997234bc77e0bc57
Author: Dave Brondsema 
AuthorDate: Fri Feb 9 11:23:44 2024 -0500

[#8536] use Markup's own interpolation
---
 Allura/allura/lib/app_globals.py  | 15 +
 Allura/allura/lib/search.py   |  2 +-
 Allura/allura/lib/utils.py| 10 -
 Allura/allura/lib/widgets/forms.py| 27 ++-
 Allura/allura/tasks/mail_tasks.py |  2 +-
 Allura/allura/tests/test_globals.py   |  1 +
 ForgeActivity/forgeactivity/templates/macros.html |  2 +-
 ForgeTracker/forgetracker/model/ticket.py |  2 +-
 ForgeTracker/forgetracker/widgets/ticket_form.py  |  2 +-
 9 files changed, 28 insertions(+), 35 deletions(-)

diff --git a/Allura/allura/lib/app_globals.py b/Allura/allura/lib/app_globals.py
index eadabd9bd..9cc3d86bb 100644
--- a/Allura/allura/lib/app_globals.py
+++ b/Allura/allura/lib/app_globals.py
@@ -99,17 +99,14 @@ class ForgeMarkdown:
 # if text is too big, markdown can take a long time to process it,
 # so we return it as a plain text
 log.info('Text is too big. Skipping markdown processing')
-escaped = html.escape(h.really_unicode(source))
-return Markup('%s' % escaped)
+return Markup('{}').format(h.really_unicode(source))
 try:
 return 
self.make_markdown_instance(**self.forge_ext_kwargs).convert(source)
 except Exception:
 log.info('Invalid markdown: %s  Upwards trace is %s', source,
  ''.join(traceback.format_stack()), exc_info=True)
-escaped = h.really_unicode(source)
-escaped = html.escape(escaped)
 return Markup("""ERROR! The markdown supplied 
could not be parsed correctly.
-Did you forget to surround a code snippet with 
""?%s""" % escaped)
+Did you forget to surround a code snippet with 
""?%s""") % h.really_unicode(source)
 
 @LazyProperty
 def uncacheable_macro_regex(self):
@@ -471,10 +468,8 @@ class Globals:
 lexer = pygments.lexers.get_lexer_by_name(lexer, 
encoding='chardet')
 
 if lexer is None or len(text) >= 
asint(config.get('scm.view.max_syntax_highlight_bytes', 50)):
-# no highlighting, but we should escape, encode, and wrap it in
-# a 
-text = html.escape(text)
-return Markup('' + text + '')
+# no highlighting, but we should wrap it in a  safely
+return Markup('{}').format(text)
 else:
 return Markup(pygments.highlight(text, lexer, formatter))
 
@@ -686,7 +681,7 @@ class Icon:
 if tag == 'a':
 attrs['href'] = '#'
 attrs.update(kw)
-attrs = ew._Jinja2Widget().j2_attrs(attrs)
+attrs = ew._Jinja2Widget().j2_attrs(attrs)  # this escapes them
 visible_title = ''
 if show_title:
 visible_title = f'{Markup.escape(title)}'
diff --git a/Allura/allura/lib/search.py b/Allura/allura/lib/search.py
index 27a29f738..388384798 100644
--- a/Allura/allura/lib/search.py
+++ b/Allura/allura/lib/search.py
@@ -409,4 +409,4 @@ def mapped_artifacts_from_index_ids(index_ids, model, 
objectid_id=True):
 map = {}
 for m in models:
 map[str(m._id)] = m
-return map
\ No newline at end of file
+return map
diff --git a/Allura/allura/lib/utils.py b/Allura/allura/lib/utils.py
index 683a7fcae..0cf6b8c3c 100644
--- a/Allura/allura/lib/utils.py
+++ b/Allura/allura/lib/utils.py
@@ -211,10 +211,10 @@ def chunked_iter(iterable, max_size):
 class AntiSpam:
 
 '''Helper class for bot-protecting forms'''
-honey_field_template = string.Template('''
-You seem to have CSS turned off.
+honey_field_template = '''
+You seem to have CSS turned off.
 Please don't fill out this field.
-''')
+'''
 
 def __init__(self, request=None, num_honey=2, timestamp=None, 
spinner=None):
 self.num_honey = num_honey
@@ -307,10 +307,10 @@ class AntiSpam:
 for fldno in range(self.num_honey):
 fld_name = self.enc('honey%d' % (fldno))
 fld_id = self.enc('honey%d%d' % (self.counter, fldno))
-yield Markup(self.honey_field_template.substitute(
+yield Markup(self.honey_field_template).format(
 honey_class=self.honey_class,
 fld_id=fld_id,
-fld_name=fld_name))
+fld_name=fld_name)
 self.counter += 1
 
 def make_spinner(self, timestamp=None):
diff --git a/Allura/allura/lib/widgets/forms.py 
b/Allura/allura/lib/widgets/forms.py
index 5252819e1..134cd6f40 100

(allura) 08/08: [#8536] use h.clean_html and |safe_html

2024-02-15 Thread brondsem
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a commit to branch db/8536
in repository https://gitbox.apache.org/repos/asf/allura.git

commit 38e48ad3ca147af48f7a409bb664d6278a8b40fe
Author: Dave Brondsema 
AuthorDate: Mon Feb 12 12:20:06 2024 -0500

[#8536] use h.clean_html and |safe_html
---
 Allura/allura/config/app_cfg.py | 1 +
 Allura/allura/ext/admin/templates/project_trove.html| 2 +-
 Allura/allura/lib/helpers.py| 9 -
 Allura/allura/templates/jinja_master/master.html| 4 ++--
 Allura/allura/templates/neighborhood_project_list.html  | 2 +-
 Allura/allura/templates_responsive/jinja_master/master.html | 4 ++--
 Allura/allura/tests/test_helpers.py | 5 +
 7 files changed, 20 insertions(+), 7 deletions(-)

diff --git a/Allura/allura/config/app_cfg.py b/Allura/allura/config/app_cfg.py
index 33e5148c4..e0a5cfb4c 100644
--- a/Allura/allura/config/app_cfg.py
+++ b/Allura/allura/config/app_cfg.py
@@ -143,6 +143,7 @@ class AlluraJinjaRenderer(JinjaRenderer):
 jinja2_env.filters['filter'] = lambda s, t=None: list(filter(t and 
jinja2_env.tests[t], s))
 jinja2_env.filters['nl2br'] = helpers.nl2br_jinja_filter
 jinja2_env.filters['subrender'] = helpers.subrender_jinja_filter
+jinja2_env.filters['safe_html'] = helpers.clean_html
 jinja2_env.globals.update({
 'hasattr': hasattr,
 'h': helpers,
diff --git a/Allura/allura/ext/admin/templates/project_trove.html 
b/Allura/allura/ext/admin/templates/project_trove.html
index 0d1a9da78..1fbff6e95 100644
--- a/Allura/allura/ext/admin/templates/project_trove.html
+++ b/Allura/allura/ext/admin/templates/project_trove.html
@@ -27,7 +27,7 @@
   {% set help_text = config.get('trovecategories.admin.help.'+base.shortname, 
'') %}
   {% if help_text %}
 
-  {{ help_text|safe }}
+  {{ help_text|safe_html }}
   
 
   {% endif %}
diff --git a/Allura/allura/lib/helpers.py b/Allura/allura/lib/helpers.py
index 26dd2d94f..f0675e443 100644
--- a/Allura/allura/lib/helpers.py
+++ b/Allura/allura/lib/helpers.py
@@ -809,7 +809,7 @@ def subrender_jinja_filter(context, html_tmpl: str) -> 
Markup:
 log.exception(f'Could not replace {var} in jinja "subrender" for 
site notification')
 continue
 html_tmpl = html_tmpl.replace(var, val)
-return Markup(html_tmpl)
+return clean_html(html_tmpl)
 
 
 def nl2br_jinja_filter(value):
@@ -1378,3 +1378,10 @@ def pluralize_tool_name(tool_name: string, count: int):
 def parse_fediverse_address(username: str):
 pieces = username.split('@')
 return f'https://{pieces[-1]}/@{pieces[1]}'
+
+
+def clean_html(value: str) -> Markup:
+from allura.lib.markdown_extensions import HTMLSanitizer
+return Markup(
+HTMLSanitizer().run(value)
+)
diff --git a/Allura/allura/templates/jinja_master/master.html 
b/Allura/allura/templates/jinja_master/master.html
index 6d0d829c1..19cb43ca1 100644
--- a/Allura/allura/templates/jinja_master/master.html
+++ b/Allura/allura/templates/jinja_master/master.html
@@ -56,11 +56,11 @@
 
 {% if c.project and c.project.neighborhood.css %}
 
-{{c.project.neighborhood.get_custom_css()|safe}}
+{{ c.project.neighborhood.get_custom_css()|safe_html }}
 
 {% elif neighborhood|default and neighborhood.css %}
 
-{{neighborhood.get_custom_css()}}
+{{ neighborhood.get_custom_css()|safe_html }}
 
 {% endif %}
 {% block extra_css %}{% endblock %}
diff --git a/Allura/allura/templates/neighborhood_project_list.html 
b/Allura/allura/templates/neighborhood_project_list.html
index 91fecd345..53e33b3e1 100644
--- a/Allura/allura/templates/neighborhood_project_list.html
+++ b/Allura/allura/templates/neighborhood_project_list.html
@@ -45,7 +45,7 @@
   {{ text }}
 {% endif %}
 {% if neighborhood.homepage %}
-  {{neighborhood.homepage|safe}}
+  {{neighborhood.homepage|safe_html}}
 {% endif %}
 {% if neighborhood.allow_browse %}
   {% if not projects %}
diff --git a/Allura/allura/templates_responsive/jinja_master/master.html 
b/Allura/allura/templates_responsive/jinja_master/master.html
index 3786e2b88..5d28d00dc 100644
--- a/Allura/allura/templates_responsive/jinja_master/master.html
+++ b/Allura/allura/templates_responsive/jinja_master/master.html
@@ -58,11 +58,11 @@
 
 {% if c.project and c.project.neighborhood.css %}
 
-{{c.project.neighborhood.get_custom_css()|safe}}
+{{ c.project.neighborhood.get_custom_css()|safe_html }}
 
 {% elif neighborhood|default and neighborhood.css %}
 
-{{neighborhood.get_custom_css()}}
+{{ neighborhood.get_custom_css()|safe_html }}
 
 {% endif %}
 {% block extra_css %}{% endblock %}
diff --git

(allura) 06/08: [#8536] more move/improve |safe

2024-02-15 Thread brondsem
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a commit to branch db/8536
in repository https://gitbox.apache.org/repos/asf/allura.git

commit ccd6e86694438b05239256ba3b815ca144fafdca
Author: Dave Brondsema 
AuthorDate: Mon Feb 12 18:16:21 2024 -0500

[#8536] more move/improve |safe
---
 Allura/allura/lib/widgets/search.py   | 5 +++--
 Allura/allura/templates/user_prefs.html   | 2 +-
 Allura/allura/templates/widgets/lightbox.html | 2 +-
 3 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/Allura/allura/lib/widgets/search.py 
b/Allura/allura/lib/widgets/search.py
index 2bef28700..cec39ad44 100644
--- a/Allura/allura/lib/widgets/search.py
+++ b/Allura/allura/lib/widgets/search.py
@@ -18,6 +18,7 @@
 import ew as ew_core
 import ew.jinja2_ew as ew
 import jinja2
+from markupsafe import Markup
 
 from allura.lib.widgets import form_fields as ffw
 
@@ -53,8 +54,8 @@ class SearchHelp(ffw.Lightbox):
 # can't use g.jinja2_env since this widget gets imported too early :(
 jinja2_env = jinja2.Environment(
 loader=jinja2.PackageLoader('allura', 'templates/widgets'))
-self.content = jinja2_env.get_template('search_help.html').render(dict(
+self.content = 
Markup(jinja2_env.get_template('search_help.html').render(dict(
 comments=comments,
 history=history,
 fields=fields,
-))
+)))
diff --git a/Allura/allura/templates/user_prefs.html 
b/Allura/allura/templates/user_prefs.html
index 6610ad19f..62d95352d 100644
--- a/Allura/allura/templates/user_prefs.html
+++ b/Allura/allura/templates/user_prefs.html
@@ -85,7 +85,7 @@
   
 
   
-  {{c.enter_password.display(content='Enter password')}}
+  {{c.enter_password.display(content='Enter password'|safe)}}
   
 
   {% endif %}  {# allow_edit_prefs #}
diff --git a/Allura/allura/templates/widgets/lightbox.html 
b/Allura/allura/templates/widgets/lightbox.html
index 82972260f..624a49f2d 100644
--- a/Allura/allura/templates/widgets/lightbox.html
+++ b/Allura/allura/templates/widgets/lightbox.html
@@ -21,6 +21,6 @@
   {% if content_template %}
 {% include content_template with context %}
   {% else %}
-{{content|safe}}
+{{content}}
   {% endif %}
 



(allura) 02/08: [#8536] remove old unused oembed templates

2024-02-15 Thread brondsem
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a commit to branch db/8536
in repository https://gitbox.apache.org/repos/asf/allura.git

commit 77ae6f4ac8d9a3f31e6404c9d3a764f32da8ddda
Author: Dave Brondsema 
AuthorDate: Fri Feb 9 16:10:46 2024 -0500

[#8536] remove old unused oembed templates
---
 Allura/allura/templates/oembed/__init__.py   | 16 -
 Allura/allura/templates/oembed/generic.html  | 23 ---
 Allura/allura/templates/oembed/html_tpl.html | 25 
 Allura/allura/templates/oembed/link.html | 26 -
 Allura/allura/templates/oembed/link_opera.html   | 27 --
 Allura/allura/templates/oembed/link_twitter.html | 29 
 Allura/allura/templates/oembed/photo.html| 25 
 7 files changed, 171 deletions(-)

diff --git a/Allura/allura/templates/oembed/__init__.py 
b/Allura/allura/templates/oembed/__init__.py
deleted file mode 100644
index 144e29886..0
--- a/Allura/allura/templates/oembed/__init__.py
+++ /dev/null
@@ -1,16 +0,0 @@
-#   Licensed to the Apache Software Foundation (ASF) under one
-#   or more contributor license agreements.  See the NOTICE file
-#   distributed with this work for additional information
-#   regarding copyright ownership.  The ASF licenses this file
-#   to you under the Apache License, Version 2.0 (the
-#   "License"); you may not use this file except in compliance
-#   with the License.  You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-#   Unless required by applicable law or agreed to in writing,
-#   software distributed under the License is distributed on an
-#   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-#   KIND, either express or implied.  See the License for the
-#   specific language governing permissions and limitations
-#   under the License.
diff --git a/Allura/allura/templates/oembed/generic.html 
b/Allura/allura/templates/oembed/generic.html
deleted file mode 100644
index 40a9f0fe2..0
--- a/Allura/allura/templates/oembed/generic.html
+++ /dev/null
@@ -1,23 +0,0 @@
-{#-
-   Licensed to the Apache Software Foundation (ASF) under one
-   or more contributor license agreements.  See the NOTICE file
-   distributed with this work for additional information
-   regarding copyright ownership.  The ASF licenses this file
-   to you under the Apache License, Version 2.0 (the
-   "License"); you may not use this file except in compliance
-   with the License.  You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-   Unless required by applicable law or agreed to in writing,
-   software distributed under the License is distributed on an
-   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-   KIND, either express or implied.  See the License for the
-   specific language governing permissions and limitations
-   under the License.
--#}
-
-  
-{{href}} (cannot be embedded)
-  
-
diff --git a/Allura/allura/templates/oembed/html_tpl.html 
b/Allura/allura/templates/oembed/html_tpl.html
deleted file mode 100644
index 0b063a2c0..0
--- a/Allura/allura/templates/oembed/html_tpl.html
+++ /dev/null
@@ -1,25 +0,0 @@
-{#-
-   Licensed to the Apache Software Foundation (ASF) under one
-   or more contributor license agreements.  See the NOTICE file
-   distributed with this work for additional information
-   regarding copyright ownership.  The ASF licenses this file
-   to you under the Apache License, Version 2.0 (the
-   "License"); you may not use this file except in compliance
-   with the License.  You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-   Unless required by applicable law or agreed to in writing,
-   software distributed under the License is distributed on an
-   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-   KIND, either express or implied.  See the License for the
-   specific language governing permissions and limitations
-   under the License.
--#}
-http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd;>
-
-  
-{{data.html|safe}}
-  
-
diff --git a/Allura/allura/templates/oembed/link.html 
b/Allura/allura/templates/oembed/link.html
deleted file mode 100644
index f3517a821..0
--- a/Allura/allura/templates/oembed/link.html
+++ /dev/null
@@ -1,26 +0,0 @@
-{#-
-   Licensed to the Apache Software Foundation (ASF) under one
-   or more contributor license agreements.  See the NOTICE file
-   distributed with this work for additional information
-   regarding copyright ownership.  The ASF licenses this file
-   to you under the Apach

(allura) 04/08: [#8536] remove unnecessary |safe usages

2024-02-15 Thread brondsem
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a commit to branch db/8536
in repository https://gitbox.apache.org/repos/asf/allura.git

commit 8f1efe7987fb0d889336c2e4080d8f488376e5a3
Author: Dave Brondsema 
AuthorDate: Fri Feb 9 16:13:42 2024 -0500

[#8536] remove unnecessary |safe usages
---
 Allura/allura/controllers/search.py  |  2 +-
 Allura/allura/lib/app_globals.py |  4 ++--
 Allura/allura/templates/oauth_applications.html  |  4 ++--
 Allura/allura/templates/oauth_authorize.html |  2 +-
 Allura/allura/templates/project_list.html|  4 
 Allura/allura/templates/repo/merge_request.html  |  2 +-
 Allura/allura/templates/widgets/include.html |  2 +-
 Allura/allura/templates/widgets/post_widget.html |  4 ++--
 .../templates/blog_widgets/preview_post.html |  2 +-
 .../forgeblog/templates/blog_widgets/view_post.html  |  2 +-
 ForgeChat/forgechat/templates/chat/day.html  |  2 +-
 .../templates/discussion_widgets/forum_header.html   |  2 +-
 .../templates/discussionforums/admin_forums.html |  2 +-
 .../forgetracker/templates/tracker/ticket.html   |  2 +-
 .../templates/tracker_widgets/ticket_form.html   | 20 ++--
 ForgeWiki/forgewiki/templates/wiki/browse.html   |  2 +-
 16 files changed, 27 insertions(+), 31 deletions(-)

diff --git a/Allura/allura/controllers/search.py 
b/Allura/allura/controllers/search.py
index f0db69f73..31c5f1e48 100644
--- a/Allura/allura/controllers/search.py
+++ b/Allura/allura/controllers/search.py
@@ -130,4 +130,4 @@ class ProjectBrowseController(BaseController):
 projects, count = self._find_projects()
 title = self._build_title()
 c.custom_sidebar_menu = self._build_nav()
-return dict(projects=projects, title=title, text=None)
+return dict(projects=projects, title=title)
diff --git a/Allura/allura/lib/app_globals.py b/Allura/allura/lib/app_globals.py
index 9cc3d86bb..0bdf8be08 100644
--- a/Allura/allura/lib/app_globals.py
+++ b/Allura/allura/lib/app_globals.py
@@ -94,7 +94,7 @@ class ForgeMarkdown:
 'markdown_checklist.extension'],
 output_format='html')
 
-def convert(self, source, render_limit=True):
+def convert(self, source, render_limit=True) -> Markup:
 if render_limit and len(source) > 
asint(config.get('markdown_render_max_length', 8)):
 # if text is too big, markdown can take a long time to process it,
 # so we return it as a plain text
@@ -113,7 +113,7 @@ class ForgeMarkdown:
 regex_names = '|'.join(uncacheable_macros_names())
 return re.compile(rf"\[\[\s*({regex_names})\b")
 
-def cached_convert(self, artifact: MappedClass, field_name: str) -> str:
+def cached_convert(self, artifact: MappedClass, field_name: str) -> Markup:
 """
 Convert ``artifact.field_name`` markdown source to html, caching
 the result if the render time is greater than the defined threshold.
diff --git a/Allura/allura/templates/oauth_applications.html 
b/Allura/allura/templates/oauth_applications.html
index 9114f3d3e..c788e7722 100644
--- a/Allura/allura/templates/oauth_applications.html
+++ b/Allura/allura/templates/oauth_applications.html
@@ -83,7 +83,7 @@
 Name:{{access_token.consumer_token.name}}
 
 
-
Description:{{access_token.consumer_token.description_html | 
safe}}
+
Description:{{access_token.consumer_token.description_html }}
 
 {% if access_token.is_bearer %}
 
@@ -117,7 +117,7 @@
 {% for consumer_token in consumer_tokens %}
 
 Name:{{consumer_token.name}}
-Description:{{consumer_token.description_html 
| safe}}
+Description:{{consumer_token.description_html 
}}
 Consumer 
Key:{{consumer_token.api_key}}
 Consumer 
Secret:{{consumer_token.secret_key}}
 
diff --git a/Allura/allura/templates/oauth_authorize.html 
b/Allura/allura/templates/oauth_authorize.html
index cd8f9655e..d3afc8b3d 100644
--- a/Allura/allura/templates/oauth_authorize.html
+++ b/Allura/allura/templates/oauth_authorize.html
@@ -51,7 +51,7 @@
 
 
 App Name: {{consumer.name}}
-Description:  
{{consumer.description_html|safe}}
+Description:  {{consumer.description_html}}
 
 
 
diff --git a/Allura/allura/templates/project_list.html 
b/Allura/allura/templates/project_list.html
index 6232a2411..9d68850ae 100644
--- a/Allura/allura/templates/project_list.html
+++ b/Allura/allura/templates/project_list.html
@@ -51,10 +51,6 @@
 {% block content %}
   {% set old_project = c.project %}
   
-  {% if text %}
-{{text|safe}}
-  {% endif %}
-  
   {% if not projects %}
 No projects found
   {% else %}
diff --git a/Allura/allura/templates/rep

(allura) 07/08: [#8536] don't use jinja for site notifications; add autoescape

2024-02-15 Thread brondsem
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a commit to branch db/8536
in repository https://gitbox.apache.org/repos/asf/allura.git

commit 997a58206dcd37dfe8d46776fbb76fbb0f9a6e4a
Author: Dave Brondsema 
AuthorDate: Thu Feb 15 12:05:00 2024 -0500

[#8536] don't use jinja for site notifications; add autoescape
---
 Allura/allura/lib/helpers.py   | 24 ++
 Allura/allura/lib/widgets/search.py|  1 +
 Allura/allura/public/nf/js/allura-base.js  |  2 +-
 .../templates/jinja_master/theme_macros.html   |  2 +-
 .../jinja_master/theme_macros.html |  2 +-
 Allura/allura/tests/test_helpers.py| 19 +
 6 files changed, 43 insertions(+), 7 deletions(-)

diff --git a/Allura/allura/lib/helpers.py b/Allura/allura/lib/helpers.py
index bc52a5638..26dd2d94f 100644
--- a/Allura/allura/lib/helpers.py
+++ b/Allura/allura/lib/helpers.py
@@ -790,10 +790,26 @@ def render_any_markup(name, txt, code_mode=False, 
linenumbers_style=TABLE):
 
 
 @pass_context
-def subrender_jinja_filter(context, value):
-_template = context.eval_ctx.environment.from_string(value)
-result = _template.render(**context)
-return result
+def subrender_jinja_filter(context, html_tmpl: str) -> Markup:
+# jinja templates can execute potentially dangerous things
+#   _template = context.eval_ctx.environment.from_string(html_tmpl)
+#   return _template.render(**context)
+
+# so instead, support just a few things
+
+limited_vars = {
+'{{ c.project.url() }}': lambda: c.project.url(),
+}
+for var, fn in limited_vars.items():
+if var not in html_tmpl:
+continue
+try:
+val = fn()
+except Exception:
+log.exception(f'Could not replace {var} in jinja "subrender" for 
site notification')
+continue
+html_tmpl = html_tmpl.replace(var, val)
+return Markup(html_tmpl)
 
 
 def nl2br_jinja_filter(value):
diff --git a/Allura/allura/lib/widgets/search.py 
b/Allura/allura/lib/widgets/search.py
index cec39ad44..c772992d1 100644
--- a/Allura/allura/lib/widgets/search.py
+++ b/Allura/allura/lib/widgets/search.py
@@ -53,6 +53,7 @@ class SearchHelp(ffw.Lightbox):
 super().__init__()
 # can't use g.jinja2_env since this widget gets imported too early :(
 jinja2_env = jinja2.Environment(
+autoescape=True,
 loader=jinja2.PackageLoader('allura', 'templates/widgets'))
 self.content = 
Markup(jinja2_env.get_template('search_help.html').render(dict(
 comments=comments,
diff --git a/Allura/allura/public/nf/js/allura-base.js 
b/Allura/allura/public/nf/js/allura-base.js
index 779f4ebca..839408dee 100644
--- a/Allura/allura/public/nf/js/allura-base.js
+++ b/Allura/allura/public/nf/js/allura-base.js
@@ -209,7 +209,7 @@ $(function(){
 });
 
 $('#site-notification .btn-close').click(function(e) {
-var $note = $(this).parent();
+var $note = $(this).parents('section:first');
 $note.hide();
 var note_id = $note.attr('data-notification-id');
 var cookie = $.cookie('site-notification');
diff --git a/Allura/allura/templates/jinja_master/theme_macros.html 
b/Allura/allura/templates/jinja_master/theme_macros.html
index e06f5d7a2..c9ee789b3 100644
--- a/Allura/allura/templates/jinja_master/theme_macros.html
+++ b/Allura/allura/templates/jinja_master/theme_macros.html
@@ -178,7 +178,7 @@ 
http://stackoverflow.com/questions/26582731/redefining-imported-jinja-macros
 {% if note %}
 
 
-{{ note.content|subrender|safe }}
+{{ note.content|subrender }}
 Close
 
 
diff --git a/Allura/allura/templates_responsive/jinja_master/theme_macros.html 
b/Allura/allura/templates_responsive/jinja_master/theme_macros.html
index 5c639115d..dd0e70ed1 100644
--- a/Allura/allura/templates_responsive/jinja_master/theme_macros.html
+++ b/Allura/allura/templates_responsive/jinja_master/theme_macros.html
@@ -195,7 +195,7 @@ 
http://stackoverflow.com/questions/26582731/redefining-imported-jinja-macros
 {% if note %}
 
 
-{{note.content|safe}}
+{{ note.content|subrender }}
 
   {#  .btn-close instead of data-close, since allura-base.js 
handles closing it, not Foundation #}
   
diff --git a/Allura/allura/tests/test_helpers.py 
b/Allura/allura/tests/test_helpers.py
index 9a12062bd..bb7908c9b 100644
--- a/Allura/allura/tests/test_helpers.py
+++ b/Allura/allura/tests/test_helpers.py
@@ -24,6 +24,8 @@ import time
 import PIL
 from mock import Mock, patch
 from tg import tmpl_context as c
+from tg import config
+
 from alluratest.tools import module_not_available
 from webob import Request
 from webob.exc import HTTPUnauthorized
@@ -

(allura) 05/08: [#8536] improve safety

2024-02-15 Thread brondsem
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a commit to branch db/8536
in repository https://gitbox.apache.org/repos/asf/allura.git

commit dd6f57588365a2a6282efa863647c8620ea5c8e8
Author: Dave Brondsema 
AuthorDate: Fri Feb 9 16:17:26 2024 -0500

[#8536] improve safety
---
 Allura/allura/ext/personal_dashboard/templates/sections/projects.html | 4 ++--
 Allura/allura/ext/user_profile/templates/sections/projects.html   | 2 +-
 Allura/allura/lib/widgets/forms.py| 3 ++-
 Allura/allura/templates/jinja_master/master.html  | 2 +-
 Allura/allura/templates_responsive/jinja_master/master.html   | 2 +-
 5 files changed, 7 insertions(+), 6 deletions(-)

diff --git 
a/Allura/allura/ext/personal_dashboard/templates/sections/projects.html 
b/Allura/allura/ext/personal_dashboard/templates/sections/projects.html
index ccbd270a3..b65f7971d 100644
--- a/Allura/allura/ext/personal_dashboard/templates/sections/projects.html
+++ b/Allura/allura/ext/personal_dashboard/templates/sections/projects.html
@@ -43,7 +43,7 @@
 {%- endif -%}
 
 {{ project.name }}
-{{ project.summary or ''|safe }}
+{{ project.summary or (''|safe) }}
 
 
 Last Updated:
@@ -71,4 +71,4 @@
 $(this).hide().closest('.section-body').find('li.hidden').show();
 });
 
-{% endblock %}
\ No newline at end of file
+{% endblock %}
diff --git a/Allura/allura/ext/user_profile/templates/sections/projects.html 
b/Allura/allura/ext/user_profile/templates/sections/projects.html
index e774111d6..3b306ec8d 100644
--- a/Allura/allura/ext/user_profile/templates/sections/projects.html
+++ b/Allura/allura/ext/user_profile/templates/sections/projects.html
@@ -43,7 +43,7 @@
 {%- endif -%}
 
 {{project.name}}
-{{project.summary or ''|safe}}
+{{project.summary or (''|safe)}}
 
 
 Last Updated:
diff --git a/Allura/allura/lib/widgets/forms.py 
b/Allura/allura/lib/widgets/forms.py
index 134cd6f40..65121ed5c 100644
--- a/Allura/allura/lib/widgets/forms.py
+++ b/Allura/allura/lib/widgets/forms.py
@@ -18,6 +18,7 @@
 import logging
 from html import escape as html_escape
 
+import html
 from tg import app_globals as g, tmpl_context as c
 from formencode import validators as fev
 import formencode
@@ -616,7 +617,7 @@ class RemoveTroveCategoryForm(ForgeForm):
 text=cat.fullname,
 href="/categories/%s" % cat.trove_cat_id),
 ew.HTMLField(
-text=cat.shortname,
+text=html.escape(cat.shortname),
 attrs={'disabled': True, 'value': cat.shortname}),
 ew.SubmitButton(
 show_errors=False,
diff --git a/Allura/allura/templates/jinja_master/master.html 
b/Allura/allura/templates/jinja_master/master.html
index 72c03bc2d..6d0d829c1 100644
--- a/Allura/allura/templates/jinja_master/master.html
+++ b/Allura/allura/templates/jinja_master/master.html
@@ -173,7 +173,7 @@
 {{ theme_macros.custom_js() }}
 
 {% if flash %}
-{{ flash | safe }}
+{{ flash | safe }}{# comes from 
flash.static_template in root.py and escaped by tg.flash allow_html setting #}
 {% endif %}
 
 $(document).ready(function () {
diff --git a/Allura/allura/templates_responsive/jinja_master/master.html 
b/Allura/allura/templates_responsive/jinja_master/master.html
index be687919c..3786e2b88 100644
--- a/Allura/allura/templates_responsive/jinja_master/master.html
+++ b/Allura/allura/templates_responsive/jinja_master/master.html
@@ -161,7 +161,7 @@
 {% endif %}
 {{ theme_macros.custom_js() }}
 {% if flash %}
-<script type="text/javascript">{{ flash | safe }}
+{{ flash | safe }}{# comes from 
flash.static_template in root.py and escaped by tg.flash allow_html setting #}
 {% endif %}
 
 



(allura) branch db/8536 created (now 38e48ad3c)

2024-02-15 Thread brondsem
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a change to branch db/8536
in repository https://gitbox.apache.org/repos/asf/allura.git


  at 38e48ad3c [#8536] use h.clean_html and |safe_html

This branch includes the following new commits:

 new 8fb39f641 [#8536] use Markup's own interpolation
 new 77ae6f4ac [#8536] remove old unused oembed templates
 new 2869dfdf5 [#8536] move/improve |safe usage
 new 8f1efe798 [#8536] remove unnecessary |safe usages
 new dd6f57588 [#8536] improve safety
 new ccd6e8669 [#8536] more move/improve |safe
 new 997a58206 [#8536] don't use jinja for site notifications; add 
autoescape
 new 38e48ad3c [#8536] use h.clean_html and |safe_html

The 8 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.




(allura) branch master updated: make active notifications easier to see in the list

2024-02-12 Thread brondsem
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/allura.git


The following commit(s) were added to refs/heads/master by this push:
 new 573e81e4b make active notifications easier to see in the list
573e81e4b is described below

commit 573e81e4b3b9af9f6f565afceec3544fa704236b
Author: Dave Brondsema 
AuthorDate: Mon Feb 12 12:24:46 2024 -0500

make active notifications easier to see in the list
---
 Allura/allura/templates/site_admin_site_notifications_list.html | 6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/Allura/allura/templates/site_admin_site_notifications_list.html 
b/Allura/allura/templates/site_admin_site_notifications_list.html
index b289c355c..dce9e6504 100644
--- a/Allura/allura/templates/site_admin_site_notifications_list.html
+++ b/Allura/allura/templates/site_admin_site_notifications_list.html
@@ -41,7 +41,7 @@
   
 
 {% for note in notifications %}
-
+
   {{ note.active }}
   {{ note.impressions}}
   {{ 
note.content|truncate(50) }}
@@ -68,6 +68,10 @@
 td {
 max-width: 200px;
 }
+#site_notifications tr.active {
+font-weight: bold;
+background: lightcyan;
+}
 
 {% endblock %}
 



(allura) branch master updated: test attribute cleanup (was causing TestProjectModel.test_project to fail depending on test distribution/order)

2024-01-22 Thread brondsem
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/allura.git


The following commit(s) were added to refs/heads/master by this push:
 new 9eb2752e3 test attribute cleanup (was causing 
TestProjectModel.test_project to fail depending on test distribution/order)
9eb2752e3 is described below

commit 9eb2752e3125172016741390f19bae3171aaf31f
Author: Dave Brondsema 
AuthorDate: Mon Jan 22 13:20:06 2024 -0500

test attribute cleanup (was causing TestProjectModel.test_project to fail 
depending on test distribution/order)
---
 Allura/allura/tests/unit/test_app.py | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/Allura/allura/tests/unit/test_app.py 
b/Allura/allura/tests/unit/test_app.py
index e7d0fbd79..18b7eafec 100644
--- a/Allura/allura/tests/unit/test_app.py
+++ b/Allura/allura/tests/unit/test_app.py
@@ -19,6 +19,7 @@ from unittest import TestCase
 
 from allura.app import Application
 from allura import model
+from allura.lib import helpers as h
 from allura.tests.unit import WithDatabase
 from allura.tests.unit.patches import fake_app_patch
 from allura.tests.unit.factories import create_project, create_app_config
@@ -36,8 +37,8 @@ class TestApplication(TestCase):
 mount_point = '1.2+foo_bar'
 self.assertIsNone(app.validate_mount_point(mount_point))
 
-app.relaxed_mount_points = True
-self.assertIsNotNone(app.validate_mount_point(mount_point))
+with h.push_config(app, relaxed_mount_points=True):
+self.assertIsNotNone(app.validate_mount_point(mount_point))
 
 def test_describe_permission(self):
 class DummyApp(Application):



(allura) branch db/unpin created (now 6e1009d8e)

2024-01-22 Thread brondsem
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a change to branch db/unpin
in repository https://gitbox.apache.org/repos/asf/allura.git


  at 6e1009d8e unpin pastedeploy, upgrade it with latest pastescript which 
is now compatible

This branch includes the following new commits:

 new 6e1009d8e unpin pastedeploy, upgrade it with latest pastescript which 
is now compatible

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.




(allura) 01/01: unpin pastedeploy, upgrade it with latest pastescript which is now compatible

2024-01-22 Thread brondsem
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a commit to branch db/unpin
in repository https://gitbox.apache.org/repos/asf/allura.git

commit 6e1009d8e92f0d8cf5a48ae8163eb86fbd289ec0
Author: Dave Brondsema 
AuthorDate: Mon Jan 22 12:23:00 2024 -0500

unpin pastedeploy, upgrade it with latest pastescript which is now 
compatible
---
 requirements.in  | 3 +--
 requirements.txt | 8 +++-
 2 files changed, 4 insertions(+), 7 deletions(-)

diff --git a/requirements.in b/requirements.in
index a6302901b..4870618c7 100644
--- a/requirements.in
+++ b/requirements.in
@@ -6,7 +6,6 @@ colander
 cryptography
 decorator
 EasyWidgets
-# https://github.com/carpedm20/emoji/issues/191
 emoji
 faust-cchardet
 feedgenerator
@@ -22,7 +21,7 @@ Ming
 oauthlib
 paginate
 Paste
-PasteDeploy<3
+PasteDeploy
 PasteScript
 Pillow
 # profanity filter for feedback
diff --git a/requirements.txt b/requirements.txt
index cbe63a9e5..08e802bee 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -17,9 +17,7 @@ beautifulsoup4==4.12.2
 #   -r requirements.in
 #   webtest
 bleach[css]==6.1.0
-# via
-#   bleach
-#   pypeline
+# via pypeline
 certifi==2023.11.17
 # via requests
 cffi==1.16.0
@@ -128,11 +126,11 @@ paste==3.7.1
 #   -r requirements.in
 #   easywidgets
 #   pastescript
-pastedeploy==2.1.1
+pastedeploy==3.1.0
 # via
 #   -r requirements.in
 #   pastescript
-pastescript==3.3.0
+pastescript==3.4.0
 # via -r requirements.in
 pillow==10.2.0
 # via -r requirements.in



(allura) branch master updated: in password reset, also try lowercasing the email to see if that matches

2024-01-22 Thread brondsem
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/allura.git


The following commit(s) were added to refs/heads/master by this push:
 new a50d92165 in password reset, also try lowercasing the email to see if 
that matches
a50d92165 is described below

commit a50d9216587e28416b19cb26624ed6e8164c7c92
Author: Dave Brondsema 
AuthorDate: Mon Jan 22 12:16:51 2024 -0500

in password reset, also try lowercasing the email to see if that matches
---
 Allura/allura/controllers/auth.py   |  5 +
 Allura/allura/tests/functional/test_auth.py | 19 +++
 2 files changed, 24 insertions(+)

diff --git a/Allura/allura/controllers/auth.py 
b/Allura/allura/controllers/auth.py
index 1d11394f5..d74f48445 100644
--- a/Allura/allura/controllers/auth.py
+++ b/Allura/allura/controllers/auth.py
@@ -223,6 +223,11 @@ class AuthController(BaseController):
 redirect('/')
 
 user_record = M.User.by_email_address(email, only_confirmed=False)
+if not user_record and email != email.lower():
+# try again lowercase
+email = email.lower()
+user_record = M.User.by_email_address(email, only_confirmed=False)
+
 allow_non_primary_email_reset = 
asbool(config.get('auth.allow_non_primary_email_password_reset', True))
 
 if not re.match(r"[^@]+@[^@]+\.[^@]+", email):
diff --git a/Allura/allura/tests/functional/test_auth.py 
b/Allura/allura/tests/functional/test_auth.py
index b75eb91a8..10dbd380d 100644
--- a/Allura/allura/tests/functional/test_auth.py
+++ b/Allura/allura/tests/functional/test_auth.py
@@ -1764,6 +1764,25 @@ To update your password on %s, please visit the 
following URL:
 r = r.follow().follow()
 assert 'Log Out' in r, r
 
+
+@patch('allura.tasks.mail_tasks.sendsimplemail')
+@patch('allura.lib.helpers.gen_message_id')
+def test_capitalized_email_entered(self, gen_message_id, sendmail):
+self.app.get('/').follow()  # establish session
+user = M.User.query.get(username='test-admin')
+email = M.EmailAddress.find({'claimed_by_user_id': user._id}).first()
+email.confirmed = True
+ThreadLocalODMSession.flush_all()
+
+# request a reset
+with td.audits('Password recovery link sent to: ' + email.email, 
user=True):
+r = self.app.post('/auth/password_recovery_hash', {'email': 
email.email.capitalize(),  # NOTE THIS
+   '_session_id': 
self.app.cookies['_session_id'],
+   })
+# confirm it worked
+hash = user.get_tool_data('AuthPasswordReset', 'hash')
+assert hash is not None
+
 @patch('allura.tasks.mail_tasks.sendsimplemail')
 @patch('allura.lib.helpers.gen_message_id')
 def test_hash_expired(self, gen_message_id, sendmail):



(allura) branch db/ldap_ctxmgr updated: make ldap_conn() be a context manager, so unbind_s can be run automatically

2024-01-22 Thread brondsem
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a commit to branch db/ldap_ctxmgr
in repository https://gitbox.apache.org/repos/asf/allura.git


The following commit(s) were added to refs/heads/db/ldap_ctxmgr by this push:
 new 3f15d172d make ldap_conn() be a context manager, so unbind_s can be 
run automatically
3f15d172d is described below

commit 3f15d172d9e04341408dd4de986abbe3908327c5
Author: Dave Brondsema 
AuthorDate: Mon Jan 22 12:09:01 2024 -0500

make ldap_conn() be a context manager, so unbind_s can be run automatically
---
 Allura/allura/lib/plugin.py | 62 +
 1 file changed, 34 insertions(+), 28 deletions(-)

diff --git a/Allura/allura/lib/plugin.py b/Allura/allura/lib/plugin.py
index 80c0525a2..47defa5db 100644
--- a/Allura/allura/lib/plugin.py
+++ b/Allura/allura/lib/plugin.py
@@ -25,6 +25,7 @@ import subprocess
 import string
 import crypt
 import random
+from contextlib import contextmanager
 from urllib.request import urlopen
 from urllib.parse import urlparse
 from io import BytesIO
@@ -628,17 +629,27 @@ class LocalAuthenticationProvider(AuthenticationProvider):
 d = self.user_registration_date(user)
 return d
 
-
-def ldap_conn(who=None, cred=None):
+def ldap_conn_staysopen(who=None, cred=None):
 '''
-Init & bind a connection with the given creds, or the admin creds if not
-specified. Remember to unbind the connection when done.
+You must call .unbind_s() when done with this
 '''
 con = ldap.initialize(config['auth.ldap.server'])
 con.simple_bind_s(who or config['auth.ldap.admin_dn'],
   cred or config['auth.ldap.admin_password'])
 return con
 
+@contextmanager
+def ldap_conn(who=None, cred=None):
+'''
+Init & bind a connection with the given creds, or the admin creds if not
+specified.
+'''
+con = ldap_conn_staysopen(who, cred)
+try:
+yield con
+finally:
+con.unbind_s()
+
 
 def ldap_user_dn(username):
 'return a Distinguished Name for a given username'
@@ -667,7 +678,6 @@ class LdapAuthenticationProvider(AuthenticationProvider):
 
 # full registration into LDAP
 uid = str(M.AuthGlobals.get_next_uid()).encode('utf-8')
-con = ldap_conn()
 uname = user_doc['username'].encode('utf-8')
 display_name = user_doc['display_name'].encode('utf-8')
 ldif_u = modlist.addModlist(dict(
@@ -681,12 +691,12 @@ class LdapAuthenticationProvider(AuthenticationProvider):
 loginShell=b'/bin/bash',
 gecos=uname,
 description=b'SCM user account'))
-try:
-con.add_s(ldap_user_dn(user_doc['username']), ldif_u)
-except ldap.ALREADY_EXISTS:
-log.exception('Trying to create existing user %s', uname)
-raise
-con.unbind_s()
+with ldap_conn() as con:
+try:
+con.add_s(ldap_user_dn(user_doc['username']), ldif_u)
+except ldap.ALREADY_EXISTS:
+log.exception('Trying to create existing user %s', uname)
+raise
 
 if asbool(config.get('auth.ldap.use_schroot', True)):
 argv = ('schroot -d / -c {} -u root /ldap-userconfig.py init 
{}'.format(
@@ -742,11 +752,10 @@ class LdapAuthenticationProvider(AuthenticationProvider):
 else:
 ldap_ident = ldap_pass = None
 try:
-con = ldap_conn(ldap_ident, ldap_pass)
 new_password = self._encode_password(new_password)
-con.modify_s(
-dn, [(ldap.MOD_REPLACE, 'userPassword', new_password)])
-con.unbind_s()
+with ldap_conn(ldap_ident, ldap_pass) as con:
+con.modify_s(
+dn, [(ldap.MOD_REPLACE, 'userPassword', new_password)])
 user.last_password_updated = datetime.utcnow()
 session(user).flush(user)
 except ldap.INVALID_CREDENTIALS:
@@ -792,8 +801,8 @@ class LdapAuthenticationProvider(AuthenticationProvider):
 except ValueError:
 return False
 try:
-con = ldap_conn(ldap_user, password)
-con.unbind_s()
+with ldap_conn(ldap_user, password):
+pass
 return True
 except (ldap.INVALID_CREDENTIALS, ldap.UNWILLING_TO_PERFORM, 
ldap.NO_SUCH_OBJECT):
 log.debug(f'LdapAuth: could not authenticate {username}', 
exc_info=True)
@@ -1740,13 +1749,11 @@ class 
LdapUserPreferencesProvider(UserPreferencesProvider):
 return LocalUserPreferencesProvider().get_pref(user, pref_name)
 
 def _get_pref(self, username, pref_name, multi=False):
-con = ldap_conn()
-try:
-rs = con.search_s(ldap_user_dn(username), ldap.SCOPE_BASE)
-except ldap.NO_SUCH_OBJECT:
-rs = []
-else:
-con.unbind_s()
+with l

(allura) branch db/ldap_ctxmgr created (now 83b71b998)

2024-01-19 Thread brondsem
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a change to branch db/ldap_ctxmgr
in repository https://gitbox.apache.org/repos/asf/allura.git


  at 83b71b998 add conftest.py that mocks out tg context

No new revisions were added by this update.



(allura) 01/02: set ruff target version

2024-01-10 Thread brondsem
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/allura.git

commit 45edd0de5436b10afeccf36a7930852662fd4752
Author: Dave Brondsema 
AuthorDate: Wed Jan 10 11:39:21 2024 -0500

set ruff target version
---
 ruff.toml | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/ruff.toml b/ruff.toml
index 2b8e99ba6..e1cf41377 100644
--- a/ruff.toml
+++ b/ruff.toml
@@ -17,6 +17,7 @@
 
 line-length = 119
 show-source = true
+target-version = "py38"
 
 select = [
 # all flake8 & pep8 (except 'ignore' below)
@@ -42,6 +43,7 @@ ignore = [
 'B006', # Do not use mutable data structures for argument defaults
 'B007', # Loop control variable not used within the loop body
 'B904', # use raise from
+'B905', # zip(strict=True) would be good, but need to closely evaluate all 
existing cases first
 ]
 
 [per-file-ignores]



(allura) 02/02: remove some old six.PY3 checks

2024-01-10 Thread brondsem
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/allura.git

commit 6f75550763fec52583db4fb3b4feb054ac64845c
Author: Dave Brondsema 
AuthorDate: Wed Jan 10 11:41:06 2024 -0500

remove some old six.PY3 checks
---
 Allura/allura/config/middleware.py| 2 +-
 Allura/allura/lib/helpers.py  | 2 +-
 Allura/allura/tests/unit/test_repo.py | 3 +--
 3 files changed, 3 insertions(+), 4 deletions(-)

diff --git a/Allura/allura/config/middleware.py 
b/Allura/allura/config/middleware.py
index 75aa2a160..e481a1621 100644
--- a/Allura/allura/config/middleware.py
+++ b/Allura/allura/config/middleware.py
@@ -91,7 +91,7 @@ def make_app(global_conf: dict, **app_conf):
 class BeakerPickleSerializerWithLatin1(PickleSerializer):
 def loads(self, data_string):
 # need latin1 to decode py2 timestamps in py  
https://docs.python.org/3/library/pickle.html#pickle.Unpickler
-return pickle.loads(data_string, **{'encoding': 'latin1'} if six.PY3 
else {})
+return pickle.loads(data_string, encoding='latin1')
 
 
 def _make_core_app(root, global_conf: dict, **app_conf):
diff --git a/Allura/allura/lib/helpers.py b/Allura/allura/lib/helpers.py
index c822d9e00..bc52a5638 100644
--- a/Allura/allura/lib/helpers.py
+++ b/Allura/allura/lib/helpers.py
@@ -239,7 +239,7 @@ def _attempt_encodings(s, encodings):
 for enc in encodings:
 try:
 if enc is None:
-if six.PY3 and isinstance(s, bytes):
+if isinstance(s, bytes):
 # special handling for bytes (avoid b'asdf' turning into 
"b'asfd'")
 return s.decode('utf-8')
 return str(s)  # try default encoding, and handle other types 
like int, etc
diff --git a/Allura/allura/tests/unit/test_repo.py 
b/Allura/allura/tests/unit/test_repo.py
index 5f9756ea7..9aed47208 100644
--- a/Allura/allura/tests/unit/test_repo.py
+++ b/Allura/allura/tests/unit/test_repo.py
@@ -277,8 +277,7 @@ class TestZipDir(unittest.TestCase):
 emsg = str(cm.exception)
 self.assertIn(
 "Command: " +
-("['/bin/zip', '-y', '-q', '-r', '/fake/zip/file.tmp', b'repo'] " 
if six.PY3 else
- "[u'/bin/zip', u'-y', u'-q', u'-r', u'/fake/zip/file.tmp', 
'repo'] ") +
+"['/bin/zip', '-y', '-q', '-r', '/fake/zip/file.tmp', b'repo'] " +
 "returned non-zero exit code 1", emsg)
 self.assertTrue("STDOUT: 1" in emsg)
 self.assertTrue("STDERR: 2" in emsg)



(allura) branch master updated (d40226287 -> 6f7555076)

2024-01-10 Thread brondsem
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/allura.git


from d40226287 [#8533] remove old quoted-printable line length approach
 new 45edd0de5 set ruff target version
 new 6f7555076 remove some old six.PY3 checks

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 Allura/allura/config/middleware.py| 2 +-
 Allura/allura/lib/helpers.py  | 2 +-
 Allura/allura/tests/unit/test_repo.py | 3 +--
 ruff.toml | 2 ++
 4 files changed, 5 insertions(+), 4 deletions(-)



(allura) 01/02: update RAT config to work with 0.16

2024-01-09 Thread brondsem
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/allura.git

commit 0a0c13c73f25c0c92a4f22989416d8391e0aaaf0
Author: Dave Brondsema 
AuthorDate: Tue Jan 9 11:37:36 2024 -0500

update RAT config to work with 0.16
---
 scripts/src-license-check/build.xml |  5 +-
 scripts/src-license-check/report_stylesheet.xsl | 81 -
 2 files changed, 1 insertion(+), 85 deletions(-)

diff --git a/scripts/src-license-check/build.xml 
b/scripts/src-license-check/build.xml
index b02cb3189..cd1ca3927 100644
--- a/scripts/src-license-check/build.xml
+++ b/scripts/src-license-check/build.xml
@@ -22,13 +22,10 @@
xmlns:rat="antlib:org.apache.rat.anttasks">

-   
+   



-   
-   
-   


 
diff --git a/scripts/src-license-check/report_stylesheet.xsl 
b/scripts/src-license-check/report_stylesheet.xsl
deleted file mode 100644
index 051c858a7..0
--- a/scripts/src-license-check/report_stylesheet.xsl
+++ /dev/null
@@ -1,81 +0,0 @@
-
-
-http://www.w3.org/1999/XSL/Transform;>
-
-
-*
-Summary

-Generated at: 
-Notes: 
-Binaries: 
-Archives: 
-Standards: 
-
-Apache Licensed: 
-Generated Documents: 
-
-Generated files do not required license headers
-
- Unknown 
Licenses
-
-***
-
-Unapproved licenses:
-
-
-
-  
-  
-
-
-***
-
-Archives:
-
- + 
- 
- 
- 
-*
-  Files with Apache License headers will be marked AL
-  Binary files (which do not require AL headers) will be marked B
-  Compressed archives will be marked A
-  Notices, licenses etc will be marked N
- 
-  
-!
- 
- 
- 
-N
-A
-B
-
-!
- 
-  
- 
- 
- 
- 
-
-
\ No newline at end of file



(allura) branch master updated (5c508e379 -> fdbabc029)

2024-01-09 Thread brondsem
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/allura.git


from 5c508e379 better --profile behavior for scripts, add option for 
outputfile
 new 0a0c13c73 update RAT config to work with 0.16
 new fdbabc029 more license headers on some files

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../override/allura/templates/README.md| 20 +-
 AlluraTest/setup.cfg   | 19 -
 ForgeActivity/setup.cfg| 19 -
 ForgeBlog/setup.cfg| 19 -
 ForgeChat/setup.cfg| 19 -
 ForgeDiscussion/setup.cfg  | 19 -
 ForgeFeedback/setup.cfg| 19 -
 ForgeFiles/setup.cfg   | 19 -
 ForgeGit/setup.cfg | 19 -
 ForgeImporters/setup.cfg   | 19 -
 ForgeLink/setup.cfg| 19 -
 ForgeSVN/setup.cfg | 19 -
 ForgeShortUrl/setup.cfg| 19 -
 ForgeTracker/setup.cfg | 19 -
 ForgeUserStats/setup.cfg   | 19 -
 ForgeWiki/setup.cfg| 19 -
 rat-excludes.txt   |  3 +-
 scripts/src-license-check/build.xml|  5 +-
 scripts/src-license-check/report_stylesheet.xsl| 81 --
 19 files changed, 291 insertions(+), 103 deletions(-)
 delete mode 100644 scripts/src-license-check/report_stylesheet.xsl



(allura) 02/02: more license headers on some files

2024-01-09 Thread brondsem
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/allura.git

commit fdbabc029b1b574f5f3ee0d3d47d302762063010
Author: Dave Brondsema 
AuthorDate: Tue Jan 9 11:39:53 2024 -0500

more license headers on some files
---
 .../override/allura/templates/README.md  | 20 +++-
 AlluraTest/setup.cfg | 19 ++-
 ForgeActivity/setup.cfg  | 19 ++-
 ForgeBlog/setup.cfg  | 19 ++-
 ForgeChat/setup.cfg  | 19 ++-
 ForgeDiscussion/setup.cfg| 19 ++-
 ForgeFeedback/setup.cfg  | 19 ++-
 ForgeFiles/setup.cfg | 19 ++-
 ForgeGit/setup.cfg   | 19 ++-
 ForgeImporters/setup.cfg | 19 ++-
 ForgeLink/setup.cfg  | 19 ++-
 ForgeSVN/setup.cfg   | 19 ++-
 ForgeShortUrl/setup.cfg  | 19 ++-
 ForgeTracker/setup.cfg   | 19 ++-
 ForgeUserStats/setup.cfg | 19 ++-
 ForgeWiki/setup.cfg  | 19 ++-
 rat-excludes.txt |  3 +--
 17 files changed, 290 insertions(+), 18 deletions(-)

diff --git 
a/Allura/allura/templates_responsive/override/allura/templates/README.md 
b/Allura/allura/templates_responsive/override/allura/templates/README.md
index 48b208556..3144390ac 100644
--- a/Allura/allura/templates_responsive/override/allura/templates/README.md
+++ b/Allura/allura/templates_responsive/override/allura/templates/README.md
@@ -1,6 +1,24 @@
+
 
 # Responsive Migration
 
 As we plot a course to migrate allura's default layout to be responsive, new 
templates can be placed in this directory to supercede their legacy 
counterparts.
 
-To see the overridden templates take effect, ensure 
`disable_entry_points.allura.theme.override = responsive` is *disabled* (by 
commenting out or removing entirely) in your INI file.  
\ No newline at end of file
+To see the overridden templates take effect, ensure 
`disable_entry_points.allura.theme.override = responsive` is *disabled* (by 
commenting out or removing entirely) in your INI file.  
diff --git a/AlluraTest/setup.cfg b/AlluraTest/setup.cfg
index dc59fc75c..839913fe4 100644
--- a/AlluraTest/setup.cfg
+++ b/AlluraTest/setup.cfg
@@ -1,3 +1,20 @@
+#   Licensed to the Apache Software Foundation (ASF) under one
+#   or more contributor license agreements.  See the NOTICE file
+#   distributed with this work for additional information
+#   regarding copyright ownership.  The ASF licenses this file
+#   to you under the Apache License, Version 2.0 (the
+#   "License"); you may not use this file except in compliance
+#   with the License.  You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+#   Unless required by applicable law or agreed to in writing,
+#   software distributed under the License is distributed on an
+#   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+#   KIND, either express or implied.  See the License for the
+#   specific language governing permissions and limitations
+#   under the License.
+
 [pycodestyle]
 max-line-length = 119
 
@@ -7,4 +24,4 @@ max-line-length = 119
 [coverage:run]
 parallel=true
 concurrency=multiprocessing
-source=../Allura/allura,alluratest
\ No newline at end of file
+source=../Allura/allura,alluratest
diff --git a/ForgeActivity/setup.cfg b/ForgeActivity/setup.cfg
index c86f54040..98f77026f 100644
--- a/ForgeActivity/setup.cfg
+++ b/ForgeActivity/setup.cfg
@@ -1,3 +1,20 @@
+#   Licensed to the Apache Software Foundation (ASF) under one
+#   or more contributor license agreements.  See the NOTICE file
+#   distributed with this work for additional information
+#   regarding copyright ownership.  The ASF licenses this file
+#   to you under the Apache License, Version 2.0 (the
+#   "License"); you may not use this file except in compliance
+#   with the License.  You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+#   Unless required by applicable law or agreed to in writing,
+#   software distributed under the License is distributed on an
+#   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+#   KIND, either express or implied.  See the License for the
+#   specific langua

(allura) branch master updated: better --profile behavior for scripts, add option for outputfile

2024-01-08 Thread brondsem
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/allura.git


The following commit(s) were added to refs/heads/master by this push:
 new 5c508e379 better --profile behavior for scripts, add option for 
outputfile
5c508e379 is described below

commit 5c508e3795b4d44f35149505347f3e1aaa86c2b5
Author: Dave Brondsema 
AuthorDate: Mon Jan 8 17:34:59 2024 -0500

better --profile behavior for scripts, add option for outputfile

and check outputfile writability at beginning, rather than at end
See https://stackoverflow.com/a/48622889 about cProfile change
---
 Allura/allura/command/script.py | 21 +
 1 file changed, 17 insertions(+), 4 deletions(-)

diff --git a/Allura/allura/command/script.py b/Allura/allura/command/script.py
index 92384d1b5..52e58b2fb 100644
--- a/Allura/allura/command/script.py
+++ b/Allura/allura/command/script.py
@@ -38,6 +38,8 @@ class ScriptCommand(base.Command):
 parser = base.Command.standard_parser(verbose=True)
 parser.add_option('--profile', action='store_true', dest='profile',
   help='Dump profiling data to 

(allura) 02/02: [#8534] fix some codeql warnings

2024-01-05 Thread brondsem
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a commit to branch db/8534
in repository https://gitbox.apache.org/repos/asf/allura.git

commit c60e869b9a08b4b48ca0c9eb5d2372fee921aed5
Author: Dave Brondsema 
AuthorDate: Fri Jan 5 13:26:16 2024 -0500

[#8534] fix some codeql warnings
---
 Allura/allura/lib/widgets/resources/js/jquery.colorPicker.js | 2 +-
 Allura/allura/templates/repo/commit.html | 5 +++--
 ForgeImporters/forgeimporters/github/tracker.py  | 2 +-
 ForgeTracker/forgetracker/widgets/resources/js/mass-edit.js  | 2 +-
 4 files changed, 6 insertions(+), 5 deletions(-)

diff --git a/Allura/allura/lib/widgets/resources/js/jquery.colorPicker.js 
b/Allura/allura/lib/widgets/resources/js/jquery.colorPicker.js
index 78bb1291b..3a3088a62 100644
--- a/Allura/allura/lib/widgets/resources/js/jquery.colorPicker.js
+++ b/Allura/allura/lib/widgets/resources/js/jquery.colorPicker.js
@@ -179,7 +179,7 @@
 var selector = activePalette,
 selectorParent = $(event.target).parents("#" + 
selector.attr('id')).length;
 
-if (event.target === $(selector)[0] || event.target === 
selectorOwner || selectorParent > 0) {
+if (event.target === $.find(selector)[0] || event.target === 
selectorOwner || selectorParent > 0) {
 return;
 }
 
diff --git a/Allura/allura/templates/repo/commit.html 
b/Allura/allura/templates/repo/commit.html
index f92483821..630a1aaa4 100644
--- a/Allura/allura/templates/repo/commit.html
+++ b/Allura/allura/templates/repo/commit.html
@@ -49,9 +49,10 @@ Commit {{commit.shorthand_id()}} {
 {{ super() }}
   

(allura) branch db/8534 created (now c60e869b9)

2024-01-05 Thread brondsem
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a change to branch db/8534
in repository https://gitbox.apache.org/repos/asf/allura.git


  at c60e869b9 [#8534] fix some codeql warnings

This branch includes the following new commits:

 new 4a79713cf [#8534] set up github codeql workflow
 new c60e869b9 [#8534] fix some codeql warnings

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.




(allura) 01/02: [#8534] set up github codeql workflow

2024-01-05 Thread brondsem
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a commit to branch db/8534
in repository https://gitbox.apache.org/repos/asf/allura.git

commit 4a79713cf8bca0fe15b7c4977228868e41a66471
Author: Dave Brondsema 
AuthorDate: Fri Jan 5 12:07:23 2024 -0500

[#8534] set up github codeql workflow
---
 .github/codeql/codeql-config.yml | 22 +++
 .github/workflows/codeql.yml | 84 
 2 files changed, 106 insertions(+)

diff --git a/.github/codeql/codeql-config.yml b/.github/codeql/codeql-config.yml
new file mode 100644
index 0..f367b6322
--- /dev/null
+++ b/.github/codeql/codeql-config.yml
@@ -0,0 +1,22 @@
+#   Licensed to the Apache Software Foundation (ASF) under one
+#   or more contributor license agreements.  See the NOTICE file
+#   distributed with this work for additional information
+#   regarding copyright ownership.  The ASF licenses this file
+#   to you under the Apache License, Version 2.0 (the
+#   "License"); you may not use this file except in compliance
+#   with the License.  You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+#   Unless required by applicable law or agreed to in writing,
+#   software distributed under the License is distributed on an
+#   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+#   KIND, either express or implied.  See the License for the
+#   specific language governing permissions and limitations
+#   under the License.
+
+query-filters:
+  - exclude:
+  id: js/unsafe-jquery-plugin
+  - exclude:
+  id: js/unsafe-external-link
diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml
new file mode 100644
index 0..0e9e88fd7
--- /dev/null
+++ b/.github/workflows/codeql.yml
@@ -0,0 +1,84 @@
+#   Licensed to the Apache Software Foundation (ASF) under one
+#   or more contributor license agreements.  See the NOTICE file
+#   distributed with this work for additional information
+#   regarding copyright ownership.  The ASF licenses this file
+#   to you under the Apache License, Version 2.0 (the
+#   "License"); you may not use this file except in compliance
+#   with the License.  You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+#   Unless required by applicable law or agreed to in writing,
+#   software distributed under the License is distributed on an
+#   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+#   KIND, either express or implied.  See the License for the
+#   specific language governing permissions and limitations
+#   under the License.
+
+name: "CodeQL"
+
+on:
+  push:
+branches: [ "master" ]
+  pull_request:
+branches: [ "master" ]
+  schedule:
+- cron: '29 0 * * 6'
+
+jobs:
+  analyze:
+name: Analyze
+# Runner size impacts CodeQL analysis time. To learn more, please see:
+#   - https://gh.io/recommended-hardware-resources-for-running-codeql
+#   - https://gh.io/supported-runners-and-hardware-resources
+#   - https://gh.io/using-larger-runners
+# Consider using larger runners for possible analysis time improvements.
+runs-on: ${{ (matrix.language == 'swift' && 'macos-latest') || 
'ubuntu-latest' }}
+timeout-minutes: ${{ (matrix.language == 'swift' && 120) || 360 }}
+permissions:
+  actions: read
+  contents: read
+  security-events: write
+
+strategy:
+  fail-fast: false
+  matrix:
+language: [ 'javascript-typescript', 'python' ]
+# Use only 'javascript-typescript' to analyze code written in 
JavaScript, TypeScript or both
+# Learn more about CodeQL language support at 
https://aka.ms/codeql-docs/language-support
+
+steps:
+- name: Checkout repository
+  uses: actions/checkout@v4
+
+# Initializes the CodeQL tools for scanning.
+- name: Initialize CodeQL
+  uses: github/codeql-action/init@v3
+  with:
+languages: ${{ matrix.language }}
+# If you wish to specify custom queries, you can do so here or in a 
config file.
+# By default, queries listed here will override any specified in a 
config file.
+# Prefix the list here with "+" to use these queries and those in the 
config file.
+
+# For more details on CodeQL's query packs, refer to: 
https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
+# queries: security-extended
+
+config-file: ./.github/codeql/codeql-config.yml
+
+
+# Autobuild attempts to build any compiled languages (C/C++, C#, Go, Java, 
or Swift).
+# If this step fails, then you should remove it and run the b

(allura) branch db/remove_i18n created (now e9979fc5d)

2024-01-04 Thread brondsem
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a change to branch db/remove_i18n
in repository https://gitbox.apache.org/repos/asf/allura.git


  at e9979fc5d remove i18n, only was used a tiny bit in templates

This branch includes the following new commits:

 new e9979fc5d remove i18n, only was used a tiny bit in templates

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.




(allura) 01/01: remove i18n, only was used a tiny bit in templates

2024-01-04 Thread brondsem
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a commit to branch db/remove_i18n
in repository https://gitbox.apache.org/repos/asf/allura.git

commit e9979fc5d6d1204f8ddee50b33530e6dced4
Author: Dave Brondsema 
AuthorDate: Thu Jan 4 16:19:43 2024 -0500

remove i18n, only was used a tiny bit in templates
---
 Allura/MANIFEST.in   |  1 -
 Allura/allura/config/app_cfg.py  |  3 +--
 Allura/allura/i18n/ru/LC_MESSAGES/pyforge.po | 38 
 Allura/allura/templates/widgets/vote.html|  5 +---
 Allura/setup.cfg | 25 +-
 Allura/setup.py  |  3 +--
 6 files changed, 4 insertions(+), 71 deletions(-)

diff --git a/Allura/MANIFEST.in b/Allura/MANIFEST.in
index 80ad819df..56269d817 100644
--- a/Allura/MANIFEST.in
+++ b/Allura/MANIFEST.in
@@ -1,4 +1,3 @@
 recursive-include allura/public *
 include allura/public/favicon.ico
-recursive-include allura/i18n *
 recursive-include allura/templates *
diff --git a/Allura/allura/config/app_cfg.py b/Allura/allura/config/app_cfg.py
index ee4a74d65..33e5148c4 100644
--- a/Allura/allura/config/app_cfg.py
+++ b/Allura/allura/config/app_cfg.py
@@ -138,8 +138,7 @@ class AlluraJinjaRenderer(JinjaRenderer):
 autoescape=True,
 bytecode_cache=bcc,
 cache_size=asint(config.get('jinja_cache_size', -1)),
-extensions=['jinja2.ext.do', 'jinja2.ext.i18n'])
-jinja2_env.install_gettext_translations(tg.i18n)
+extensions=['jinja2.ext.do'])
 jinja2_env.filters['datetimeformat'] = helpers.datetimeformat
 jinja2_env.filters['filter'] = lambda s, t=None: list(filter(t and 
jinja2_env.tests[t], s))
 jinja2_env.filters['nl2br'] = helpers.nl2br_jinja_filter
diff --git a/Allura/allura/i18n/ru/LC_MESSAGES/pyforge.po 
b/Allura/allura/i18n/ru/LC_MESSAGES/pyforge.po
deleted file mode 100644
index 675b0c1d1..0
--- a/Allura/allura/i18n/ru/LC_MESSAGES/pyforge.po
+++ /dev/null
@@ -1,38 +0,0 @@
-#   Licensed to the Apache Software Foundation (ASF) under one
-#   or more contributor license agreements.  See the NOTICE file
-#   distributed with this work for additional information
-#   regarding copyright ownership.  The ASF licenses this file
-#   to you under the Apache License, Version 2.0 (the
-#   "License"); you may not use this file except in compliance
-#   with the License.  You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-#   Unless required by applicable law or agreed to in writing,
-#   software distributed under the License is distributed on an
-#   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-#   KIND, either express or implied.  See the License for the
-#   specific language governing permissions and limitations
-#   under the License.
-
-# Russian translations for Allura.
-#
-msgid ""
-msgstr ""
-"Project-Id-Version: ${package} 0.0.0\n"
-"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
-"POT-Creation-Date: 2008-01-13 14:00+0200\n"
-"PO-Revision-Date: 2008-01-13 14:00+0200\n"
-"Last-Translator: FULL NAME \n"
-"Language-Team: ru \n"
-"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && "
-"n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2)\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=utf-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Generated-By: Babel 0.9.1\n"
-
-#: ${package}/controllers/root.py:13
-msgid "Your application is now running"
-msgstr "Ваши приложение успешно запущено"
-
diff --git a/Allura/allura/templates/widgets/vote.html 
b/Allura/allura/templates/widgets/vote.html
index 3dc856bf3..ce5124b25 100644
--- a/Allura/allura/templates/widgets/vote.html
+++ b/Allura/allura/templates/widgets/vote.html
@@ -37,10 +37,7 @@
 {{ artifact.votes_up_percent }}%
   
   
-  {% trans num_comments = artifact.discussion_thread.num_replies %}
-{{ num_comments }} comment
-{% pluralize %}{{ num_comments}} comments
-  {% endtrans %}
+  {{ h.text.plural(artifact.discussion_thread.num_replies, 'comment', 
'comments') }}
   
   
   {% if can_vote %}
diff --git a/Allura/setup.cfg b/Allura/setup.cfg
index 453efd7e3..311cd7f08 100644
--- a/Allura/setup.cfg
+++ b/Allura/setup.cfg
@@ -24,30 +24,7 @@ max-line-length = 119
 [egg_info]
 tag_build = dev0
 
-# Babel configuration
-[compile_catalog]
-domain = allura
-directory = allura/i18n
-statistics = true
-
-[extract_messages]
-add_comments = TRANSLATORS:
-output_file = allura/i18n/allura.pot
-width = 80
-keywords = l_
-
-[init_catalog]
-domain = allura
-input_file = allura/i18n/allura.pot
-output_dir = allura/i18n
-

(allura) 02/02: [#8533] remove old quoted-printable line length approach

2024-01-04 Thread brondsem
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a commit to branch db/8533
in repository https://gitbox.apache.org/repos/asf/allura.git

commit ba28298cdaf57932033aad72b9561c3051c6e10c
Author: Dave Brondsema 
AuthorDate: Thu Jan 4 14:52:17 2024 -0500

[#8533] remove old quoted-printable line length approach
---
 Allura/allura/lib/mail_util.py| 16 +---
 Allura/allura/tests/test_tasks.py |  9 +
 2 files changed, 6 insertions(+), 19 deletions(-)

diff --git a/Allura/allura/lib/mail_util.py b/Allura/allura/lib/mail_util.py
index 5e7907d65..24f1eb8c6 100644
--- a/Allura/allura/lib/mail_util.py
+++ b/Allura/allura/lib/mail_util.py
@@ -199,21 +199,7 @@ def encode_email_part(content, content_type):
 encoded_content = content.encode('utf-8')
 encoding = 'utf-8'
 
-for line in encoded_content.splitlines():
-if len(line) > MAX_MAIL_LINE_OCTETS:
-# switch to Quoted-Printable encoding to avoid too-long lines
-# we could always Quoted-Printabl, but it makes the output a 
little messier and less human-readable
-# the particular order of all these operations seems to be very 
important for everything to end up right
-msg = MIMEText('', content_type, policy=email_policy)
-msg.replace_header('content-transfer-encoding', 'quoted-printable')
-cs = email.charset.Charset('utf-8')
-cs.header_encoding = email.charset.QP
-cs.body_encoding = email.charset.QP
-payload = cs.body_encode(content.encode('utf-8'))
-msg.set_payload(payload, 'utf-8')
-return msg
-else:
-return MIMEText(encoded_content, content_type, encoding, 
policy=email_policy)
+return MIMEText(encoded_content, content_type, encoding, 
policy=email_policy)
 
 
 def make_multipart_message(*parts):
diff --git a/Allura/allura/tests/test_tasks.py 
b/Allura/allura/tests/test_tasks.py
index 9e00970b6..8ecbeeb05 100644
--- a/Allura/allura/tests/test_tasks.py
+++ b/Allura/allura/tests/test_tasks.py
@@ -480,12 +480,13 @@ class TestMailTasks(unittest.TestCase):
 for line in body:
 assert len(line) <= MAX_MAIL_LINE_OCTETS
 
+bodystr = ''.join(body)
 # plain text
-assert 
'012345678901234567890123456789012345678901234567890123456789012345678901234=' 
in body
-assert '=D0=93=D1=80=D0=BE=D0=BC=D0=B0=D0=B4=D1=8B 
=D1=81=D1=82=D1=80=D0=BE =D0=93=' in body
+assert b64encode(b'012345678901234567890123').decode('utf8') in 
bodystr
+assert b64encode('Громады стро '.encode('utf8')).decode('utf8') in 
bodystr
 # html
-assert '0123456789012345678901234567890123456789=' in body
-assert '=D0=93=D1=80=D0=BE=D0=BC=D0=B0=D0=B4=D1=8B 
=D1=81=D1=82=D1=80=D0=BE =D0=' in body
+assert b64encode(b'012345678901234567890123').decode('utf8') in bodystr
+assert b64encode('Громады стро '.encode('utf8')).decode('utf8') 
in bodystr
 
 @td.with_wiki
 def test_receive_email_ok(self):



(allura) 01/02: [#8533] switch to RFC-compliant email formatting which will wrap long unbreaking subjects correctly

2024-01-04 Thread brondsem
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a commit to branch db/8533
in repository https://gitbox.apache.org/repos/asf/allura.git

commit bf020d137405070eb9bd0d2413d7f0cda05b8a98
Author: Dave Brondsema 
AuthorDate: Thu Jan 4 14:37:16 2024 -0500

[#8533] switch to RFC-compliant email formatting which will wrap long 
unbreaking subjects correctly
---
 Allura/allura/lib/mail_util.py | 33 --
 Allura/allura/tests/test_mail_util.py  | 21 --
 Allura/allura/tests/test_tasks.py  | 27 +-
 .../forgediscussion/tests/functional/test_forum.py | 22 +--
 .../forgetracker/tests/functional/test_root.py |  3 +-
 5 files changed, 59 insertions(+), 47 deletions(-)

diff --git a/Allura/allura/lib/mail_util.py b/Allura/allura/lib/mail_util.py
index fb8459ec9..5e7907d65 100644
--- a/Allura/allura/lib/mail_util.py
+++ b/Allura/allura/lib/mail_util.py
@@ -48,25 +48,28 @@ EMAIL_VALIDATOR = fev.Email(not_empty=True)
 # http://www.jebriggs.com/blog/2010/07/smtp-maximum-line-lengths/
 MAX_MAIL_LINE_OCTETS = 990
 
+email_policy = email.policy.SMTP + email.policy.strict
 
-def Header(text, *more_text):
-'''Helper to make sure we encode headers properly'''
+def Header(text, *more_text) -> str:
+'''
+Helper to make sure we encode headers properly
+This used to return an email.header.Header instance
+But needs to be a plain str now that we're using email.policy.SMTP
+'''
 if isinstance(text, header.Header):
-return text
-# email.header.Header handles str vs unicode differently
-# see
-# 
http://docs.python.org/library/email.header.html#email.header.Header.append
+return str(text)
+
 if not isinstance(text, str):
 raise TypeError('This must be unicode: %r' % text)
-head = header.Header(text)
+
+hdr_text = text
 for m in more_text:
 if not isinstance(m, str):
 raise TypeError('This must be unicode: %r' % text)
-head.append(m)
-return head
-
+hdr_text += ' ' + m
+return hdr_text
 
-def AddrHeader(fromaddr):
+def AddrHeader(fromaddr) -> str:
 '''Accepts any of:
 Header() instance
 f...@bar.com
@@ -201,7 +204,7 @@ def encode_email_part(content, content_type):
 # switch to Quoted-Printable encoding to avoid too-long lines
 # we could always Quoted-Printabl, but it makes the output a 
little messier and less human-readable
 # the particular order of all these operations seems to be very 
important for everything to end up right
-msg = MIMEText('', content_type)
+msg = MIMEText('', content_type, policy=email_policy)
 msg.replace_header('content-transfer-encoding', 'quoted-printable')
 cs = email.charset.Charset('utf-8')
 cs.header_encoding = email.charset.QP
@@ -210,13 +213,13 @@ def encode_email_part(content, content_type):
 msg.set_payload(payload, 'utf-8')
 return msg
 else:
-return MIMEText(encoded_content, content_type, encoding)
+return MIMEText(encoded_content, content_type, encoding, 
policy=email_policy)
 
 
 def make_multipart_message(*parts):
-msg = MIMEMultipart('related')
+msg = MIMEMultipart('related', policy=email_policy)
 msg.preamble = 'This is a multi-part message in MIME format.'
-alt = MIMEMultipart('alternative')
+alt = MIMEMultipart('alternative', policy=email_policy)
 msg.attach(alt)
 for part in parts:
 alt.attach(part)
diff --git a/Allura/allura/tests/test_mail_util.py 
b/Allura/allura/tests/test_mail_util.py
index 76fd42965..50b5b208b 100644
--- a/Allura/allura/tests/test_mail_util.py
+++ b/Allura/allura/tests/test_mail_util.py
@@ -35,6 +35,7 @@ from allura.lib.mail_util import (
 is_autoreply,
 identify_sender,
 _parse_message_id,
+email_policy,
 )
 from allura.lib.exceptions import AddressException
 from allura.tests import decorators as td
@@ -91,7 +92,8 @@ class TestReactor(unittest.TestCase):
 Толпой со всех концов земли
 К богатым пристаням стремятся;'''.encode(charset),
 'plain',
-charset)
+charset,
+policy=email_policy)
 msg1['Message-ID'] = ''
 s_msg = msg1.as_string()
 msg2 = parse_message(s_msg)
@@ -189,15 +191,17 @@ Content-Type: text/html; charset="utf-8"
 Толпой со всех концов земли
 К богатым пристаням стремятся;'''.encode(charset),
   'plain',
-  charset)
+  charset,
+  policy=email_policy)
 p2 = MIMEText('''По оживлённым берегам
 Громады стройные теснятся
 Дворцов и башен; корабли
 Толпой со всех концов земли
 К богатым пристаням стремятся;'''.encode(charset),
 

(allura) branch db/8533 created (now ba28298cd)

2024-01-04 Thread brondsem
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a change to branch db/8533
in repository https://gitbox.apache.org/repos/asf/allura.git


  at ba28298cd [#8533] remove old quoted-printable line length approach

This branch includes the following new commits:

 new bf020d137 [#8533] switch to RFC-compliant email formatting which will 
wrap long unbreaking subjects correctly
 new ba28298cd [#8533] remove old quoted-printable line length approach

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.




(allura) 02/04: [#8532] add Bugbear ruff checks, other fixes

2024-01-03 Thread brondsem
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a commit to branch db/8532
in repository https://gitbox.apache.org/repos/asf/allura.git

commit ca17f10ce3082b0d7b6285fd655bc91a772b9d6f
Author: Dave Brondsema 
AuthorDate: Tue Jan 2 17:42:29 2024 -0500

[#8532] add Bugbear ruff checks, other fixes
---
 Allura/allura/controllers/auth.py  |  4 +--
 Allura/allura/lib/custom_middleware.py |  5 ++--
 Allura/allura/lib/macro.py |  2 +-
 Allura/allura/model/timeline.py|  2 +-
 Allura/allura/tasks/repo_tasks.py  |  2 +-
 Allura/allura/tests/model/test_artifact.py |  2 +-
 Allura/allura/tests/model/test_auth.py |  2 +-
 Allura/allura/tests/model/test_project.py  |  6 ++---
 .../allura/tests/unit/test_package_path_loader.py  |  2 +-
 ForgeDiscussion/forgediscussion/model/forum.py |  2 +-
 .../forgediscussion/tests/functional/test_forum.py |  2 +-
 ForgeGit/forgegit/tests/model/test_repository.py   | 10 
 ForgeSVN/forgesvn/tests/model/test_repository.py   |  6 ++---
 ForgeTracker/forgetracker/model/ticket.py  |  2 +-
 ruff.toml  | 30 +++---
 15 files changed, 46 insertions(+), 33 deletions(-)

diff --git a/Allura/allura/controllers/auth.py 
b/Allura/allura/controllers/auth.py
index 7cd0189c2..1d11394f5 100644
--- a/Allura/allura/controllers/auth.py
+++ b/Allura/allura/controllers/auth.py
@@ -452,8 +452,8 @@ class AuthController(BaseController):
 return '.'.join(reversed(parts))
 
 repos = []
-for p in user.my_projects():
-for p in [p] + p.direct_subprojects:
+for up in user.my_projects():
+for p in [up] + up.direct_subprojects:
 for app in p.app_configs:
 if not issubclass(g.entry_points["tool"][app.tool_name], 
RepositoryApp):
 continue
diff --git a/Allura/allura/lib/custom_middleware.py 
b/Allura/allura/lib/custom_middleware.py
index e74594aa0..d9ca652fb 100644
--- a/Allura/allura/lib/custom_middleware.py
+++ b/Allura/allura/lib/custom_middleware.py
@@ -286,7 +286,8 @@ class SetRequestHostFromConfig:
 #   'HTTP_X_FORWARDED_PROTO' == 'https'
 req = Request(environ)
 try:
-req.params  # check for malformed unicode or POSTs, this is the 
first middleware that might trip over it.
+# check for malformed unicode or POSTs, this is the first 
middleware that might trip over it:
+req.params  # noqa: B018
 resp = self.app
 except (UnicodeError, ValueError):
 resp = exc.HTTPBadRequest()
@@ -456,7 +457,7 @@ class MingTaskSessionSetupMiddleware:
 
 def __call__(self, environ, start_response):
 # this is sufficient to ensure an ODM session is always established
-session(M.MonQTask).impl
+session(M.MonQTask).impl  # noqa: B018
 return self.app(environ, start_response)
 
 
diff --git a/Allura/allura/lib/macro.py b/Allura/allura/lib/macro.py
index 20d8fb244..7d0aba893 100644
--- a/Allura/allura/lib/macro.py
+++ b/Allura/allura/lib/macro.py
@@ -67,7 +67,7 @@ class macro:
 Decorator to declare a function is a custom markdown macro
 """
 
-def __init__(self, context: str = None, cacheable: bool = False):
+def __init__(self, context: str | None = None, cacheable: bool = False):
 """
 :param context: either "neighborhood-wiki" or "userproject-wiki" to 
limit the macro to be used in those contexts
 :param cacheable: indicates if its ok to cache the macro's output 
permanently
diff --git a/Allura/allura/model/timeline.py b/Allura/allura/model/timeline.py
index 85d28eda0..9048b6c1e 100644
--- a/Allura/allura/model/timeline.py
+++ b/Allura/allura/model/timeline.py
@@ -43,7 +43,7 @@ class Director(ActivityDirector):
 
 """
 
-def create_activity(self, actor, verb, obj, target=None,
+def create_activity(self, actor: ActivityNode, verb: str, obj: 
ActivityObject, target=None,
 related_nodes=None, tags=None):
 if c.project and c.project.notifications_disabled:
 return
diff --git a/Allura/allura/tasks/repo_tasks.py 
b/Allura/allura/tasks/repo_tasks.py
index 296358fde..b7185bc39 100644
--- a/Allura/allura/tasks/repo_tasks.py
+++ b/Allura/allura/tasks/repo_tasks.py
@@ -179,7 +179,7 @@ def can_merge(merge_request_id):
 def determine_mr_commits(merge_request_id):
 from allura import model as M
 mr = M.MergeRequest.query.get(_id=merge_request_id)
-mr.commits  # build & cache the commits
+mr.commits  # noqa: B018.  build & cache the commits
 
 
 @task
diff --git a/Allura/allura/tests/model/test_artifact.py 
b/Allura/allura/tests/model/test_artifact.py
index aed8add97..9eb2c8b4e 1006

(allura) 03/04: [#8532] fix E402

2024-01-03 Thread brondsem
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a commit to branch db/8532
in repository https://gitbox.apache.org/repos/asf/allura.git

commit e4ec8e799010bd03e9959e55b7ee17decd3dd69c
Author: Dave Brondsema 
AuthorDate: Wed Jan 3 11:46:13 2024 -0500

[#8532] fix E402
---
 Allura/allura/config/middleware.py | 1 +
 Allura/allura/lib/app_globals.py   | 5 ++---
 Allura/allura/websetup/__init__.py | 9 +++--
 ruff.toml  | 1 -
 4 files changed, 6 insertions(+), 10 deletions(-)

diff --git a/Allura/allura/config/middleware.py 
b/Allura/allura/config/middleware.py
index f8378b1fe..75aa2a160 100644
--- a/Allura/allura/config/middleware.py
+++ b/Allura/allura/config/middleware.py
@@ -44,6 +44,7 @@ from beaker_session_jwt import JWTCookieSession
 
 # Must apply patches before other Allura imports to ensure all the patches are 
effective.
 # This file gets imported from paste/deploy/loadwsgi.py pretty early in the 
app execution
+# ruff: noqa: E402
 from allura.lib import patches
 patches.apply()
 try:
diff --git a/Allura/allura/lib/app_globals.py b/Allura/allura/lib/app_globals.py
index 2016d6b48..eadabd9bd 100644
--- a/Allura/allura/lib/app_globals.py
+++ b/Allura/allura/lib/app_globals.py
@@ -17,9 +17,6 @@
 from __future__ import annotations
 
 import re
-
-"""The application's Globals object"""
-
 import logging
 import html
 import hashlib
@@ -69,6 +66,8 @@ from allura.lib.solr import MockSOLR, make_solr_from_config
 from allura.model.session import artifact_orm_session
 import six
 
+"""The application's Globals object"""
+
 __all__ = ['Globals']
 
 log = logging.getLogger(__name__)
diff --git a/Allura/allura/websetup/__init__.py 
b/Allura/allura/websetup/__init__.py
index 936dd149b..f8a254fdb 100644
--- a/Allura/allura/websetup/__init__.py
+++ b/Allura/allura/websetup/__init__.py
@@ -15,19 +15,16 @@
 #   specific language governing permissions and limitations
 #   under the License.
 
-"""Setup the allura application"""
-
 import logging
-
 from allura.config.app_cfg import base_config
+from .schema import setup_schema
+from . import bootstrap
+
 __all__ = ['setup_app']
 
 
 log = logging.getLogger(__name__)
 
-from .schema import setup_schema
-from . import bootstrap
-
 
 def setup_app(command, conf, vars):
 """Place any commands to setup allura here"""
diff --git a/ruff.toml b/ruff.toml
index f7453d735..7fdb9bcd6 100644
--- a/ruff.toml
+++ b/ruff.toml
@@ -33,7 +33,6 @@ ignore = [
 'F401', # Imported but unused,
 'F811', # Redefinition of unused
 'F841', # Assigned to but never used
-'E402', # Module level import not at top of file
 'E731', # Do not assign a lambda expression, use a def
 'E741', # Ambiguous variable name: I,
 'E501', # Line too long



(allura) 01/04: [#8532] precommit autoupdate

2024-01-03 Thread brondsem
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a commit to branch db/8532
in repository https://gitbox.apache.org/repos/asf/allura.git

commit 33619713ee516fe256e55ebdc7ac2c5e9aad
Author: Dave Brondsema 
AuthorDate: Tue Jan 2 17:42:07 2024 -0500

[#8532] precommit autoupdate
---
 .pre-commit-config.yaml | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index fe4356950..10f947e3d 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -18,7 +18,7 @@
 default_stages: [commit]
 repos:
 -   repo: https://github.com/pre-commit/pre-commit-hooks
-rev: v4.1.0
+rev: v4.5.0
 hooks:
 # general checks
 -   id: check-xml
@@ -41,7 +41,7 @@ repos:
 
 
 -   repo: https://github.com/pre-commit/pygrep-hooks
-rev: v1.9.0
+rev: v1.10.0
 hooks:
 -   id: python-check-blanket-noqa
 exclude: '^Allura/setup.py$'
@@ -109,7 +109,7 @@ repos:
 
 
 - repo:  https://github.com/milin/giticket
-  rev: v1.3
+  rev: v1.4
   hooks:
   - id:  giticket
 args: ['--mode=regex_match', '--format=[#{ticket}] {commit_msg}', 
'--regex=[0-9]{4,}']
@@ -117,7 +117,7 @@ repos:
 
 - repo: https://github.com/astral-sh/ruff-pre-commit
   # Ruff version.
-  rev: v0.0.283
+  rev: v0.1.11
   hooks:
 - id: ruff
   types: [python]



(allura) branch db/8532 created (now 2790de3e9)

2024-01-03 Thread brondsem
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a change to branch db/8532
in repository https://gitbox.apache.org/repos/asf/allura.git


  at 2790de3e9 [#8532] use ruff to check for print/debug/etc

This branch includes the following new commits:

 new 33619 [#8532] precommit autoupdate
 new ca17f10ce [#8532] add Bugbear ruff checks, other fixes
 new e4ec8e799 [#8532] fix E402
 new 2790de3e9 [#8532] use ruff to check for print/debug/etc

The 4 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.




(allura) 04/04: [#8532] use ruff to check for print/debug/etc

2024-01-03 Thread brondsem
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a commit to branch db/8532
in repository https://gitbox.apache.org/repos/asf/allura.git

commit 2790de3e9ecf1b85af7b6b90834ab4a43c4bfb82
Author: Dave Brondsema 
AuthorDate: Wed Jan 3 14:58:33 2024 -0500

[#8532] use ruff to check for print/debug/etc
---
 .pre-commit-config.yaml | 37 -
 Allura/allura/lib/utils.py  |  2 +-
 Allura/ldap-userconfig.py   |  6 +-
 Allura/setup.py |  2 +-
 ruff.toml   | 13 ++---
 scripts/teamforge-import.py |  3 ++-
 6 files changed, 19 insertions(+), 44 deletions(-)

diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 10f947e3d..0e3a5168f 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -27,9 +27,6 @@ repos:
 exclude: '.babelrc'
 -   id: check-merge-conflict
 fail_fast: true
-# python checks
--   id: debug-statements
-exclude: '^Allura/allura/lib/utils.py$'
 # other checks
 -   id: check-docstring-first
 exclude: |
@@ -43,11 +40,6 @@ repos:
 -   repo: https://github.com/pre-commit/pygrep-hooks
 rev: v1.10.0
 hooks:
--   id: python-check-blanket-noqa
-exclude: '^Allura/setup.py$'
--   id: python-check-mock-methods
-exclude: '^Allura/allura/tests/test_tasks.py$'
--   id: python-no-log-warn
 -   id: rst-backticks
 exclude:
   (?x)^(
@@ -70,35 +62,6 @@ repos:
 language: pygrep
 types: [python]
 entry: '\.now\(|\.fromtimestamp\(|\.mktime\('
-  - id: noprint
-name: check for print statements
-language: pygrep
-types: [python]
-entry: '\bprint\('
-exclude: |
-(?x)^(
-/tests/.*|
-Allura/allura/command/.*|
-Allura/ldap-setup.py|
-scripts/.*|
-Allura/ldap-userconfig.py|
-/scripts/.*|
-ForgeSVN/setup.py|
-Allura/allura/scripts/.*|
-Allura/allura/tests/.*|
-AlluraTest/alluratest/.*|
-ForgeGit/forgegit/tests/.*|
-fuse/.*|
-run_tests|
-ForgeSVN/forgesvn/tests/.*|
-ForgeWiki/forgewiki/tests/.*|
-ForgeImporters/forgeimporters/tests/.*
-)$
-  - id: notab
-name: check for tabs
-language: pygrep
-types: [python]
-entry: '   '
 # SCSS Syntax: could use placeholders instead of extending a class or tag 
directly
   - id: scss_extend_pattern
 name: search for scss invalid extend patterns in class elements
diff --git a/Allura/allura/lib/utils.py b/Allura/allura/lib/utils.py
index df42b..683a7fcae 100644
--- a/Allura/allura/lib/utils.py
+++ b/Allura/allura/lib/utils.py
@@ -461,7 +461,7 @@ class CaseInsensitiveDict(TransformedDict):
 
 def postmortem_hook(etype, value, tb):  # pragma no cover
 import sys
-import pdb
+import pdb  # noqa: T100
 import traceback
 sys.stderr.write('Entering post-mortem PDB shell\n')
 traceback.print_exception(etype, value, tb)
diff --git a/Allura/ldap-userconfig.py b/Allura/ldap-userconfig.py
index a300d4d02..dd1c270c0 100644
--- a/Allura/ldap-userconfig.py
+++ b/Allura/ldap-userconfig.py
@@ -26,7 +26,11 @@ import grp
 def main():
 command = sys.argv[1]
 uname = sys.argv[2]
-eval(command)(uname, *sys.argv[3:])
+fn = {
+'init': init,
+'upload': upload,
+}[command]
+fn(uname, *sys.argv[3:])
 
 
 def init(uname):
diff --git a/Allura/setup.py b/Allura/setup.py
index ece157874..a6016bbbf 100644
--- a/Allura/setup.py
+++ b/Allura/setup.py
@@ -26,7 +26,7 @@ lists, wiki pages, blogs and more for any number of 
individual projects.
 '''
 setup(
 name='Allura',
-version=__version__, # noqa
+version=__version__, # noqa: F821
 description='Base distribution of the Allura development platform',
 long_description=PROJECT_DESCRIPTION,
 author='Allura Team',
diff --git a/ruff.toml b/ruff.toml
index 7fdb9bcd6..2b8e99ba6 100644
--- a/ruff.toml
+++ b/ruff.toml
@@ -16,7 +16,7 @@
 #   under the License.
 
 line-length = 119
-
+show-source = true
 
 select = [
 # all flake8 & pep8 (except 'ignore' below)
@@ -27,6 +27,9 @@ select = [
 "RUF013",  # implicit Optional (=None)
 "ISC001",  # NIC001 in flake8 codes
 "B",
+"PGH",  # https://github.com/pre-commit/pygrep-hooks
+"T10",  # debugger breakpoints
+"T20",  # print()
 ]
 
 ignore = [
@@ -41,7 +44,11 @@ ignore = [
 'B904', # use raise from
 ]
 
-
 [per-file-ignores]
 '__init__.py' = ['F403']  # import *
-'**/{alluratest,tests}/*' = ['B011']  # assert False
+'**/{alluratest,tests}/*' = [
+'B011',  # assert False
+'T20',  # print
+]
+'{scripts,Al

(allura) branch db/oauth_user_index updated: restore c.project.notifications_disabled after a task (can matter in tests)

2023-12-22 Thread brondsem
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a commit to branch db/oauth_user_index
in repository https://gitbox.apache.org/repos/asf/allura.git


The following commit(s) were added to refs/heads/db/oauth_user_index by this 
push:
 new ce5a0a21b restore c.project.notifications_disabled after a task (can 
matter in tests)
ce5a0a21b is described below

commit ce5a0a21b6b08797c8e235907ec9c9345492dbc5
Author: Dave Brondsema 
AuthorDate: Fri Dec 22 12:44:15 2023 -0500

restore c.project.notifications_disabled after a task (can matter in tests)
---
 Allura/allura/model/monq_model.py | 16 
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/Allura/allura/model/monq_model.py 
b/Allura/allura/model/monq_model.py
index 770899b16..61ea3d863 100644
--- a/Allura/allura/model/monq_model.py
+++ b/Allura/allura/model/monq_model.py
@@ -33,7 +33,7 @@ from ming import schema as S
 from ming.odm import session, FieldProperty
 from ming.odm.declarative import MappedClass
 
-from allura.lib.helpers import log_output, null_contextmanager
+from allura.lib.helpers import log_output, null_contextmanager, 
notifications_disabled
 from .session import task_orm_session
 
 if typing.TYPE_CHECKING:
@@ -165,8 +165,7 @@ class MonQTask(MappedClass):
 notifications_disabled=False)
 if getattr(c, 'project', None):
 context['project_id'] = c.project._id
-context[
-'notifications_disabled'] = c.project.notifications_disabled
+context['notifications_disabled'] = 
c.project.notifications_disabled
 if getattr(c, 'app', None):
 context['app_config_id'] = c.app.config._id
 if getattr(c, 'user', None):
@@ -246,15 +245,16 @@ class MonQTask(MappedClass):
 func = self.function
 c.project = M.Project.query.get(_id=self.context.project_id)
 c.app = None
+maybe_notif_disabled = null_contextmanager()
 if c.project:
-c.project.notifications_disabled = self.context.get(
-'notifications_disabled', False)
-app_config = M.AppConfig.query.get(
-_id=self.context.app_config_id)
+maybe_notif_disabled = notifications_disabled(c.project,
+  
self.context.get('notifications_disabled', False))
+app_config = 
M.AppConfig.query.get(_id=self.context.app_config_id)
 if app_config:
 c.app = c.project.app_instance(app_config)
 c.user = M.User.query.get(_id=self.context.user_id)
-with null_contextmanager() if nocapture else log_output(log):
+with null_contextmanager() if nocapture else log_output(log), \
+maybe_notif_disabled:
 self.result = func(*self.args, **self.kwargs)
 self.state = 'complete'
 return self.result



(allura) 01/01: add user_id index to oauth collections

2023-12-22 Thread brondsem
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a commit to branch db/oauth_user_index
in repository https://gitbox.apache.org/repos/asf/allura.git

commit c8e092fefcbb5a6286a60abb64b0fbdc8b69c8b8
Author: Dave Brondsema 
AuthorDate: Fri Dec 22 11:03:15 2023 -0500

add user_id index to oauth collections
---
 Allura/allura/model/oauth.py | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/Allura/allura/model/oauth.py b/Allura/allura/model/oauth.py
index ce0baada6..b7d539acf 100644
--- a/Allura/allura/model/oauth.py
+++ b/Allura/allura/model/oauth.py
@@ -47,6 +47,9 @@ class OAuthToken(MappedClass):
 session = main_orm_session
 name = 'oauth_token'
 unique_indexes = ['api_key']
+indexes = [
+('user_id'),
+]
 polymorphic_on = 'type'
 polymorphic_identity = None
 



(allura) branch db/oauth_user_index created (now c8e092fef)

2023-12-22 Thread brondsem
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a change to branch db/oauth_user_index
in repository https://gitbox.apache.org/repos/asf/allura.git


  at c8e092fef add user_id index to oauth collections

This branch includes the following new commits:

 new c8e092fef add user_id index to oauth collections

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.




(allura) branch db/syntax_escaping created (now 919ab928c)

2023-12-19 Thread brondsem
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a change to branch db/syntax_escaping
in repository https://gitbox.apache.org/repos/asf/allura.git


  at 919ab928c improve JS syntax and escaping

This branch includes the following new commits:

 new 919ab928c improve JS syntax and escaping

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.




(allura) 01/01: improve JS syntax and escaping

2023-12-19 Thread brondsem
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a commit to branch db/syntax_escaping
in repository https://gitbox.apache.org/repos/asf/allura.git

commit 919ab928c5907a24a97e308df261b6d0dc6f8293
Author: Dave Brondsema 
AuthorDate: Tue Dec 19 14:06:20 2023 -0500

improve JS syntax and escaping
---
 Allura/allura/ext/admin/templates/project_trove.html  | 2 +-
 Allura/allura/lib/widgets/forms.py| 7 ++-
 Allura/allura/lib/widgets/resources/js/post.js| 6 +++---
 Allura/allura/public/nf/js/site_admin_new_projects.js | 2 +-
 ForgeTracker/forgetracker/templates/tracker/ticket.html   | 2 +-
 ForgeTracker/forgetracker/widgets/resources/js/mass-edit.js   | 4 ++--
 ForgeTracker/forgetracker/widgets/resources/js/ticket-list.js | 2 +-
 7 files changed, 11 insertions(+), 14 deletions(-)

diff --git a/Allura/allura/ext/admin/templates/project_trove.html 
b/Allura/allura/ext/admin/templates/project_trove.html
index e93aac4f5..0d1a9da78 100644
--- a/Allura/allura/ext/admin/templates/project_trove.html
+++ b/Allura/allura/ext/admin/templates/project_trove.html
@@ -130,7 +130,7 @@
 insertAfter = this;
 }
   });
-  var $newItem = $(''+resp.trove_full_path+' '+del_btn+'');
+  var $newItem = $(''+escape_html(resp.trove_full_path)+' '+del_btn+'');
   if (insertAfter) {
 $newItem.insertAfter(insertAfter);
   } else {
diff --git a/Allura/allura/lib/widgets/forms.py 
b/Allura/allura/lib/widgets/forms.py
index 0ac373b2d..5252819e1 100644
--- a/Allura/allura/lib/widgets/forms.py
+++ b/Allura/allura/lib/widgets/forms.py
@@ -16,7 +16,7 @@
 #   under the License.
 
 import logging
-import warnings
+from html import escape as html_escape
 
 from tg import app_globals as g, tmpl_context as c
 from formencode import validators as fev
@@ -35,8 +35,6 @@ from allura.lib import plugin
 from allura.lib.widgets import form_fields as ffw
 from allura.lib import exceptions as forge_exc
 from allura import model as M
-import six
-from functools import reduce
 
 
 log = logging.getLogger(__name__)
@@ -104,8 +102,7 @@ class ForgeForm(ew.SimpleForm):
 or ctx.get('label')
 or getattr(field, 'label', None)
 or ctx['name'])
-html = '{}'.format(
-ctx['id'], label_text)
+html = '{}'.format(html_escape(ctx['id']), 
html_escape(label_text))
 return Markup(html)
 
 def context_for(self, field):
diff --git a/Allura/allura/lib/widgets/resources/js/post.js 
b/Allura/allura/lib/widgets/resources/js/post.js
index 6103944eb..d23c6af9c 100644
--- a/Allura/allura/lib/widgets/resources/js/post.js
+++ b/Allura/allura/lib/widgets/resources/js/post.js
@@ -76,8 +76,8 @@
 } else if (data.username) {
 flash('User blocked', 'success');
 // full page form submit
-$('' +
-'')
+$('' +
+'')
 .appendTo('body')
 .submit();
 } else {
@@ -162,4 +162,4 @@
 });
 }
 });
-}());
\ No newline at end of file
+}());
diff --git a/Allura/allura/public/nf/js/site_admin_new_projects.js 
b/Allura/allura/public/nf/js/site_admin_new_projects.js
index 302f4f7ef..b2798a5aa 100644
--- a/Allura/allura/public/nf/js/site_admin_new_projects.js
+++ b/Allura/allura/public/nf/js/site_admin_new_projects.js
@@ -35,7 +35,7 @@ $(document).ready(function() {
   $('.js-select-project').change(function() {
 var shortname = $(this).attr('data-shortname');
 if ($(this).is(':checked')) {
-  $('#selected-projects').append(' ' + shortname);
+  $('#selected-projects').append(' ' + escape_html(shortname));
 } else {
   var shortnames = $('#selected-projects').text().split(' ');
   for (var i = 0; i < shortnames.length; i++) {
diff --git a/ForgeTracker/forgetracker/templates/tracker/ticket.html 
b/ForgeTracker/forgetracker/templates/tracker/ticket.html
index 9136127f5..e17020bf7 100644
--- a/ForgeTracker/forgetracker/templates/tracker/ticket.html
+++ b/ForgeTracker/forgetracker/templates/tracker/ticket.html
@@ -228,7 +228,7 @@
 view_holder.show();
 discussion_holder.show();
 ticket_content.show();
-title_holder.find('span').html(original_title_text)
+title_holder.find('span').text(original_title_text);
 title_actions.appendTo(title_holder);
 title_actions.show();
 vote.show();
diff --git a/ForgeTracker/forgetracker/widgets/resources/js/mass-edit.js 
b/ForgeTracker/forgetracker/widgets/resources/js/mass-edit.js
index 35d91aa92..886f973ef 100644
--- a/ForgeTracker/forgetracker/widgets/resources/js/mass-edit.js
+++ b/ForgeTrac

(allura) 01/01: [#8529] fix repo root and /ref/ controller to handle unicode branch names

2023-12-05 Thread brondsem
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a commit to branch db/8529
in repository https://gitbox.apache.org/repos/asf/allura.git

commit bb431c44260c945d700d1d81bbda90e4486a11f9
Author: Dave Brondsema 
AuthorDate: Tue Dec 5 15:44:02 2023 -0500

[#8529] fix repo root and /ref/ controller to handle unicode branch names
---
 Allura/allura/controllers/repository.py| 3 ++-
 ForgeGit/forgegit/controllers.py   | 3 ++-
 ForgeGit/forgegit/tests/functional/test_controllers.py | 6 ++
 ForgeSVN/forgesvn/controllers.py   | 4 ++--
 4 files changed, 12 insertions(+), 4 deletions(-)

diff --git a/Allura/allura/controllers/repository.py 
b/Allura/allura/controllers/repository.py
index 224e5decf..351d3642f 100644
--- a/Allura/allura/controllers/repository.py
+++ b/Allura/allura/controllers/repository.py
@@ -91,7 +91,7 @@ class RepoRootController(BaseController, FeedController):
 def index(self, offset=0, branch=None, **kw):
 if branch is None:
 branch = c.app.default_branch_name
-permanent_redirect(c.app.repo.url_for_commit(branch, url_type='ref'))
+permanent_redirect(h.urlquote(c.app.repo.url_for_commit(branch, 
url_type='ref')))
 
 @with_trailing_slash
 @expose('jinja:allura:templates/repo/forks.html')
@@ -628,6 +628,7 @@ class RefsController:
 def _lookup(self, ref=None, *remainder):
 if ref is None:
 raise exc.HTTPNotFound
+ref = unquote(ref)
 EOR = c.app.END_OF_REF_ESCAPE
 if EOR in remainder:
 i = remainder.index(EOR)
diff --git a/ForgeGit/forgegit/controllers.py b/ForgeGit/forgegit/controllers.py
index 0c504e935..2062d0c24 100644
--- a/ForgeGit/forgegit/controllers.py
+++ b/ForgeGit/forgegit/controllers.py
@@ -21,6 +21,7 @@ from tg import expose, redirect
 from tg.decorators import with_trailing_slash
 from tg import tmpl_context as c
 
+from allura.lib import helpers as h
 from allura.controllers import repository
 
 
@@ -33,4 +34,4 @@ class BranchBrowser(repository.BranchBrowser):
 latest = c.app.repo.latest(branch=self._branch)
 if is_empty or not latest:
 return dict(allow_fork=False, log=[], is_empty=is_empty)
-permanent_redirect(c.app.repo.url_for_commit(self._branch) + 'tree/')
+permanent_redirect(h.urlquote(c.app.repo.url_for_commit(self._branch) 
+ 'tree/'))
diff --git a/ForgeGit/forgegit/tests/functional/test_controllers.py 
b/ForgeGit/forgegit/tests/functional/test_controllers.py
index cb5c7bba7..3d994ca4f 100644
--- a/ForgeGit/forgegit/tests/functional/test_controllers.py
+++ b/ForgeGit/forgegit/tests/functional/test_controllers.py
@@ -525,6 +525,12 @@ class TestRootController(_TestCase):
 assert 'bad' not in r
 assert 'README' in r
 
+def test_index_branch_unicode(self):
+# more realistic case is the default branch having unicode, but 
passing the branch name is easier
+resp = self.app.get('/p/test/src-git/', params={'branch':'ƒ∂ß'})
+assert resp.location == 
'http://localhost/p/test/src-git/ref/%C6%92%E2%88%82%C3%9F/'
+# further testing needs a real branch in our test repo
+
 def test_set_checkout_url(self):
 r = self.app.get('/p/test/admin/src-git/checkout_url')
 r.form['external_checkout_url'].value = 'http://foo.bar/baz'
diff --git a/ForgeSVN/forgesvn/controllers.py b/ForgeSVN/forgesvn/controllers.py
index cf10c2ee9..ac07d05a5 100644
--- a/ForgeSVN/forgesvn/controllers.py
+++ b/ForgeSVN/forgesvn/controllers.py
@@ -21,6 +21,7 @@ from tg import expose, redirect
 from tg.decorators import with_trailing_slash
 from tg import tmpl_context as c
 
+from allura.lib import helpers as h
 from allura.controllers import repository
 from allura.controllers.feed import FeedController
 
@@ -40,8 +41,7 @@ class BranchBrowser(repository.BranchBrowser, FeedController):
 latest = c.app.repo.latest(branch=self._branch)
 if is_empty or not latest:
 return dict(allow_fork=False, log=[], is_empty=is_empty)
-permanent_redirect(c.app.repo.url_for_commit(c.app.default_branch_name)
- + 'tree/')
+
permanent_redirect(h.urlquote(c.app.repo.url_for_commit(c.app.default_branch_name)
 + 'tree/'))
 
 @expose()
 def _lookup(self, rev, *remainder):



(allura) branch db/8529 created (now bb431c442)

2023-12-05 Thread brondsem
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a change to branch db/8529
in repository https://gitbox.apache.org/repos/asf/allura.git


  at bb431c442 [#8529] fix repo root and /ref/ controller to handle unicode 
branch names

This branch includes the following new commits:

 new bb431c442 [#8529] fix repo root and /ref/ controller to handle unicode 
branch names

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.




(allura) branch master updated: [#8527] display thread subject instead of app name and tool label in header

2023-11-27 Thread brondsem
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/allura.git


The following commit(s) were added to refs/heads/master by this push:
 new 2c30b10ec [#8527] display thread subject instead of app name and tool 
label in header
2c30b10ec is described below

commit 2c30b10ec7ee14bb90618692aea55be814ef8225
Author: Guillermo Cruz 
AuthorDate: Thu Nov 16 14:08:40 2023 -0700

[#8527] display thread subject instead of app name and tool label in header
---
 Allura/allura/controllers/discuss.py | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/Allura/allura/controllers/discuss.py 
b/Allura/allura/controllers/discuss.py
index 5756ec9c6..d0006c6e4 100644
--- a/Allura/allura/controllers/discuss.py
+++ b/Allura/allura/controllers/discuss.py
@@ -48,6 +48,7 @@ from allura.model.artifact import ArtifactReference
 from .attachments import AttachmentsController, AttachmentController
 from .feed import FeedArgs, FeedController
 import six
+from jinja2.filters import do_truncate as truncate
 
 log = logging.getLogger(__name__)
 
@@ -204,6 +205,8 @@ class ThreadController(BaseController, FeedController, 
metaclass=h.ProxiedAttrMe
 c.thread_header = self.W.thread_header
 limit, page, start = g.handle_paging(limit, page)
 self.thread.num_views += 1
+h1_text = self.thread.subject or c.app.config.options.mount_label
+h1_text = truncate(None, h1_text, 80, end="...", leeway=3)
 # the update to num_views shouldn't affect it
 M.session.artifact_orm_session._get().skip_mod_date = True
 M.session.artifact_orm_session._get().skip_last_updated = True
@@ -216,7 +219,7 @@ class ThreadController(BaseController, FeedController, 
metaclass=h.ProxiedAttrMe
 thread=self.thread,
 page=int(page),
 count=int(count),
-limit=int(limit),
+limit=int(limit), h1_text=h1_text,
 show_moderate=kw.get('show_moderate'))
 
 def error_handler(self, *args, **kwargs):



(allura) branch db/8528 created (now e0ce8c2ba)

2023-11-21 Thread brondsem
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a change to branch db/8528
in repository https://gitbox.apache.org/repos/asf/allura.git


  at e0ce8c2ba [#8528] pass allura_command to allura.command_init entry 
point functions; document it

This branch includes the following new commits:

 new e0ce8c2ba [#8528] pass allura_command to allura.command_init entry 
point functions; document it

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.




(allura) 01/01: [#8528] pass allura_command to allura.command_init entry point functions; document it

2023-11-21 Thread brondsem
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a commit to branch db/8528
in repository https://gitbox.apache.org/repos/asf/allura.git

commit e0ce8c2ba87cb81ae389c34d959a3c09be33ce51
Author: Dave Brondsema 
AuthorDate: Tue Nov 21 09:51:16 2023 -0500

[#8528] pass allura_command to allura.command_init entry point functions; 
document it
---
 Allura/allura/command/base.py | 3 +++
 Allura/docs/development/extending.rst | 5 +++--
 2 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/Allura/allura/command/base.py b/Allura/allura/command/base.py
index efa3add20..65b7c758e 100644
--- a/Allura/allura/command/base.py
+++ b/Allura/allura/command/base.py
@@ -112,7 +112,10 @@ class Command(command.Command, 
metaclass=MetaParserDocstring):
 # Probably being called from another script (websetup, perhaps?)
 log = logging.getLogger('allura.command')
 conf = tg.config
+
 self.tools = list(tg.app_globals.entry_points['tool'].values())
+
+conf['allura_command'] = self
 for ep in h.iter_entry_points('allura.command_init'):
 log.info('Running command_init for %s', ep.name)
 ep.load()(conf)
diff --git a/Allura/docs/development/extending.rst 
b/Allura/docs/development/extending.rst
index 9129b462e..7a9484927 100644
--- a/Allura/docs/development/extending.rst
+++ b/Allura/docs/development/extending.rst
@@ -41,13 +41,14 @@ The available extension points for Allura are:
 * :class:`allura.lib.phone.PhoneService`
 * ``site_stats`` in the root API data.  Docs in 
:class:`allura.controllers.rest.RestController`
 * :mod:`allura.lib.package_path_loader` (for overriding templates)
-* ``[allura.timers]`` functions which return a list or single 
:class:`timermiddleware.Timer` which will be included in stats.log timings
+* ``[allura.timers]`` entry-point functions which return a list or single 
:class:`timermiddleware.Timer` which will be included in stats.log timings
 * :mod:`allura.ext.user_profile.user_main`
 * :mod:`allura.ext.personal_dashboard.dashboard_main`
-* ``[allura.middleware]`` classes, which are standard WSGI middleware.  They 
will receive the ``app`` instance and a ``config`` dict as constructor 
parameters.
+* ``[allura.middleware]`` entry-point classes, which are standard WSGI 
middleware.  They will receive the ``app`` instance and a ``config`` dict as 
constructor parameters.
   The middleware will be used for all requests.  By default the middleware 
wraps the base app directly and other middleware wrap around it.
   If your middleware needs to wrap around the other Allura middleware (except 
error handling), set ``when = 'outer'`` on your middleware.
 * :class:`allura.webhooks.WebhookSender`
+* ``[allura.command_init]`` entry-point functions which will be run before all 
commands like ``ensure_index``, ``taskd`` etc.  Receives a ``config`` dict with 
full config plus a ``allura_command`` key which references the current 
command's class.
 
 A listing of available 3rd-party extensions is at 
https://forge-allura.apache.org/p/allura/wiki/Extensions/
 



(allura) branch db/8526 updated (31caa73c4 -> a25057da8)

2023-11-17 Thread brondsem
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a change to branch db/8526
in repository https://gitbox.apache.org/repos/asf/allura.git


 discard 31caa73c4 [#8526] use new session cookie implementation
 new a25057da8 [#8526] use new session cookie implementation

This update added new revisions after undoing existing revisions.
That is to say, some revisions that were in the old version of the
branch are not in the new version.  This situation occurs
when a user --force pushes a change and generates a repository
containing something like this:

 * -- * -- B -- O -- O -- O   (31caa73c4)
\
 N -- N -- N   refs/heads/db/8526 (a25057da8)

You should already have received notification emails for all of the O
revisions, and so the following emails describe only the N revisions
from the common base, B.

Any revisions marked "omit" are not gone; other references still
refer to them.  Any revisions marked "discard" are gone forever.

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 Allura/allura/config/middleware.py | 14 +++---
 requirements.txt   |  2 +-
 2 files changed, 12 insertions(+), 4 deletions(-)



(allura) 01/01: [#8526] use new session cookie implementation

2023-11-17 Thread brondsem
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a commit to branch db/8526
in repository https://gitbox.apache.org/repos/asf/allura.git

commit a25057da8ef8736f7b44891000245ac0f83d1fbe
Author: Dave Brondsema 
AuthorDate: Wed Nov 15 15:50:58 2023 -0500

[#8526] use new session cookie implementation
---
 Allura/allura/config/middleware.py   | 13 -
 Allura/allura/lib/decorators.py  |  2 +-
 Allura/development.ini   |  6 +++---
 Allura/docs/getting_started/installation.rst |  9 +++--
 Allura/production-docker-example.ini |  7 ---
 requirements.in  |  3 ++-
 requirements.txt | 12 ++--
 7 files changed, 35 insertions(+), 17 deletions(-)

diff --git a/Allura/allura/config/middleware.py 
b/Allura/allura/config/middleware.py
index c7503f17a..f8378b1fe 100644
--- a/Allura/allura/config/middleware.py
+++ b/Allura/allura/config/middleware.py
@@ -21,6 +21,9 @@ import ast
 import importlib
 import mimetypes
 import pickle
+import re
+import warnings
+
 import six
 import tg
 import pkg_resources
@@ -37,6 +40,7 @@ import ew
 import formencode
 import ming
 from ming.odm.middleware import MingMiddleware
+from beaker_session_jwt import JWTCookieSession
 
 # Must apply patches before other Allura imports to ensure all the patches are 
effective.
 # This file gets imported from paste/deploy/loadwsgi.py pretty early in the 
app execution
@@ -135,7 +139,14 @@ def _make_core_app(root, global_conf: dict, **app_conf):
 # broswer permissions policy
 app = SetHeadersMiddleware(app, config)
 # Required for sessions
-app = SessionMiddleware(app, config, 
data_serializer=BeakerPickleSerializerWithLatin1())
+with warnings.catch_warnings():
+# the session_class= arg triggers this warning but is the only way it 
works, so suppress warning
+warnings.filterwarnings('ignore',
+re.escape('Session options should start with 
session. instead of session_.'),
+DeprecationWarning)
+app = SessionMiddleware(app, config,
+
original_format_data_serializer=BeakerPickleSerializerWithLatin1(),
+session_class=JWTCookieSession)
 # Handle "Remember me" functionality
 app = RememberLoginMiddleware(app, config)
 # Redirect 401 to the login page
diff --git a/Allura/allura/lib/decorators.py b/Allura/allura/lib/decorators.py
index c889ea799..eaf8016f8 100644
--- a/Allura/allura/lib/decorators.py
+++ b/Allura/allura/lib/decorators.py
@@ -245,4 +245,4 @@ def memorable_forget():
 forget(None, ex)
 raise ex
 
-return _inner
\ No newline at end of file
+return _inner
diff --git a/Allura/development.ini b/Allura/development.ini
index 0f93fcc41..4cad5509a 100644
--- a/Allura/development.ini
+++ b/Allura/development.ini
@@ -107,13 +107,13 @@ jinja_cache_size = -1
 
 ; Docs at 
http://beaker.readthedocs.org/en/latest/configuration.html#session-options
 ; and 
http://beaker.readthedocs.org/en/latest/modules/session.html#beaker.session.CookieSession
+; and https://github.com/brondsem/beaker-session-jwt#additional-config-options
 session.key = allura
-session.type = cookie
 session.httponly = true
 ; set this to true if you use HTTPS
 session.secure = false
-; CHANGE THIS VALUE FOR YOUR SITE
-session.validate_key = 714bfe3612c42390726f
+; CHANGE THIS VALUE FOR YOUR SITE.  Can be a comma-separated list to allow for 
key rotation
+session.jwt_secret_keys = 
330c2e698fcadfe46524b57223656404a47a9d80d76f8afb4cae34657247a1ea
 
 ;
 ; Settings for global navigation
diff --git a/Allura/docs/getting_started/installation.rst 
b/Allura/docs/getting_started/installation.rst
index 035c3f5ba..fddfa16f2 100644
--- a/Allura/docs/getting_started/installation.rst
+++ b/Allura/docs/getting_started/installation.rst
@@ -246,20 +246,17 @@ Change `[handler_console]` section, so that logs go to a 
file and will include b
 
 Add write permissions to the :file:`/path/to/allura.log` for the user you use 
to run allura proccess.
 
-Change "secrets".
+Change the secret key used for signing session cookies.
 
 .. code-block:: ini
 
-beaker.session.secret = 
-beaker.session.validate_key = 
-
-The first one is used for simple cookies, the latter is used for encrypted 
cookies.
+beaker.session.jwt_secret_keys = 
 
 You can use the following command to generate a good key:
 
 .. code-block:: bash
 
-~$ python -c 'import secrets; print(secrets.token_hex(20));'
+~$ python -c 'import secrets; print(secrets.token_hex());'
 
 Production-quality web server
 ^
diff --git a/Allura/production-docker-example.ini 
b/Allura/production-docker-example.ini
index 55e5142bd..6ee0ddcee 100644
--- a/Allura/production-docker-example.ini
+++ b/Allura/production-docker-exampl

(allura) 01/01: [#8526] use new session cookie implementation

2023-11-16 Thread brondsem
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a commit to branch db/8526
in repository https://gitbox.apache.org/repos/asf/allura.git

commit 31caa73c4d7b8bb1acd855b14d5da02515d0bbde
Author: Dave Brondsema 
AuthorDate: Wed Nov 15 15:50:58 2023 -0500

[#8526] use new session cookie implementation
---
 Allura/allura/config/middleware.py   |  5 -
 Allura/allura/lib/decorators.py  |  2 +-
 Allura/development.ini   |  6 +++---
 Allura/docs/getting_started/installation.rst |  9 +++--
 Allura/production-docker-example.ini |  7 ---
 requirements.in  |  3 ++-
 requirements.txt | 12 ++--
 7 files changed, 27 insertions(+), 17 deletions(-)

diff --git a/Allura/allura/config/middleware.py 
b/Allura/allura/config/middleware.py
index c7503f17a..c926292c4 100644
--- a/Allura/allura/config/middleware.py
+++ b/Allura/allura/config/middleware.py
@@ -37,6 +37,7 @@ import ew
 import formencode
 import ming
 from ming.odm.middleware import MingMiddleware
+from beaker_session_jwt import JWTCookieSession
 
 # Must apply patches before other Allura imports to ensure all the patches are 
effective.
 # This file gets imported from paste/deploy/loadwsgi.py pretty early in the 
app execution
@@ -135,7 +136,9 @@ def _make_core_app(root, global_conf: dict, **app_conf):
 # broswer permissions policy
 app = SetHeadersMiddleware(app, config)
 # Required for sessions
-app = SessionMiddleware(app, config, 
data_serializer=BeakerPickleSerializerWithLatin1())
+app = SessionMiddleware(app, config,
+
original_format_data_serializer=BeakerPickleSerializerWithLatin1(),
+session_class=JWTCookieSession)
 # Handle "Remember me" functionality
 app = RememberLoginMiddleware(app, config)
 # Redirect 401 to the login page
diff --git a/Allura/allura/lib/decorators.py b/Allura/allura/lib/decorators.py
index c889ea799..eaf8016f8 100644
--- a/Allura/allura/lib/decorators.py
+++ b/Allura/allura/lib/decorators.py
@@ -245,4 +245,4 @@ def memorable_forget():
 forget(None, ex)
 raise ex
 
-return _inner
\ No newline at end of file
+return _inner
diff --git a/Allura/development.ini b/Allura/development.ini
index 0f93fcc41..4cad5509a 100644
--- a/Allura/development.ini
+++ b/Allura/development.ini
@@ -107,13 +107,13 @@ jinja_cache_size = -1
 
 ; Docs at 
http://beaker.readthedocs.org/en/latest/configuration.html#session-options
 ; and 
http://beaker.readthedocs.org/en/latest/modules/session.html#beaker.session.CookieSession
+; and https://github.com/brondsem/beaker-session-jwt#additional-config-options
 session.key = allura
-session.type = cookie
 session.httponly = true
 ; set this to true if you use HTTPS
 session.secure = false
-; CHANGE THIS VALUE FOR YOUR SITE
-session.validate_key = 714bfe3612c42390726f
+; CHANGE THIS VALUE FOR YOUR SITE.  Can be a comma-separated list to allow for 
key rotation
+session.jwt_secret_keys = 
330c2e698fcadfe46524b57223656404a47a9d80d76f8afb4cae34657247a1ea
 
 ;
 ; Settings for global navigation
diff --git a/Allura/docs/getting_started/installation.rst 
b/Allura/docs/getting_started/installation.rst
index 035c3f5ba..fddfa16f2 100644
--- a/Allura/docs/getting_started/installation.rst
+++ b/Allura/docs/getting_started/installation.rst
@@ -246,20 +246,17 @@ Change `[handler_console]` section, so that logs go to a 
file and will include b
 
 Add write permissions to the :file:`/path/to/allura.log` for the user you use 
to run allura proccess.
 
-Change "secrets".
+Change the secret key used for signing session cookies.
 
 .. code-block:: ini
 
-beaker.session.secret = 
-beaker.session.validate_key = 
-
-The first one is used for simple cookies, the latter is used for encrypted 
cookies.
+beaker.session.jwt_secret_keys = 
 
 You can use the following command to generate a good key:
 
 .. code-block:: bash
 
-~$ python -c 'import secrets; print(secrets.token_hex(20));'
+~$ python -c 'import secrets; print(secrets.token_hex());'
 
 Production-quality web server
 ^
diff --git a/Allura/production-docker-example.ini 
b/Allura/production-docker-example.ini
index 55e5142bd..6ee0ddcee 100644
--- a/Allura/production-docker-example.ini
+++ b/Allura/production-docker-example.ini
@@ -24,7 +24,8 @@
 ; Also change:
 ;  site_name
 ;  smtp_server
-;  session.validate_key
+;  session.jwt_secret_keys
+;  session.secure
 ;
 ; This file inherits settings from docker-dev.ini and development.ini
 ; You are free to make additional changes/additions to this file for other 
settings
@@ -61,7 +62,7 @@ smtp_tls = true
 forgemail.domain = .myexamplesite.com
 forgemail.return_path = nore...@myexamplesite.com
 
-session.validate_key = 712de83fa0cb0d0f0a383
+session.jwt_secret_keys = d2de2cf67814d69691f7

(allura) branch db/8526 created (now 31caa73c4)

2023-11-16 Thread brondsem
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a change to branch db/8526
in repository https://gitbox.apache.org/repos/asf/allura.git


  at 31caa73c4 [#8526] use new session cookie implementation

This branch includes the following new commits:

 new 31caa73c4 [#8526] use new session cookie implementation

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.




(allura) branch master updated: fully delete history snapshots when deleting artifacts (incl remove from solr)

2023-11-16 Thread brondsem
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/allura.git


The following commit(s) were added to refs/heads/master by this push:
 new 3974e65f6 fully delete history snapshots when deleting artifacts (incl 
remove from solr)
3974e65f6 is described below

commit 3974e65f6cd426785ac84ae7fa9af1043ed71499
Author: Dillon Walls 
AuthorDate: Fri Nov 10 16:11:23 2023 +

fully delete history snapshots when deleting artifacts (incl remove from 
solr)
---
 Allura/allura/model/artifact.py|  5 +++--
 Allura/allura/tests/model/test_artifact.py | 23 +--
 2 files changed, 24 insertions(+), 4 deletions(-)

diff --git a/Allura/allura/model/artifact.py b/Allura/allura/model/artifact.py
index 3527b1d48..efb345739 100644
--- a/Allura/allura/model/artifact.py
+++ b/Allura/allura/model/artifact.py
@@ -705,9 +705,10 @@ class VersionedArtifact(Artifact):
 
 def delete(self):
 # remove history so that the snapshots aren't left orphaned
-super().delete()
 HC = self.__mongometa__.history_class
-HC.query.remove(dict(artifact_id=self._id))
+for version in HC.query.find(dict(artifact_id=self._id)):
+version.delete()
+super().delete()
 
 @classmethod
 def is_limit_exceeded(cls, *args, **kwargs):
diff --git a/Allura/allura/tests/model/test_artifact.py 
b/Allura/allura/tests/model/test_artifact.py
index d62c01cd5..aed8add97 100644
--- a/Allura/allura/tests/model/test_artifact.py
+++ b/Allura/allura/tests/model/test_artifact.py
@@ -21,8 +21,8 @@ Model tests for artifact
 import re
 from datetime import datetime
 
-from tg import tmpl_context as c
-from mock import patch
+from tg import tmpl_context as c, app_globals as g
+from mock import patch, Mock
 import pytest
 from ming.odm.odmsession import ThreadLocalODMSession
 from ming.odm import Mapper
@@ -145,6 +145,7 @@ class TestArtifact:
 assert re.match(r'%s.wiki@test.p.localhost' %
 str(p._id), p.message_id())
 
+@patch('allura.tasks.mail_tasks.sendmail', Mock())
 def test_versioning(self):
 pg = WM.Page(title='TestPage3')
 with patch('allura.model.artifact.request', Request.blank('/', 
remote_addr='1.1.1.1')):
@@ -171,6 +172,24 @@ class TestArtifact:
 assert ss.text != pg.text
 assert pg.history().count() == 3
 
+_id = pg._id
+M.MonQTask.run_ready()
+assert g.solr.search('id:' + pg.index_id()).hits == 1
+ph = WM.PageHistory.query.find({'artifact_id': _id, 'version': 
2}).first()
+assert ph
+ph_index = ph.index_id()
+solr_hist = g.solr.search('id:' + ph_index)
+if not solr_hist:  # sometimes history doesn't get added to solr
+g.solr.add([ph.solarize()])
+g.solr.commit()
+assert g.solr.search('id:' + ph_index).hits == 1
+pg.delete()
+ThreadLocalODMSession.flush_all()
+M.MonQTask.run_ready()
+WM.PageHistory.query.find({'artifact_id': _id}).count() == 0
+# history should be deleted from solr
+assert g.solr.search('id:' + ph_index).hits == 0
+
 def test_messages_unknown_lookup(self):
 from bson import ObjectId
 m = Checkmessage()



svn commit: r65075 - in /release/allura: allura-1.15.0.tar.gz allura-1.15.0.tar.gz.asc allura-1.15.0.tar.gz.sha512

2023-11-06 Thread brondsem
Author: brondsem
Date: Mon Nov  6 22:37:11 2023
New Revision: 65075

Log:
Remove allura 1.15.0 release

Removed:
release/allura/allura-1.15.0.tar.gz
release/allura/allura-1.15.0.tar.gz.asc
release/allura/allura-1.15.0.tar.gz.sha512



(allura-site) branch asf-site updated: publish 1.16 with security notice

2023-11-06 Thread brondsem
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a commit to branch asf-site
in repository https://gitbox.apache.org/repos/asf/allura-site.git


The following commit(s) were added to refs/heads/asf-site by this push:
 new 4a31a3e  publish 1.16 with security notice
4a31a3e is described below

commit 4a31a3e55af55e8cb2647b1620a9ac939a298b7c
Author: Dave Brondsema 
AuthorDate: Mon Nov 6 17:26:55 2023 -0500

publish 1.16 with security notice
---
 _src/content/2023-allura-1.16.0.md |  56 +++
 _src/pelicanconf.py|   6 +-
 download.html  |   8 +-
 feeds/all.atom.xml |  30 +-
 feeds/tag.release.atom.xml |  30 +-
 index.html |   8 +-
 news.html  |  11 ++
 download.html => posts/2023-allura-1.16.0.html | 133 ++---
 tag/release.html   |  11 ++
 9 files changed, 197 insertions(+), 96 deletions(-)

diff --git a/_src/content/2023-allura-1.16.0.md 
b/_src/content/2023-allura-1.16.0.md
new file mode 100644
index 000..edfa6b7
--- /dev/null
+++ b/_src/content/2023-allura-1.16.0.md
@@ -0,0 +1,56 @@
+Title: Apache Allura 1.16.0 released with critical security fix
+Date: 2023-11-06
+Tags: release
+Slug: allura-1.16.0
+Summary: Version 1.16.0 of Allura released with critical security fix
+
+ What's New?
+
+Apache Allura 1.16.0 has been released.  It has a critical security fix and 
also drops Python 3.7 support.
+
+For full details of all the changes and fixes, see the [CHANGES 
file](https://forge-allura.apache.org/p/allura/git/ci/master/tree/CHANGES). 
+
+ Critical Security Fix
+
+CVE-2023-46851 sensitive information exposure via import 
+
+Severity: Critical
+Versions Affected: 1.0.1 through 1.15.0
+
+**Description:**
+Allura Discussion and Allura Forum importing does not restrict URL values 
specified in attachments. Project administrators can run these imports, which 
could cause Allura to read local files and expose them.  Exposing internal 
files then can lead to other exploits, like session hijacking, or remote code 
execution.
+
+**Mitigation:**
+Users of Allura should upgrade to Allura 1.16.0 immediately.
+
+If you are unable to upgrade, set this in your .ini config file:
+
+```
+disable_entry_points.allura.importers = forge-tracker, forge-discussion
+```
+
+That same .ini setting is also recommend for users who want maximum security 
on their Allura instance and don't need those importers available.
+
+**Credit:**
+This issue was discovered by Stefan Schiller (Sonar)
+
+ Python 3.8 through 3.11 supported
+
+This release drops support for Python 3.7 and supports Python 3.8 through 
Python 3.11
+
+ Upgrade Instructions
+
+To install updated dependencies, run: `pip install -r requirements.txt 
--no-deps --upgrade --upgrade-strategy=only-if-needed`
+
+Run: `paster ensure_index development.ini` in Allura dir
+
+If switching to a new version of Python, you will need to make a completely 
new python virtual environment,
+and run `pip install ...` in it, and then use it to run Allura.
+
+If using docker, rebuild the allura image and restart containers.
+
+Feel free to ask any questions on the [dev mailing 
list](https://lists.apache.org/list.html?d...@allura.apache.org).
+
+ Get 1.16.0
+
+[Download Allura](//allura.apache.org/download.html) and [install 
it](https://forge-allura.apache.org/docs/getting_started/installation.html) 
today.
diff --git a/_src/pelicanconf.py b/_src/pelicanconf.py
index a5be8f9..c7265bb 100644
--- a/_src/pelicanconf.py
+++ b/_src/pelicanconf.py
@@ -45,9 +45,9 @@ TAG_FEED_ATOM = 'feeds/tag.{slug}.atom.xml'
 
 CURRENT_YEAR = dt.date.today().year
 
-RELEASE_VERSION = '1.15.0'
-RELEASE_DATE = 'Sep 2023'
-RELEASE_NEWS = 'posts/2023-allura-1.15.0.html'
+RELEASE_VERSION = '1.16.0'
+RELEASE_DATE = 'Nov 2023'
+RELEASE_NEWS = 'posts/2023-allura-1.16.0.html'
 DIST_URL = 'https://downloads.apache.org/allura/'
 
 FORGE_ALLURA_URL = 'https://forge-allura.apache.org/'
diff --git a/download.html b/download.html
index d9e681a..91dabd8 100644
--- a/download.html
+++ b/download.html
@@ -54,15 +54,15 @@
 
   
 
-https://www.apache.org/dyn/closer.cgi/allura/allura-1.15.0.tar.gz;>Download
 Allura v1.15.0.  This is the latest release of Apache Allura, released Sep 
2023.
-  Read what's new.
+https://www.apache.org/dyn/closer.cgi/allura/allura-1.16.0.tar.gz;>Download
 Allura v1.16.0.  This is the latest release of Apache Allura, released Nov 
2023.
+  Read what's new.
 
 
 Verify the download:
 
 
-https://downloads.apache.org/allura/allura-1.15.0.tar.gz.sha512;>SHA-512
 checksum
-PGP https://downloads.apache.org/allura/allura-1.15.0.tar.gz.asc;>sig

(allura) branch master updated: update changelog for 1.16.0

2023-11-06 Thread brondsem
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/allura.git


The following commit(s) were added to refs/heads/master by this push:
 new b35f2cfe7 update changelog for 1.16.0
b35f2cfe7 is described below

commit b35f2cfe7a3811ff292725b89416e495f96c2930
Author: Dave Brondsema 
AuthorDate: Mon Nov 6 17:27:10 2023 -0500

update changelog for 1.16.0
---
 CHANGES | 5 +
 1 file changed, 5 insertions(+)

diff --git a/CHANGES b/CHANGES
index da6fb57f5..9aa253606 100644
--- a/CHANGES
+++ b/CHANGES
@@ -10,6 +10,9 @@ Upgrade Instructions
 
   If using docker, rebuild the allura image and restart containers.
 
+Critical Security Fix
+ * [#8525] CVE-2023-46851 import mechanisms allow local file access
+
 Major Changes
  * [#8519] Drop support for Python 3.7. Python 3.8 through Python 3.11 are 
officially supported.
 
@@ -26,6 +29,8 @@ For Developers
  * minor improvements to release script
  * update build status icon on readme
  * ignore warnings from inside other pkgs, fix a few warnings
+ * [#8524] update node version
+ * [#8523] github api improvements
 
 
 Version 1.15.0  (September 2023)



(allura) tag rel/1.16.0 created (now 705f6d38c)

2023-11-06 Thread brondsem
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a change to tag rel/1.16.0
in repository https://gitbox.apache.org/repos/asf/allura.git


  at 705f6d38c (commit)
No new revisions were added by this update.



svn commit: r65071 - /dev/allura/allura-1.16.0.tar.gz /dev/allura/allura-1.16.0.tar.gz.asc /dev/allura/allura-1.16.0.tar.gz.sha512 /release/allura/allura-1.16.0.tar.gz /release/allura/allura-1.16.0.ta

2023-11-06 Thread brondsem
Author: brondsem
Date: Mon Nov  6 20:15:44 2023
New Revision: 65071

Log:
Move allura 1.16.0 from dev to release

Added:
release/allura/allura-1.16.0.tar.gz
  - copied unchanged from r65070, dev/allura/allura-1.16.0.tar.gz
release/allura/allura-1.16.0.tar.gz.asc
  - copied unchanged from r65070, dev/allura/allura-1.16.0.tar.gz.asc
release/allura/allura-1.16.0.tar.gz.sha512
  - copied unchanged from r65070, dev/allura/allura-1.16.0.tar.gz.sha512
Removed:
dev/allura/allura-1.16.0.tar.gz
dev/allura/allura-1.16.0.tar.gz.asc
dev/allura/allura-1.16.0.tar.gz.sha512



(allura) branch master updated: CHANGES updated for ASF release 1.16.0

2023-11-03 Thread brondsem
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/allura.git


The following commit(s) were added to refs/heads/master by this push:
 new 705f6d38c CHANGES updated for ASF release 1.16.0
705f6d38c is described below

commit 705f6d38c47347113eb7b7032aa4932f4ef645bc
Author: Dave Brondsema 
AuthorDate: Fri Nov 3 14:32:01 2023 -0400

CHANGES updated for ASF release 1.16.0
---
 CHANGES | 28 ++--
 1 file changed, 26 insertions(+), 2 deletions(-)

diff --git a/CHANGES b/CHANGES
index 293acefa0..da6fb57f5 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,7 +1,31 @@
-NEXT RELEASE (future)
+Version 1.16.0  (November 2023)
+
+Upgrade Instructions
+
+  To install updated dependencies, run:
+pip install -r requirements.txt --no-deps --upgrade 
--upgrade-strategy=only-if-needed
+
+  If switching to a new version of Python, you will need to make a completely 
new python virtual environment,
+  and run `pip install ...` in it, and then use it to run Allura.
+
+  If using docker, rebuild the allura image and restart containers.
+
+Major Changes
+ * [#8519] Drop support for Python 3.7. Python 3.8 through Python 3.11 are 
officially supported.
+
+SEO
+ * [#8521] Do not index empty ticket pages
 
 General
- * [#8519] Drop support for Python 3.7. Python 3.8 or Python 3.11 are 
officially supported.
+ * package upgrades
+ * specify formats supported for screenshots (BMP or GIF could work too, but 
not recommended)
+ * replace deprecated "docker-compose" cmd with "docker compose"
+ * fix solr 413 request too big for big batches
+
+For Developers
+ * minor improvements to release script
+ * update build status icon on readme
+ * ignore warnings from inside other pkgs, fix a few warnings
 
 
 Version 1.15.0  (September 2023)



svn commit: r65009 - in /dev/allura: allura-1.16.0.tar.gz allura-1.16.0.tar.gz.asc allura-1.16.0.tar.gz.sha512

2023-11-03 Thread brondsem
Author: brondsem
Date: Fri Nov  3 18:38:52 2023
New Revision: 65009

Log:
allura 1.16

Added:
dev/allura/allura-1.16.0.tar.gz   (with props)
dev/allura/allura-1.16.0.tar.gz.asc
dev/allura/allura-1.16.0.tar.gz.sha512

Added: dev/allura/allura-1.16.0.tar.gz
==
Binary file - no diff available.

Propchange: dev/allura/allura-1.16.0.tar.gz
--
svn:mime-type = application/octet-stream

Added: dev/allura/allura-1.16.0.tar.gz.asc
==
--- dev/allura/allura-1.16.0.tar.gz.asc (added)
+++ dev/allura/allura-1.16.0.tar.gz.asc Fri Nov  3 18:38:52 2023
@@ -0,0 +1,17 @@
+-BEGIN PGP SIGNATURE-
+Comment: GPGTools - http://gpgtools.org
+
+iQIzBAABCAAdFiEE0YkrXHcuZD67lzl+ZzfqVWLvu3MFAmVFPLUACgkQZzfqVWLv
+u3OV0hAAioBQWtFQQY8wmkEKvWejLCo32O6UjMWBVCY61Ab181aaDE/wuVbowBNf
+nJ2GmpS1tt20am8E3jIAkofVm34oxOpV1ilWYQvrdrm8sd2PsngOju792DA2BNjm
+nvUXltcJeSTs/647KMCpkPYShrR0YZlQil/cQ2OZHEjZg2Oykit9rcNSeFIjGzmi
+nTbgh90nv+CYYno5k90aOmY+3WIUheb2tJT7jebvr+Q1zkOHwlP8D32V2BKAAYpY
+yDCa1tjf2e5rACamT/4krkwxcwp01OuopgwKlEbR0oyW2ETadv0h3S+UkoMsYE1W
+QK8BI1vfrN/oizjVvxaSzgoMkk86U8O0dED7Lu3rbbDJuUfsmRzNcxRXwSkSnv//
+oi+TDpkVmpCWniZhwSFonPiXyY8jv4X2e8CJwHqWMpAZTPbW4YZy5hwytY9GH6B/
+o/h22bWIfHLpqkkazd5vnlPRTqb91C+iDRVSTX5yVeMtqzXfo00YZ/6SD9Pzi3GP
+DR8iYrlP9J6GeZzZXeMfRi2sEu4YzA+UW4EI3TH2IMnUwBtNeD/N/6hPwxMTwux/
+bbscE/ooTNhnyGDRGQG9RtEgkhFDwHGUV96mvxxjBQfNeYp0wop1tu3UaMEXnKjB
+IKpSnRvvreJh7Nx1OjXhInOV17P7yv+4VJWIYDyim3TlZayCxeU=
+=EnHy
+-END PGP SIGNATURE-

Added: dev/allura/allura-1.16.0.tar.gz.sha512
==
--- dev/allura/allura-1.16.0.tar.gz.sha512 (added)
+++ dev/allura/allura-1.16.0.tar.gz.sha512 Fri Nov  3 18:38:52 2023
@@ -0,0 +1 @@
+1ca0ea9752db7033030d50f47c931929fb5b053a0e82ab7a7fe184068a843affc4754e7353d8b70d7021568ddc887d68f312c7c7342779417dbfba2119b08ae6
  allura-1.16.0.tar.gz




(allura) branch master updated: [#8525] urlopen cleanup

2023-11-03 Thread brondsem
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/allura.git


The following commit(s) were added to refs/heads/master by this push:
 new a484f5056 [#8525] urlopen cleanup
a484f5056 is described below

commit a484f5056e02b452eb09255b6d887cfc9715f2fb
Author: Dave Brondsema 
AuthorDate: Fri Nov 3 10:42:49 2023 -0400

[#8525] urlopen cleanup
---
 Allura/allura/lib/helpers.py | 44 ++--
 Allura/allura/tests/test_helpers.py  | 22 ++--
 Allura/development.ini   |  3 ++
 ForgeImporters/forgeimporters/base.py| 16 -
 ForgeImporters/forgeimporters/tests/test_base.py | 34 --
 5 files changed, 86 insertions(+), 33 deletions(-)

diff --git a/Allura/allura/lib/helpers.py b/Allura/allura/lib/helpers.py
index 9e9f8b294..c822d9e00 100644
--- a/Allura/allura/lib/helpers.py
+++ b/Allura/allura/lib/helpers.py
@@ -14,6 +14,8 @@
 #   KIND, either express or implied.  See the License for the
 #   specific language governing permissions and limitations
 #   under the License.
+from __future__ import annotations
+
 import base64
 import sys
 import os
@@ -21,9 +23,9 @@ import os.path
 import difflib
 import jinja2
 
-import six.moves.urllib.request
-import six.moves.urllib.parse
-import six.moves.urllib.error
+import urllib.request
+import urllib.parse
+import urllib.error
 import re
 import unicodedata
 import json
@@ -65,6 +67,7 @@ from webob.exc import HTTPUnauthorized
 
 from allura.lib import exceptions as exc
 from allura.lib import utils
+from allura.lib import validators
 import urllib.parse as urlparse
 from urllib.parse import urlencode
 import math
@@ -201,16 +204,16 @@ def monkeypatch(*objs):
 
 def urlquote(url, safe=b"/"):
 try:
-return six.moves.urllib.parse.quote(str(url), safe=safe)
+return urllib.parse.quote(str(url), safe=safe)
 except UnicodeEncodeError:
-return six.moves.urllib.parse.quote(url.encode('utf-8'), safe=safe)
+return urllib.parse.quote(url.encode('utf-8'), safe=safe)
 
 
 def urlquoteplus(url, safe=b""):
 try:
-return six.moves.urllib.parse.quote_plus(str(url), safe=safe)
+return urllib.parse.quote_plus(str(url), safe=safe)
 except UnicodeEncodeError:
-return six.moves.urllib.parse.quote_plus(url.encode('utf-8'), 
safe=safe)
+return urllib.parse.quote_plus(url.encode('utf-8'), safe=safe)
 
 
 def urlquote_path_only(url):
@@ -1027,7 +1030,18 @@ class exceptionless:
 return inner
 
 
-def urlopen(url, retries=3, codes=(408, 500, 502, 503, 504), timeout=None):
+class NoRedirectToInternal(urllib.request.HTTPRedirectHandler):
+def redirect_request(self, req: urllib.request.Request, fp, code, msg, 
headers, newurl: str):
+if not asbool(tg.config.get('urlopen_allow_internal_hostnames', 
'false')):
+validators.URLIsPrivate().to_python(newurl, None)
+return super().redirect_request(req, fp, code, msg, headers, newurl)
+
+
+opener = urllib.request.build_opener(NoRedirectToInternal)
+urllib.request.install_opener(opener)
+
+
+def urlopen(url: str | urllib.request.Request, retries=3, codes=(408, 500, 
502, 503, 504), timeout=None):
 """Open url, optionally retrying if an error is encountered.
 
 Socket and other IO errors will always be retried if retries > 0.
@@ -1037,12 +1051,22 @@ def urlopen(url, retries=3, codes=(408, 500, 502, 503, 
504), timeout=None):
 :param codes: HTTP error codes that should be retried.
 
 """
+if isinstance(url, urllib.request.Request):
+url_str =  url.full_url
+else:
+url_str = url
+if not url_str.startswith(('http://', 'https://')):
+raise ValueError(f'URL must be http(s), got {url_str}')
+if not asbool(tg.config.get('urlopen_allow_internal_hostnames', 'false')):
+# will raise error if hostname resolves to private address space:
+validators.URLIsPrivate().to_python(url_str, None)
+
 attempts = 0
 while True:
 try:
-return six.moves.urllib.request.urlopen(url, timeout=timeout)
+return urllib.request.urlopen(url, timeout=timeout)
 except OSError as e:
-no_retry = isinstance(e, six.moves.urllib.error.HTTPError) and 
e.code not in codes
+no_retry = isinstance(e, urllib.error.HTTPError) and e.code not in 
codes
 if attempts < retries and not no_retry:
 attempts += 1
 continue
diff --git a/Allura/allura/tests/test_helpers.py 
b/Allura/allura/tests/test_helpers.py
index 9db093a81..9a12062bd 100644
--- a/Allura/allura/tests/test_helpers.py
+++ b/Allura/allura/tests/test_helpers.py
@@ -454,13 +454,13 @@ back\\\-slash escaped
 
 class TestUrlOpen(TestCase):
 
-@patch('six.moves.urll

[allura] branch master updated: upgrade werkzeug

2023-10-26 Thread brondsem
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/allura.git


The following commit(s) were added to refs/heads/master by this push:
 new 3cef5a5d7 upgrade werkzeug
3cef5a5d7 is described below

commit 3cef5a5d7cd1880dfc9b46fc47d2ae8e4a8fd0c9
Author: Dave Brondsema 
AuthorDate: Thu Oct 26 14:25:39 2023 +

upgrade werkzeug
---
 requirements.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/requirements.txt b/requirements.txt
index 7fde259af..a2ae42e31 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -260,7 +260,7 @@ webob==1.8.7
 #   webtest
 webtest==3.0.0
 # via -r requirements.in
-werkzeug==3.0.0
+werkzeug==3.0.1
 # via -r requirements.in
 wrapt==1.15.0
 # via -r requirements.in



  1   2   3   4   5   6   7   8   9   10   >