Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: Add a third method for permissions classes (has_list_permissions) #3220

Closed
ralmidani opened this issue Aug 5, 2015 · 3 comments
Closed

Comments

@ralmidani
Copy link

Real use case: An HR app.

I want only admin users to be able to see a list of all employees, and employees to only be able to see their own employee object.

Here is my current code:

from rest_framework import permissions

class IsEmployeeOrIsAdmin(permissions.BasePermission):

    def has_permission(self, request, view):
        return request.user.is_staff

    def has_object_permission(self, request, view, obj):
        return request.user.is_staff or request.user == obj.user

The problem with the above is has_permission() always runs. If I keep it, users will not be able to see their own info. If I remove it, they will be able to see a list of all employees.

The has_object_permissions() method was added in DRF 2.2 to eliminate the need to check for an obj argument.

I propose allowing the implementation of a has_list_permission() method which only runs when requesting a list of all objects. This would allow more flexible permissions systems without having to define custom behavior in the View or ViewSet.

I tried filtering in the get_queryset() method, but when requesting another Employee as a non-admin I would get the status HTTP_404_NOT_FOUND, which is not the proper status for a forbidden request.

@tomchristie
Copy link
Member

You can already achieve permission behavior specific to list actions be any of:

  • Separate views for the list and detail views, apply differing permission classes to each.
  • Inspect view.action == 'list' in the permission class and act accordingly.
  • Inspect request.method == 'GET' and not 'pk' in view.kwarg (For example) and act accordingly.

@ralmidani
Copy link
Author

@tomchristie Everything is working now. Thank you.

Your issue #2941 calls for documentation of view.action and this is the approach I used to solve my problem.

@tomchristie
Copy link
Member

Great. That ones def on the radar - we'll get around to it soon enough.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants