refactor: 重构权限管理
1.更新字段管理
This commit is contained in:
@@ -13,7 +13,6 @@ class Role(CoreModel):
|
||||
key = models.CharField(max_length=64, unique=True, verbose_name="权限字符", help_text="权限字符")
|
||||
sort = models.IntegerField(default=1, verbose_name="角色顺序", help_text="角色顺序")
|
||||
status = models.BooleanField(default=True, verbose_name="角色状态", help_text="角色状态")
|
||||
admin = models.BooleanField(default=False, verbose_name="是否为admin", help_text="是否为admin")
|
||||
|
||||
class Meta:
|
||||
db_table = table_prefix + "system_role"
|
||||
@@ -179,21 +178,27 @@ class Menu(CoreModel):
|
||||
verbose_name_plural = verbose_name
|
||||
ordering = ("sort",)
|
||||
|
||||
|
||||
class Columns(CoreModel):
|
||||
role = models.ForeignKey(to='Role', on_delete=models.CASCADE, verbose_name='角色', db_constraint=False)
|
||||
app = models.CharField(max_length=64, verbose_name='应用名')
|
||||
model = models.CharField(max_length=64, verbose_name='表名')
|
||||
class MenuField(CoreModel):
|
||||
model = models.CharField(max_length=64, verbose_name='表名',null=True,blank=True)
|
||||
menu = models.ForeignKey(to='Menu', on_delete=models.CASCADE, verbose_name='菜单', db_constraint=False)
|
||||
field_name = models.CharField(max_length=64, verbose_name='模型表字段名')
|
||||
title = models.CharField(max_length=64, verbose_name='字段显示名')
|
||||
class Meta:
|
||||
db_table = table_prefix + "system_menu_field"
|
||||
verbose_name = "菜单字段表"
|
||||
verbose_name_plural = verbose_name
|
||||
ordering = ("id",)
|
||||
|
||||
class FieldPermission(CoreModel):
|
||||
role = models.ForeignKey(to='Role', on_delete=models.CASCADE, verbose_name='角色', db_constraint=False)
|
||||
field = models.ForeignKey(to='MenuField', on_delete=models.CASCADE,related_name='menu_field', verbose_name='字段', db_constraint=False)
|
||||
is_query = models.BooleanField(default=1, verbose_name='是否可查询')
|
||||
is_create = models.BooleanField(default=1, verbose_name='是否可创建')
|
||||
is_update = models.BooleanField(default=1, verbose_name='是否可更新')
|
||||
|
||||
class Meta:
|
||||
db_table = table_prefix + "system_columns"
|
||||
verbose_name = "列权限表"
|
||||
db_table = table_prefix + "system_field_permission"
|
||||
verbose_name = "字段权限表"
|
||||
verbose_name_plural = verbose_name
|
||||
ordering = ("id",)
|
||||
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from django.apps import apps
|
||||
from rest_framework import serializers
|
||||
from rest_framework.decorators import action
|
||||
from rest_framework.permissions import IsAuthenticated
|
||||
|
||||
from dvadmin.system.models import Columns, Role
|
||||
from dvadmin.system.models import Role, MenuField
|
||||
from dvadmin.utils.models import get_custom_app_models
|
||||
from dvadmin.utils.viewset import CustomModelViewSet
|
||||
from dvadmin.utils.serializers import CustomModelSerializer
|
||||
@@ -16,7 +17,7 @@ class ColumnSerializer(CustomModelSerializer):
|
||||
"""
|
||||
|
||||
class Meta:
|
||||
model = Columns
|
||||
model = MenuField
|
||||
fields = '__all__'
|
||||
read_only_fields = ['id']
|
||||
|
||||
@@ -25,33 +26,34 @@ class ColumnViewSet(CustomModelViewSet):
|
||||
"""
|
||||
列权限视图集
|
||||
"""
|
||||
queryset = Columns.objects.all()
|
||||
queryset = MenuField.objects.all()
|
||||
serializer_class = ColumnSerializer
|
||||
|
||||
def list(self, request, *args, **kwargs):
|
||||
role_id = request.query_params.get('role')
|
||||
app_name = request.query_params.get('app')
|
||||
model_name = request.query_params.get('model')
|
||||
menu = request.query_params.get('menu')
|
||||
if not role_id or not model_name or not app_name or not menu:
|
||||
if not menu:
|
||||
return SuccessResponse([])
|
||||
queryset = self.filter_queryset(self.get_queryset().filter(role_id=role_id, model=model_name, app=app_name,menu_id=menu))
|
||||
page = self.paginate_queryset(queryset)
|
||||
if page is not None:
|
||||
serializer = self.get_serializer(page, many=True, request=request)
|
||||
return self.get_paginated_response(serializer.data)
|
||||
queryset = self.filter_queryset(self.get_queryset().filter(menu=menu))
|
||||
# page = self.paginate_queryset(queryset)
|
||||
# if page is not None:
|
||||
# serializer = self.get_serializer(page, many=True, request=request)
|
||||
# return self.get_paginated_response(serializer.data)
|
||||
serializer = self.get_serializer(queryset, many=True, request=request)
|
||||
return SuccessResponse(data=serializer.data, msg="获取成功")
|
||||
|
||||
def create(self, request, *args, **kwargs):
|
||||
payload = request.data
|
||||
for model in get_custom_app_models(payload.get('app')):
|
||||
if payload.get('model') == model['model']:
|
||||
print(11,get_custom_app_models())
|
||||
for model in apps.get_models():
|
||||
print(model.__name__)
|
||||
if payload.get('model') == model.__name__:
|
||||
break
|
||||
else:
|
||||
return ErrorResponse(msg='模型表不存在')
|
||||
|
||||
if Columns.objects.filter(app=model['app'], model=model['model'], field_name=payload.get('field_name')).exists():
|
||||
if MenuField.objects.filter(menu=payload.get('menu'),model=model.__name__, field_name=payload.get('field_name')).exists():
|
||||
return ErrorResponse(msg='‘%s’ 字段权限已有,不可重复创建' % payload.get('title'))
|
||||
|
||||
return super().create(request, *args, **kwargs)
|
||||
@@ -72,21 +74,21 @@ class ColumnViewSet(CustomModelViewSet):
|
||||
@action(methods=['POST'], detail=False, permission_classes=[IsAuthenticated])
|
||||
def auto_match_fields(self, request):
|
||||
"""自动匹配已有的字段"""
|
||||
role_id = request.data.get('role')
|
||||
menu_id = request.data.get('menu')
|
||||
app_name = request.data.get('app')
|
||||
model_name = request.data.get('model')
|
||||
if not role_id or not model_name or not app_name:
|
||||
return DetailResponse([], msg='无操作')
|
||||
if not menu_id or not model_name or not app_name:
|
||||
return ErrorResponse( msg='参数错误')
|
||||
for model in get_custom_app_models(app_name):
|
||||
if model['model'] != model_name:
|
||||
continue
|
||||
for field in model['fields']:
|
||||
if Columns.objects.filter(
|
||||
role_id=role_id, app=app_name, model=model_name, field_name=field['name']
|
||||
if MenuField.objects.filter(
|
||||
menu_id=menu_id, app=app_name, model=model_name, field_name=field['name']
|
||||
).exists():
|
||||
continue
|
||||
data = {
|
||||
'role': role_id,
|
||||
'menu': menu_id,
|
||||
'app': app_name,
|
||||
'model': model_name,
|
||||
'field_name': field['name'],
|
||||
|
||||
@@ -119,8 +119,7 @@ class MenuViewSet(CustomModelViewSet):
|
||||
def web_router(self, request):
|
||||
"""用于前端获取当前角色的路由"""
|
||||
user = request.user
|
||||
is_admin = user.role.values_list('admin', flat=True)
|
||||
if user.is_superuser or True in is_admin:
|
||||
if user.is_superuser:
|
||||
queryset = self.queryset.filter(status=1)
|
||||
else:
|
||||
role_list = user.role.values_list('id', flat=True)
|
||||
|
||||
@@ -63,8 +63,7 @@ class MenuButtonViewSet(CustomModelViewSet):
|
||||
:return:
|
||||
"""
|
||||
is_superuser = request.user.is_superuser
|
||||
is_admin = request.user.role.values_list('admin', flat=True)
|
||||
if is_superuser or True in is_admin:
|
||||
if is_superuser:
|
||||
queryset = MenuButton.objects.values_list('value',flat=True)
|
||||
else:
|
||||
role_id = request.user.role.values_list('id', flat=True)
|
||||
|
||||
@@ -11,7 +11,8 @@ from rest_framework import serializers
|
||||
from rest_framework.decorators import action
|
||||
from rest_framework.permissions import IsAuthenticated
|
||||
|
||||
from dvadmin.system.models import RoleMenuButtonPermission, Menu, MenuButton, Dept, RoleMenuPermission, Columns
|
||||
from dvadmin.system.models import RoleMenuButtonPermission, Menu, MenuButton, Dept, RoleMenuPermission, FieldPermission, \
|
||||
MenuField
|
||||
from dvadmin.system.views.menu import MenuSerializer
|
||||
from dvadmin.utils.json_response import DetailResponse, ErrorResponse
|
||||
from dvadmin.utils.serializers import CustomModelSerializer
|
||||
@@ -71,12 +72,41 @@ class RoleButtonPermissionSerializer(CustomModelSerializer):
|
||||
model = MenuButton
|
||||
fields = ['id','name','value','isCheck','data_range']
|
||||
|
||||
class RoleColumnsSerializer(CustomModelSerializer):
|
||||
class RoleFieldPermissionSerializer(CustomModelSerializer):
|
||||
|
||||
class Meta:
|
||||
model = Columns
|
||||
model = FieldPermission
|
||||
fields = "__all__"
|
||||
|
||||
class RoleMenuFieldSerializer(CustomModelSerializer):
|
||||
is_query = serializers.SerializerMethodField()
|
||||
is_create = serializers.SerializerMethodField()
|
||||
is_update = serializers.SerializerMethodField()
|
||||
|
||||
def get_is_query(self, instance):
|
||||
params = self.request.query_params
|
||||
queryset = instance.menu_field.filter(role=params.get('role')).first()
|
||||
if queryset:
|
||||
return queryset.is_query
|
||||
return False
|
||||
|
||||
def get_is_create(self, instance):
|
||||
params = self.request.query_params
|
||||
queryset = instance.menu_field.filter(role=params.get('role')).first()
|
||||
if queryset:
|
||||
return queryset.is_create
|
||||
return False
|
||||
|
||||
def get_is_update(self, instance):
|
||||
params = self.request.query_params
|
||||
queryset = instance.menu_field.filter(role=params.get('role')).first()
|
||||
if queryset:
|
||||
return queryset.is_update
|
||||
return False
|
||||
class Meta:
|
||||
model = MenuField
|
||||
fields = ['id','field_name','title','is_query','is_create','is_update']
|
||||
|
||||
|
||||
class RoleMenuPermissionSerializer(CustomModelSerializer):
|
||||
"""
|
||||
@@ -99,9 +129,8 @@ class RoleMenuPermissionSerializer(CustomModelSerializer):
|
||||
return serializer.data
|
||||
|
||||
def get_columns(self, instance):
|
||||
params = self.request.query_params
|
||||
col_list = Columns.objects.filter(role__id=params.get('role'),menu__id=instance['id'])
|
||||
serializer = RoleColumnsSerializer(col_list,many=True,request=self.request)
|
||||
col_list = MenuField.objects.filter(menu=instance['id'])
|
||||
serializer = RoleMenuFieldSerializer(col_list,many=True,request=self.request)
|
||||
return serializer.data
|
||||
|
||||
|
||||
@@ -165,10 +194,11 @@ class RoleMenuButtonPermissionViewSet(CustomModelViewSet):
|
||||
RoleMenuPermission.objects.create(role_id=pk, menu_id=menu.get('id'))
|
||||
for btn in menu.get('btns'):
|
||||
if btn.get('isCheck'):
|
||||
instance = RoleMenuButtonPermission.objects.create(role_id=pk, menu_button_id=btn.get('id'),data_range=btn.get('data_range'))
|
||||
data_range = btn.get('data_range',0) or 0
|
||||
instance = RoleMenuButtonPermission.objects.create(role_id=pk, menu_button_id=btn.get('id'),data_range=data_range)
|
||||
instance.dept.set(btn.get('dept',[]))
|
||||
for col in menu.get('columns'):
|
||||
Columns.objects.filter(id=col.get('id')).update(is_query=col.get('is_query'),is_create=col.get('is_create'),is_update=col.get('is_update'))
|
||||
FieldPermission.objects.update_or_create(role_id=pk,field_id=col.get('id'),is_query=col.get('is_query'),is_create=col.get('is_create'),is_update=col.get('is_update'))
|
||||
return DetailResponse(msg="授权成功")
|
||||
|
||||
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from django.db.models import F
|
||||
from rest_framework.decorators import action
|
||||
from rest_framework.permissions import IsAuthenticated
|
||||
|
||||
from dvadmin.system.models import Columns
|
||||
from dvadmin.system.models import FieldPermission, MenuField
|
||||
from dvadmin.utils.json_response import DetailResponse
|
||||
from dvadmin.utils.models import get_custom_app_models
|
||||
|
||||
@@ -23,16 +24,17 @@ class FieldPermissionMixin:
|
||||
break
|
||||
if finded is False:
|
||||
return []
|
||||
roles = request.user.role.values_list('id', flat=True)
|
||||
print(266666,model)
|
||||
user = request.user
|
||||
if user.is_superuser==1:
|
||||
data = Columns.objects.filter(app=model['app'], model=model['model']).values('field_name', 'is_create', 'is_query', 'is_update')
|
||||
data = MenuField.objects.filter( model=model['model']).values('field_name')
|
||||
for item in data:
|
||||
item['is_create'] = True
|
||||
item['is_query'] = True
|
||||
item['is_update'] = True
|
||||
else:
|
||||
data= Columns.objects.filter(
|
||||
app=model['app'], model=model['model'],role__in=roles
|
||||
).values('field_name', 'is_create', 'is_query', 'is_update')
|
||||
roles = request.user.role.values_list('id', flat=True)
|
||||
data= FieldPermission.objects.filter(
|
||||
field__model=model['model'],role__in=roles
|
||||
).values( 'is_create', 'is_query', 'is_update',field_name=F('field__field_name'))
|
||||
return DetailResponse(data=data)
|
||||
@@ -121,13 +121,12 @@ class DataLevelPermissionsFilter(BaseFilterBackend):
|
||||
role__status=1,
|
||||
menu_button__api=re_api,
|
||||
menu_button__method=method).values(
|
||||
'data_range',
|
||||
role_admin=F('role__admin')
|
||||
'data_range'
|
||||
)
|
||||
dataScope_list = [] # 权限范围列表
|
||||
for ele in role_permission_list:
|
||||
# 判断用户是否为超级管理员角色/如果拥有[全部数据权限]则返回所有数据
|
||||
if ele.get("data_range") == 3 or ele.get("role_admin") == True:
|
||||
if ele.get("data_range") == 3:
|
||||
return queryset
|
||||
dataScope_list.append(ele.get("data_range"))
|
||||
dataScope_list = list(set(dataScope_list))
|
||||
|
||||
@@ -136,10 +136,11 @@ def get_model_from_app(app_name):
|
||||
|
||||
|
||||
def get_custom_app_models(app_name=None):
|
||||
"""获取所有项目写的app里的models"""
|
||||
"""获取所有项目下的app里的models"""
|
||||
if app_name:
|
||||
return get_model_from_app(app_name)
|
||||
res = []
|
||||
for app in settings.CUSTOM_APPS:
|
||||
# print(222,get_model_from_app(app))
|
||||
res.append(get_model_from_app(app))
|
||||
return res
|
||||
|
||||
@@ -79,6 +79,5 @@ class CustomPagination(PageNumberPagination):
|
||||
('total', total),
|
||||
('is_next', is_next),
|
||||
('is_previous', is_previous),
|
||||
('data', data),
|
||||
('permission', self.request.permission_fields)
|
||||
('data', data)
|
||||
]))
|
||||
|
||||
@@ -17,7 +17,7 @@ from dvadmin.utils.import_export_mixin import ExportSerializerMixin, ImportSeria
|
||||
from dvadmin.utils.json_response import SuccessResponse, ErrorResponse, DetailResponse
|
||||
from dvadmin.utils.permission import CustomPermission
|
||||
from dvadmin.utils.models import get_custom_app_models
|
||||
from dvadmin.system.models import Columns
|
||||
from dvadmin.system.models import FieldPermission, MenuField
|
||||
from django_restql.mixins import QueryArgumentsMixin
|
||||
|
||||
|
||||
@@ -64,7 +64,7 @@ class CustomModelViewSet(ModelViewSet, ImportSerializerMixin, ExportSerializerMi
|
||||
serializer_class = self.get_serializer_class()
|
||||
kwargs.setdefault('context', self.get_serializer_context())
|
||||
# 全部以可见字段为准
|
||||
can_see = self.get_column_permission(serializer_class)
|
||||
can_see = self.get_menu_field(serializer_class)
|
||||
# 排除掉序列化器级的字段
|
||||
# sub_set = set(serializer_class._declared_fields.keys()) - set(can_see)
|
||||
# for field in sub_set:
|
||||
@@ -79,8 +79,8 @@ class CustomModelViewSet(ModelViewSet, ImportSerializerMixin, ExportSerializerMi
|
||||
else:
|
||||
return serializer_class(*args, **kwargs)
|
||||
|
||||
def get_column_permission(self, serializer_class):
|
||||
"""获取列权限"""
|
||||
def get_menu_field(self, serializer_class):
|
||||
"""获取字段权限"""
|
||||
finded = False
|
||||
for app in get_custom_app_models():
|
||||
for model in app:
|
||||
@@ -91,9 +91,8 @@ class CustomModelViewSet(ModelViewSet, ImportSerializerMixin, ExportSerializerMi
|
||||
break
|
||||
if finded is False:
|
||||
return []
|
||||
return Columns.objects.filter(
|
||||
app=model['app'], model=model['model']
|
||||
).values('field_name', 'is_create', 'is_query', 'is_update')
|
||||
return MenuField.objects.filter(model=model['model']
|
||||
).values('field_name', 'title')
|
||||
|
||||
def create(self, request, *args, **kwargs):
|
||||
serializer = self.get_serializer(data=request.data, request=request)
|
||||
|
||||
Reference in New Issue
Block a user