Skip to content

Instantly share code, notes, and snippets.

@blapid
Last active February 24, 2017 01:45
Show Gist options
  • Save blapid/359d120bcc73609a42cb to your computer and use it in GitHub Desktop.
Save blapid/359d120bcc73609a42cb to your computer and use it in GitHub Desktop.
django-rest-framework - raise permission denied instead of not found
def HideNotFoundSubClass(base_class):
'''
So apparently, django-rest-framework's permission checks aren't quite enough
for me.
It has 2 steps:
1. Check global permissions by calling has_permission for each of the
permission classes
2. Check object permissions by calling has_object_permission for each
of the permission classes
Between 1 and 2, it tries to find the object with get_object().
Now, if the object does not exist, we get a 404, which would make sense
in most cases. However, if the object does exist but test 2 fails, we get
403. That allows authenticated users to know whether a resource
exists or not, even though they wouldn't have permissions for it if it did.
This is quite a serious problem for me, so I made this function.
Basically, this wraps a given class by a subclass that overrides get_object().
The new get_object() function catches the 404 and raises a 403 instead.
'''
cls = type(base_class.__name__+'_HideNotFoundSubClass', (base_class,), {})
def get_object(self, queryset=None):
try:
obj = super(cls, self).get_object(queryset)
return obj
except Http404 as e:
raise PermissionDenied()
cls.get_object = get_object
return cls
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment