django-rest-framework icon indicating copy to clipboard operation
django-rest-framework copied to clipboard

DjangoModelPermissions shows API root for unauthenticated users

Open mschoettle opened this issue 3 years ago • 2 comments

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.

mschoettle avatar Mar 24 '22 01:03 mschoettle

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?

TTycho avatar Apr 07 '22 19:04 TTycho

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.

stale[bot] avatar Jun 13 '22 05:06 stale[bot]

https://github.com/encode/django-rest-framework/commit/c0d95cb9678b1693f8f1a8658d4665c51de87ddf

auvipy avatar Nov 28 '22 13:11 auvipy

c0d95cb

does this fix the issue?

auvipy avatar Nov 28 '22 13:11 auvipy

Yes! :-) This issue can be closed as fixed!

TTycho avatar Nov 28 '22 19:11 TTycho

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.

TTycho avatar Dec 06 '22 12:12 TTycho

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.

mschoettle avatar Dec 17 '22 16:12 mschoettle