You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
209 lines
7.7 KiB
Python
209 lines
7.7 KiB
Python
# Copyright (C) 2021-2022 Intel Corporation
|
|
# Copyright (C) 2022-2023 CVAT.ai Corporation
|
|
#
|
|
# SPDX-License-Identifier: MIT
|
|
|
|
from rest_framework import mixins, viewsets
|
|
from rest_framework.permissions import SAFE_METHODS
|
|
from django.utils.crypto import get_random_string
|
|
|
|
from drf_spectacular.utils import OpenApiResponse, extend_schema, extend_schema_view
|
|
from cvat.apps.engine.mixins import PartialUpdateModelMixin, DestroyModelMixin, CreateModelMixin
|
|
|
|
from cvat.apps.iam.permissions import (
|
|
InvitationPermission, MembershipPermission, OrganizationPermission)
|
|
from .models import Invitation, Membership, Organization
|
|
|
|
from .serializers import (
|
|
InvitationReadSerializer, InvitationWriteSerializer,
|
|
MembershipReadSerializer, MembershipWriteSerializer,
|
|
OrganizationReadSerializer, OrganizationWriteSerializer)
|
|
|
|
@extend_schema(tags=['organizations'])
|
|
@extend_schema_view(
|
|
retrieve=extend_schema(
|
|
summary='Method returns details of an organization',
|
|
responses={
|
|
'200': OrganizationReadSerializer,
|
|
}),
|
|
list=extend_schema(
|
|
summary='Method returns a paginated list of organizations',
|
|
responses={
|
|
'200': OrganizationReadSerializer(many=True),
|
|
}),
|
|
partial_update=extend_schema(
|
|
summary='Methods does a partial update of chosen fields in an organization',
|
|
request=OrganizationWriteSerializer(partial=True),
|
|
responses={
|
|
'200': OrganizationReadSerializer, # check OrganizationWriteSerializer.to_representation
|
|
}),
|
|
create=extend_schema(
|
|
summary='Method creates an organization',
|
|
request=OrganizationWriteSerializer,
|
|
responses={
|
|
'201': OrganizationReadSerializer, # check OrganizationWriteSerializer.to_representation
|
|
}),
|
|
destroy=extend_schema(
|
|
summary='Method deletes an organization',
|
|
responses={
|
|
'204': OpenApiResponse(description='The organization has been deleted'),
|
|
})
|
|
)
|
|
class OrganizationViewSet(viewsets.GenericViewSet,
|
|
mixins.RetrieveModelMixin,
|
|
mixins.ListModelMixin,
|
|
mixins.CreateModelMixin,
|
|
mixins.DestroyModelMixin,
|
|
PartialUpdateModelMixin,
|
|
):
|
|
queryset = Organization.objects.all()
|
|
search_fields = ('name', 'owner')
|
|
filter_fields = list(search_fields) + ['id', 'slug']
|
|
simple_filters = list(search_fields) + ['slug']
|
|
lookup_fields = {'owner': 'owner__username'}
|
|
ordering_fields = list(filter_fields)
|
|
ordering = '-id'
|
|
http_method_names = ['get', 'post', 'patch', 'delete', 'head', 'options']
|
|
iam_organization_field = None
|
|
|
|
def get_queryset(self):
|
|
queryset = super().get_queryset()
|
|
permission = OrganizationPermission.create_scope_list(self.request)
|
|
return permission.filter(queryset)
|
|
|
|
def get_serializer_class(self):
|
|
if self.request.method in SAFE_METHODS:
|
|
return OrganizationReadSerializer
|
|
else:
|
|
return OrganizationWriteSerializer
|
|
|
|
def perform_create(self, serializer):
|
|
extra_kwargs = { 'owner': self.request.user }
|
|
if not serializer.validated_data.get('name'):
|
|
extra_kwargs.update({ 'name': serializer.validated_data['slug'] })
|
|
serializer.save(**extra_kwargs)
|
|
|
|
class Meta:
|
|
model = Membership
|
|
fields = ("user", )
|
|
|
|
@extend_schema(tags=['memberships'])
|
|
@extend_schema_view(
|
|
retrieve=extend_schema(
|
|
summary='Method returns details of a membership',
|
|
responses={
|
|
'200': MembershipReadSerializer,
|
|
}),
|
|
list=extend_schema(
|
|
summary='Method returns a paginated list of memberships',
|
|
responses={
|
|
'200': MembershipReadSerializer(many=True),
|
|
}),
|
|
partial_update=extend_schema(
|
|
summary='Methods does a partial update of chosen fields in a membership',
|
|
request=MembershipWriteSerializer(partial=True),
|
|
responses={
|
|
'200': MembershipReadSerializer, # check MembershipWriteSerializer.to_representation
|
|
}),
|
|
destroy=extend_schema(
|
|
summary='Method deletes a membership',
|
|
responses={
|
|
'204': OpenApiResponse(description='The membership has been deleted'),
|
|
})
|
|
)
|
|
class MembershipViewSet(mixins.RetrieveModelMixin, DestroyModelMixin,
|
|
mixins.ListModelMixin, PartialUpdateModelMixin, viewsets.GenericViewSet):
|
|
queryset = Membership.objects.all()
|
|
ordering = '-id'
|
|
http_method_names = ['get', 'patch', 'delete', 'head', 'options']
|
|
search_fields = ('user', 'role')
|
|
filter_fields = list(search_fields) + ['id']
|
|
simple_filters = list(search_fields)
|
|
ordering_fields = list(filter_fields)
|
|
lookup_fields = {'user': 'user__username'}
|
|
iam_organization_field = 'organization'
|
|
|
|
def get_serializer_class(self):
|
|
if self.request.method in SAFE_METHODS:
|
|
return MembershipReadSerializer
|
|
else:
|
|
return MembershipWriteSerializer
|
|
|
|
def get_queryset(self):
|
|
queryset = super().get_queryset()
|
|
permission = MembershipPermission.create_scope_list(self.request)
|
|
return permission.filter(queryset)
|
|
|
|
@extend_schema(tags=['invitations'])
|
|
@extend_schema_view(
|
|
retrieve=extend_schema(
|
|
summary='Method returns details of an invitation',
|
|
responses={
|
|
'200': InvitationReadSerializer,
|
|
}),
|
|
list=extend_schema(
|
|
summary='Method returns a paginated list of invitations',
|
|
responses={
|
|
'200': InvitationReadSerializer(many=True),
|
|
}),
|
|
partial_update=extend_schema(
|
|
summary='Methods does a partial update of chosen fields in an invitation',
|
|
request=InvitationWriteSerializer(partial=True),
|
|
responses={
|
|
'200': InvitationReadSerializer, # check InvitationWriteSerializer.to_representation
|
|
}),
|
|
create=extend_schema(
|
|
summary='Method creates an invitation',
|
|
request=InvitationWriteSerializer,
|
|
responses={
|
|
'201': InvitationReadSerializer, # check InvitationWriteSerializer.to_representation
|
|
}),
|
|
destroy=extend_schema(
|
|
summary='Method deletes an invitation',
|
|
responses={
|
|
'204': OpenApiResponse(description='The invitation has been deleted'),
|
|
})
|
|
)
|
|
class InvitationViewSet(viewsets.GenericViewSet,
|
|
mixins.RetrieveModelMixin,
|
|
mixins.ListModelMixin,
|
|
PartialUpdateModelMixin,
|
|
CreateModelMixin,
|
|
DestroyModelMixin,
|
|
):
|
|
queryset = Invitation.objects.all()
|
|
http_method_names = ['get', 'post', 'patch', 'delete', 'head', 'options']
|
|
iam_organization_field = 'membership__organization'
|
|
|
|
search_fields = ('owner',)
|
|
filter_fields = list(search_fields)
|
|
simple_filters = list(search_fields)
|
|
ordering_fields = list(filter_fields) + ['created_date']
|
|
ordering = '-created_date'
|
|
lookup_fields = {'owner': 'owner__username'}
|
|
|
|
def get_serializer_class(self):
|
|
if self.request.method in SAFE_METHODS:
|
|
return InvitationReadSerializer
|
|
else:
|
|
return InvitationWriteSerializer
|
|
|
|
def get_queryset(self):
|
|
queryset = super().get_queryset()
|
|
permission = InvitationPermission.create_scope_list(self.request)
|
|
return permission.filter(queryset)
|
|
|
|
def perform_create(self, serializer, **kwargs):
|
|
extra_kwargs = {
|
|
'owner': self.request.user,
|
|
'key': get_random_string(length=64),
|
|
'organization': self.request.iam_context['organization']
|
|
}
|
|
super().perform_create(serializer, **extra_kwargs)
|
|
|
|
def perform_update(self, serializer):
|
|
if 'accepted' in self.request.query_params:
|
|
serializer.instance.accept()
|
|
else:
|
|
super().perform_update(serializer)
|