Esempio n. 1
0
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
Esempio n. 2
0
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
Esempio n. 3
0
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)
Esempio n. 4
0
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
Esempio n. 5
0
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
Esempio n. 6
0
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)
Esempio n. 7
0
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
Esempio n. 8
0
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
Esempio n. 9
0
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
Esempio n. 10
0
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
Esempio n. 11
0
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
Esempio n. 12
0
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
Esempio n. 13
0
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
Esempio n. 14
0
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]
Esempio n. 15
0
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)
Esempio n. 16
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
Esempio n. 17
0
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)
Esempio n. 18
0
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)
Esempio n. 19
0
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()
Esempio n. 20
0
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()
Esempio n. 21
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)

    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
Esempio n. 22
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

	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
Esempio n. 23
0
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
Esempio n. 24
0
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)
Esempio n. 25
0
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
Esempio n. 26
0
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
Esempio n. 27
0
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
Esempio n. 28
0
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
Esempio n. 29
0
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
Esempio n. 30
0
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
Esempio n. 31
0
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
Esempio n. 32
0
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)
Esempio n. 34
0
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
    }
Esempio n. 35
0
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
Esempio n. 36
0
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