From fe03ceb35e8d3702bddc8fc9ec39a327390d05b4 Mon Sep 17 00:00:00 2001 From: Ankush Menat Date: Fri, 13 Jun 2025 11:29:30 +0530 Subject: [PATCH] fix: don't apply strict user permission on local document (#32798) --- frappe/permissions.py | 20 ++++++++++++++------ frappe/tests/test_permissions.py | 4 ++++ 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/frappe/permissions.py b/frappe/permissions.py index 21761ba941..f720e9cc7e 100644 --- a/frappe/permissions.py +++ b/frappe/permissions.py @@ -236,7 +236,7 @@ def get_doc_permissions(doc, user=None, ptype=None, debug=False): "User is owner of document, so permissions are updated to: " + frappe.as_json(permissions) ) - if not has_user_permission(doc, user, debug=debug): + if not has_user_permission(doc, user, debug=debug, ptype=ptype): if is_user_owner(): # replace with owner permissions permissions = permissions.get("if_owner", {}) @@ -323,7 +323,7 @@ def get_user_permissions(user): return get_user_permissions(user) -def has_user_permission(doc, user=None, debug=False): +def has_user_permission(doc, user=None, debug=False, *, ptype=None): """Return True if User is allowed to view considering User Permissions.""" from frappe.core.doctype.user_permission.user_permission import get_user_permissions @@ -334,6 +334,9 @@ def has_user_permission(doc, user=None, debug=False): debug and _debug_log("User is not affected by any user permissions") return True + doctype = doc.get("doctype") + docname = doc.get("name") + # don't apply strict user permissions for single doctypes since they contain empty link fields apply_strict_user_permissions = ( False if doc.meta.issingle else frappe.get_system_settings("apply_strict_user_permissions") @@ -341,8 +344,14 @@ def has_user_permission(doc, user=None, debug=False): if apply_strict_user_permissions: debug and _debug_log("Strict user permissions will be applied") - doctype = doc.get("doctype") - docname = doc.get("name") + if ( + apply_strict_user_permissions + and doc.get("__islocal") + and ptype == "read" + and (not docname or (docname and not frappe.db.exists(doctype, docname, cache=True))) + ): + apply_strict_user_permissions = False + debug and _debug_log("Strict permissions will be skipped on local document") # STEP 1: --------------------- # check user permissions on self @@ -372,7 +381,7 @@ def has_user_permission(doc, user=None, debug=False): # # called for both parent and child records - meta = frappe.get_meta(d.get("doctype")) + meta = frappe.get_meta(d.doctype) # check all link fields for user permissions for field in meta.get_link_fields(): @@ -381,7 +390,6 @@ def has_user_permission(doc, user=None, debug=False): # empty value, do you still want to apply user permissions? if not d.get(field.fieldname) and not apply_strict_user_permissions: - # nah, not strict continue if field.options not in user_permissions: diff --git a/frappe/tests/test_permissions.py b/frappe/tests/test_permissions.py index a9ed74b552..7bbc17aaea 100644 --- a/frappe/tests/test_permissions.py +++ b/frappe/tests/test_permissions.py @@ -417,6 +417,10 @@ class TestPermissions(IntegrationTestCase): self.assertFalse(other_contact.has_permission("read")) self.assertTrue(len(frappe.get_list("Contact")), 1) + # This is a temporary WIP doc that user is using run_doc_method on + local_doc = frappe.copy_doc(other_contact) + self.assertTrue(local_doc.has_permission("read")) + frappe.set_user("Administrator") self.set_strict_user_permissions(0)