From 89b8d11f9cac32d3f32c648d2a02a371e03118b8 Mon Sep 17 00:00:00 2001 From: Anand Doshi Date: Tue, 29 Sep 2015 20:06:53 +0530 Subject: [PATCH] [fix] Apply permissions on address and contact based on permissions of Customer, Supplier --- erpnext/hooks.py | 10 ++++ erpnext/utilities/address_and_contact.py | 65 ++++++++++++++++++++++++ 2 files changed, 75 insertions(+) diff --git a/erpnext/hooks.py b/erpnext/hooks.py index 7d40d8537f..a747510464 100644 --- a/erpnext/hooks.py +++ b/erpnext/hooks.py @@ -93,6 +93,16 @@ has_website_permission = { "Issue": "erpnext.support.doctype.issue.issue.has_website_permission" } +permission_query_conditions = { + "Contact": "erpnext.utilities.address_and_contact.get_permission_query_conditions_for_contact", + "Address": "erpnext.utilities.address_and_contact.get_permission_query_conditions_for_address" +} + +has_permission = { + "Contact": "erpnext.utilities.address_and_contact.has_permission", + "Address": "erpnext.utilities.address_and_contact.has_permission" +} + dump_report_map = "erpnext.startup.report_data_map.data_map" before_tests = "erpnext.setup.utils.before_tests" diff --git a/erpnext/utilities/address_and_contact.py b/erpnext/utilities/address_and_contact.py index d386d67256..9341adfb41 100644 --- a/erpnext/utilities/address_and_contact.py +++ b/erpnext/utilities/address_and_contact.py @@ -17,3 +17,68 @@ def load_address_and_contact(doc, key): doc.get("__onload").contact_list = frappe.get_all("Contact", fields="*", filters={key: doc.name}, order_by="is_primary_contact desc, modified desc") + +def has_permission(doc, ptype, user): + links = get_permitted_and_not_permitted_links(doc.doctype) + if not links.get("not_permitted_links"): + # optimization: don't determine permissions based on link fields + return True + + # True if any one is True or all are empty + names = [] + for df in (links.get("permitted_links") + links.get("not_permitted_links")): + doctype = df.options + name = doc.get(df.fieldname) + + names.append(name) + + if name and frappe.has_permission(doctype, ptype, doc=name): + return True + + if not any(names): + return True + + else: + return False + +def get_permission_query_conditions_for_contact(user): + return get_permission_query_conditions("Contact") + +def get_permission_query_conditions_for_address(user): + return get_permission_query_conditions("Address") + +def get_permission_query_conditions(doctype): + links = get_permitted_and_not_permitted_links(doctype) + + if not links.get("not_permitted_links"): + # when everything is permitted, don't add additional condition + return "" + + else: + conditions = [] + + for df in links.get("permitted_links"): + # like ifnull(customer, '')!='' or ifnull(supplier, '')!='' + conditions.append("ifnull(`tab{doctype}`.`{fieldname}`, '')!=''".format(doctype=doctype, fieldname=df.fieldname)) + + return "( " + " or ".join(conditions) + " )" + +def get_permitted_and_not_permitted_links(doctype): + permitted_links = [] + not_permitted_links = [] + + meta = frappe.get_meta(doctype) + + for df in meta.get_link_fields(): + if df.options not in ("Customer", "Supplier", "Sales Partner"): + continue + + if frappe.has_permission(df.options): + permitted_links.append(df) + else: + not_permitted_links.append(df) + + return { + "permitted_links": permitted_links, + "not_permitted_links": not_permitted_links + }