diff --git a/app/access/serializers/team_user.py b/app/access/serializers/team_user.py new file mode 100644 index 000000000..45c97f9e0 --- /dev/null +++ b/app/access/serializers/team_user.py @@ -0,0 +1,118 @@ +from rest_framework.reverse import reverse + +from rest_framework import serializers +from rest_framework.exceptions import ParseError + +from access.models import TeamUsers +from app.serializers.user import UserBaseSerializer + + + +class TeamUserBaseSerializer(serializers.ModelSerializer): + + + display_name = serializers.SerializerMethodField('get_display_name') + + def get_display_name(self, item): + + return str( item ) + + url = serializers.SerializerMethodField('get_url') + + def get_url(self, item): + + return reverse( + "API:_api_v2_organization_team_user-detail", + request=self.context['view'].request, + kwargs={ + 'organization_id': item.team.organization.id, + 'team_id': item.team.id, + 'pk': item.pk + } + ) + + + class Meta: + + model = TeamUsers + + fields = [ + 'id', + 'display_name', + 'url', + ] + + read_only_fields = [ + 'id', + 'display_name', + 'url', + ] + + + +class TeamUserModelSerializer(TeamUserBaseSerializer): + + _urls = serializers.SerializerMethodField('get_url') + + def get_url(self, item): + + return { + '_self': reverse( + 'API:_api_v2_organization_team_user-detail', + request=self.context['view'].request, + kwargs={ + 'organization_id': item.team.organization.id, + 'team_id': item.team.id, + 'pk': item.pk + } + ) + } + + + class Meta: + + model = TeamUsers + + fields = [ + 'id', + 'display_name', + 'manager', + 'user', + 'created', + 'modified', + '_urls', + ] + + read_only_fields = [ + 'id', + 'display_name', + 'created', + 'modified', + '_urls', + ] + + + + def is_valid(self, *, raise_exception=True) -> bool: + + is_valid = False + + try: + + is_valid = super().is_valid(raise_exception=raise_exception) + + self.validated_data['team_id'] = int(self._context['view'].kwargs['team_id']) + + except Exception as unhandled_exception: + + ParseError( + detail=f"Server encountered an error during validation, Traceback: {unhandled_exception.with_traceback}" + ) + + return is_valid + + + +class TeamUserViewSerializer(TeamUserModelSerializer): + + user = UserBaseSerializer(read_only = True) diff --git a/app/access/serializers/teams.py b/app/access/serializers/teams.py index 2fdaf2ed9..7bda46b18 100644 --- a/app/access/serializers/teams.py +++ b/app/access/serializers/teams.py @@ -67,6 +67,14 @@ def get_url(self, item): 'organization_id': item.organization.id, 'pk': item.pk } + ), + 'users': reverse( + 'API:_api_v2_organization_team_user-list', + request=self.context['view'].request, + kwargs={ + 'organization_id': item.organization.id, + 'team_id': item.pk + } ) } diff --git a/app/access/viewsets/team_user.py b/app/access/viewsets/team_user.py new file mode 100644 index 000000000..e6c464d38 --- /dev/null +++ b/app/access/viewsets/team_user.py @@ -0,0 +1,99 @@ +from drf_spectacular.utils import extend_schema, extend_schema_view, OpenApiResponse + +from access.serializers.team_user import ( + TeamUsers, + TeamUserModelSerializer, + TeamUserViewSerializer +) + +from api.viewsets.common import ModelViewSet + + + +@extend_schema_view( + create=extend_schema( + summary = 'Create a user within this team', + description='', + responses = { + # 200: OpenApiResponse(description='Allready exists', response=TeamUserViewSerializer), + 201: OpenApiResponse(description='Created', response=TeamUserViewSerializer), + # 400: OpenApiResponse(description='Validation failed.'), + 403: OpenApiResponse(description='User is missing add permissions'), + } + ), + destroy = extend_schema( + summary = 'Delete a user from this team', + description = '', + responses = { + 204: OpenApiResponse(description=''), + 403: OpenApiResponse(description='User is missing delete permissions'), + } + ), + list = extend_schema( + summary = 'Fetch all users from this team', + description='', + responses = { + 200: OpenApiResponse(description='', response=TeamUserViewSerializer), + 403: OpenApiResponse(description='User is missing view permissions'), + } + ), + retrieve = extend_schema( + summary = 'Fetch a single user from this team', + description='', + responses = { + 200: OpenApiResponse(description='', response=TeamUserViewSerializer), + 403: OpenApiResponse(description='User is missing view permissions'), + } + ), + update = extend_schema(exclude = True), + partial_update = extend_schema( + summary = 'Update a user within this team', + description = '', + responses = { + 200: OpenApiResponse(description='', response=TeamUserViewSerializer), + # 201: OpenApiResponse(description='Created', response=OrganizationViewSerializer), + # # 400: OpenApiResponse(description='Validation failed.'), + 403: OpenApiResponse(description='User is missing change permissions'), + } + ), +) +class ViewSet( ModelViewSet ): + + filterset_fields = [ + 'manager', + 'team__organization', + ] + + search_fields = [] + + model = TeamUsers + + documentation: str = '' + + view_description = 'Users belonging to a single team' + + def get_queryset(self): + + queryset = super().get_queryset() + + queryset = queryset.filter( + team_id = self.kwargs['team_id'] + ) + + self.queryset = queryset + + return self.queryset + + + def get_serializer_class(self): + + if ( + self.action == 'list' + or self.action == 'retrieve' + ): + + return globals()[str( self.model._meta.verbose_name).replace(' ', '') + 'ViewSerializer'] + + + return globals()[str( self.model._meta.verbose_name).replace(' ', '') + 'ModelSerializer'] + diff --git a/app/api/urls.py b/app/api/urls.py index f127e1e3a..f2644b736 100644 --- a/app/api/urls.py +++ b/app/api/urls.py @@ -43,7 +43,8 @@ from access.viewsets import ( index as access_v2, organization as organization_v2, - team as team_v2 + team as team_v2, + team_user as team_user_v2 ) from assistance.viewset import ( @@ -111,7 +112,8 @@ router.register('v2/access', access_v2.Index, basename='_api_v2_access_home') router.register('v2/access/organization', organization_v2.ViewSet, basename='_api_v2_organization') -router.register('v2/access/organization/(?P[0-9]+)/teams', team_v2.ViewSet, basename='_api_v2_organization_team') +router.register('v2/access/organization/(?P[0-9]+)/team', team_v2.ViewSet, basename='_api_v2_organization_team') +router.register('v2/access/organization/(?P[0-9]+)/team/(?P[0-9]+)/user', team_user_v2.ViewSet, basename='_api_v2_organization_team_user') router.register('v2/assistance', assistance_index_v2.Index, basename='_api_v2_assistance_home')