import json import requests 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.permissions import AllowAny from rest_framework.response import Response from apps.authorization.api.v1.serializers import ( RoleSerializer, PermissionSerializer, UserRelationSerializer, PageSerializer ) from apps.authorization.exception import AdminRoleDeleteException from apps.authorization.models import ( Role, Permissions, UserRelations, Page ) from apps.core.api import BaseViewSet from apps.core.exceptions import ConflictException from apps.core.mixins.search_mixin import DynamicSearchMixin from apps.core.mixins.soft_delete_mixin import SoftDeleteMixin from common.helpers import get_organization_by_user class UpdatePageAccessViewSet(BaseViewSet, SoftDeleteMixin, viewsets.ModelViewSet): queryset = Page.objects.all() serializer_class = PageSerializer permission_classes = [AllowAny] def list(self, request, *args, **kwargs): queryset = self.queryset.all() page_serializer = self.get_serializer(queryset, many=True) return Response(page_serializer.data) @transaction.atomic def create(self, request, *args, **kwargs): """ sync update page & access on development version with production """ url = 'http://127.0.0.1:8000/auth/api/v1/update_access/' # get data page & permissions data from development req = requests.get(url) response = json.loads(req.text.encode('utf-8')) url = 'http://127.0.0.1:8000/auth/api/v1/update_access/update_access' # # delete all pages # Page.objects.all().delete() # # # delete all permissions # Permissions.objects.all().delete() # # # recreate page & permissions # for page in response: # page_obj = Page.objects.create( # name=page['name'], # code=page['code'], # is_active=page['is_active'] # ) # for permission in page['permissions']: # Permissions.objects.create( # name=permission['name'], # description=permission['description'], # category=permission['category'], # page_id=page_obj.id, # is_active=permission['is_active'], # modify_state=permission['modify_state'] # ) # # return Response(response) @action(methods=['post'], detail=False, url_name='update_page_access', url_path='update_page_access') def update_page_access(self, request, *args, **kwargs): return Response(request.data) class RoleViewSet(BaseViewSet, SoftDeleteMixin, viewsets.ModelViewSet): """ Crud Operations For User Roles """ queryset = Role.objects.all() serializer_class = RoleSerializer filter_backends = [filters.SearchFilter] search_fields = ['role_name', 'type__name'] def list(self, request, *args, **kwargs): """ all roles """ role = self.paginate_queryset(self.get_queryset().order_by('-modify_date')) if role is not None: # noqa serializer = self.get_serializer(role, many=True) return self.get_paginated_response(serializer.data) def destroy(self, request, pk=None, *args, **kwargs): """ soft delete of role except Admin """ role = self.get_object() if role.type.key == 'ADM': raise AdminRoleDeleteException() role.soft_delete() return Response(status=status.HTTP_200_OK) 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.filter_queryset(self.queryset.order_by('-modify_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', 'name'] def list(self, request, *args, **kwargs): """ all permissions """ if 'modify_state' in request.GET.keys(): param = self.request.query_params.get('modify_state') # noqa if param == 'true': self.queryset = self.get_queryset().filter(modify_state=True).order_by('-modify_date') elif param == 'false': self.queryset = self.get_queryset().filter(modify_state=False).order_by('-modify_date') else: self.queryset = self.get_queryset().filter().order_by('-modify_date') else: self.queryset = self.queryset.order_by('-modify_date') queryset = self.filter_queryset(self.queryset) # 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( user_relation_num=Count('userrelations'), # noqa role_num=Count('role'), ).filter(user_relation_num=0, role_num=0) # noqa page = self.paginate_queryset(self.filter_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(BaseViewSet, SoftDeleteMixin, viewsets.ModelViewSet, DynamicSearchMixin): """ Crud Operations for User Relations """ queryset = UserRelations.objects.select_related('organization', 'role', 'user') serializer_class = UserRelationSerializer filter_backends = [filters.SearchFilter] search_fields = [ 'user__username', 'user__mobile', 'user__phone', 'user__first_name', 'user__last_name', 'user__national_code', 'user__province__name', 'user__city__name', 'user__unit_name', 'user__unit_national_id', ] def list(self, request, *args, **kwargs): role_param = self.request.query_params.get('role') # noqa org = get_organization_by_user(request.user) queryset = self.get_queryset( visibility_by_org_scope=True ) if org.free_visibility_by_scope else self.get_queryset() print(queryset) if role_param != '': queryset = queryset.filter(role_id=int(role_param)) else: queryset = queryset.order_by('-create_date') queryset = self.filter_queryset(queryset) # 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)