I'm trying to use Django Tastypie to create a simple API. I have custom auth (not really that custom since it's copied directly from their example) that exposes only entries
from the current user. It returns all users though, and I only want it to expose the one that's logged on. Right now I'm using this as my api.py
:
class UserResource(ModelResource):
class Meta:
queryset = User.objects.all()
excludes = ['password', 'is_superuser']
resource_name = 'user'
authentication=MultiAuthentication(SessionAuthentication(),ApiKeyAuthentication())
authorization=DjangoAuthorization()
allow_methods=['get']
class EntryResource(ModelResource):
user = fields.ForeignKey(UserResource, 'user')
class Meta:
queryset = Entry.objects.all()
resource_name = 'entry'
authentication=MultiAuthentication(SessionAuthentication(),ApiKeyAuthentication())
authorization=UserObjectsOnlyAuthorization()
And this for the UserObjectsOnlyAuthorization
from tastypie.authorization import Authorization
from tastypie.exceptions import Unauthorized
class UserObjectsOnlyAuthorization(Authorization):
def read_list(self, object_list, bundle):
# This assumes a ``QuerySet`` from ``ModelResource``.
return object_list.filter(user=bundle.request.user)
def read_detail(self, object_list, bundle):
# Is the requested object owned by the user?
return bundle.obj.user == bundle.request.user
def create_list(self, object_list, bundle):
# Assuming they're auto-assigned to ``user``.
return object_list
def create_detail(self, object_list, bundle):
return bundle.obj.user == bundle.request.user
def update_list(self, object_list, bundle):
allowed = []
# Since they may not all be saved, iterate over them.
for obj in object_list:
if obj.user == bundle.request.user:
allowed.append(obj)
return allowed
def update_detail(self, object_list, bundle):
return bundle.obj.user == bundle.request.user
def delete_list(self, object_list, bundle):
# Sorry user, no deletes for you!
raise Unauthorized("Sorry, no deletes.")
def delete_detail(self, object_list, bundle):
raise Unauthorized("Sorry, no deletes.")
If I apply that Authentication to the UserResource
in api.py
, like I am for the EntryResource
it gives me errors. I can provide more detail if necessary.
You should define your filter in a new CustomUserAuthorization
, check the details of this implementation and check the Tastypie documentation about Authorization.
from tastypie.authorization import Authorization
from tastypie.exceptions import Unauthorized
class CustomUserAuthorization(Authorization):
def read_list(self, object_list, bundle):
# This you put your filter
return object_list.filter(id=bundle.request.user.id)
def read_detail(self, object_list, bundle):
# This is to check the current user
return bundle.obj.id == bundle.request.user.id
def create_list(self, object_list, bundle):
raise Unauthorized("Sorry, not allowed.")
def create_detail(self, object_list, bundle):
raise Unauthorized("Sorry, not allowed.")
def update_list(self, object_list, bundle):
raise Unauthorized("Sorry, not allowed.")
def update_detail(self, object_list, bundle):
# Only update your details
return bundle.obj.id== bundle.request.user.id
def delete_list(self, object_list, bundle):
raise Unauthorized("Sorry, no deletes.")
def delete_detail(self, object_list, bundle):
raise Unauthorized("Sorry, no deletes.")