Вызвать ошибку условного разрешения в get_queryset DRF

Я хочу получить всех пользователей организации по uuid. Я следую стандартам REST, поэтому хочу, чтобы мой url выглядел как 'organizations/uuid/users/'. Если супер-администратор обратится к этому API, это должно быть разрешено, но если пользователь-администратор попытается использовать этот API, то это должно быть разрешено только в том случае, если администратор принадлежит к той же организации, для которой запрашиваются пользователи. Я использовал класс представления ListAPIView и смог получить список всех пользователей в организации от администратора другой организации, но он все еще возвращает info, когда должен возвращать 403 ошибку.

urls.py

    path('organizations/<uuid:pk>/users/', OrganizationUsersView.as_view()),

views.py

    class OrganizationUsersView(ListAPIView):
        serializer_class = UserSerializer
        permission_classes = (IsAuthenticated, IsSuperAdmin|IsAdmin,)

        def get_queryset(self):
            uuid = self.kwargs['pk']
            if self.request.user.role == 'admin':
                if self.request.user.org.id != uuid:
                    return IsOrganizationAdmin()
            org = Organization.objects.get(id=uuid)
            return User.objects.filter(org=org)

models.py

    class Organization(models.Model):
        name = models.CharField(max_length=255, null=False)

    class User(AbstractBaseUser):
        ....
        other fields
        ....
        org = models.ForeignKey(Organization, on_delete=models.CASCADE, null=False, related_name='users')

Похоже, что вы на правильном пути, но в представленном вами коде есть несколько проблем. Во-первых, в методе get_queryset вы возвращаете класс разрешения IsOrganizationAdmin, когда пользователь является администратором и не принадлежит к организации. Вместо этого вы должны поднять исключение permission denied, например, так:

    class OrganizationUsersView(ListAPIView):
        serializer_class = UserSerializer
        permission_classes = (IsAuthenticated, IsSuperAdmin|IsAdmin,)

        def get_queryset(self):
            uuid = self.kwargs['pk']
            if self.request.user.role == 'admin':
                if self.request.user.org.id != uuid:
                    raise PermissionDenied()
            org = Organization.objects.get(id=uuid)
            return User.objects.filter(org=org)

Во-вторых, не гарантируется, что у пользователя будет поле org, так как это не является требованием для модели пользователя. Вы должны проверить, есть ли у пользователя поле org, прежде чем обращаться к нему.

    class OrganizationUsersView(ListAPIView):
        serializer_class = UserSerializer
        permission_classes = (IsAuthenticated, IsSuperAdmin|IsAdmin,)

        def get_queryset(self):
            uuid = self.kwargs['pk']
            if self.request.user.role == 'admin':
                if not hasattr(self.request.user, "org") or self.request.user.org.id != uuid:
                    raise PermissionDenied()
            org = Organization.objects.get(id=uuid)
            return User.objects.filter(org=org)

Наконец, вы можете рассмотреть возможность использования пользовательского класса разрешения IsOrganizationAdmin вместо IsSuperAdmin|IsAdmin. Это гарантирует, что только пользователи с ролью администратора и принадлежащие к указанной организации могут получить доступ к API.

Вернуться на верх