Search code examples
pythondjangotastypie

how to limit GET,POST access to resources using customize user type in tastypie


I have extended Django default 'User' model for add new user type field. user type categories are user, admin and viewer. And i want to implement RESTapi for this using tastypie and give permission to access that api based on user type. for example Admin users have full access to this API, user can view all fields but can only update their own account, viewer have no access to this api.

api.py

    class UserResource(ModelResource):
        class Meta:
            queryset = CustomUser.objects.all()
            resource_name = 'user'
            allowed_methods = ['get','post']
            filtering = {"id": ALL}
            excludes = ['is_staff','password','is_superuser','id','is_active','date_joined']
            authentication =  BasicAuthentication()

What is the best way to handle this?


Solution

  • First, write Your own authentication class. In this class check if user is viewer. If yes, return False.

    class MyAuthentication(BasicAuthentication):
        def is_authenticated(self, request, **kwargs):
            is_authenticated = super(MyAuthentication, self).is_authenticated(request, **kwargs)
            if not is_authenticated:
                return False
            return request.user.user_type_category != 'viewer'
    

    Second, write Your own authorization class. In this class overwrite functions [create|update|delete]_[list|detail] and in create/delete functions check if user is user. If yes, raise exception (in details) or return [] (in list). In update check if user update himself. If no, raise exception or return [].

    class MyAuthorization(DjangoAuthorization):
        def create_detail(self, object_list, bundle):
            super(MyAuthorization, self).create_detail(object_list, bundle)
            if bundle.request.user.user_type_category != 'admin':
                raise Unauthorized("You are not allowed to create that resource.")
            return True
    
        def create_list(self, object_list, bundle):
            if bundle.request.user.user_type_category != 'admin':
                return []
            return super(MyAuthorization, self).create_list(object_list, bundle)
    
        def delete_detail(self, object_list, bundle):
            super(MyAuthorization, self).delete_detail(object_list, bundle)
            if bundle.request.user.user_type_category != 'admin':
                raise Unauthorized("You are not allowed to delete that resource.")
            return True
    
        def delete_list(self, object_list, bundle):
            if bundle.request.user.user_type_category != 'admin':
                return []
            return super(MyAuthorization, self).delete_list(object_list, bundle)
    
        def update_detail(self, object_list, bundle):
            super(MyAuthorization, self).delete_detail(object_list, bundle)
            if bundle.request.user != bundle.obj:
                raise Unauthorized("You are not allowed to update that resource.")
            return True
    
        def update_list(self, object_list, bundle):
            object_list = super(MyAuthorization, self).update_list(object_list, bundle)
            if object_list.count() == object_list.filter(pk=bundle.obj.pk).count():
                return object_list
            return []