Collection/item viewsets: enforce access.

This commit is contained in:
Tom Hacohen 2020-05-27 16:40:08 +03:00
parent 6e7fd5d0dd
commit e159bf971b
2 changed files with 48 additions and 2 deletions

View File

@ -36,3 +36,49 @@ class IsCollectionAdmin(permissions.BasePermission):
except Collection.DoesNotExist: except Collection.DoesNotExist:
# If the collection does not exist, we want to 404 later, not permission denied. # If the collection does not exist, we want to 404 later, not permission denied.
return True return True
class IsCollectionAdminOrReadOnly(permissions.BasePermission):
"""
Custom permission to only allow owners of a collection to edit it
"""
message = 'Only collection admins can edit collections.'
code = 'admin_access_required'
def has_permission(self, request, view):
collection_uid = view.kwargs.get('collection_uid', None)
# Allow creating new collections
if collection_uid is None:
return True
try:
collection = view.get_collection_queryset().get(uid=collection_uid)
if request.method in permissions.SAFE_METHODS:
return True
return is_collection_admin(collection, request.user)
except Collection.DoesNotExist:
# If the collection does not exist, we want to 404 later, not permission denied.
return True
class HasWriteAccessOrReadOnly(permissions.BasePermission):
"""
Custom permission to restrict write
"""
message = 'You need write access to write to this collection'
code = 'no_write_access'
def has_permission(self, request, view):
collection_uid = view.kwargs['collection_uid']
try:
collection = view.get_collection_queryset().get(uid=collection_uid)
if request.method in permissions.SAFE_METHODS:
return True
else:
member = collection.members.get(user=request.user)
return member.accessLevel != AccessLevels.READ_ONLY
except Collection.DoesNotExist:
# If the collection does not exist, we want to 404 later, not permission denied.
return True

View File

@ -127,7 +127,7 @@ class BaseViewSet(viewsets.ModelViewSet):
class CollectionViewSet(BaseViewSet): class CollectionViewSet(BaseViewSet):
allowed_methods = ['GET', 'POST', 'DELETE'] allowed_methods = ['GET', 'POST', 'DELETE']
permission_classes = BaseViewSet.permission_classes permission_classes = BaseViewSet.permission_classes + (permissions.IsCollectionAdminOrReadOnly, )
queryset = Collection.objects.all() queryset = Collection.objects.all()
serializer_class = CollectionSerializer serializer_class = CollectionSerializer
lookup_field = 'uid' lookup_field = 'uid'
@ -196,7 +196,7 @@ class CollectionViewSet(BaseViewSet):
class CollectionItemViewSet(BaseViewSet): class CollectionItemViewSet(BaseViewSet):
allowed_methods = ['GET', 'POST', 'PUT'] allowed_methods = ['GET', 'POST', 'PUT']
permission_classes = BaseViewSet.permission_classes permission_classes = BaseViewSet.permission_classes + (permissions.HasWriteAccessOrReadOnly, )
queryset = CollectionItem.objects.all() queryset = CollectionItem.objects.all()
serializer_class = CollectionItemSerializer serializer_class = CollectionItemSerializer
lookup_field = 'uid' lookup_field = 'uid'