From ef8a365ec0405aa4c14b092fd12f5c0b15e99ae4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E5=BC=BA?= <1206709430@qq.com> Date: Tue, 30 Mar 2021 01:23:09 +0800 Subject: [PATCH] =?UTF-8?q?!11=20=E4=BF=AE=E5=A4=8D=E5=A4=9A=E4=B8=AAbug?= =?UTF-8?q?=20*=20=E4=BF=AE=E5=A4=8DBUG(=E4=B8=AD=E9=97=B4=E4=BB=B6bug):?= =?UTF-8?q?=20=E6=97=A5=E5=BF=97=E4=B8=AD=E9=97=B4=E4=BB=B6=E5=AD=98?= =?UTF-8?q?=E5=85=A5=E6=A8=A1=E5=9D=97=E4=BF=A1=E6=81=AF=E4=B8=8D=E5=85=A8?= =?UTF-8?q?=20*=20=E6=B5=8B=E8=AF=95(=E9=83=A8=E7=BD=B2=E6=B5=8B=E8=AF=95)?= =?UTF-8?q?:=20*=20=E4=BF=AE=E5=A4=8DBUG(=E6=96=87=E4=BB=B6=E4=B8=8A?= =?UTF-8?q?=E4=BC=A0):=20doc=EF=BC=8Cdocx=EF=BC=8Cxlsx=E6=96=87=E4=BB=B6?= =?UTF-8?q?=E9=83=BD=E6=97=A0=E6=B3=95=E4=B8=8A=E4=BC=A0=E6=88=90=E5=8A=9F?= =?UTF-8?q?=20*=20=E4=BF=AE=E5=A4=8DBUG(=E5=88=A0=E9=99=A4=E9=83=A8?= =?UTF-8?q?=E9=97=A8):=20=E9=83=A8=E9=97=A8=E9=87=8C=E9=9D=A2=E5=AD=98?= =?UTF-8?q?=E5=9C=A8=E7=94=A8=E6=88=B7=EF=BC=8C=E4=BE=9D=E7=84=B6=E8=83=BD?= =?UTF-8?q?=E5=A4=9F=E5=88=A0=E9=99=A4=E9=83=A8=E9=97=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dvadmin-backend/application/settings.py | 2 +- .../apps/vadmin/op_drf/logging/view_logger.py | 7 ---- .../apps/vadmin/op_drf/middleware.py | 35 ++++++++++++------- .../apps/vadmin/permission/permissions.py | 20 +++++++++++ .../apps/vadmin/permission/views.py | 4 +-- .../apps/vadmin/system/models/save_file.py | 2 +- .../apps/vadmin/utils/exceptions.py | 2 -- 7 files changed, 46 insertions(+), 26 deletions(-) diff --git a/dvadmin-backend/application/settings.py b/dvadmin-backend/application/settings.py index ee3fc5b..4b385f0 100644 --- a/dvadmin-backend/application/settings.py +++ b/dvadmin-backend/application/settings.py @@ -54,7 +54,6 @@ INSTALLED_APPS = [ ] MIDDLEWARE = [ - 'vadmin.op_drf.middleware.PermissionModeMiddleware', # 权限中间件 'corsheaders.middleware.CorsMiddleware', 'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', @@ -64,6 +63,7 @@ MIDDLEWARE = [ 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', 'vadmin.op_drf.middleware.ApiLoggingMiddleware', # 用于记录API访问日志 + 'vadmin.op_drf.middleware.PermissionModeMiddleware', # 权限中间件 ] # 允许跨域源 CORS_ORIGIN_ALLOW_ALL = CORS_ORIGIN_ALLOW_ALL diff --git a/dvadmin-backend/apps/vadmin/op_drf/logging/view_logger.py b/dvadmin-backend/apps/vadmin/op_drf/logging/view_logger.py index 3e03558..eb110d8 100644 --- a/dvadmin-backend/apps/vadmin/op_drf/logging/view_logger.py +++ b/dvadmin-backend/apps/vadmin/op_drf/logging/view_logger.py @@ -18,13 +18,6 @@ class ViewLogger(object): self.request = request self.model = None self.log_prefix: str = '' - if self.view and hasattr(self.view.get_queryset(), 'model'): - self.model: Model = self.view.get_queryset().model - elif self.view and hasattr(self.view.get_serializer(), 'Meta') and hasattr(self.view.get_serializer().Meta, - 'model'): - self.model: Model = self.view.get_serializer().Meta.model - if self.model: - request.session['model_name'] = str(getattr(self.model, '_meta').verbose_name) def handle(self, request: Request, *args, **kwargs): pass diff --git a/dvadmin-backend/apps/vadmin/op_drf/middleware.py b/dvadmin-backend/apps/vadmin/op_drf/middleware.py index 5e2f1d1..bb19c28 100644 --- a/dvadmin-backend/apps/vadmin/op_drf/middleware.py +++ b/dvadmin-backend/apps/vadmin/op_drf/middleware.py @@ -1,6 +1,7 @@ """ django中间件 """ +import json import logging import os @@ -11,7 +12,7 @@ from django.utils.deprecation import MiddlewareMixin from apps.vadmin.permission.models import Menu from apps.vadmin.system.models import OperationLog from ..utils.request_util import get_request_ip, get_request_data, get_request_path, get_browser, get_os, \ - get_login_location, get_request_canonical_path, get_request_user + get_login_location, get_request_canonical_path, get_request_user, get_verbose_name from ..utils.response import ErrorJsonResponse logger = logging.getLogger(__name__) @@ -42,9 +43,16 @@ class ApiLoggingMiddleware(MiddlewareMixin): body['password'] = '*' * len(body['password']) if not hasattr(response, 'data') or not isinstance(response.data, dict): response.data = {} + if not response.data and response.content: + try: + content = json.loads(response.content.decode()) + response.data = content if isinstance(content, dict) else {} + except: + pass + user = get_request_user(request) info = { 'request_ip': getattr(request, 'request_ip', 'unknown'), - 'creator': request.user, + 'creator': user if not isinstance(user, AnonymousUser) else '', 'dept_belong_id': getattr(request.user, 'dept_id', None), 'request_method': request.method, 'request_path': request.request_path, @@ -58,11 +66,14 @@ 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() + def process_view(self, request, view_func, view_args, view_kwargs): + if view_func.cls and hasattr(view_func.cls, 'queryset'): + request.session['model_name'] = get_verbose_name(view_func.cls.queryset) + return + def process_request(self, request): self.__handle_request(request) @@ -85,14 +96,7 @@ class PermissionModeMiddleware(MiddlewareMixin): """ def process_request(self, request): - """ - 判断环境变量中,是否为演示模式(正常可忽略此判断) - :param request: - :return: - """ - white_list = ['/admin/logout/', '/admin/login/'] - if os.getenv('DEMO_ENV') and not request.method == 'GET' and request.path not in white_list: - return ErrorJsonResponse(data={}, msg=f'演示模式,不允许操作!') + return def has_interface_permission(self, request, method, view_path, user=None): """ @@ -135,13 +139,18 @@ class PermissionModeMiddleware(MiddlewareMixin): return -10 def process_view(self, request, view_func, view_args, view_kwargs): + # 判断环境变量中,是否为演示模式(正常可忽略此判断) + white_list = ['/admin/logout/', '/admin/login/'] + if not os.getenv('DEMO_ENV') and not request.method in ['GET', 'OPTIONS'] and request.path not in white_list: + return ErrorJsonResponse(data={}, msg=f'演示模式,不允许操作!') + if not settings.INTERFACE_PERMISSION: return user = get_request_user(request) if user and not isinstance(user, AnonymousUser): method = request.method.upper() - if method == 'GET': # GET 不设置接口权限 + if method == 'GET': # GET 不设置接口权限 return view_path = get_request_canonical_path(request, *view_args, **view_kwargs) auth_code = self.has_interface_permission(request, method, view_path, user) diff --git a/dvadmin-backend/apps/vadmin/permission/permissions.py b/dvadmin-backend/apps/vadmin/permission/permissions.py index 0186adb..3c09387 100644 --- a/dvadmin-backend/apps/vadmin/permission/permissions.py +++ b/dvadmin-backend/apps/vadmin/permission/permissions.py @@ -93,3 +93,23 @@ class CommonPermission(CustomPermission): self.message = f"没有此数据操作权限!" res = self.check_queryset(request, instance) return res + + +class DeptDestroyPermission(CustomPermission): + """ + 部门删除权限校验:判断部门下是否有用户存在,存在不可删除 + """ + message = '没有有操作权限' + + def has_permission(self, request: Request, view: APIView): + return True + + def check_queryset(self, request, instance): + if instance.values_list('userprofile', flat=True): + self.message = "该部门下有关联用户,无法删除!" + return False + return True + + def has_object_permission(self, request: Request, view: APIView, instance): + res = self.check_queryset(request, instance) + return res diff --git a/dvadmin-backend/apps/vadmin/permission/views.py b/dvadmin-backend/apps/vadmin/permission/views.py index bec3b8e..72855b4 100644 --- a/dvadmin-backend/apps/vadmin/permission/views.py +++ b/dvadmin-backend/apps/vadmin/permission/views.py @@ -2,7 +2,7 @@ from django.contrib.auth import authenticate from rest_framework.request import Request from rest_framework.views import APIView -from .permissions import CommonPermission +from .permissions import CommonPermission, DeptDestroyPermission from ..op_drf.filters import DataLevelPermissionsFilter from ..op_drf.viewsets import CustomModelViewSet from ..permission.filters import MenuFilter, DeptFilter, PostFilter, RoleFilter, UserProfileFilter @@ -129,7 +129,7 @@ class DeptModelViewSet(CustomModelViewSet): filter_class = DeptFilter extra_filter_backends = [DataLevelPermissionsFilter] update_extra_permission_classes = (CommonPermission,) - destroy_extra_permission_classes = (CommonPermission,) + destroy_extra_permission_classes = (CommonPermission, DeptDestroyPermission) create_extra_permission_classes = (CommonPermission,) search_fields = ('deptName',) ordering = 'create_datetime' # 默认排序 diff --git a/dvadmin-backend/apps/vadmin/system/models/save_file.py b/dvadmin-backend/apps/vadmin/system/models/save_file.py index b43757d..30407cf 100644 --- a/dvadmin-backend/apps/vadmin/system/models/save_file.py +++ b/dvadmin-backend/apps/vadmin/system/models/save_file.py @@ -13,7 +13,7 @@ def files_path(instance, filename): class SaveFile(CoreModel): name = CharField(max_length=128, verbose_name="文件名称", null=True, blank=True) - type = CharField(max_length=32, verbose_name="文件类型", null=True, blank=True) + type = CharField(max_length=200, verbose_name="文件类型", null=True, blank=True) size = CharField(max_length=64, verbose_name="文件大小", null=True, blank=True) address = CharField(max_length=16, verbose_name="存储位置", null=True, blank=True) # 本地、阿里云、腾讯云.. source = CharField(max_length=16, verbose_name="文件来源", null=True, blank=True) # 导出、用户上传. diff --git a/dvadmin-backend/apps/vadmin/utils/exceptions.py b/dvadmin-backend/apps/vadmin/utils/exceptions.py index cbd065e..f018592 100644 --- a/dvadmin-backend/apps/vadmin/utils/exceptions.py +++ b/dvadmin-backend/apps/vadmin/utils/exceptions.py @@ -65,8 +65,6 @@ def op_exception_handler(ex, context): """ msg = '' code = '201' - request = context.get('request') - request.session['model_name'] = str(get_verbose_name(view=context.get('view'))) if isinstance(ex, AuthenticationFailed): code = 401