Skip to content

Commit

Permalink
feat: allow wildcard for doctype in permission hooks (#25729) (#25892)
Browse files Browse the repository at this point in the history
* feat: allow wildcard for doctype in permission hooks

* fix: pass doctype to permission query

* fix: combine methods instead of alternate

* test: wildcard has_permssion hook

* test: wildcard has_permssion make note public

* fix: fetch list of hooks once

(cherry picked from commit 7e16e90)

Co-authored-by: Revant Nandgaonkar <revant.one@gmail.com>
  • Loading branch information
mergify[bot] and revant committed Apr 10, 2024
1 parent 4007d20 commit 7a4fa2f
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 3 deletions.
5 changes: 3 additions & 2 deletions frappe/model/db_query.py
Expand Up @@ -1028,10 +1028,11 @@ def add_user_permissions(self, user_permissions):

def get_permission_query_conditions(self):
conditions = []
condition_methods = frappe.get_hooks("permission_query_conditions", {}).get(self.doctype, [])
hooks = frappe.get_hooks("permission_query_conditions", {})
condition_methods = hooks.get(self.doctype, []) + hooks.get("*", [])
if condition_methods:
for method in condition_methods:
c = frappe.call(frappe.get_attr(method), self.user)
c = frappe.call(frappe.get_attr(method), self.user, doctype=self.doctype)
if c:
conditions.append(c)

Expand Down
3 changes: 2 additions & 1 deletion frappe/permissions.py
Expand Up @@ -433,7 +433,8 @@ def has_controller_permissions(doc, ptype, user=None, debug=False) -> bool:
if not user:
user = frappe.session.user

methods = frappe.get_hooks("has_permission").get(doc.doctype, [])
hooks = frappe.get_hooks("has_permission")
methods = hooks.get(doc.doctype, []) + hooks.get("*", [])

if not methods:
return True
Expand Down
16 changes: 16 additions & 0 deletions frappe/tests/test_hooks.py
Expand Up @@ -44,6 +44,14 @@ def test_has_permission(self):

hooks.has_permission["Address"] = address_has_permission_hook

wildcard_has_permission_hook = hooks.has_permission.get("*", [])
if isinstance(wildcard_has_permission_hook, str):
wildcard_has_permission_hook = [wildcard_has_permission_hook]

wildcard_has_permission_hook.append("frappe.tests.test_hooks.custom_has_permission")

hooks.has_permission["*"] = wildcard_has_permission_hook

# Clear cache
frappe.cache.delete_value("app_hooks")

Expand All @@ -53,12 +61,20 @@ def test_has_permission(self):
user.add_roles("System Manager")
address = frappe.new_doc("Address")

# Create Note
note = frappe.new_doc("Note")
note.public = 1

# Test!
self.assertTrue(frappe.has_permission("Address", doc=address, user=username))
self.assertTrue(frappe.has_permission("Note", doc=note, user=username))

address.flags.dont_touch_me = True
self.assertFalse(frappe.has_permission("Address", doc=address, user=username))

note.flags.dont_touch_me = True
self.assertFalse(frappe.has_permission("Note", doc=note, user=username))

def test_ignore_links_on_delete(self):
email_unsubscribe = frappe.get_doc(
{"doctype": "Email Unsubscribe", "email": "test@example.com", "global_unsubscribe": 1}
Expand Down

0 comments on commit 7a4fa2f

Please sign in to comment.