You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@allura.apache.org by br...@apache.org on 2024/04/03 18:41:39 UTC
(allura) 01/07: [#8555] some specific checks for blocked users, when creating new forum threads
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 <db...@slashdotmedia.com>
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,
- parent_id=None,
- deleted=False))
+ # check app-level access to guarantee enforcement of Block Users. In addition to per-forum checks below
+ if has_access(c.app, 'post'):
+ forums = model.Forum.query.find(dict(app_config_id=c.app.config._id,
+ parent_id=None,
+ deleted=False))
+ else:
+ forums = []
c.new_topic = self.W.new_topic
my_forums = []
forum_name = h.really_unicode(unquote(forum_name)) if forum_name else None