Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

How do we check permissions for related entities? #450

Closed
@Anton-Shutik

Description

@Anton-Shutik

Let's say we have config like this:

views.py

classCustomerProfileViewSet(viewsets.ModelViewSet):permission_classes= (IsCustomerOrCreation,)classProductViewSet(viewsets.ModelViewSet):permission_classes= []defget_object(self,):customer_pk=self.kwargs.get('customer_pk',None)ifcustomer_pkisnotNone:customer=get_object_or_None(Customer,pk=customer_pk)ifcustomerisnotNone:returncustomer.favourite_productreturnsuper(ProductViewSet,self).get_object()

urls.py

url(r'^api/customer/(?P<pk>\d+)/$',CustomerProfileViewSet.as_view({'get':'retrieve'})),url(r'^api/customer/(?P<customer_pk>\d+)/favorite-product$',ProductViewSet.as_view({'get':'retrieve'})),

GET api/customer/1/ Will give 403 error for any user whose id differs from 1. And that is fine.
Then if anon user goes toapi/customer/1/favourite-product/ they will get 200 response with product payload, because permissions for product checked inProductViewSet, which have no permissions for any role. But I think it is wrong and should return 403, since we have to check permission for customer first. We actually just told everybody what is customer's 1 favorite product!

I understand that permissions it is out of json api spec, but may be there is a nice way I can handle permissions with this lib correctly?

For now I do it like below:
A RelatedMixin class will get a related entity and will find corresponding a serializer for that. And all that stuff will happenafter we check permissions for parent ("customer" in the case) entity

classRelatedMixin(object):serializer_mapping= {}field_name_mapping= {}defget_related(self,request,*args,**kwargs):serializer_kwargs= {}instance=self.get_related_instance()ifcallable(instance):instance=instance()ifhasattr(instance,'all'):instance=instance.all()ifinstanceisNone:returnResponse(data=None)ifisinstance(instance,Iterable):serializer_kwargs['many']=Trueserializer=self.get_serializer(instance,**serializer_kwargs)returnResponse(serializer.data)defget_serializer_class(self):field_name=self.get_related_field_name()returnself.serializer_mapping[field_name]defget_related_field_name(self):field_name=self.kwargs['related_field']iffield_nameinself.field_name_mapping:returnself.field_name_mapping[field_name]returnfield_namedefget_related_instance(self):try:returngetattr(self.get_object(),self.get_related_field_name())exceptAttributeError:fromrest_framework.exceptionsimportNotFoundraiseNotFound

and then just make a view that will handle all Customer's related entities:

classCustomerProfileRelatedViewSet(RelatedMixin,CustomerProfileViewSet):serializer_mapping= {'favourite_product':ProductSerializer,#'order_list': OrderSerializer}

urls.py # Only one url route required for all related entities

url(r'^api/customer/(?P<customer_pk>\d+)/(?P<related_field>\w+)/$',CustomerProfileRelatedViewSet.as_view({'get':'get_related'})),

What do you think about it ? If you like the idea I'm ready to come up with PR

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions


      [8]ページ先頭

      ©2009-2025 Movatter.jp