Add a viewset to control collection membership.
This commit is contained in:
parent
4ca74bc69b
commit
edd88427b0
@ -121,12 +121,13 @@ class RevisionChunkRelation(models.Model):
|
|||||||
ordering = ('id', )
|
ordering = ('id', )
|
||||||
|
|
||||||
|
|
||||||
class CollectionMember(models.Model):
|
class AccessLevels(models.TextChoices):
|
||||||
class AccessLevels(models.TextChoices):
|
ADMIN = 'adm'
|
||||||
ADMIN = 'adm'
|
READ_WRITE = 'rw'
|
||||||
READ_WRITE = 'rw'
|
READ_ONLY = 'ro'
|
||||||
READ_ONLY = 'ro'
|
|
||||||
|
|
||||||
|
|
||||||
|
class CollectionMember(models.Model):
|
||||||
collection = models.ForeignKey(Collection, related_name='members', on_delete=models.CASCADE)
|
collection = models.ForeignKey(Collection, related_name='members', on_delete=models.CASCADE)
|
||||||
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
|
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
|
||||||
encryptionKey = models.BinaryField(editable=True, blank=False, null=False)
|
encryptionKey = models.BinaryField(editable=True, blank=False, null=False)
|
||||||
|
@ -211,7 +211,7 @@ class CollectionSerializer(serializers.ModelSerializer):
|
|||||||
|
|
||||||
models.CollectionMember(collection=instance,
|
models.CollectionMember(collection=instance,
|
||||||
user=validated_data.get('owner'),
|
user=validated_data.get('owner'),
|
||||||
accessLevel=models.CollectionMember.AccessLevels.ADMIN,
|
accessLevel=models.AccessLevels.ADMIN,
|
||||||
encryptionKey=encryption_key,
|
encryptionKey=encryption_key,
|
||||||
).save()
|
).save()
|
||||||
|
|
||||||
@ -238,6 +238,30 @@ class CollectionSerializer(serializers.ModelSerializer):
|
|||||||
return instance
|
return instance
|
||||||
|
|
||||||
|
|
||||||
|
class CollectionMemberSerializer(serializers.ModelSerializer):
|
||||||
|
username = serializers.SlugRelatedField(
|
||||||
|
source='user',
|
||||||
|
slug_field=User.USERNAME_FIELD,
|
||||||
|
queryset=User.objects
|
||||||
|
)
|
||||||
|
encryptionKey = BinaryBase64Field()
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
model = models.CollectionMember
|
||||||
|
fields = ('username', 'encryptionKey', 'accessLevel')
|
||||||
|
|
||||||
|
def create(self, validated_data):
|
||||||
|
raise NotImplementedError()
|
||||||
|
|
||||||
|
def update(self, instance, validated_data):
|
||||||
|
with transaction.atomic():
|
||||||
|
# We only allow updating accessLevel
|
||||||
|
instance.accessLevel = validated_data.pop('accessLevel')
|
||||||
|
instance.save()
|
||||||
|
|
||||||
|
return instance
|
||||||
|
|
||||||
|
|
||||||
class UserSerializer(serializers.ModelSerializer):
|
class UserSerializer(serializers.ModelSerializer):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = User
|
model = User
|
||||||
|
@ -33,8 +33,8 @@ import nacl.signing
|
|||||||
import nacl.secret
|
import nacl.secret
|
||||||
import nacl.hash
|
import nacl.hash
|
||||||
|
|
||||||
from . import app_settings
|
from . import app_settings, permissions
|
||||||
from .models import Collection, CollectionItem, CollectionItemRevision
|
from .models import Collection, CollectionItem, CollectionItemRevision, CollectionMember
|
||||||
from .serializers import (
|
from .serializers import (
|
||||||
b64encode,
|
b64encode,
|
||||||
AuthenticationSignupSerializer,
|
AuthenticationSignupSerializer,
|
||||||
@ -47,6 +47,7 @@ from .serializers import (
|
|||||||
CollectionItemDepSerializer,
|
CollectionItemDepSerializer,
|
||||||
CollectionItemRevisionSerializer,
|
CollectionItemRevisionSerializer,
|
||||||
CollectionItemChunkSerializer,
|
CollectionItemChunkSerializer,
|
||||||
|
CollectionMemberSerializer,
|
||||||
UserSerializer,
|
UserSerializer,
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -395,6 +396,33 @@ class CollectionItemChunkViewSet(viewsets.ViewSet):
|
|||||||
return serve(request, basename, dirname)
|
return serve(request, basename, dirname)
|
||||||
|
|
||||||
|
|
||||||
|
class CollectionMemberViewSet(BaseViewSet):
|
||||||
|
allowed_methods = ['GET', 'PUT', 'DELETE']
|
||||||
|
permission_classes = BaseViewSet.permission_classes + (permissions.IsCollectionAdmin, )
|
||||||
|
queryset = CollectionMember.objects.all()
|
||||||
|
serializer_class = CollectionMemberSerializer
|
||||||
|
lookup_field = 'user__' + User.USERNAME_FIELD
|
||||||
|
lookup_url_kwarg = 'username'
|
||||||
|
|
||||||
|
# FIXME: need to make sure that there's always an admin, and maybe also don't let an owner remove adm access
|
||||||
|
# (if we want to transfer, we need to do that specifically)
|
||||||
|
|
||||||
|
def get_queryset(self, queryset=None):
|
||||||
|
collection_uid = self.kwargs['collection_uid']
|
||||||
|
try:
|
||||||
|
collection = self.get_collection_queryset(Collection.objects).get(uid=collection_uid)
|
||||||
|
except Collection.DoesNotExist:
|
||||||
|
raise Http404('Collection does not exist')
|
||||||
|
|
||||||
|
if queryset is None:
|
||||||
|
queryset = type(self).queryset
|
||||||
|
|
||||||
|
return queryset.filter(collection=collection)
|
||||||
|
|
||||||
|
def create(self, request):
|
||||||
|
return Response(status=status.HTTP_405_METHOD_NOT_ALLOWED)
|
||||||
|
|
||||||
|
|
||||||
class AuthenticationViewSet(viewsets.ViewSet):
|
class AuthenticationViewSet(viewsets.ViewSet):
|
||||||
allowed_methods = ['POST']
|
allowed_methods = ['POST']
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user