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:40 UTC
(allura) 02/07: [#8555] debugging option within has_access
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 <db...@slashdotmedia.com>
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)