Django Rest Framework is ignoring my IsOwnerOrReadOnly permissions

I created a permissions file for permission isOwnerOrReadOnly

, but the has_object_permission function is not called at all (I am setting the print instruction there).

This is how I use this permission in my view:

class CarDetail(generics.RetrieveUpdateDestroyAPIView):
  .....

  serializer_class = car_serializers.CarSerializer
  authentication_classes = (authentication.TokenAuthentication,)
  permission_classes = (permissions.IsAuthenticatedOrReadOnly,IsOwnerOrReadOnly,)

      

What am I missing?

+3


source to share


2 answers


@adeleinr I am assuming you have declared your own get_object method (I would ask you about this in a comment, but have no good reason to do so: D), in which case you need to use check_object_permissions on get_object (also in PUT, DELETE). Use this in your get_object



obj = get_object_or_404(queryset, **filter)
self.check_object_permissions(self.request, obj)

      

+3


source


I was inspired by the article How can I delete any YouTube video and wanted to check if django works safely in my project, and ended up here.

This is a pretty important question! And the answer is very good.

Django Rest Framework

makes the false impression that everything is working fine when you look at it through the API view.

The object that authenticates the user: enter image description here

The entity that authenticates the user has NOT : enter image description here

The hidden DELETE button makes you feel like everything is fine.

You are authenticated, the delete button is hidden. Cool! You don't notice until you test it with CURL or some other tool and spot this huge security hole.

Django is sometimes too much magic ...

Example:

views.py



@authentication_classes((ExpiringTokenAuthentication, SessionAuthentication))
@permission_classes((IsOwnerOrReadOnly, ))
class UserFavouritesSpotDetail(RetrieveUpdateDestroyAPIView):
    model = UsersSpotsList
    serializer_class = FavouritesSpotsListSerializer

    def get_queryset(self):
        queryset = UsersSpotsList.objects.filter(
            role=1)
        return queryset

    def get_object(self):
        queryset = self.get_queryset()
        obj = get_object_or_404(
            queryset,
            pk=self.kwargs['pk'],
            role=1)
        self.check_object_permissions(self.request, obj)
        return obj

      

Note the key line mentioned by Shivansh:

 self.check_object_permissions(self.request, obj)

      

When I was absent, this vulnerability existed.

permissions.py

from rest_framework import permissions


class IsOwnerOrReadOnly(permissions.BasePermission):
    """
    Object-level permission to only allow owners of an object to edit it.
    Assumes the model instance has an `user` attribute.
    """

    def has_object_permission(self, request, view, obj):
        # Read permissions are allowed to any request,
        # so we'll always allow GET, HEAD or OPTIONS requests.
        if request.method in permissions.SAFE_METHODS:
            return True

        return obj.user == request.user

      

TEST, for example http://www.getpostman.com/

provide the token of the user who does not own the object.

If everything is in order, you should see a "detail": "You do not have permission to perform this action."

enter image description here

+2


source







All Articles