diff --git a/dvadmin-backend/apps/op_drf/filters.py b/dvadmin-backend/apps/op_drf/filters.py index 0ac31a8..0a7a5bc 100644 --- a/dvadmin-backend/apps/op_drf/filters.py +++ b/dvadmin-backend/apps/op_drf/filters.py @@ -6,10 +6,13 @@ import logging import operator from functools import reduce +from django.db.models import Q from django.utils import six from mongoengine.queryset import visitor from rest_framework.filters import BaseFilterBackend, SearchFilter, OrderingFilter +from apps.permission.models import Dept + logger = logging.getLogger(__name__) @@ -94,3 +97,59 @@ class MongoAdvancedSearchFilter(BaseFilterBackend): if as_kwargs: queryset = queryset.filter(**as_kwargs) return queryset + + +class DataLevelPermissionsFilter(BaseFilterBackend): + """ + 数据 级权限过滤器 + 0. 判断过滤的数据是否有创建人 "creator" 字段 + 1. 判断用户是否为超级管理员角色 + 2. 根据角色的最大权限进行数据过滤(会有多个角色,进行去重取最大权限) + 3. 只为仅本人数据权限时只返回过滤本人数据 + 4. 自定数据权限 获取部门,根据部门过滤 + """ + project_resource_name: str = 'project__tenant__managers' + + def filter_queryset(self, request, queryset, view): + # 0. 判断过滤的数据是否有创建人 "creator" 字段 + if not hasattr(queryset.model, 'creator'): + return queryset + # 1. 判断用户是否为超级管理员角色 + if not hasattr(request.user, 'role'): + return queryset.filter(creator=request.user) + role_list = request.user.role.all().values('id', 'admin', 'dataScope') + if True in list(set([ele.get('admin') for ele in role_list])): + return queryset + + # 2. 根据角色的最大权限进行数据过滤(会有多个角色,进行去重取最大权限) + dataScope_list = list(set([ele.get('dataScope') for ele in role_list])) + if '1' in dataScope_list: # 返回所有数据 + return queryset + + # 3. 只为仅本人数据权限时只返回过滤本人数据 + if dataScope_list == ['5']: + return queryset.filter(Q(creator=request.user)) + + # 4. 自定数据权限 获取部门,根据部门过滤 + dept_list = [] + for ele in dataScope_list: + if ele == '2': + dept_list.extend(request.user.role.all().values_list('dept__id', flat=True)) + elif ele == '3': + dept_list.append(request.user.dept.id) + elif ele == '4': + dept_list.extend(self.get_dept(request.user.dept.id, Dept.objects.all().values('id', 'parentId'))) + dept_list.append(request.user.dept.id) + return queryset.filter(Q(creator=request.user) | Q(creator__dept__in=list(set(dept_list)))) + + def get_dept(self, id, dept_all_list, dept_list=[]): + """ + 获取部门的所有下级部门 + :param id: + :return: + """ + for ele in dept_all_list: + if ele.get('parentId') == id: + dept_list.append(ele.get('id')) + self.get_dept(ele.get('id'), dept_all_list, dept_list) + return dept_list diff --git a/dvadmin-backend/apps/permission/views.py b/dvadmin-backend/apps/permission/views.py index 3ddbab6..0c866f4 100644 --- a/dvadmin-backend/apps/permission/views.py +++ b/dvadmin-backend/apps/permission/views.py @@ -9,6 +9,7 @@ from apps.permission.serializers import UserProfileSerializer, MenuSerializer, R MenuCreateUpdateSerializer, DeptSerializer, DeptCreateUpdateSerializer, PostSerializer, PostCreateUpdateSerializer, \ RoleCreateUpdateSerializer, DeptTreeSerializer, MenuTreeSerializer, UserProfileCreateUpdateSerializer, \ PostSimpleSerializer, RoleSimpleSerializer, ExportUserProfileSerializer, ExportRoleSerializer, ExportPostSerializer +from apps.op_drf.filters import DataLevelPermissionsFilter from utils.export_excel import export_excel_save_model from utils.response import SuccessResponse, ErrorResponse @@ -78,6 +79,7 @@ class MenuModelViewSet(CustomModelViewSet): create_serializer_class = MenuCreateUpdateSerializer update_serializer_class = MenuCreateUpdateSerializer filter_class = MenuFilter + extra_filter_backends = [DataLevelPermissionsFilter] # update_extra_permission_classes = (IsManagerPermission,) # destroy_extra_permission_classes = (IsManagerPermission,) # create_extra_permission_classes = (IsManagerPermission,) @@ -126,6 +128,7 @@ class DeptModelViewSet(CustomModelViewSet): create_serializer_class = DeptCreateUpdateSerializer update_serializer_class = DeptCreateUpdateSerializer filter_class = DeptFilter + extra_filter_backends = [DataLevelPermissionsFilter] # update_extra_permission_classes = (IsManagerPermission,) # destroy_extra_permission_classes = (IsManagerPermission,) # create_extra_permission_classes = (IsManagerPermission,) @@ -190,6 +193,7 @@ class PostModelViewSet(CustomModelViewSet): create_serializer_class = PostCreateUpdateSerializer update_serializer_class = PostCreateUpdateSerializer filter_class = PostFilter + extra_filter_backends = [DataLevelPermissionsFilter] # update_extra_permission_classes = (IsManagerPermission,) # destroy_extra_permission_classes = (IsManagerPermission,) # create_extra_permission_classes = (IsManagerPermission,) @@ -218,6 +222,7 @@ class RoleModelViewSet(CustomModelViewSet): create_serializer_class = RoleCreateUpdateSerializer update_serializer_class = RoleCreateUpdateSerializer filter_class = RoleFilter + extra_filter_backends = [DataLevelPermissionsFilter] # update_extra_permission_classes = (IsManagerPermission,) # destroy_extra_permission_classes = (IsManagerPermission,) # create_extra_permission_classes = (IsManagerPermission,) @@ -246,6 +251,7 @@ class UserProfileModelViewSet(CustomModelViewSet): create_serializer_class = UserProfileCreateUpdateSerializer update_serializer_class = UserProfileCreateUpdateSerializer filter_class = UserProfileFilter + extra_filter_backends = [DataLevelPermissionsFilter] # update_extra_permission_classes = (IsManagerPermission,) # destroy_extra_permission_classes = (IsManagerPermission,) # create_extra_permission_classes = (IsManagerPermission,) diff --git a/dvadmin-backend/apps/system/views.py b/dvadmin-backend/apps/system/views.py index f847858..a58a348 100644 --- a/dvadmin-backend/apps/system/views.py +++ b/dvadmin-backend/apps/system/views.py @@ -7,6 +7,7 @@ from apps.system.serializers import DictDataSerializer, DictDataCreateUpdateSeri DictDetailsCreateUpdateSerializer, DictDetailsListSerializer, ConfigSettingsSerializer, \ ConfigSettingsCreateUpdateSerializer, SaveFileSerializer, SaveFileCreateUpdateSerializer, \ ExportConfigSettingsSerializer, ExportDictDataSerializer, ExportDictDetailsSerializer +from op_drf.filters import DataLevelPermissionsFilter from utils.export_excel import export_excel_save_model from utils.response import SuccessResponse @@ -50,6 +51,7 @@ class DictDetailsModelViewSet(CustomModelViewSet): create_serializer_class = DictDetailsCreateUpdateSerializer update_serializer_class = DictDetailsCreateUpdateSerializer filter_class = DictDetailsFilter + extra_filter_backends = [DataLevelPermissionsFilter] # update_extra_permission_classes = (IsManagerPermission,) # destroy_extra_permission_classes = (IsManagerPermission,) # create_extra_permission_classes = (IsManagerPermission,) @@ -93,6 +95,7 @@ class ConfigSettingsModelViewSet(CustomModelViewSet): create_serializer_class = ConfigSettingsCreateUpdateSerializer update_serializer_class = ConfigSettingsCreateUpdateSerializer filter_class = ConfigSettingsFilter + extra_filter_backends = [DataLevelPermissionsFilter] # update_extra_permission_classes = (IsManagerPermission,) # destroy_extra_permission_classes = (IsManagerPermission,) # create_extra_permission_classes = (IsManagerPermission,) @@ -134,5 +137,6 @@ class SaveFileModelViewSet(CustomModelViewSet): create_serializer_class = SaveFileCreateUpdateSerializer update_serializer_class = SaveFileCreateUpdateSerializer # filter_class = ConfigSettingsFilter + extra_filter_backends = [DataLevelPermissionsFilter] search_fields = ('configName',) ordering = 'id' # 默认排序