DjangoModelPermissions shows API root for unauthenticated users
I noticed that when using permissions.IsAuthenticated, the APIRootView returns a 403. However, when using DjangoModelPermissions this is not the case. It does show the root with all available endpoints.
DjangoModelPermissions.has_permission(...) does have a check to ensure the user is authenticated in the code (introduced in #5376) but it happens after the special case handling is done for APIRootView (introduced in #2905).
https://github.com/encode/django-rest-framework/blob/7e4e6d207070d50736827a281b5cb70eb161b782/rest_framework/permissions.py#L219-L227
The authentication check should come first followed by the special case for APIRootView to be consistent with other permission classes.
I would be happy to provide a PR to address this.
I agree, I had the same problem. I solved this by changing the order of checking for _ignore_model_permissions and checking the authentication status. So:
def has_permission(self, request, view):
if not request.user or (
not request.user.is_authenticated and self.authenticated_users_only):
return False
# Workaround to ensure DjangoModelPermissions are not applied
# to the root view when using DefaultRouter.
if getattr(view, '_ignore_model_permissions', False):
return True
I think this is the correct order because _ignore_model_permissions does not imply that it authenticated_users_only should be ignored.
Can anyone argue why it should not be in this order?
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.
https://github.com/encode/django-rest-framework/commit/c0d95cb9678b1693f8f1a8658d4665c51de87ddf
Yes! :-) This issue can be closed as fixed!
For others stumbling upon this ticket, this fix only solves the root view being visible to unauthenticated users. An that endpoints a user has no permissions to is still be visible to all authenticated users.
For others stumbling upon this ticket, this fix only solves the root view being visible to unauthenticated users.
That's what this ticket is about :)
An that endpoints a user has no permissions to is still be visible to all authenticated users.
Do you mean that the root view shows endpoints that the authenticated user even though the user has no permission to "use" them? If that is something you are looking for I suggest to open a new issue for this.