Reputation: 828
I'm working on an API and have this ViewSet:
class ProjectViewSet(viewsets.ModelViewSet):
# API endpoint that allows projects to be viewed or edited.
queryset = Project.objects.all()
serializer_class = ProjectSerializer
authentication_classes = used_authentication_classes
permission_classes = (IsOwner,)
@detail_route(methods=['get'])
def functions(self, request, pk=None):
project = self.get_object()
if project is None:
return Response({'detail': 'Missing project id'}, status=404)
return Response([FunctionSerializer(x).data for x in Function.objects.filter(project=project)])
A permission system is attached to this API. The permissions work fine for a single resource. But when I call api/projects
which should return all of the projects the user has access to, it does in fact return all of the projects, regardless whether the user should be able to GET a certain project in the list or not.
So I overwrote the get_queryset
method to only return the projects the user has access to:
def get_queryset(self):
if self.request.user.is_superuser or self.request.user.is_staff:
return Project.objects.all()
else:
return Project.objects.filter(user=self.request.user.user)
This works, but now the API returns a 404 instead of a 403 when I ask for a specific resource I don't have access to.
I understand why, because the PK from the resource I try to get is undefined since I only return projects the user has access to. What I don't understand is how to fix this.
Does anyone know how I can make it return a 403, or maybe an idea towards where I should look?
Upvotes: 3
Views: 632
Reputation:
as @Alasdair say the 404 is a deliberate choice, but if you still want to get 403 you can try:
def get_queryset(self):
user = self.request.user
allow_all = user.is_superuser or user.is_staff
if self.action == 'list' and not allow_all:
return Project.objects.filter(user=user)
return Project.objects.all()
Upvotes: 4