From 092807cb183deb36c44b75fa67f4cb5c71ede1e9 Mon Sep 17 00:00:00 2001 From: Suraj Shetty Date: Tue, 26 Jun 2018 10:16:20 +0530 Subject: [PATCH] User permission patch (#5718) * Add patch to replicate old user permissions * Add comments and refactor code - Rename patch file - Add patch entry * Fix codacy * Remove unwanted code and code format --- frappe/patches.txt | 3 +- .../v11_0/replicate_old_user_permissions.py | 68 +++++++++++++++++++ 2 files changed, 70 insertions(+), 1 deletion(-) create mode 100644 frappe/patches/v11_0/replicate_old_user_permissions.py diff --git a/frappe/patches.txt b/frappe/patches.txt index a4e59a9ff6..4bfeaacf38 100644 --- a/frappe/patches.txt +++ b/frappe/patches.txt @@ -217,4 +217,5 @@ frappe.patches.v11_0.sync_stripe_settings_before_migrate frappe.patches.v11_0.update_list_user_settings frappe.patches.v11_0.rename_workflow_action_to_workflow_action_master #13-06-2018 frappe.patches.v11_0.rename_email_alert_to_notification #13-06-2018 -frappe.patches.v11_0.delete_duplicate_user_permissions \ No newline at end of file +frappe.patches.v11_0.delete_duplicate_user_permissions +frappe.patches.v11_0.replicate_old_user_permissions \ No newline at end of file diff --git a/frappe/patches/v11_0/replicate_old_user_permissions.py b/frappe/patches/v11_0/replicate_old_user_permissions.py new file mode 100644 index 0000000000..846794f784 --- /dev/null +++ b/frappe/patches/v11_0/replicate_old_user_permissions.py @@ -0,0 +1,68 @@ +import frappe +import json +from frappe.permissions import get_valid_perms, get_linked_doctypes + +def execute(): + user_permissions = frappe.get_all('User Permission', fields=['allow', 'name', 'user']) + + doctype_to_skip_map = {} + + for permission in user_permissions: + doctype_to_skip_map[permission.name] = get_doctypes_to_skip(permission.allow, permission.user) + + if not doctype_to_skip_map: return + + for perm_name, doctype_to_skip in doctype_to_skip_map.items(): + if not doctype_to_skip: continue + doctype_to_skip = '\n'.join(doctype_to_skip) + frappe.db.set_value('User Permission', perm_name, 'skip_for_doctype', doctype_to_skip) + + +def get_doctypes_to_skip(doctype, user): + ''' Returns doctypes to be skipped from user permission check''' + doctypes_to_skip = [] + valid_perms = get_user_valid_perms(user) or [] + + for perm in valid_perms: + + parent_doctype = perm.parent + + try: + if doctype not in get_linked_doctypes(parent_doctype): continue + except frappe.DoesNotExistError: + # if doctype not found (may be due to rename) it should not be considered for skip + continue + + if not perm.apply_user_permission: + # add doctype to skip list if any of the perm does not apply user permission + doctypes_to_skip.append(doctype) + + elif parent_doctype not in doctypes_to_skip: + + user_permission_doctypes = get_user_permission_doctypes(perm) + + # "No doctypes present" indicates that user permission will be applied to each link field + if not user_permission_doctypes: continue + + elif doctype in user_permission_doctypes: continue + + else: doctypes_to_skip.append(doctype) + + # to remove possible duplicates + doctypes_to_skip = list(set(doctypes_to_skip)) + + return doctypes_to_skip + +# store user's valid perms to avoid repeated query +user_valid_perm = {} + +def get_user_valid_perms(user): + if not user_valid_perm.get(user): + user_valid_perm[user] = get_valid_perms(user=user) + return user_valid_perm.get(user) + +def get_user_permission_doctypes(perm): + try: + return json.loads(perm.user_permission_doctypes or '[]') + except ValueError: + return [] \ No newline at end of file