Search code examples
pythondjangotastypiedjango-guardian

Restrict access to only owned content django


I'm writing an API using django-tastypie. I have two custom permisions issues that I'm hoping django-guardian can fix.

I have two user groups Clinicians and Patients. Clinicians should be able to access the objects belonging to only their Patients and Patients should only be able to access objects created by themselves.

My code is as follows:

class UserResource(ModelResource):
    class Meta:
        queryset = User.objects.all()
        resource_name = 'auth/user'
        excludes = ['email', 'password', 'is_superuser']


class BlogPostResource(ModelResource):
    author = fields.ToOneField(UserResource, 'author', full=True)

    class Meta:
        queryset = BlogPost.objects.all()
        resource_name = 'posts'
        allowed_methods = ["get", "post"]
        # Add it here.
        authentication = BasicAuthentication()
        authorization = DjangoAuthorization()
        filtering = {
            'author': ALL_WITH_RELATIONS,
        }

How can I used permissions to restrict access on this BlogPostResource?


Solution

  • I based my final solution off of the answer from @JamesO. The issue with his answer was it was written for an older version of django-tastypie before the Authorization class was rewritten. Here is my code for future reference:

    from tastypie.authorization import Authorization
    from django.contrib.auth.models import Group
    from extendedusers.models import ExtendedUser
    
    
    class CustomAuthorization(Authorization):
        def read_list(self, object_list, bundle):
            clinician_group = Group.objects.get(name='clinician')
            if bundle.request and hasattr(bundle.request, 'user'):
                if clinician_group in bundle.request.user.groups.all():
                    patients = ExtendedUser.objects.filter(clinician_id=bundle.request.user.id)
                    object_list = object_list.filter(author__id__in=patients)
                else:
                    object_list = object_list.filter(author=bundle.request.user)
                return object_list
            else:
                return object_list.none()