refactor: store hide_descendants within user permissions data

Signed-off-by: Akhil Narang <me@akhilnarang.dev>
This commit is contained in:
Akhil Narang 2025-06-16 16:14:25 +05:30
parent 6d8ebeb09f
commit 60dd0377e8
No known key found for this signature in database
GPG key ID: 9DCC61E211BF645F
2 changed files with 16 additions and 18 deletions

View file

@ -105,7 +105,7 @@ def get_user_permissions(user=None):
out = {}
def add_doc_to_perm(perm, doc_name, is_default):
def add_doc_to_perm(perm, doc_name, is_default, hide_descendants):
# group rules for each type
# for example if allow is "Customer", then build all allowed customers
# in a list
@ -114,7 +114,12 @@ def get_user_permissions(user=None):
out[perm.allow].append(
frappe._dict(
{"doc": doc_name, "applicable_for": perm.get("applicable_for"), "is_default": is_default}
{
"doc": doc_name,
"applicable_for": perm.get("applicable_for"),
"is_default": is_default,
"hide_descendants": hide_descendants,
}
)
)
@ -125,12 +130,12 @@ def get_user_permissions(user=None):
filters=dict(user=user),
):
meta = frappe.get_meta(perm.allow)
add_doc_to_perm(perm, perm.for_value, perm.is_default)
add_doc_to_perm(perm, perm.for_value, perm.is_default, perm.hide_descendants)
if meta.is_nested_set() and not perm.hide_descendants:
decendants = frappe.db.get_descendants(perm.allow, perm.for_value)
for doc in decendants:
add_doc_to_perm(perm, doc, False)
add_doc_to_perm(perm, doc, False, False)
out = frappe._dict(out)
frappe.cache.hset("user_permissions", user, out)

View file

@ -356,7 +356,8 @@ def has_user_permission(doc, user=None, debug=False, *, ptype=None):
# STEP 1: ---------------------
# check user permissions on self
if doctype in user_permissions:
allowed_docs = get_allowed_docs_for_doctype(user_permissions.get(doctype, []), doctype)
doctype_up = user_permissions.get(doctype, [])
allowed_docs = get_allowed_docs_for_doctype(doctype_up, doctype)
# if allowed_docs is empty it states that there is no applicable permission under the current doctype
@ -367,20 +368,12 @@ def has_user_permission(doc, user=None, debug=False, *, ptype=None):
if parent := doc.get(doc.nsm_parent_field):
from frappe.utils.nestedset import get_ancestors_of
doc_hide_descendants = {d.doc: d.hide_descendants for d in doctype_up}
for d in [parent, *get_ancestors_of(doctype, parent)]:
if d in allowed_docs:
try:
up = frappe.get_doc(
"User Permission",
{"allow": doctype, "for_value": d, "user": user},
fields=["hide_descendants"],
)
except frappe.DoesNotExistError:
frappe.clear_last_message()
continue
if not up.hide_descendants:
condition = False
break
if d in allowed_docs and not doc_hide_descendants[d]:
condition = False
break
else:
condition = str(docname) not in allowed_docs