Fix user permission on link fields

This commit is contained in:
Suraj Shetty 2018-11-01 20:36:39 +05:30
parent 0ffa645e10
commit 83a17a8242
2 changed files with 32 additions and 8 deletions

View file

@ -70,8 +70,8 @@ def get_user_default_value(df, defaults, user_permissions):
# We don't want to include permissions of transactions to be used for defaults.
if (frappe.get_meta(df.options).document_type=="Setup"
and user_permissions_exist(df, user_permissions)
and len(user_permissions[df.options].get("docs", []))==1):
return user_permissions[df.options].get("docs")[0]
and len(user_permissions.get(df.options))==1):
return user_permissions.get(df.options)[0].get("doc")
# 2 - Look in user defaults
user_default = defaults.get(df.fieldname)

View file

@ -34,7 +34,7 @@ class DatabaseQuery(object):
ignore_permissions=False, user=None, with_comment_count=False,
join='left join', distinct=False, start=None, page_length=None, limit=None,
ignore_ifnull=False, save_user_settings=False, save_user_settings_fields=False,
update=None, add_total_row=None, user_settings=None):
update=None, add_total_row=None, user_settings=None, reference_doctype=None):
if not ignore_permissions and not frappe.has_permission(self.doctype, "read", user=user):
frappe.flags.error_message = _('Insufficient Permission for {0}').format(frappe.bold(self.doctype))
raise frappe.PermissionError(self.doctype)
@ -78,6 +78,10 @@ class DatabaseQuery(object):
self.update = update
self.user_settings_fields = copy.deepcopy(self.fields)
# for contextual user permission check
# to determine which user permission is applicable on link field of specific doctype
self.reference_doctype = reference_doctype
if user_settings:
self.user_settings = json.loads(user_settings)
@ -218,10 +222,10 @@ class DatabaseQuery(object):
if any("{0}(".format(keyword) in field.lower() for keyword in blacklisted_functions):
_raise_exception()
if re.compile("[a-zA-Z]+\s*'").match(field):
if re.compile(r"[a-zA-Z]+\s*'").match(field):
_raise_exception()
if re.compile('[a-zA-Z]+\s*,').match(field):
if re.compile(r'[a-zA-Z]+\s*,').match(field):
_raise_exception()
_is_query(field)
@ -507,6 +511,7 @@ class DatabaseQuery(object):
match_conditions = []
for df in doctype_link_fields:
user_permission_values = user_permissions.get(df.get('options'), {})
if df.get('ignore_user_permissions'): continue
empty_value_condition = 'ifnull(`tab{doctype}`.`{fieldname}`, "")=""'.format(
@ -521,8 +526,20 @@ class DatabaseQuery(object):
condition = empty_value_condition + " or "
for permission in user_permission_values:
if (not permission.get('applicable_for') # if applicable for all doctypes
or self.doctype==permission.get('applicable_for')):
if not permission.get('applicable_for'):
docs.append(permission.get('doc'))
# append docs based on user permission applicable on reference doctype
# This is useful when getting list of doc from a link field
# in this case parent doctype of the link will be the
# will be the reference doctype
elif df.get('fieldname') == 'name' and self.reference_doctype:
if permission.get('applicable_for') == self.reference_doctype:
docs.append(permission.get('doc'))
elif permission.get('applicable_for') == self.doctype:
docs.append(permission.get('doc'))
if docs:
@ -534,7 +551,14 @@ class DatabaseQuery(object):
)
match_conditions.append("({condition})".format(condition=condition))
match_filters[df.get('options')] = docs
elif user_permission_values:
# this
condition += "`tab{doctype}`.`{fieldname}` in ('undefined')".format(
doctype=self.doctype,
fieldname=df.get('fieldname')
)
match_conditions.append("({condition})".format(condition=condition))
if match_conditions:
self.match_conditions.append(" and ".join(match_conditions))