def get_doc_permissions(doc, verbose=False, user=None): if not user: user = frappe.session.user if frappe.is_table(doc.doctype): return {"read":1, "write":1} meta = frappe.get_meta(doc.doctype) role_permissions = copy.deepcopy(get_role_permissions(meta, user=user, verbose=verbose)) if not cint(meta.is_submittable): role_permissions["submit"] = 0 if not cint(meta.allow_import): role_permissions["import"] = 0 if role_permissions.get("apply_user_permissions"): # no user permissions, switch off all user-level permissions for ptype in role_permissions: if role_permissions["apply_user_permissions"].get(ptype) and not user_has_permission(doc, verbose=verbose, user=user, user_permission_doctypes=role_permissions.get("user_permission_doctypes", {}).get(ptype) or []): role_permissions[ptype] = 0 # update share permissions role_permissions.update(frappe.db.get_value("DocShare", {"share_doctype": doc.doctype, "share_name": doc.name, "user": user}, ["read", "write", "share"], as_dict=True) or {}) return role_permissions
def has_permission(doctype, ptype="read", doc=None, verbose=True, user=None): """check if user has permission""" if not user: user = frappe.session.user 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 user=="Administrator": return True role_permissions = get_role_permissions(meta, user=user) if not role_permissions.get(ptype): return False if doc: if isinstance(doc, basestring): doc = frappe.get_doc(meta.name, doc) if role_permissions["apply_user_permissions"].get(ptype): if not user_has_permission(doc, verbose=verbose, user=user, user_permission_doctypes=role_permissions.get("user_permission_doctypes", {}).get(ptype) or []): return False if not has_controller_permissions(doc, ptype, user=user): return False return True
def get_value(doctype, fieldname, filters=None, as_dict=True, debug=False, parent=None): '''Returns a value form a document :param doctype: DocType to be queried :param fieldname: Field to be returned (default `name`) :param filters: dict or string for identifying the record''' if frappe.is_table(doctype): check_parent_permission(parent, doctype) if not frappe.has_permission(doctype): frappe.throw(_("No permission for {0}".format(doctype)), frappe.PermissionError) try: filters = json.loads(filters) if isinstance(filters, (integer_types, float)): filters = frappe.as_unicode(filters) except (TypeError, ValueError): # filters are not passesd, not json pass try: fieldname = json.loads(fieldname) except (TypeError, ValueError): # name passed, not json pass # check whether the used filters were really parseable and usable # and did not just result in an empty string or dict if not filters: filters = None return frappe.db.get_value(doctype, filters, fieldname, as_dict=as_dict, debug=debug)
def get_doc_permissions(doc, verbose=False, user=None): """Returns a dict of evaluated permissions for given `doc` like `{"read":1, "write":1}`""" if not user: user = frappe.session.user if frappe.is_table(doc.doctype): return {"read":1, "write":1} meta = frappe.get_meta(doc.doctype) role_permissions = copy.deepcopy(get_role_permissions(meta, user=user, verbose=verbose)) if not cint(meta.is_submittable): role_permissions["submit"] = 0 if not cint(meta.allow_import): role_permissions["import"] = 0 if role_permissions.get("apply_user_permissions"): # no user permissions, switch off all user-level permissions for ptype in role_permissions: if role_permissions["apply_user_permissions"].get(ptype) and not user_has_permission(doc, verbose=verbose, user=user, user_permission_doctypes=role_permissions.get("user_permission_doctypes", {}).get(ptype) or []): role_permissions[ptype] = 0 # apply owner permissions on top of existing permissions if doc.owner == frappe.session.user: role_permissions.update(role_permissions.if_owner) update_share_permissions(role_permissions, doc, user) return role_permissions
def get_list(doctype, fields=None, filters=None, order_by=None, limit_start=None, limit_page_length=20, parent=None): '''Returns a list of records by filters, fields, ordering and limit :param doctype: DocType of the data to be queried :param fields: fields to be returned. Default is `name` :param filters: filter list by this dict :param order_by: Order by this fieldname :param limit_start: Start at this index :param limit_page_length: Number of records to be returned (default 20)''' if frappe.is_table(doctype): check_parent_permission(parent, doctype) return frappe.get_list(doctype, fields=fields, filters=filters, order_by=order_by, limit_start=limit_start, limit_page_length=limit_page_length, ignore_permissions=False)
def has_permission(doctype, ptype="read", doc=None, verbose=True, user=None): """check if user has permission""" if not user: user = frappe.session.user 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 user == "Administrator": return True role_permissions = get_role_permissions(meta, user=user) if not role_permissions.get(ptype): return False if doc: if isinstance(doc, basestring): doc = frappe.get_doc(meta.name, doc) if role_permissions["apply_user_permissions"].get(ptype): if not user_has_permission(doc, verbose=verbose, user=user): return False if not has_controller_permissions(doc, ptype, user=user): return False return True
def get_doc_permissions(doc, verbose=False, user=None): if not user: user = frappe.session.user if frappe.is_table(doc.doctype): return {"read": 1, "write": 1} meta = frappe.get_meta(doc.doctype) role_permissions = copy.deepcopy(get_role_permissions(meta, user=user)) if not cint(meta.is_submittable): role_permissions["submit"] = 0 if not cint(meta.allow_import): role_permissions["import"] = 0 if role_permissions.get("apply_user_permissions"): # no user permissions, switch off all user-level permissions for ptype in role_permissions: if role_permissions["apply_user_permissions"].get( ptype) and not user_has_permission( doc, verbose=verbose, user=user, user_permission_doctypes=role_permissions.get( "user_permission_doctypes", {}).get(ptype) or []): role_permissions[ptype] = 0 return role_permissions
def get_doc_permissions(doc, verbose=False, user=None, ptype=None): """Returns a dict of evaluated permissions for given `doc` like `{"read":1, "write":1}`""" if not user: user = frappe.session.user if frappe.is_table(doc.doctype): return {"read": 1, "write": 1} meta = frappe.get_meta(doc.doctype) if has_controller_permissions(doc, ptype, user=user) == False: return {ptype: 0} permissions = copy.deepcopy( get_role_permissions(meta, user=user, verbose=verbose)) if not cint(meta.is_submittable): permissions["submit"] = 0 if not cint(meta.allow_import): permissions["import"] = 0 if not has_user_permission(doc, user): if not permissions.get("if_owner"): return {} if not frappe.session.user or not doc.owner: return {} # apply owner permissions on top of existing permissions if (doc.owner.lower() == frappe.session.user.lower()): permissions = permissions.get("if_owner") # if_owner does not come with create rights... permissions['create'] = 0 else: permissions = {} return permissions
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 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 has_permission(doctype, ptype="read", doc=None, verbose=False, user=None): """check if user has permission""" if not user: user = frappe.session.user if frappe.is_table(doctype): if verbose: print "Table type, always true" return True meta = frappe.get_meta(doctype) if ptype == "submit" and not cint(meta.is_submittable): if verbose: print "Not submittable" return False if ptype == "import" and not cint(meta.allow_import): if verbose: print "Not importable" return False if user == "Administrator": if verbose: print "Administrator" return True def false_if_not_shared(): if ptype in ("read", "write", "share"): shared = frappe.share.get_shared(doctype, user, [ptype]) if doc: if doc.name in shared: if verbose: print "Shared" return True else: if verbose: print "Has a shared document" return True return False role_permissions = get_role_permissions(meta, user=user) if not role_permissions.get(ptype): return false_if_not_shared() if doc: if isinstance(doc, basestring): doc = frappe.get_doc(meta.name, doc) if role_permissions["apply_user_permissions"].get(ptype): if not user_has_permission( doc, verbose=verbose, user=user, user_permission_doctypes=role_permissions.get( "user_permission_doctypes", {}).get(ptype) or []): if verbose: print "No user permission" return false_if_not_shared() if not has_controller_permissions(doc, ptype, user=user): if verbose: print "No controller permission" return false_if_not_shared() if verbose: print "Has Role" return True
def has_permission(doctype, ptype="read", doc=None, verbose=False, user=None): """check if user has permission""" if not user: user = frappe.session.user if frappe.is_table(doctype): if verbose: print "Table type, always true" return True meta = frappe.get_meta(doctype) if ptype=="submit" and not cint(meta.is_submittable): if verbose: print "Not submittable" return False if ptype=="import" and not cint(meta.allow_import): if verbose: print "Not importable" return False if user=="Administrator": if verbose: print "Administrator" return True def false_if_not_shared(): if ptype in ("read", "write", "share"): shared = frappe.share.get_shared(doctype, user, [ptype]) if doc: doc_name = doc if isinstance(doc, basestring) else doc.name if doc_name in shared: if verbose: print "Shared" return True else: if verbose: print "Has a shared document" return True return False role_permissions = get_role_permissions(meta, user=user, verbose=verbose) if not role_permissions.get(ptype): return false_if_not_shared() if doc: if isinstance(doc, basestring): doc = frappe.get_doc(meta.name, doc) if role_permissions["apply_user_permissions"].get(ptype): if not user_has_permission(doc, verbose=verbose, user=user, user_permission_doctypes=role_permissions.get("user_permission_doctypes", {}).get(ptype) or []): if verbose: print "No user permission" return false_if_not_shared() if not has_controller_permissions(doc, ptype, user=user): if verbose: print "No controller permission" return false_if_not_shared() if verbose: print "Has Role" return True
def get_value(doctype, fieldname, filters=None, as_dict=True, debug=False, parent=None): """Returns a value form a document :param doctype: DocType to be queried :param fieldname: Field to be returned (default `name`) :param filters: dict or string for identifying the record""" if frappe.is_table(doctype): check_parent_permission(parent, doctype) if not frappe.has_permission(doctype): frappe.throw( _("No permission for {0}").format(doctype), frappe.PermissionError) filters = get_safe_filters(filters) if isinstance(filters, string_types): filters = {"name": filters} try: fields = frappe.parse_json(fieldname) except (TypeError, ValueError): # name passed, not json fields = [fieldname] # check whether the used filters were really parseable and usable # and did not just result in an empty string or dict if not filters: filters = None if frappe.get_meta(doctype).issingle: value = frappe.db.get_values_from_single(fields, filters, doctype, as_dict=as_dict, debug=debug) else: value = get_list( doctype, filters=filters, fields=fields, debug=debug, limit_page_length=1, parent=parent, as_dict=as_dict, ) if as_dict: return value[0] if value else {} if not value: return return value[0] if len(fields) > 1 else value[0][0]
def get_doc_permissions(doc, user=None, ptype=None): """Returns a dict of evaluated permissions for given `doc` like `{"read":1, "write":1}`""" if not user: user = frappe.session.user if frappe.is_table(doc.doctype): return {"read": 1, "write": 1} meta = frappe.get_meta(doc.doctype) if has_controller_permissions(doc, ptype, user=user) == False : push_perm_check_log('Not allowed via controller permission check') return {ptype: 0} permissions = copy.deepcopy(get_role_permissions(meta, user=user)) if not cint(meta.is_submittable): permissions["submit"] = 0 if not cint(meta.allow_import): permissions["import"] = 0 if cint(meta.is_sealed) and doc.docstatus > 0: permissions["delete"] = 0 def is_user_owner(): doc_owner = doc.get('owner') or '' doc_owner = doc_owner.lower() session_user = frappe.session.user.lower() return doc_owner == session_user if is_user_owner(): # apply owner permissions on top of existing permissions # some access might be only for the owner # eg. everyone might have read access but only owner can delete permissions.update(permissions.get("if_owner", {})) if not has_user_permission(doc, user): if is_user_owner(): # replace with owner permissions permissions = permissions.get("if_owner", {}) # if_owner does not come with create rights... permissions['create'] = 0 else: permissions = {} return permissions
def get_list(doctype, *args, **kwargs): '''wrapper for DatabaseQuery''' kwargs.pop('cmd', None) kwargs.pop('ignore_permissions', None) # If doctype is child table if frappe.is_table(doctype): # Example frappe.db.get_list('Purchase Receipt Item', {'parent': 'Purchase Receipt'}) # Here purchase receipt is the parent doctype of the child doctype Purchase Receipt Item if not kwargs.get('parent'): frappe.flags.error_message = _('Parent is required to get child table data') raise frappe.PermissionError(doctype) check_parent_permission(kwargs.get('parent'), doctype) del kwargs['parent'] return DatabaseQuery(doctype).execute(None, *args, **kwargs)
def get_value(doctype, fieldname, filters=None, as_dict=True, debug=False, parent=None): '''Returns a value form a document :param doctype: DocType to be queried :param fieldname: Field to be returned (default `name`) :param filters: dict or string for identifying the record''' if frappe.is_table(doctype): check_parent_permission(parent) if not frappe.has_permission(doctype): frappe.throw(_("No permission for {0}".format(doctype)), frappe.PermissionError) try: filters = json.loads(filters) if isinstance(filters, (integer_types, float)): filters = frappe.as_unicode(filters) except (TypeError, ValueError): # filters are not passesd, not json pass try: fieldname = json.loads(fieldname) except (TypeError, ValueError): # name passed, not json pass # check whether the used filters were really parseable and usable # and did not just result in an empty string or dict if not filters: filters = None return frappe.db.get_value(doctype, filters, fieldname, as_dict=as_dict, debug=debug)
def get(doctype, name=None, filters=None, parent=None): '''Returns a document by name or filters :param doctype: DocType of the document to be returned :param name: return document of this `name` :param filters: If name is not set, filter by these values and return the first match''' if frappe.is_table(doctype): check_parent_permission(parent, doctype) if filters and not name: name = frappe.db.get_value(doctype, json.loads(filters)) if not name: frappe.throw(_("No document found for given filters")) doc = frappe.get_doc(doctype, name) if not doc.has_permission("read"): raise frappe.PermissionError return frappe.get_doc(doctype, name).as_dict()
def get_doc_permissions(doc, user=None, ptype=None): """Returns a dict of evaluated permissions for given `doc` like `{"read":1, "write":1}`""" if not user: user = frappe.session.user if frappe.is_table(doc.doctype): return {"read": 1, "write": 1} meta = frappe.get_meta(doc.doctype) def is_user_owner(): return (doc.get("owner") or "").lower() == frappe.session.user.lower() if has_controller_permissions(doc, ptype, user=user) is False: push_perm_check_log("Not allowed via controller permission check") return {ptype: 0} permissions = copy.deepcopy( get_role_permissions(meta, user=user, is_owner=is_user_owner())) if not cint(meta.is_submittable): permissions["submit"] = 0 if not cint(meta.allow_import): permissions["import"] = 0 # Override with `if_owner` perms irrespective of user if permissions.get("has_if_owner_enabled"): # apply owner permissions on top of existing permissions # some access might be only for the owner # eg. everyone might have read access but only owner can delete permissions.update(permissions.get("if_owner", {})) if not has_user_permission(doc, user): if is_user_owner(): # replace with owner permissions permissions = permissions.get("if_owner", {}) # if_owner does not come with create rights... permissions["create"] = 0 else: permissions = {} return permissions
def get_doc_permissions(doc, user=None, ptype=None): """Returns a dict of evaluated permissions for given `doc` like `{"read":1, "write":1}`""" if not user: user = frappe.session.user if frappe.is_table(doc.doctype): return {"read": 1, "write": 1} meta = frappe.get_meta(doc.doctype) if has_controller_permissions(doc, ptype, user=user) == False : push_perm_check_log('Not allowed via controller permission check') return {ptype: 0} permissions = copy.deepcopy(get_role_permissions(meta, user=user)) if not cint(meta.is_submittable): permissions["submit"] = 0 if not cint(meta.allow_import): permissions["import"] = 0 def is_user_owner(): doc_owner = doc.get('owner') or '' doc_owner = doc_owner.lower() session_user = frappe.session.user.lower() return doc_owner == session_user if is_user_owner(): # apply owner permissions on top of existing permissions # some access might be only for the owner # eg. everyone might have read access but only owner can delete permissions.update(permissions.get("if_owner", {})) if not has_user_permission(doc, user): if is_user_owner(): # replace with owner permissions permissions = permissions.get("if_owner", {}) # if_owner does not come with create rights... permissions['create'] = 0 else: permissions = {} return permissions
def get_doc_permissions(doc, verbose=False, user=None): if not user: user = frappe.session.user if frappe.is_table(doc.doctype): return {"read": 1, "write": 1} meta = frappe.get_meta(doc.doctype) role_permissions = copy.deepcopy( get_role_permissions(meta, user=user, verbose=verbose)) if not cint(meta.is_submittable): role_permissions["submit"] = 0 if not cint(meta.allow_import): role_permissions["import"] = 0 if role_permissions.get("apply_user_permissions"): # no user permissions, switch off all user-level permissions for ptype in role_permissions: if role_permissions["apply_user_permissions"].get( ptype) and not user_has_permission( doc, verbose=verbose, user=user, user_permission_doctypes=role_permissions.get( "user_permission_doctypes", {}).get(ptype) or []): role_permissions[ptype] = 0 # update share permissions role_permissions.update( frappe.db.get_value("DocShare", { "share_doctype": doc.doctype, "share_name": doc.name, "user": user }, ["read", "write", "share"], as_dict=True) or {}) return role_permissions
def get_list( doctype, fields=None, filters=None, order_by=None, limit_start=None, limit_page_length=20, parent=None, debug=False, as_dict=True, or_filters=None, ): """Returns a list of records by filters, fields, ordering and limit :param doctype: DocType of the data to be queried :param fields: fields to be returned. Default is `name` :param filters: filter list by this dict :param order_by: Order by this fieldname :param limit_start: Start at this index :param limit_page_length: Number of records to be returned (default 20)""" if frappe.is_table(doctype): check_parent_permission(parent, doctype) args = frappe._dict( doctype=doctype, fields=fields, filters=filters, or_filters=or_filters, order_by=order_by, limit_start=limit_start, limit_page_length=limit_page_length, debug=debug, as_list=not as_dict, ) validate_args(args) return frappe.get_list(**args)
def get_thumbnail_url(dt, dn, df): """ Fetches the thumbnail url (if it exists) of an image field given: dt: `str` The Doc-type it is defined on dn: `str` The name of Doc it is attached to df: `str` The field on the Doc it is attached to i.e: the "Attach" field """ file_url = frappe.get_value(dt, dn, df) if not file_url: return if frappe.is_table(dt): dt, dn = frappe.get_value(dt, dn, ("parenttype", "parent")) thumbnail_url = get_thumbnail_url_by_docfield(dt, dn, df, file_url) if not thumbnail_url: thumbnail_url = get_thumbnail_url_by_file_url(file_url) return thumbnail_url
def get_doc_permissions(doc, verbose=False, user=None): if not user: user = frappe.session.user if frappe.is_table(doc.doctype): return {"read":1, "write":1} meta = frappe.get_meta(doc.doctype) role_permissions = copy.deepcopy(get_role_permissions(meta, user=user)) if not cint(meta.is_submittable): role_permissions["submit"] = 0 if not cint(meta.allow_import): role_permissions["import"] = 0 if role_permissions.get("apply_user_permissions"): # no user permissions, switch off all user-level permissions for ptype in role_permissions: if role_permissions["apply_user_permissions"].get(ptype) and not user_has_permission(doc, verbose=verbose, user=user, user_permission_doctypes=role_permissions.get("user_permission_doctypes", {}).get(ptype) or []): role_permissions[ptype] = 0 return role_permissions
def has_permission(doctype, ptype="read", doc=None, verbose=False, user=None): """Returns True if user has permission `ptype` for given `doctype`. If `doc` is passed, it also checks user, share and owner permissions. Note: if Table DocType is passed, it always returns True. """ if not user: user = frappe.session.user if frappe.is_table(doctype): if verbose: print "Table type, always true" return True meta = frappe.get_meta(doctype) if ptype == "submit" and not cint(meta.is_submittable): if verbose: print "Not submittable" return False if ptype == "import" and not cint(meta.allow_import): if verbose: print "Not importable" return False if user == "Administrator": if verbose: print "Administrator" return True def false_if_not_shared(): if ptype in ("read", "write", "share", "email", "print"): shared = frappe.share.get_shared( doctype, user, ["read" if ptype in ("email", "print") else ptype]) if doc: doc_name = doc if isinstance(doc, basestring) else doc.name if doc_name in shared: if verbose: print "Shared" if ptype in ("read", "write", "share") or meta.permissions[0].get(ptype): return True elif shared: # if atleast one shared doc of that type, then return True # this is used in db_query to check if permission on DocType if verbose: print "Has a shared document" return True return False role_permissions = get_role_permissions(meta, user=user, verbose=verbose) if not role_permissions.get(ptype): return false_if_not_shared() if doc: if isinstance(doc, basestring): doc = frappe.get_doc(meta.name, doc) # if owner match, then return True if doc.owner == frappe.session.user and role_permissions[ "if_owner"].get(ptype) and ptype != "create": return True # check if user permission if role_permissions["apply_user_permissions"].get(ptype): if not user_has_permission( doc, verbose=verbose, user=user, user_permission_doctypes=role_permissions.get( "user_permission_doctypes", {}).get(ptype) or []): if verbose: print "No user permission" return false_if_not_shared() if not has_controller_permissions(doc, ptype, user=user): if verbose: print "No controller permission" return false_if_not_shared() if verbose: print "Has Role" return True
def has_permission(doctype, ptype="read", doc=None, verbose=False, user=None, raise_exception=True): """Returns True if user has permission `ptype` for given `doctype`. If `doc` is passed, it also checks user, share and owner permissions. Note: if Table DocType is passed, it always returns True. """ if not user: user = frappe.session.user if not doc and hasattr(doctype, 'doctype'): # first argument can be doc or doctype doc = doctype doctype = doc.doctype if frappe.is_table(doctype): return True if user == "Administrator": return True meta = frappe.get_meta(doctype) if doc: if isinstance(doc, string_types): doc = frappe.get_doc(meta.name, doc) perm = get_doc_permissions(doc, user=user, ptype=ptype).get(ptype) if not perm: push_perm_check_log('User do not have document access') else: if ptype == "submit" and not cint(meta.is_submittable): push_perm_check_log("Doctype is not submittable") return False if ptype == "import" and not cint(meta.allow_import): push_perm_check_log("Doctype is not importable") return False role_permissions = get_role_permissions(meta, user=user) perm = role_permissions.get(ptype) if not perm: push_perm_check_log( 'User do not have doctype access via role permission') def false_if_not_shared(): if ptype in ("read", "write", "share", "email", "print"): shared = frappe.share.get_shared( doctype, user, ["read" if ptype in ("email", "print") else ptype]) if doc: doc_name = get_doc_name(doc) if doc_name in shared: if ptype in ("read", "write", "share") or meta.permissions[0].get(ptype): return True elif shared: # if atleast one shared doc of that type, then return True # this is used in db_query to check if permission on DocType return True return False if not perm: perm = false_if_not_shared() return perm
def has_permission(doctype, ptype="read", doc=None, verbose=False, user=None): """Returns True if user has permission `ptype` for given `doctype`. If `doc` is passed, it also checks user, share and owner permissions. Note: if Table DocType is passed, it always returns True. """ if not user: user = frappe.session.user if not doc and hasattr(doctype, 'doctype'): # first argument can be doc or doctype doc = doctype doctype = doc.doctype if verbose: doc_name = get_doc_name(doc) or '_' print('--- Checking for {0} {1} ---'.format(doctype, doc_name)) if frappe.is_table(doctype): if verbose: print("Table type, always true") return True if user == "Administrator": if verbose: print("Allowing Administrator") return True meta = frappe.get_meta(doctype) if doc: if isinstance(doc, string_types): doc = frappe.get_doc(meta.name, doc) perm = get_doc_permissions(doc, user=user, ptype=ptype).get(ptype) else: if ptype == "submit" and not cint(meta.is_submittable): if verbose: print("Not submittable") return False if ptype == "import" and not cint(meta.allow_import): if verbose: print("Not importable") return False role_permissions = get_role_permissions(meta, user=user, verbose=verbose) perm = role_permissions.get(ptype) def false_if_not_shared(): if ptype in ("read", "write", "share", "email", "print"): shared = frappe.share.get_shared( doctype, user, ["read" if ptype in ("email", "print") else ptype]) if doc: doc_name = get_doc_name(doc) if doc_name in shared: if verbose: print("Shared") if ptype in ("read", "write", "share") or meta.permissions[0].get(ptype): if verbose: print("Is shared") return True elif shared: # if atleast one shared doc of that type, then return True # this is used in db_query to check if permission on DocType if verbose: print("Has a shared document") return True if verbose: print("Not Shared") return False if not perm: perm = false_if_not_shared() if perm and frappe.message_log: frappe.message_log.pop() if verbose: print("Final Permission: {0}".format(perm)) return perm
def has_permission(doctype, ptype="read", doc=None, verbose=False, user=None): """Returns True if user has permission `ptype` for given `doctype`. If `doc` is passed, it also checks user, share and owner permissions. Note: if Table DocType is passed, it always returns True. """ if not user: user = frappe.session.user if verbose: print('--- Checking for {0} {1} ---'.format(doctype, doc.name if doc else '-')) if frappe.is_table(doctype): if verbose: print("Table type, always true") return True meta = frappe.get_meta(doctype) if ptype=="submit" and not cint(meta.is_submittable): if verbose: print("Not submittable") return False if ptype=="import" and not cint(meta.allow_import): if verbose: print("Not importable") return False if user=="Administrator": if verbose: print("Allowing Administrator") return True def false_if_not_shared(): if ptype in ("read", "write", "share", "email", "print"): shared = frappe.share.get_shared(doctype, user, ["read" if ptype in ("email", "print") else ptype]) if doc: doc_name = doc if isinstance(doc, string_types) else doc.name if doc_name in shared: if verbose: print("Shared") if ptype in ("read", "write", "share") or meta.permissions[0].get(ptype): if verbose: print("Is shared") return True elif shared: # if atleast one shared doc of that type, then return True # this is used in db_query to check if permission on DocType if verbose: print("Has a shared document") return True if verbose: print("Not Shared") return False role_permissions = get_role_permissions(meta, user=user, verbose=verbose) if not role_permissions.get(ptype): return false_if_not_shared() perm = True if doc: if isinstance(doc, string_types): doc = frappe.get_doc(meta.name, doc) owner_perm = user_perm = controller_perm = None if role_permissions["if_owner"].get(ptype) and ptype!="create": owner_perm = doc.owner == frappe.session.user if verbose: print("Owner permission: {0}".format(owner_perm)) # check if user permission if not owner_perm and role_permissions["apply_user_permissions"].get(ptype): user_perm = user_has_permission(doc, verbose=verbose, user=user, user_permission_doctypes=role_permissions.get("user_permission_doctypes", {}).get(ptype) or []) if verbose: print("User permission: {0}".format(user_perm)) if not owner_perm and not user_perm: controller_perm = has_controller_permissions(doc, ptype, user=user) if verbose: print("Controller permission: {0}".format(controller_perm)) # permission true if any one condition is explicitly True or all permissions are undefined (None) perm = any([owner_perm, user_perm, controller_perm]) or \ all([owner_perm==None, user_perm==None, controller_perm==None]) if not perm: perm = false_if_not_shared() if verbose: print("Final Permission: {0}".format(perm)) return perm
def format_value(value, df=None, doc=None, currency=None, translated=False): '''Format value based on given fieldtype, document reference, currency reference. If docfield info (df) is not given, it will try and guess based on the datatype of the value''' if isinstance(df, string_types): df = frappe._dict(fieldtype=df) if not df: df = frappe._dict() if isinstance(value, datetime.datetime): df.fieldtype = 'Datetime' elif isinstance(value, datetime.date): df.fieldtype = 'Date' elif isinstance(value, datetime.timedelta): df.fieldtype = 'Time' elif isinstance(value, int): df.fieldtype = 'Int' elif isinstance(value, float): df.fieldtype = 'Float' else: df.fieldtype = 'Data' elif (isinstance(df, dict)): # Convert dict to object if necessary df = frappe._dict(df) if value is None: value = "" elif translated: value = frappe._(value) if not df: return value elif df.get("fieldtype")=="Date": return formatdate(value) elif df.get("fieldtype")=="Datetime": return format_datetime(value) elif df.get("fieldtype")=="Time": return format_time(value) elif value==0 and df.get("fieldtype") in ("Int", "Float", "Currency", "Percent") and df.get("print_hide_if_no_value"): # this is required to show 0 as blank in table columns return "" elif df.get("fieldtype") == "Currency" or (df.get("fieldtype")=="Float" and (df.options or "").strip()): if df.get("fieldtype") == "Currency": if doc: if frappe.is_table(doc.doctype): return fmt_money(value, precision=get_field_precision(df, doc)) return fmt_money(value, precision=get_field_precision(df, doc), currency=currency if currency else (get_field_currency(df, doc) if doc else None)) elif df.get("fieldtype") == "Float": precision = get_field_precision(df, doc) # show 1.000000 as 1 # options should not specified if not df.options and value is not None: temp = cstr(value).split(".") if len(temp)==1 or cint(temp[1])==0: precision = 0 return fmt_money(value, precision=precision) elif df.get("fieldtype") == "Percent": return "{}%".format(flt(value, 2)) elif df.get("fieldtype") in ("Text", "Small Text"): if not re.search("(\<br|\<div|\<p)", value): return value.replace("\n", "<br>") return value
def has_permission(doctype, ptype="read", doc=None, verbose=False, user=None): """Returns True if user has permission `ptype` for given `doctype`. If `doc` is passed, it also checks user, share and owner permissions. Note: if Table DocType is passed, it always returns True. """ if not user: user = frappe.session.user if frappe.is_table(doctype): if verbose: print "Table type, always true" return True meta = frappe.get_meta(doctype) if ptype=="submit" and not cint(meta.is_submittable): if verbose: print "Not submittable" return False if ptype=="import" and not cint(meta.allow_import): if verbose: print "Not importable" return False if user=="Administrator": if verbose: print "Administrator" return True def false_if_not_shared(): if ptype in ("read", "write", "share", "email", "print"): shared = frappe.share.get_shared(doctype, user, ["read" if ptype in ("email", "print") else ptype]) if doc: doc_name = doc if isinstance(doc, basestring) else doc.name if doc_name in shared: if verbose: print "Shared" if ptype in ("read", "write", "share") or meta.permissions[0].get(ptype): return True elif shared: # if atleast one shared doc of that type, then return True # this is used in db_query to check if permission on DocType if verbose: print "Has a shared document" return True return False role_permissions = get_role_permissions(meta, user=user, verbose=verbose) if not role_permissions.get(ptype): return false_if_not_shared() if doc: if isinstance(doc, basestring): doc = frappe.get_doc(meta.name, doc) # if owner match, then return True if doc.owner == frappe.session.user and role_permissions["if_owner"].get(ptype) and ptype!="create": return True # check if user permission if role_permissions["apply_user_permissions"].get(ptype): if not user_has_permission(doc, verbose=verbose, user=user, user_permission_doctypes=role_permissions.get("user_permission_doctypes", {}).get(ptype) or []): if verbose: print "No user permission" return false_if_not_shared() if not has_controller_permissions(doc, ptype, user=user): if verbose: print "No controller permission" return false_if_not_shared() if verbose: print "Has Role" return True
def document_resolver(obj, info: GraphQLResolveInfo, **kwargs): doctype = obj.get('doctype') or get_singular_doctype(info.parent_type.name) if not doctype: return None cached_doc = obj __ignore_perms = cint(obj.get("__ignore_perms", 0) == 1) if not isinstance(cached_doc, BaseDocument) and info.field_name not in cached_doc: try: cached_doc = frappe.get_cached_doc(doctype, obj.get("name")) except BaseException: pass if frappe.is_table(doctype=doctype) and isinstance(cached_doc, BaseDocument): # Saves a lot of frappe.get_cached_doc calls # - We do not want to check perms for child tables # - We load child doc only if doc is not an instance of BaseDocument pass elif __ignore_perms: pass else: try: # Permission check after the document is confirmed to exist # verbose check of is_owner of doc # In the case when object signature lead into document resolver # But the document no longer exists in database if not isinstance(cached_doc, BaseDocument): cached_doc = frappe.get_cached_doc(doctype, obj.get("name")) frappe.has_permission(doctype=doctype, doc=cached_doc, throw=True) role_permissions = frappe.permissions.get_role_permissions(doctype) if role_permissions.get("if_owner", {}).get("read"): if cached_doc.get("owner") != frappe.session.user: frappe.throw( frappe._("No permission for {0}").format( doctype + " " + obj.get("name"))) # apply field level read perms cached_doc.apply_fieldlevel_read_permissions() except frappe.DoesNotExistError: pass meta = frappe.get_meta(doctype) df = meta.get_field(info.field_name) if not df: if info.field_name in default_fields: df = get_default_field_df(info.field_name) def _get_value(fieldname, ignore_translation=False): # Preference to fetch from obj first, cached_doc later if obj.get(fieldname) is not None: value = obj.get(fieldname) else: value = cached_doc.get(fieldname) # ignore_doc_resolver_translation might be helpful for overriding document_resolver # which might be a simple wrapper around this function (document_resolver) if not ignore_translation and isinstance( value, str) and not frappe.flags.ignore_doc_resolver_translation: return frappe._(value) if __ignore_perms: if isinstance(value, list): for item in value: item.update({"__ignore_perms": __ignore_perms}) elif isinstance(value, (BaseDocument, dict)): value.update({"__ignore_perms": __ignore_perms}) return value if info.field_name.endswith("__name"): fieldname = info.field_name.split("__name")[0] return _get_value(fieldname, ignore_translation=True) elif df: if df.fieldtype in ("Link", "Dynamic Link"): if not _get_value(df.fieldname): return None link_dt = df.options if df.fieldtype == "Link" else \ _get_value(df.options, ignore_translation=True) return frappe._dict(name=_get_value(df.fieldname, ignore_translation=True), doctype=link_dt, __ignore_perms=__ignore_perms) elif df.fieldtype == "Select": # We allow Select fields whose returnType is just Strings return_type = info.return_type if isinstance(return_type, GraphQLNonNull): return_type = return_type.of_type if isinstance(return_type, GraphQLEnumType): value = _get_value(df.fieldname, ignore_translation=True) or "" return frappe.scrub(value).upper() return _get_value(info.field_name)
def get_translations(language: str, doctype: str, docname: str = None, docfield: str = None): """ Try and get all possible translations as seen in Translation doctype only.. Arguments: language: [Required] doctype: [Required] docname: [Optional] docfield: [Optional] """ __check_read_renovation_translation_tool_perm() if is_single(doctype): docname = doctype possible_contexts = __formulate_possible_contexts(doctype=doctype, fieldname=docfield, docname=docname) if frappe.is_table(doctype): possible_parenttypes_and_parents = frappe.get_all(doctype, fields="Distinct parent,parenttype", filters=[["parenttype", "!=", ""], ['parent', '!=', '']]) for p in possible_parenttypes_and_parents: possible_contexts.extend( __formulate_possible_contexts(parenttype=p.get("parenttype"), parent=p.get("parent"))) filters = [["language", "=", language]] context_filters = [["context", "in", possible_contexts]] filters_conditions = [] context_filters_conditions = [] DatabaseQuery("Translation").build_filter_conditions(filters, filters_conditions, ignore_permissions=True) DatabaseQuery("Translation").build_filter_conditions(context_filters, context_filters_conditions, ignore_permissions=True) filters_conditions = ' and '.join(filters_conditions) where_conditions = filters_conditions context_filters_conditions = ' or '.join(context_filters_conditions) if doctype and not docname and not docfield: context_filters_conditions += f" or context LIKE '{doctype}:%'" if doctype and docfield and not docname: context_filters_conditions += f" or (context LIKE '{doctype}:%' and context LIKE '%:{docfield}')" if doctype and docname and not docfield: context_filters_conditions += f" or context LIKE '{doctype}:{docname}%'" where_conditions += f" and ( {context_filters_conditions} )" sql = """ SELECT `tabTranslation`.name, # extract doctype from context SUBSTRING_INDEX(context, ':', 1) as 'document_type', # extract docname from context CASE LENGTH(context) - LENGTH(REPLACE(context, ':', '')) WHEN 2 THEN SUBSTR(context, LOCATE(':', context) + 1, LOCATE(':', SUBSTR(context, LOCATE(':', context) + 1), 1) - 1) WHEN 1 THEN SUBSTRING_INDEX(context, ':', -1) ELSE '' END as 'docname', # extract docfield from context IF(LENGTH(context) - LENGTH(REPLACE(context, ':', '')) = 2, SUBSTRING_INDEX(context, ':', -1),'') as 'docfield', # extract value from context if docname and docfield are present IF(length(SUBSTRING_INDEX(context, ':', 1)) and length((SUBSTR(context, LOCATE(':', context) + 1, LOCATE(':', SUBSTR(context, LOCATE(':', context) + 1), 1) - 1))) and length(IF(LENGTH(context) - LENGTH(REPLACE(context, ':', '')) = 2, SUBSTRING_INDEX(context, ':', -1), '')),({select_condition}), '') as 'value', source_text, translated_text , context from `tabTranslation` where {where_conditions} """.format(where_conditions=where_conditions, select_condition=( "(SELECT `tab{doctype}`.{docfield} from `tab{doctype}` WHERE `tab{doctype}`.name ='{docname}')".format( doctype=doctype, docfield=docfield, docname=docname) if not is_single(doctype) else """ (SELECT `tabSingles`.value from `tabSingles` WHERE `tabSingles`.doctype = '{doctype}' and `tabSingles`.field = '{docfield}') """.format(doctype=doctype, docfield=docfield)) if docfield else frappe.db.escape("")) translations = [{**translation, 'value': frappe.get_cached_value(translation.get("document_type"), translation.get("docname"), translation.get("docfield")) if translation.get( "document_type") and translation.get("docname") and translation.get( "docfield") and (frappe.db.table_exists(translation.get("document_type")) or is_single( translation.get("document_type"))) and frappe.db.exists( translation.get("document_type"), translation.get("docname")) else translation.get("value") } for translation in frappe.db.sql(sql, as_dict=1, debug=0)] return { "translations": translations }
def has_permission(doctype, ptype="read", doc=None, verbose=False, user=None, raise_exception=True): """Returns True if user has permission `ptype` for given `doctype`. If `doc` is passed, it also checks user, share and owner permissions. Note: if Table DocType is passed, it always returns True. """ if not user: user = frappe.session.user if not doc and hasattr(doctype, 'doctype'): # first argument can be doc or doctype doc = doctype doctype = doc.doctype if frappe.is_table(doctype): return True if user=="Administrator": return True meta = frappe.get_meta(doctype) if doc: if isinstance(doc, string_types): doc = frappe.get_doc(meta.name, doc) perm = get_doc_permissions(doc, user=user, ptype=ptype).get(ptype) if not perm: push_perm_check_log('User do not have document access') else: if ptype=="submit" and not cint(meta.is_submittable): push_perm_check_log("Doctype is not submittable") return False if ptype=="import" and not cint(meta.allow_import): push_perm_check_log("Doctype is not importable") return False role_permissions = get_role_permissions(meta, user=user) perm = role_permissions.get(ptype) if not perm: push_perm_check_log('User do not have doctype access via role permission') def false_if_not_shared(): if ptype in ("read", "write", "share", "email", "print"): shared = frappe.share.get_shared(doctype, user, ["read" if ptype in ("email", "print") else ptype]) if doc: doc_name = get_doc_name(doc) if doc_name in shared: if ptype in ("read", "write", "share") or meta.permissions[0].get(ptype): return True elif shared: # if atleast one shared doc of that type, then return True # this is used in db_query to check if permission on DocType return True return False if not perm: perm = false_if_not_shared() return perm
def has_permission(doctype, ptype="read", doc=None, verbose=False, user=None): """Returns True if user has permission `ptype` for given `doctype`. If `doc` is passed, it also checks user, share and owner permissions. Note: if Table DocType is passed, it always returns True. """ if not user: user = frappe.session.user if frappe.is_table(doctype): if verbose: print "Table type, always true" return True meta = frappe.get_meta(doctype) if ptype=="submit" and not cint(meta.is_submittable): if verbose: print "Not submittable" return False if ptype=="import" and not cint(meta.allow_import): if verbose: print "Not importable" return False if user=="Administrator": if verbose: print "Administrator" return True def false_if_not_shared(): if ptype in ("read", "write", "share", "email", "print"): shared = frappe.share.get_shared(doctype, user, ["read" if ptype in ("email", "print") else ptype]) if doc: doc_name = doc if isinstance(doc, basestring) else doc.name if doc_name in shared: if verbose: print "Shared" if ptype in ("read", "write", "share") or meta.permissions[0].get(ptype): if verbose: print "Is shared" return True elif shared: # if atleast one shared doc of that type, then return True # this is used in db_query to check if permission on DocType if verbose: print "Has a shared document" return True if verbose: print "Not Shared" return False role_permissions = get_role_permissions(meta, user=user, verbose=verbose) if not role_permissions.get(ptype): return false_if_not_shared() perm = True if doc: if isinstance(doc, basestring): doc = frappe.get_doc(meta.name, doc) owner_perm = user_perm = controller_perm = None if role_permissions["if_owner"].get(ptype) and ptype!="create": owner_perm = doc.owner == frappe.session.user if verbose: print "Owner permission: {0}".format(owner_perm) # check if user permission if not owner_perm and role_permissions["apply_user_permissions"].get(ptype): user_perm = user_has_permission(doc, verbose=verbose, user=user, user_permission_doctypes=role_permissions.get("user_permission_doctypes", {}).get(ptype) or []) if verbose: print "User permission: {0}".format(user_perm) if not owner_perm and not user_perm: controller_perm = has_controller_permissions(doc, ptype, user=user) if verbose: print "Controller permission: {0}".format(controller_perm) # permission true if any one condition is explicitly True or all permissions are undefined (None) perm = any([owner_perm, user_perm, controller_perm]) or \ all([owner_perm==None, user_perm==None, controller_perm==None]) if not perm: perm = false_if_not_shared() if verbose: print "Final Permission: {0}".format(perm) return perm