Django DRF разрешения на создание связанных объектов - PullRequest
0 голосов
/ 12 октября 2018

Я борюсь за обеспечение безопасности при создании объектов в инфраструктуре Django REST.

По сути, я могу обеспечить безопасность на уровне объекта с помощью 'has_object_permission': зарегистрированный пользователь должен быть владельцем объекта, которым нужно манипулироватьЭто.На самом деле, как указано в документе, я сужаю поиск объектов в наборе запросов, поэтому я получил 404 вместо 403. Это, я думаю, не проблема (даже лучше, так как скрывает существование объектов)

Но мне не удается запретить другому пользователю создавать связанный объект ....

Я использую ModelSerializer и ModelViewSet.

Вот несколько наивных фрагментов:

models.py:

class Daddy(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    name = models.CharField(max_length=20)
    owner = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)

class Kiddy(models.Model):
    title = models.CharField(max_length=12)
    daddy = models.foreignKey(Daddy, on_delete=models.CASCADE)

serializers.py:

class KiddySerializer(serializers.ModelSerializer):
    class Meta:
        model = Kiddy
        fields = '__all__'

viewsets.py:

class KiddyViewSet(viewsets.ModelViewSet):
    serializer_class = KiddySerializer
    queryset = User.objects.none()

    permission_classes = (IsAuthenticated, IsOwner, )

    def get_queryset(self):
        dad_uuid = self.kwargs['dad']
        return Kiddy.objects.filter(daddy__pk=dad_uuid).filter(daddy__owner=self.request.user)

router.py:

router = routers.DefaultRouter()
router.register(r'dad', KiddyViewSet, base_name='kid')

urls.py:

path('api/<uuid:cv>/', include(router.urls))

Доступ к объектам осуществляется с помощью этих URL: http: //..../api/4ecddcdd-1c0a-4d0b-8254-b0c0d2607e6d/ ---> список всех детей

http: //..../api/4ecddcdd-1c0a-4d0b-8254-b0c0d2607e6d/1 ---> object kid

На самом деле, я получил некоторую безопасность, потому что я использую uuid, и об этом трудно догадаться ...

permissions.py:

class IsOwner(permissions.BasePermission):
"""
Object-level permission to only allow owners of an object to edit it.
Assumes the model instance has an `owner` attribute.
"""

def has_object_permission(self, request, view, obj):
    if request.user != obj.daddy.owner:
        return False
    else:
        return True

Если вы вошли в систему с неправильным владельцем,Я могу создавать связанные детские объекты!

Полагаю, мне нужно реализовать это разрешение в виде has_permission.Но я не знаю, как получить доступ к объекту там, поскольку параметры - это запрос и просмотр ...

Здесь он нашел решение.Но это совсем не универсально, потому что мне нужно специальное разрешение для всех связанных объектов ... и я получил много !!! Проверка прав доступа к связанному объекту в Django REST Framework

Есть идеи?

1 Ответ

0 голосов
/ 12 октября 2018

ОК, я решил эту проблему: -)

В permissions.py, как я и подозревал, придется, я добавил это 'has_permission':

class IsOwnerParent(permissions.BasePermission):
    def has_permission(self, request, view):
        daddy = Daddy.objects.get(pk=view.kwargs['dad'])
        return daddy.owner == request.user

и добавилэто в моем классе ModelViewSet:

class KiddyViewSet(viewsets.ModelViewSet):
    serializer_class = KiddySerializer
    queryset = User.objects.none()

    permission_classes = (IsAuthenticated, IsOwner, IsOwnerParent)

    def get_queryset(self):
        dad_uuid = self.kwargs['dad']
        return Kiddy.objects.filter(daddy__pk=dad_uuid).filter(daddy__owner=self.request.user)

Итак, на самом деле решение, предоставленное здесь Проверка прав доступа к связанному объекту в Django REST Framework , сработало.И это на самом деле довольно общий характер, так как многие мои объекты связаны с объектами «Папочка».

На самом деле, теперь поведение при получении списка объектов выглядит более «нормальным»: я получил 403 ошибки вместо 404.

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

Но, возможно, это можно сделатьлучше?

...