Added owner permission to check user has the right to read/update object

merge-requests/154/head
Eliot Berriot 2018-03-18 21:31:22 +01:00
rodzic 3e277aad4f
commit 367014f70e
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: DD6965E2476E5C27
2 zmienionych plików z 82 dodań i 0 usunięć

Wyświetl plik

@ -1,4 +1,7 @@
import operator
from django.conf import settings
from django.http import Http404
from rest_framework.permissions import BasePermission, DjangoModelPermissions
@ -20,3 +23,39 @@ class HasModelPermission(DjangoModelPermissions):
"""
def get_required_permissions(self, method, model_cls):
return super().get_required_permissions(method, self.model)
class OwnerPermission(BasePermission):
"""
Ensure the request user is the owner of the object.
Usage:
class MyView(APIView):
model = MyModel
permission_classes = [OwnerPermission]
owner_field = 'owner'
owner_checks = ['read', 'write']
"""
perms_map = {
'GET': 'read',
'OPTIONS': 'read',
'HEAD': 'read',
'POST': 'write',
'PUT': 'write',
'PATCH': 'write',
'DELETE': 'write',
}
def has_object_permission(self, request, view, obj):
method_check = self.perms_map[request.method]
owner_checks = getattr(view, 'owner_checks', ['read', 'write'])
if method_check not in owner_checks:
# check not enabled
return True
owner_field = getattr(view, 'owner_field', 'user')
owner = operator.attrgetter(owner_field)(obj)
if owner != request.user:
raise Http404
return True

Wyświetl plik

@ -0,0 +1,43 @@
import pytest
from rest_framework.views import APIView
from django.contrib.auth.models import AnonymousUser
from django.http import Http404
from funkwhale_api.common import permissions
def test_owner_permission_owner_field_ok(nodb_factories, api_request):
playlist = nodb_factories['playlists.Playlist']()
view = APIView.as_view()
permission = permissions.OwnerPermission()
request = api_request.get('/')
setattr(request, 'user', playlist.user)
check = permission.has_object_permission(request, view, playlist)
assert check is True
def test_owner_permission_owner_field_not_ok(nodb_factories, api_request):
playlist = nodb_factories['playlists.Playlist']()
view = APIView.as_view()
permission = permissions.OwnerPermission()
request = api_request.get('/')
setattr(request, 'user', AnonymousUser())
with pytest.raises(Http404):
permission.has_object_permission(request, view, playlist)
def test_owner_permission_read_only(nodb_factories, api_request):
playlist = nodb_factories['playlists.Playlist']()
view = APIView.as_view()
setattr(view, 'owner_checks', ['write'])
permission = permissions.OwnerPermission()
request = api_request.get('/')
setattr(request, 'user', AnonymousUser())
check = permission.has_object_permission(request, view, playlist)
assert check is True