Returning the Correct HTTP Status Code in TastyPie: 401 Unauthorized

In TastyPie, a library for creating REST APIs for Django projects, the recommended way to limit the objects available to a user is through the apply_authorization_limits() function. This method is extremely handy and easy to use, but has a serious flaw; by filtering out objects from the queryset that a user should not access, TastyPie acts as if that object doesn’t exist at all. This causes 2 problems:

When trying to access an object which a user doesn’t have access to, a 404 Not Found status code is returned instead of the more semantic (and less misleading) 401 Unauthorized. Normally you wouldn’t care about misleading users trying to access other users’ data, but this caused a bit of confusion with one of my clients who has another team writing a mobile app using the API I wrote. When trying to access an object while logged in as the wrong user the API tells them the object doesn’t exist, instead of telling them they don’t have access.

Sometimes your get a 500 Internal Server error. If a user tries to update (PUT) an existing resource for another user, instead of returning a 401 status code, TastyPie thinks the object doesn’t exist, tries to insert a new row in the database with an already used primary key, and an IntegrityError is thrown. Even though this only happens during incorrect usage, it still looks bad.

To solve this problem I created a CustomModelResource class with an overridden obj_get() method.