Skip to content

Backends

ObjectPermissionBackend

Django backend for checking object-level permissions.

Source code in guardian/backends.py
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
class ObjectPermissionBackend:
    """Django backend for checking object-level permissions."""

    supports_object_permissions = True
    supports_anonymous_user = True
    supports_inactive_user = True

    def authenticate(self, request: HttpRequest, username: Optional[str] = None, password: Optional[str] = None) -> Any:
        return None

    def has_perm(self, user_obj: Any, perm: str, obj: Optional[Model] = None) -> bool:
        """Check if a user has the permission for a given object.

        Returns `True` if given `user_obj` has `perm` for `obj`.
        If no `obj` is given, `False` is returned.
        The main difference between Django's `ModelBackend` is that we can pass
        `obj` instance here and `perm` doesn't have to contain
        `app_label` as it can be retrieved from given `obj`.

        **Inactive user support**

        If `user` is authenticated but inactive at the same time, all checks
        always return `False`.

        Note:
           Remember, that if user is not *active*, all checks would return `False`.

        Parameters:
            user_obj (User): User instance.
            perm (str): Permission string.
            obj (Model): Model instance.

        Returns:
            `True` if `user_obj` has permission, `False` otherwise.
        """

        # check if user_obj and object are supported
        support, user_obj = check_support(user_obj, obj)
        if not support:
            return False

        if "." in perm:
            app_label, _ = perm.split(".", 1)
            # TODO (David Graham): Check if obj is None or change the method signature
            if app_label != obj._meta.app_label:  # type: ignore[union-attr]
                # Check the content_type app_label when permission
                # and obj app labels don't match.
                ctype = get_content_type(obj)
                if app_label != ctype.app_label:
                    raise WrongAppError(
                        "Passed perm has app label of '%s' while "
                        "given obj has app label '%s' and given obj"
                        "content_type has app label '%s'" % (app_label, obj._meta.app_label, ctype.app_label)  # type: ignore[union-attr]
                    )

        check = ObjectPermissionChecker(user_obj)
        return check.has_perm(perm, obj)

    def get_group_permissions(self, user_obj: Any, obj: Optional[Model] = None) -> Iterable[str]:
        """Returns group permissions for a given object.

        Parameters:
            user_obj (User): User instance.
            obj (Model): Django Model instance. If None, returns empty set
                        since this backend only handles object-level permissions.

        Returns:
             a set of permission strings that the given `user_obj` has for `obj`
             through their group memberships.
        """
        # This backend only handles object-level permissions
        if obj is None:
            return set()

        # check if user_obj and object are supported
        support, user_obj = check_support(user_obj, obj)
        if not support:
            return set()

        check = ObjectPermissionChecker(user_obj)
        return set(check.get_group_perms(obj))

    def get_all_permissions(self, user_obj: Any, obj: Optional[Model] = None) -> Iterable[str]:
        """Returns all permissions for a given object.

        Parameters:
            user_obj (User): User instance.
            obj (Model): Django Model instance.

        Returns:
             a set of permission strings that the given `user_obj` has for `obj`.
        """
        # check if user_obj and object are supported
        support, user_obj = check_support(user_obj, obj)
        if not support:
            return set()

        check = ObjectPermissionChecker(user_obj)
        return set(check.get_perms(obj))

get_all_permissions(user_obj, obj=None)

Returns all permissions for a given object.

Parameters:

Name Type Description Default
user_obj User

User instance.

required
obj Model

Django Model instance.

None

Returns:

Type Description
Iterable[str]

a set of permission strings that the given user_obj has for obj.

Source code in guardian/backends.py
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
def get_all_permissions(self, user_obj: Any, obj: Optional[Model] = None) -> Iterable[str]:
    """Returns all permissions for a given object.

    Parameters:
        user_obj (User): User instance.
        obj (Model): Django Model instance.

    Returns:
         a set of permission strings that the given `user_obj` has for `obj`.
    """
    # check if user_obj and object are supported
    support, user_obj = check_support(user_obj, obj)
    if not support:
        return set()

    check = ObjectPermissionChecker(user_obj)
    return set(check.get_perms(obj))

get_group_permissions(user_obj, obj=None)

Returns group permissions for a given object.

Parameters:

Name Type Description Default
user_obj User

User instance.

required
obj Model

Django Model instance. If None, returns empty set since this backend only handles object-level permissions.

None

Returns:

Type Description
Iterable[str]

a set of permission strings that the given user_obj has for obj

Iterable[str]

through their group memberships.

Source code in guardian/backends.py
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
def get_group_permissions(self, user_obj: Any, obj: Optional[Model] = None) -> Iterable[str]:
    """Returns group permissions for a given object.

    Parameters:
        user_obj (User): User instance.
        obj (Model): Django Model instance. If None, returns empty set
                    since this backend only handles object-level permissions.

    Returns:
         a set of permission strings that the given `user_obj` has for `obj`
         through their group memberships.
    """
    # This backend only handles object-level permissions
    if obj is None:
        return set()

    # check if user_obj and object are supported
    support, user_obj = check_support(user_obj, obj)
    if not support:
        return set()

    check = ObjectPermissionChecker(user_obj)
    return set(check.get_group_perms(obj))

has_perm(user_obj, perm, obj=None)

Check if a user has the permission for a given object.

Returns True if given user_obj has perm for obj. If no obj is given, False is returned. The main difference between Django's ModelBackend is that we can pass obj instance here and perm doesn't have to contain app_label as it can be retrieved from given obj.

Inactive user support

If user is authenticated but inactive at the same time, all checks always return False.

Note

Remember, that if user is not active, all checks would return False.

Parameters:

Name Type Description Default
user_obj User

User instance.

required
perm str

Permission string.

required
obj Model

Model instance.

None

Returns:

Type Description
bool

True if user_obj has permission, False otherwise.

Source code in guardian/backends.py
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
def has_perm(self, user_obj: Any, perm: str, obj: Optional[Model] = None) -> bool:
    """Check if a user has the permission for a given object.

    Returns `True` if given `user_obj` has `perm` for `obj`.
    If no `obj` is given, `False` is returned.
    The main difference between Django's `ModelBackend` is that we can pass
    `obj` instance here and `perm` doesn't have to contain
    `app_label` as it can be retrieved from given `obj`.

    **Inactive user support**

    If `user` is authenticated but inactive at the same time, all checks
    always return `False`.

    Note:
       Remember, that if user is not *active*, all checks would return `False`.

    Parameters:
        user_obj (User): User instance.
        perm (str): Permission string.
        obj (Model): Model instance.

    Returns:
        `True` if `user_obj` has permission, `False` otherwise.
    """

    # check if user_obj and object are supported
    support, user_obj = check_support(user_obj, obj)
    if not support:
        return False

    if "." in perm:
        app_label, _ = perm.split(".", 1)
        # TODO (David Graham): Check if obj is None or change the method signature
        if app_label != obj._meta.app_label:  # type: ignore[union-attr]
            # Check the content_type app_label when permission
            # and obj app labels don't match.
            ctype = get_content_type(obj)
            if app_label != ctype.app_label:
                raise WrongAppError(
                    "Passed perm has app label of '%s' while "
                    "given obj has app label '%s' and given obj"
                    "content_type has app label '%s'" % (app_label, obj._meta.app_label, ctype.app_label)  # type: ignore[union-attr]
                )

    check = ObjectPermissionChecker(user_obj)
    return check.has_perm(perm, obj)