Search code examples
djangotastypie

Django Tastypie Authentication for prepend_urls methods


My application has several user types admin, user and manager.

I have defined an endpoint for a Resource, which has several prepend_urls. eg: the endpoints would be

/Profile/search/
/Profile/shortview/
/Profile/

How can I limit access to the endpoints such that

/Profile/search/ is accessible to admin, manager
/Profile/shortview/ is accessible to all
/Profile/ is accessible to admin only

I have thought of using my own class but for authentication and authorization but think they are applied to the entire resource not individual prepend_url endpoints.

authorization = MyAuthorization()
authentication= MyAuthentication()

Any help is appreciated


Solution

  • I'm going to suppose you have been configured your prepend_urls and hence you have wrapped a function called dispatch_search, so something like this will raise an exception if user is unauthorized to use the endpoint:

    def dispatch_search(self, request, *args, **kwargs):
        # check authorization here
        self._meta.authorization.is_authorized(request)
    

    Edited from here below

    When inheriting from the DjangoAuthorization class, you also can override the methods:

    • read_detail(self, object_list, bundle)
    • read_list(self, object_list, bundle)

    to raise an exception if user should not be able to read an specific resource or the resource list itself.

    And your MyAuthorization class:

    from tastypie.exceptions import Unauthorized
    from tastypie.authorization import DjangoAuthorization
    
    class MyAuthorization(DjangoAuthorization):
        def is_authorized(self, request):
            if request.user.is_superuser and 'search' in request.path:
                return True
            # more business logic here to check the other endpoints
            raise Unauthorized('Unauthorized :(')
    
        def read_list(self, object_list, bundle):
            self.is_authorized(bundle.request)  # call your custom validation
            # Fallback to the DjangoAuthorization read_list
            return super(MyAuthorization, self).read_list(object_list, bundle)
    

    Refer to the docs for a complete list of functions you can override to add more business logic: http://django-tastypie.readthedocs.org/en/latest/authorization.html#the-authorization-api