Beispiel #1
0
    def get(self, request, *args, **kwargs):
        obj = self.get_object(kwargs)
        perm = self.get_required_permission()

        if not request.user.has_perm(perm, obj):
            raise PermissionDenied('%s %s' %
                                   (resolve_permission(perm)[1], obj))

        return super().get(request, *args, **kwargs)
Beispiel #2
0
    def post(self, request, *args, **kwargs):
        perm = self.get_required_permission()

        if request.POST.get('_all'):
            qs = self.queryset.all()

            if self.filterset:
                qs = self.filterset(request.GET, qs).qs

        else:
            qs = self.queryset.filter(pk__in=request.POST.getlist('pk'))

        for obj in qs.iterator():
            if not request.user.has_perm(perm, obj):
                raise PermissionDenied('%s %s' %
                                       (resolve_permission(perm)[1], obj))

        return super().post(request, *args, **kwargs)
    def has_perm(self, user_obj, perm, obj=None):
        app_label, action, model_name = resolve_permission(perm)

        # Superusers implicitly have all permissions
        if user_obj.is_active and user_obj.is_superuser:
            return True

        # Permission is exempt from enforcement (i.e. listed in EXEMPT_VIEW_PERMISSIONS)
        if permission_is_exempt(perm):
            return True

        # Handle inactive/anonymous users
        if not user_obj.is_active or user_obj.is_anonymous:
            return False

        # If no applicable ObjectPermissions have been created for this user/permission, deny permission
        if perm not in self.get_all_permissions(user_obj):
            return False

        # If no object has been specified, grant permission. (The presence of a permission in this set tells
        # us that the user has permission for *some* objects, but not necessarily a specific object.)
        if obj is None:
            return True

        # Sanity check: Ensure that the requested permission applies to the specified object
        model = obj._meta.model
        if model._meta.label_lower != '.'.join((app_label, model_name)):
            raise ValueError(f"Invalid permission {perm} for model {model}")

        # Compile a query filter that matches all instances of the specified model
        obj_perm_constraints = self.get_all_permissions(user_obj)[perm]
        constraints = Q()
        for perm_constraints in obj_perm_constraints:
            if perm_constraints:
                constraints |= Q(**perm_constraints)
            else:
                # Found ObjectPermission with null constraints; allow model-level access
                constraints = Q()
                break

        # Permission to perform the requested action on the object depends on whether the specified object matches
        # the specified constraints. Note that this check is made against the *database* record representing the object,
        # not the instance itself.
        return model.objects.filter(constraints, pk=obj.pk).exists()