Fix "replicate user permission" patch

This commit is contained in:
Suraj Shetty 2018-11-30 15:02:07 +05:30
parent 864675ce3c
commit 33b534ac6e
2 changed files with 40 additions and 20 deletions

View file

@ -1,5 +1,6 @@
import frappe
from frappe.desk.form.linked_with import get_linked_doctypes
from frappe.patches.v11_0.replicate_old_user_permissions import get_doctypes_to_skip
# `skip_for_doctype` was a un-normalized way of storing for which
# doctypes the user permission was applicable.
@ -12,19 +13,31 @@ from frappe.desk.form.linked_with import get_linked_doctypes
def execute():
frappe.reload_doctype('User Permission')
linked_with_map = {}
# to check if we need to migrate from skip_for_doctype
has_skip_for_doctype = frappe.db.has_column("User Permission", "skip_for_doctype")
skip_for_doctype_map = {}
for user_permission in frappe.get_all('User Permission', fields=['*']):
if not user_permission.skip_for_doctype:
frappe.db.set_value('User Permission', user_permission.name, 'apply_to_all_doctypes', 1)
continue
skip_for_doctype = user_permission.skip_for_doctype.split('\n')
if has_skip_for_doctype:
if not user_permission.skip_for_doctype:
frappe.db.set_value('User Permission', user_permission.name, 'apply_to_all_doctypes', 1)
continue
skip_for_doctype = user_permission.skip_for_doctype.split('\n')
else:
if skip_for_doctype_map[(user_permission.allow, user_permission.user)] == None:
skip_for_doctype = get_doctypes_to_skip(user_permission.allow, user_permission.user)
# cache skip for doctype for same user and doctype
skip_for_doctype_map[(user_permission.allow, user_permission.user)] = skip_for_doctype
else:
skip_for_doctype = skip_for_doctype_map[(user_permission.allow, user_permission.user)]
if skip_for_doctype:
# only specific doctypes are selected
# split this into multiple records and delete
if linked_with_map.get(user_permission.allow) == None:
linked_with_map[user_permission.allow] = get_linked_doctypes(user_permission.allow, True).keys()
# linked with doctypes that are not in skip_for_doctype
applicable_for_doctypes = filter(lambda d: d not in skip_for_doctype, linked_with_map[user_permission.allow])
linked_doctypes = get_linked_doctypes(user_permission.allow, True).keys()
applicable_for_doctypes = list(set(linked_doctypes) - set(skip_for_doctype))
frappe.db.sql('DELETE FROM `tabUser Permission` WHERE `name`=%s', user_permission.name)
user_permission.name = None
user_permission.skip_for_doctype = None

View file

@ -1,7 +1,7 @@
import frappe
import json
from frappe.utils import cint
from frappe.permissions import get_valid_perms, get_linked_doctypes
from frappe.permissions import get_valid_perms
def execute():
frappe.reload_doctype("User Permission")
@ -16,12 +16,14 @@ def execute():
if not doctype_to_skip_map: return
for key, 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.sql("""
update `tabUser Permission`
set skip_for_doctype = %s
where user=%s and allow=%s
""", (doctype_to_skip, key[1], key[0]))
if not frappe.db.has_column("User Permission", "applicable_for") \
and frappe.db.has_column("User Permission", "skip_for_doctype"):
doctype_to_skip = '\n'.join(doctype_to_skip)
frappe.db.sql("""
update `tabUser Permission`
set skip_for_doctype = %s
where user=%s and allow=%s
""", (doctype_to_skip, key[1], key[0]))
def get_doctypes_to_skip(doctype, user):
@ -32,9 +34,6 @@ def get_doctypes_to_skip(doctype, user):
parent_doctype = perm.parent
try:
linked_doctypes = get_linked_doctypes(parent_doctype)
child_doctypes = [d.options for d in frappe.get_meta(parent_doctype).get_table_fields()]
for child_dt in child_doctypes:
linked_doctypes += get_linked_doctypes(child_dt)
if doctype not in linked_doctypes: continue
except frappe.DoesNotExistError:
# if doctype not found (may be due to rename) it should not be considered for skip
@ -72,4 +71,12 @@ def get_user_permission_doctypes(perm):
try:
return json.loads(perm.user_permission_doctypes or '[]')
except ValueError:
return []
return []
def get_linked_doctypes(doctype):
from frappe.permissions import get_linked_doctypes
linked_doctypes = get_linked_doctypes(doctype)
child_doctypes = [d.options for d in frappe.get_meta(doctype).get_table_fields()]
for child_dt in child_doctypes:
linked_doctypes += get_linked_doctypes(child_dt)
return linked_doctypes