question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Allow create for staff, update for staff or owner

See original GitHub issue

I’m adding a user resource to an API.

I want the following permission logic:

  • Staff may do anything
  • Users may read and update themselves

So I start out with this:

@staticmethod
def has_write_permission(request):
    return request.user.is_staff

Now staff users can create other users, but regular users can’t.

Next, I want to allow users to update themselves, so I add the following:

def has_object_write_permission(self, request):
    return request.user.is_staff or request.user == self

However, the method is never called because the write permission is already denied globally.

So I update the code as follows:

@staticmethod
def has_write_permission(request):
    return True

def has_object_write_permission(self, request):
    return request.user.is_staff or request.user == self

Now the code first calls has_write_permission, then has_object_write_permission. This is fine.

But now any user has the create permission. I want to limit creation to staff. So I add the following method:

@staticmethod
def has_create_permission(request):
    return request.user.is_staff

However, this method is never queried by dry-rest-permissions. Only has_write_permission is called, which already grants the permission.

Am I mis-understanding the concept of dry-rest-permissions?

Issue Analytics

  • State:open
  • Created 7 years ago
  • Comments:6 (2 by maintainers)

github_iconTop GitHub Comments

2reactions
dbrgncommented, Mar 17, 2017

Actually something like this helped already:

class ActionMixin:
    """
    This mixin adds an ``.action`` attribute to the view based on the
    ``action_map`` attribute, similar to the way a ``ViewSet`` does it.

    Example::

        class UserDetail(ActionMixin, generics.RetrieveUpdateAPIView):
            queryset = models.User.objects.all()
            serializer_class = serializers.UserSerializer
            action_map = {
                'get': 'retrieve',
                'put': 'update',
                'patch': 'partial_update',
            }

    """
    def initialize_request(self, request, *args, **kwargs):
        """
        Set the `.action` attribute on the view,
        depending on the request method.
        """
        request = super().initialize_request(request, *args, **kwargs)
        method = request.method.lower()
        if method == 'options':
            # This is a special case as we always provide handling for the
            # options method in the base `View` class.
            # Unlike the other explicitly defined actions, 'metadata' is implicit.
            self.action = 'metadata'
        else:
            self.action = self.action_map.get(method)
        return request


class DocumentActionMixin(ActionMixin):
    """
    Add an ``.action`` attribute to a document type view.
    """
    action_map = {
        'get': 'retrieve',
        'put': 'update',
        'patch': 'partial_update',
        'delete': 'destroy',
    }


class CollectionActionMixin(ActionMixin):
    """
    Add an ``.action`` attribute to a collection type view.
    """
    action_map = {
        'get': 'list',
        'post': 'create',
    }

But a clear note in the documentation would probably help.

0reactions
jpipascommented, Jul 19, 2017

I was using GenericAPIView’s and also had the problem of exceptions when I didn’t include has_write_permission, nor was the precedence of has_object_update_permission over the global has_write_permission being followed.

Using the mixin that @dbrgn provided with slight modification to super() (I’m using Python 2.7), I was able to get it to work properly with/using APIViews instead of ViewSets.

Here’s my modified mixin in case anyone needs it:

from rest_framework import (
    generics,
)


class ActionMixin:
    """
    This mixin adds an ``.action`` attribute to the view based on the
    ``action_map`` attribute, similar to the way a ``ViewSet`` does it.

    Example::

        class UserDetail(ActionMixin, generics.RetrieveUpdateAPIView):
            queryset = models.User.objects.all()
            serializer_class = serializers.UserSerializer
            action_map = {
                'get': 'retrieve',
                'put': 'update',
                'patch': 'partial_update',
            }

    """
    def initialize_request(self, request, *args, **kwargs):
        """
        Set the `.action` attribute on the view,
        depending on the request method.
        """
        request = super(generics.GenericAPIView, self).initialize_request(request, *args, **kwargs)
        method = request.method.lower()
        if method == 'options':
            # This is a special case as we always provide handling for the
            # options method in the base `View` class.
            # Unlike the other explicitly defined actions, 'metadata' is implicit.
            self.action = 'metadata'
        else:
            self.action = self.action_map.get(method)
        return request
Read more comments on GitHub >

github_iconTop Results From Across the Web

Managing staff - Shopify Help Center
To give the staff member all available permissions, select Select all. Click Save. Update staff details. You can always make changes to your...
Read more >
Use OneNote Staff Notebook in Teams - Microsoft Support
Staff team creators own the notebook and have administrative permissions that allow them to add other members/co-owners and manage the notebook's settings.
Read more >
Appointments: Staff Profiles Vs. Team Permission Groups
Team Permissions allow you to limit your staff's access to both the Appointments calendar and the point of sale. The preset groups (Service...
Read more >
Adding and Editing Employees and Wages in Toast's Back-end
In order to make these updates, you must have the Employee Jobs & Wages permission AND you must have the same permissions as...
Read more >
Team permissions – Figma Help Center
Who can use this feature Supported on any team or plan Teams allow you to create and share resources and collaborate on files...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found