from django.db import transaction from django.db.models import Count from rest_framework import filters from rest_framework import status from rest_framework import viewsets from rest_framework.decorators import action from rest_framework.exceptions import APIException from rest_framework.response import Response from apps.authorization.api.v1.serializers import ( RoleSerializer, PermissionSerializer, UserRelationSerializer, PageSerializer ) from apps.authorization.models import ( Role, Permissions, UserRelations, Page ) from apps.core.exceptions import ConflictException from apps.core.mixins.soft_delete_mixin import SoftDeleteMixin class RoleViewSet(SoftDeleteMixin, viewsets.ModelViewSet): """ Crud Operations For User Roles """ queryset = Role.objects.all() serializer_class = RoleSerializer class PageViewSet(SoftDeleteMixin, viewsets.ModelViewSet): """ add website pages to system to set permission on it """ queryset = Page.objects.all() serializer_class = PageSerializer filter_backends = [filters.SearchFilter] search_fields = ['name', 'code'] def list(self, request, *args, **kwargs): """ all pages """ page = self.paginate_queryset(self.queryset.order_by('-create_date')) if page is not None: # noqa serializer = self.get_serializer(page, many=True) return self.get_paginated_response(serializer.data) @action( methods=['delete'], detail=True, url_name='delete', url_path='delete', name='delete' ) @transaction.atomic def delete(self, request, pk=None): """ Full delete of page & permissions of page object """ try: page = self.queryset.get(id=pk) permissions = Permissions.objects.filter(page=page) permissions.delete() page.delete() return Response(status=status.HTTP_200_OK) except APIException as e: return Response(e, status=status.HTTP_204_NO_CONTENT) class PermissionViewSet(SoftDeleteMixin, viewsets.ModelViewSet): """ Crud Operations for Permissions """ queryset = Permissions.objects.all() serializer_class = PermissionSerializer filter_backends = [filters.SearchFilter] search_fields = ['page__name', ] def list(self, request, *args, **kwargs): queryset = self.filter_queryset(self.get_queryset().order_by('-create_date')) # noqa page = self.paginate_queryset(queryset) if page is not None: serializer = self.get_serializer(page, many=True) return self.get_paginated_response(serializer.data) serializer = self.get_serializer(queryset, many=True) return Response(serializer.data) def create(self, request, *args, **kwargs): if self.queryset.filter(name=request.data['name'], page_id=request.data['page']).exists(): raise ConflictException('a permission with this page exists.') serializer = self.serializer_class(data=request.data) if serializer.is_valid(): serializer.save() return Response(serializer.data, status=status.HTTP_200_OK) else: return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) @action( methods=['get'], detail=False, url_name='connectionless_permissions', url_path='connectionless_permissions', name='connectionless_permissions' ) @transaction.atomic def connectionless_permissions(self, request, *args, **kwargs): """ get all permissions that are not assigned to any user relation """ permissions = Permissions.objects.annotate(num=Count('userrelations')).filter(num=0) # noqa page = self.paginate_queryset(permissions) if page is not None: serializer = self.get_serializer(page, many=True) return self.get_paginated_response(serializer.data) serializer = self.get_serializer(permissions, many=True) return Response(serializer.data) class UserRelationViewSet(SoftDeleteMixin, viewsets.ModelViewSet): """ Crud Operations for User Relations """ queryset = UserRelations.objects.all() serializer_class = UserRelationSerializer def list(self, request, *args, **kwargs): queryset = self.filter_queryset(self.get_queryset().order_by('-create_date')) # noqa page = self.paginate_queryset(queryset) if page is not None: serializer = self.get_serializer(page, many=True) return self.get_paginated_response(serializer.data) serializer = self.get_serializer(queryset, many=True) return Response(serializer.data)