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

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
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
@ -102,45 +101,55 @@ class MongoAdvancedSearchFilter(BaseFilterBackend):
class DataLevelPermissionsFilter(BaseFilterBackend):
"""
数据 级权限过滤器
0. 判断过滤的数据是否有创建人 "creator" 字段
1. 判断用户是否为超级管理员角色
2. 根据角色的最大权限进行数据过滤(会有多个角色进行去重取最大权限)
3. 只为仅本人数据权限时只返回过滤本人数据
4. 自定数据权限 获取部门根据部门过滤
0. 获取用户的部门id没有部门则返回空
1. 判断过滤的数据是否有创建人所在部门 "creator" 字段,没有则返回全部
2. 如果用户没有关联角色则返回本部门数据
3. 根据角色的最大权限进行数据过滤(会有多个角色进行去重取最大权限)
3.1 判断用户是否为超级管理员角色/如果有1(所有数据) 则返回所有数据
4. 只为仅本人数据权限时只返回过滤本人数据并且部门为自己本部门(考虑到用户会变部门只能看当前用户所在的部门数据)
5. 自定数据权限 获取部门根据部门过滤
"""
project_resource_name: str = 'project__tenant__managers'
def filter_queryset(self, request, queryset, view):
# 0. 判断过滤的数据是否有创建人 "creator" 字段
if not hasattr(queryset.model, 'creator'):
# 0. 获取用户的部门id没有部门则返回空
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
# 1. 判断用户是否为超级管理员角色
# 2. 如果用户没有关联角色则返回本部门数据
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
return queryset.filter(dept_belong_id=user_dept_id)
# 2. 根据角色的最大权限进行数据过滤(会有多个角色,进行去重取最大权限)
dataScope_list = list(set([ele.get('dataScope') for ele in role_list]))
if '1' in dataScope_list: # 返回所有数据
# 3. 根据所有角色 获取所有权限范围
role_list = request.user.role.all().values('admin', 'dataScope')
dataScope_list = []
for ele in role_list:
# 3.1 判断用户是否为超级管理员角色/如果有1(所有数据) 则返回所有数据
if '1' == ele.get('dataScope') or ele.get('admin') == True:
return queryset
dataScope_list.append(ele.get('dataScope'))
dataScope_list = list(set(dataScope_list))
# 3. 只为仅本人数据权限时只返回过滤本人数据
# 4. 只为仅本人数据权限时只返回过滤本人数据,并且部门为自己本部门(考虑到用户会变部门,只能看当前用户所在的部门数据)
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 = []
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)
dept_list.append(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))))
dept_list.extend(self.get_dept(user_dept_id, Dept.objects.all().values('id', 'parentId')))
dept_list.append(user_dept_id)
return queryset.filter(dept_belong_id__in=list(set(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.contrib.auth.models import AnonymousUser
from django.utils.deprecation import MiddlewareMixin
from apps.vadmin.system.models import OperationLog
@ -38,6 +39,7 @@ class ApiLoggingMiddleware(MiddlewareMixin):
info = {
'request_ip': getattr(request, 'request_ip', 'unknown'),
'creator': request.user,
'dept_belong_id': getattr(request.user, 'dept_id', None),
'request_method': request.method,
'request_path': request.request_path,
'request_body': body,
@ -50,6 +52,8 @@ class ApiLoggingMiddleware(MiddlewareMixin):
'json_result': {"code": response.data.get('code'), "msg": response.data.get('msg')},
'request_modular': request.session.get('model_name'),
}
if isinstance(request.user, AnonymousUser):
info['creator'] = None
log = OperationLog(**info)
log.save()
@ -67,3 +71,9 @@ class ApiLoggingMiddleware(MiddlewareMixin):
if self.methods == 'ALL' or request.method in self.methods:
self.__handle_response(request, 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,
verbose_name='创建者', on_delete=SET_NULL, db_constraint=False) # 创建者
modifier = ModifierCharField() # 修改者
dept_belong_id = models.CharField(max_length=64, verbose_name="数据归属部门", null=True, blank=True)
update_datetime = UpdateDateTimeField() # 修改时间
create_datetime = CreateDateTimeField() # 创建时间

View File

@ -15,6 +15,8 @@ class CustomModelSerializer(ModelSerializer):
modifier_field_name = 'modifier'
# 创建人的审计字段名称, 默认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)
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
if self.creator_field_name in self.fields.fields:
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)
def update(self, instance, validated_data):

View File

@ -28,6 +28,7 @@ class DictDataModelViewSet(CustomModelViewSet):
update_serializer_class = DictDataCreateUpdateSerializer
# list_serializer_class = ListRoleSerializer
# retrieve_serializer_class = DetailRoleSerializer
extra_filter_backends = [DataLevelPermissionsFilter]
filter_class = DictDataFilter
# update_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) {
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});
}
return search;
@ -67,7 +67,6 @@ export function selectDictLabel(datas, value) {
var actions = [];
Object.keys(datas).some((key) => {
if (String(datas[key].dictValue) === ('' + String(value))) {
actions.push(datas[key].dictLabel);
actions.push(datas[key].dictLabel);
return true;
}

View File

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