|
|
@@ -13,39 +13,39 @@ def check_admin_or_system_manager(): |
|
|
|
if ("System Manager" not in frappe.get_roles()) and \ |
|
|
|
(frappe.session.user!="Administrator"): |
|
|
|
msgprint("Only Allowed for Role System Manager or Administrator", raise_exception=True) |
|
|
|
|
|
|
|
|
|
|
|
def has_permission(doctype, ptype="read", doc=None, verbose=True): |
|
|
|
"""check if user has permission""" |
|
|
|
if frappe.is_table(doctype): |
|
|
|
return True |
|
|
|
|
|
|
|
|
|
|
|
meta = frappe.get_meta(doctype) |
|
|
|
|
|
|
|
|
|
|
|
if ptype=="submit" and not cint(meta.is_submittable): |
|
|
|
return False |
|
|
|
|
|
|
|
|
|
|
|
if ptype=="import" and not cint(meta.allow_import): |
|
|
|
return False |
|
|
|
|
|
|
|
|
|
|
|
if frappe.session.user=="Administrator": |
|
|
|
return True |
|
|
|
|
|
|
|
|
|
|
|
# get user permissions |
|
|
|
if not get_user_perms(meta).get(ptype): |
|
|
|
return False |
|
|
|
|
|
|
|
|
|
|
|
if doc: |
|
|
|
if isinstance(doc, basestring): |
|
|
|
doc = frappe.get_doc(meta.name, doc) |
|
|
|
|
|
|
|
|
|
|
|
if not has_unrestricted_access(doc, verbose=verbose): |
|
|
|
return False |
|
|
|
|
|
|
|
|
|
|
|
if not has_controller_permissions(doc): |
|
|
|
return False |
|
|
|
|
|
|
|
return True |
|
|
|
|
|
|
|
|
|
|
|
def get_user_perms(meta, user=None): |
|
|
|
if not user: |
|
|
|
user = frappe.session.user |
|
|
@@ -53,7 +53,7 @@ def get_user_perms(meta, user=None): |
|
|
|
if not frappe.local.user_perms.get(cache_key): |
|
|
|
perms = frappe._dict() |
|
|
|
user_roles = frappe.get_roles(user) |
|
|
|
|
|
|
|
|
|
|
|
for p in meta.permissions: |
|
|
|
if cint(p.permlevel)==0 and (p.role in user_roles): |
|
|
|
for ptype in rights: |
|
|
@@ -61,18 +61,18 @@ def get_user_perms(meta, user=None): |
|
|
|
perms[ptype] = perms.get(ptype, 1) and cint(p.get(ptype)) |
|
|
|
else: |
|
|
|
perms[ptype] = perms.get(ptype, 0) or cint(p.get(ptype)) |
|
|
|
|
|
|
|
|
|
|
|
frappe.local.user_perms[cache_key] = perms |
|
|
|
|
|
|
|
return frappe.local.user_perms[cache_key] |
|
|
|
|
|
|
|
|
|
|
|
def has_unrestricted_access(doc, verbose=True): |
|
|
|
from frappe.defaults import get_restrictions |
|
|
|
restrictions = get_restrictions() |
|
|
|
meta = frappe.get_meta(doc.get("doctype")) |
|
|
|
|
|
|
|
meta = frappe.get_meta(doc.get("doctype")) |
|
|
|
if get_user_perms(meta).restricted: |
|
|
|
if doc.owner == frappe.session.user: |
|
|
|
if d.owner == frappe.session.user: |
|
|
|
# owner is always allowed for restricted permissions |
|
|
|
return True |
|
|
|
elif not restrictions: |
|
|
@@ -80,58 +80,67 @@ def has_unrestricted_access(doc, verbose=True): |
|
|
|
else: |
|
|
|
if not restrictions: |
|
|
|
return True |
|
|
|
|
|
|
|
# evaluate specific restrictions |
|
|
|
fields_to_check = meta.get_restricted_fields(restrictions.keys()) |
|
|
|
|
|
|
|
has_restricted_data = False |
|
|
|
for df in fields_to_check: |
|
|
|
if doc.get(df.fieldname) and doc.get(df.fieldname) not in restrictions[df.options]: |
|
|
|
if verbose: |
|
|
|
msg = "{not_allowed}: {doctype} {having} {label} = {value}".format( |
|
|
|
not_allowed=_("Sorry, you are not allowed to access"), doctype=_(df.options), |
|
|
|
having=_("having"), label=_(df.label), value=doc.get(df.fieldname)) |
|
|
|
|
|
|
|
if doc.parentfield: |
|
|
|
msg = "{doctype}, {row} #{idx}, ".format(doctype=_(doc.doctype), |
|
|
|
row=_("Row"), idx=doc.idx) + msg |
|
|
|
|
|
|
|
msgprint(msg) |
|
|
|
|
|
|
|
has_restricted_data = True |
|
|
|
|
|
|
|
|
|
|
|
def _has_unrestricted_access(d): |
|
|
|
meta = frappe.get_meta(d.get("doctype")) |
|
|
|
|
|
|
|
# evaluate specific restrictions |
|
|
|
fields_to_check = meta.get_restricted_fields(restrictions.keys()) |
|
|
|
|
|
|
|
_has_restricted_data = False |
|
|
|
for df in fields_to_check: |
|
|
|
if d.get(df.fieldname) and d.get(df.fieldname) not in restrictions[df.options]: |
|
|
|
if verbose: |
|
|
|
msg = "{not_allowed}: {doctype} {having} {label} = {value}".format( |
|
|
|
not_allowed=_("Sorry, you are not allowed to access"), doctype=_(df.options), |
|
|
|
having=_("having"), label=_(df.label), value=d.get(df.fieldname)) |
|
|
|
|
|
|
|
if d.parentfield: |
|
|
|
msg = "{doctype}, {row} #{idx}, ".format(doctype=_(d.doctype), |
|
|
|
row=_("Row"), idx=d.idx) + msg |
|
|
|
|
|
|
|
msgprint(msg) |
|
|
|
|
|
|
|
_has_restricted_data = True |
|
|
|
|
|
|
|
return _has_restricted_data |
|
|
|
|
|
|
|
has_restricted_data = _has_unrestricted_access(doc) |
|
|
|
for d in doc.get_all_children(): |
|
|
|
has_restricted_data = _has_unrestricted_access(d) or has_restricted_data |
|
|
|
|
|
|
|
# check all restrictions before returning |
|
|
|
return False if has_restricted_data else True |
|
|
|
|
|
|
|
|
|
|
|
def has_controller_permissions(doc): |
|
|
|
if doc.get("__islocal"): |
|
|
|
doc = frappe.get_doc(doc) |
|
|
|
else: |
|
|
|
doc = frappe.get_doc(doc.doctype, doc.name) |
|
|
|
|
|
|
|
|
|
|
|
condition_methods = frappe.get_hooks("has_permission:" + doc.doctype) |
|
|
|
for method in frappe.get_hooks("has_permission:" + doc.doctype): |
|
|
|
if not frappe.call(frappe.get_attr(method), doc=doc): |
|
|
|
return False |
|
|
|
|
|
|
|
|
|
|
|
return True |
|
|
|
|
|
|
|
|
|
|
|
def can_restrict_user(user, doctype, docname=None): |
|
|
|
if not can_restrict(doctype, docname): |
|
|
|
return False |
|
|
|
|
|
|
|
|
|
|
|
# check if target user does not have restrict permission |
|
|
|
if has_only_non_restrict_role(doctype, user): |
|
|
|
return True |
|
|
|
|
|
|
|
|
|
|
|
return False |
|
|
|
|
|
|
|
|
|
|
|
def can_restrict(doctype, docname=None): |
|
|
|
# System Manager can always restrict |
|
|
|
if "System Manager" in frappe.get_roles(): |
|
|
|
return True |
|
|
|
meta = frappe.get_meta(doctype) |
|
|
|
|
|
|
|
|
|
|
|
# check if current user has read permission for docname |
|
|
|
if docname and not has_permission(doctype, "read", docname): |
|
|
|
return False |
|
|
@@ -139,18 +148,18 @@ def can_restrict(doctype, docname=None): |
|
|
|
# check if current user has a role with restrict permission |
|
|
|
if not has_restrict_permission(meta): |
|
|
|
return False |
|
|
|
|
|
|
|
|
|
|
|
return True |
|
|
|
|
|
|
|
|
|
|
|
def has_restrict_permission(meta=None, user=None): |
|
|
|
return get_user_perms(meta, user).restrict==1 |
|
|
|
|
|
|
|
|
|
|
|
def has_only_non_restrict_role(doctype, user): |
|
|
|
meta = frappe.get_meta(doctype) |
|
|
|
# check if target user does not have restrict permission |
|
|
|
if has_restrict_permission(meta, user): |
|
|
|
return False |
|
|
|
|
|
|
|
|
|
|
|
# and has non-restrict role |
|
|
|
return get_user_perms(meta, user).restrict==0 |
|
|
|
|
|
|
@@ -161,7 +170,7 @@ def can_import(doctype, raise_exception=False): |
|
|
|
else: |
|
|
|
return False |
|
|
|
return True |
|
|
|
|
|
|
|
|
|
|
|
def can_export(doctype, raise_exception=False): |
|
|
|
if not ("System Manager" in frappe.get_roles() or has_permission(doctype, "export")): |
|
|
|
if raise_exception: |
|
|
@@ -169,4 +178,3 @@ def can_export(doctype, raise_exception=False): |
|
|
|
else: |
|
|
|
return False |
|
|
|
return True |
|
|
|
|