数据权限由创建人变为 所属部门 完成

pull/2/head
李强 2021-03-22 21:23:48 +08:00
parent a2f8878d16
commit 6d3f57af21
7 changed files with 51 additions and 33 deletions

View File

@ -6,7 +6,6 @@ import logging
import operator import operator
from functools import reduce from functools import reduce
from django.db.models import Q
from django.utils import six from django.utils import six
from mongoengine.queryset import visitor from mongoengine.queryset import visitor
from rest_framework.filters import BaseFilterBackend, SearchFilter, OrderingFilter from rest_framework.filters import BaseFilterBackend, SearchFilter, OrderingFilter
@ -102,45 +101,55 @@ class MongoAdvancedSearchFilter(BaseFilterBackend):
class DataLevelPermissionsFilter(BaseFilterBackend): class DataLevelPermissionsFilter(BaseFilterBackend):
""" """
数据 级权限过滤器 数据 级权限过滤器
0. 判断过滤的数据是否有创建人 "creator" 字段 0. 获取用户的部门id没有部门则返回空
1. 判断用户是否为超级管理员角色 1. 判断过滤的数据是否有创建人所在部门 "creator" 字段,没有则返回全部
2. 根据角色的最大权限进行数据过滤(会有多个角色进行去重取最大权限) 2. 如果用户没有关联角色则返回本部门数据
3. 只为仅本人数据权限时只返回过滤本人数据 3. 根据角色的最大权限进行数据过滤(会有多个角色进行去重取最大权限)
4. 自定数据权限 获取部门根据部门过滤 3.1 判断用户是否为超级管理员角色/如果有1(所有数据) 则返回所有数据
4. 只为仅本人数据权限时只返回过滤本人数据并且部门为自己本部门(考虑到用户会变部门只能看当前用户所在的部门数据)
5. 自定数据权限 获取部门根据部门过滤
""" """
project_resource_name: str = 'project__tenant__managers'
def filter_queryset(self, request, queryset, view): def filter_queryset(self, request, queryset, view):
# 0. 判断过滤的数据是否有创建人 "creator" 字段 # 0. 获取用户的部门id没有部门则返回空
if not hasattr(queryset.model, 'creator'): user_dept_id = getattr(request.user, 'dept_id')
if not user_dept_id:
return queryset.none()
# 1. 判断过滤的数据是否有创建人所在部门 "dept_belong_id" 字段
if not hasattr(queryset.model, 'dept_belong_id'):
return queryset return queryset
# 1. 判断用户是否为超级管理员角色
# 2. 如果用户没有关联角色则返回本部门数据
if not hasattr(request.user, 'role'): if not hasattr(request.user, 'role'):
return queryset.filter(creator=request.user) return queryset.filter(dept_belong_id=user_dept_id)
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. 根据角色的最大权限进行数据过滤(会有多个角色,进行去重取最大权限) # 3. 根据所有角色 获取所有权限范围
dataScope_list = list(set([ele.get('dataScope') for ele in role_list])) role_list = request.user.role.all().values('admin', 'dataScope')
if '1' in dataScope_list: # 返回所有数据 dataScope_list = []
for ele in role_list:
# 3.1 判断用户是否为超级管理员角色/如果有1(所有数据) 则返回所有数据
if '1' == ele.get('dataScope') or ele.get('admin') == True:
return queryset return queryset
dataScope_list.append(ele.get('dataScope'))
dataScope_list = list(set(dataScope_list))
# 3. 只为仅本人数据权限时只返回过滤本人数据 # 4. 只为仅本人数据权限时只返回过滤本人数据,并且部门为自己本部门(考虑到用户会变部门,只能看当前用户所在的部门数据)
if dataScope_list == ['5']: if dataScope_list == ['5']:
return queryset.filter(Q(creator=request.user)) return queryset.filter(creator=request.user, dept_belong_id=request.user.dept_id)
# 4. 自定数据权限 获取部门,根据部门过滤 # 5. 自定数据权限 获取部门,根据部门过滤
dept_list = [] dept_list = []
for ele in dataScope_list: for ele in dataScope_list:
if ele == '2': if ele == '2':
dept_list.extend(request.user.role.all().values_list('dept__id', flat=True)) dept_list.extend(request.user.role.all().values_list('dept__id', flat=True))
elif ele == '3': elif ele == '3':
dept_list.append(request.user.dept.id) dept_list.append(user_dept_id)
elif ele == '4': elif ele == '4':
dept_list.extend(self.get_dept(request.user.dept.id, Dept.objects.all().values('id', 'parentId'))) dept_list.extend(self.get_dept(user_dept_id, Dept.objects.all().values('id', 'parentId')))
dept_list.append(request.user.dept.id) dept_list.append(user_dept_id)
return queryset.filter(Q(creator=request.user) | Q(creator__dept__in=list(set(dept_list)))) return queryset.filter(dept_belong_id__in=list(set(dept_list)))
def get_dept(self, id, dept_all_list, dept_list=[]): def get_dept(self, id, dept_all_list, dept_list=[]):
""" """

View File

@ -3,6 +3,7 @@ django中间件
""" """
from django.conf import settings from django.conf import settings
from django.contrib.auth.models import AnonymousUser
from django.utils.deprecation import MiddlewareMixin from django.utils.deprecation import MiddlewareMixin
from apps.vadmin.system.models import OperationLog from apps.vadmin.system.models import OperationLog
@ -38,6 +39,7 @@ class ApiLoggingMiddleware(MiddlewareMixin):
info = { info = {
'request_ip': getattr(request, 'request_ip', 'unknown'), 'request_ip': getattr(request, 'request_ip', 'unknown'),
'creator': request.user, 'creator': request.user,
'dept_belong_id': getattr(request.user, 'dept_id', None),
'request_method': request.method, 'request_method': request.method,
'request_path': request.request_path, 'request_path': request.request_path,
'request_body': body, 'request_body': body,
@ -50,6 +52,8 @@ class ApiLoggingMiddleware(MiddlewareMixin):
'json_result': {"code": response.data.get('code'), "msg": response.data.get('msg')}, 'json_result': {"code": response.data.get('code'), "msg": response.data.get('msg')},
'request_modular': request.session.get('model_name'), 'request_modular': request.session.get('model_name'),
} }
if isinstance(request.user, AnonymousUser):
info['creator'] = None
log = OperationLog(**info) log = OperationLog(**info)
log.save() log.save()
@ -67,3 +71,9 @@ class ApiLoggingMiddleware(MiddlewareMixin):
if self.methods == 'ALL' or request.method in self.methods: if self.methods == 'ALL' or request.method in self.methods:
self.__handle_response(request, response) self.__handle_response(request, response)
return response return response
class PermissionModeMiddleware(MiddlewareMixin):
"""
权限模式拦截判断
"""

View File

@ -27,6 +27,7 @@ class CoreModel(models.Model):
creator = models.ForeignKey(to='permission.UserProfile', related_query_name='creator_query', null=True, creator = models.ForeignKey(to='permission.UserProfile', related_query_name='creator_query', null=True,
verbose_name='创建者', on_delete=SET_NULL, db_constraint=False) # 创建者 verbose_name='创建者', on_delete=SET_NULL, db_constraint=False) # 创建者
modifier = ModifierCharField() # 修改者 modifier = ModifierCharField() # 修改者
dept_belong_id = models.CharField(max_length=64, verbose_name="数据归属部门", null=True, blank=True)
update_datetime = UpdateDateTimeField() # 修改时间 update_datetime = UpdateDateTimeField() # 修改时间
create_datetime = CreateDateTimeField() # 创建时间 create_datetime = CreateDateTimeField() # 创建时间

View File

@ -15,6 +15,8 @@ class CustomModelSerializer(ModelSerializer):
modifier_field_name = 'modifier' modifier_field_name = 'modifier'
# 创建人的审计字段名称, 默认creator, 继承使用时可自定义覆盖 # 创建人的审计字段名称, 默认creator, 继承使用时可自定义覆盖
creator_field_name = 'creator' creator_field_name = 'creator'
# 数据所属部门字段
dept_belong_id_field_name = 'dept_belong_id'
# 添加默认时间返回格式 # 添加默认时间返回格式
create_datetime = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S", required=False, read_only=True) create_datetime = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S", required=False, read_only=True)
update_datetime = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S", required=False, read_only=True) update_datetime = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S", required=False, read_only=True)
@ -33,6 +35,8 @@ class CustomModelSerializer(ModelSerializer):
validated_data[self.modifier_field_name] = username validated_data[self.modifier_field_name] = username
if self.creator_field_name in self.fields.fields: if self.creator_field_name in self.fields.fields:
validated_data[self.creator_field_name] = self.request.user validated_data[self.creator_field_name] = self.request.user
if self.dept_belong_id_field_name in self.fields.fields:
validated_data[self.dept_belong_id_field_name] = getattr(self.request.user,'dept_id',None)
return super().create(validated_data) return super().create(validated_data)
def update(self, instance, validated_data): def update(self, instance, validated_data):

View File

@ -28,6 +28,7 @@ class DictDataModelViewSet(CustomModelViewSet):
update_serializer_class = DictDataCreateUpdateSerializer update_serializer_class = DictDataCreateUpdateSerializer
# list_serializer_class = ListRoleSerializer # list_serializer_class = ListRoleSerializer
# retrieve_serializer_class = DetailRoleSerializer # retrieve_serializer_class = DetailRoleSerializer
extra_filter_backends = [DataLevelPermissionsFilter]
filter_class = DictDataFilter filter_class = DictDataFilter
# update_extra_permission_classes = (IsManagerPermission,) # update_extra_permission_classes = (IsManagerPermission,)
# destroy_extra_permission_classes = (IsManagerPermission,) # destroy_extra_permission_classes = (IsManagerPermission,)

View File

@ -56,7 +56,7 @@ export function resetForm(refName) {
// 添加日期范围 // 添加日期范围
export function addDateRange(params, dateRange, propName) { export function addDateRange(params, dateRange, propName) {
let search = JSON.parse(JSON.stringify(params)); let search = JSON.parse(JSON.stringify(params));
if (dateRange.length !== 0) { if (null != dateRange && '' !== dateRange && dateRange.length !== 0) {
search.as = JSON.stringify({create_datetime__range : dateRange}); search.as = JSON.stringify({create_datetime__range : dateRange});
} }
return search; return search;
@ -67,7 +67,6 @@ export function selectDictLabel(datas, value) {
var actions = []; var actions = [];
Object.keys(datas).some((key) => { Object.keys(datas).some((key) => {
if (String(datas[key].dictValue) === ('' + String(value))) { if (String(datas[key].dictValue) === ('' + String(value))) {
actions.push(datas[key].dictLabel);
actions.push(datas[key].dictLabel); actions.push(datas[key].dictLabel);
return true; return true;
} }

View File

@ -369,12 +369,6 @@ export default {
this.menuOptions = this.handleTree(response.data,'id'); this.menuOptions = this.handleTree(response.data,'id');
}); });
}, },
/** 查询部门树结构 */
getDeptTreeselect() {
deptTreeselect().then(response => {
this.deptOptions = response.data;
});
},
// //
getMenuAllCheckedKeys() { getMenuAllCheckedKeys() {
// //