简体   繁体   中英

How can custom values be passed from a DRF ModelViewSet to a permissions class?

I've set up a custom permissions class to be reused from multiple views, in an app where some users have ownership-like rights on behalf of other users:

class IsOwnerLike(permissions.BasePermission):
    def has_permission(self, request, view):
        if (
            user_is_owner(request.user, request.data["owned_by"])
            | user_is_owner_like(request.user, request.data["owned_by"])
        ):
            return True

        return False

This works as expected for one ModelViewSet.

However, for legacy reasons, different requests coming in to different views may not have an "owned_by" data element -- it may be called "owned", "owner", "created_by", etc. -- and therefore I can't reuse this custom permission as written.

What is the correct way to abstract things at the viewset, to normalize data being passed to my custom permissions class? Can this be done, or should I be thinking about handling these permissions differently?

Found a solution.

I was able to add a custom attribute to the view:

class ViewOne(ModelViewSet):
    ownership_fieldname = "owned_by"
    permission_classes = [IsOwnerLike]

    ...

class ViewTwo(ModelViewSet):
    ownership_fieldname = "owner"
    permission_classes = [IsOwnerLike]
    ...

And then access it in the permission:

class IsOwnerLike(permissions.BasePermission):
    def has_permission(self, request, view):
        if (
            user_is_owner(request.user, request.data[view.ownership_fieldname])
            | user_is_owner_like(request.user, request.data[view.ownership_fieldname])
        ):
            return True

        return False

you should use from has_object_permission for object check for model access permission like this:

    def has_object_permission(self, request, view, obj):
        if hasattr(obj, 'owner'):
           if obj.user == request.user:
              return True
        return False

you can change owner with your models owner field name

and for pass owner kwargs to permission class you should write custommModelViewSet and inheritance from ModelViewSet and override get_permissions() method

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM