1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114
   | from rest_framework import permissions class CodePermission(permissions.BasePermission):     REQUEST_METHOD_MAP = {         'list': 'GET',         'create': 'POST',         'destroy': 'DELETE',         'delete': 'DELETE',         'retrieve': 'GET',         'put': 'PUT',         'get': 'GET',         'post': 'POST',         'patch': 'PATCH'     }
      def check_permission_format(self, permission_code, permission_code_by_method, view):         """检查配置的权限是否合法,不满足格式要求会抛异常"""         module_path = "{}.{}".format(view.__module__, view.__name__)         if permission_code and permission_code is not None and not isinstance(permission_code, (int, list)):             raise TypeError(                 '<%s> permission_code type was not int or list' % module_path             )         else:             if isinstance(permission_code, list):                 for action_code in permission_code:                     if not isinstance(action_code, int):                         raise TypeError(                             '<%s> permission_code list value "%s" type was not int!' % (module_path, action_code)                         )         if permission_code_by_method and permission_code_by_method is not None:             """"""             if not isinstance(permission_code_by_method, dict):                 raise TypeError(                     '<%s> permission_code_by_method type must dict!' % module_path                 )             for action in permission_code_by_method:                 if str(action).lower() not in self.REQUEST_METHOD_MAP:                     raise TypeError(                         '<%s> permission_code_by_method: action "%s" not support, allow:[%s]' % (                             module_path, action, ",".join(self.REQUEST_METHOD_MAP.keys())                         )                     )                 if not hasattr(view, action):                     raise AttributeError(                         '<%s> permission_code_by_method: method "%s" is undefined in this class.' % (                             module_path, action                         )                     )                 if not isinstance(permission_code_by_method.get(action, None), (int, list)):                     raise TypeError(                         '<%s> permission_code_by_method: "%s" permission_code type must int or list, not %s.'                         % (module_path, action, type(permission_code_by_method.get(action, None)).__name__)                     )                 else:                     if isinstance(action_list := permission_code_by_method.get(action, None), list):                         for action_code in action_list:                             if not isinstance(action_code, int):                                 raise TypeError(                                     '<%s> permission_code_by_method: "%s" code list value "%s" type was not int' % (                                         module_path, action, action_code                                     )                                 )
      def get_permission(self, view) -> tuple:         """获取配置的权限"""         return getattr(view, 'permission_code') if hasattr(view, 'permission_code') else None, \                getattr(view, 'permission_code_by_method') if hasattr(view, 'permission_code_by_method') else None
      def is_require_permission(self, view) -> bool:         """检查类是否需要权限访问"""         permission_code, permission_code_by_method = self.get_permission(view)
          if permission_code or permission_code_by_method:             return True         return False
      @staticmethod     def query_permission(role_id, code) -> bool:         """查询权限code,True为满足所有,False为任一不满足。None视为不需要权限,返回True"""         if isinstance(code, int):             code = [code]         elif role_id is None:             return True
          from apps.user.models import PermissionCodeRoleRelation         for c in code:             if isinstance(c, list):                 if not CodePermission.query_permission(role_id=role_id, code=c):                     return False                 continue             if PermissionCodeRoleRelation.objects.filter(role_id=role_id, code=c).count() == 0:                 return False         return True
      def has_permission(self, request, view):         if self.is_require_permission(view):             if not request.user.role_id:                 return False
              permission_code, permission_code_by_method = self.get_permission(view)             self.check_permission_format(permission_code, permission_code_by_method, view)             if permission_code_by_method and isinstance(permission_code_by_method, dict):                 permission_action = list(                     set(permission_code_by_method.keys()) &                     set([r for r in self.REQUEST_METHOD_MAP if self.REQUEST_METHOD_MAP[r] == request.method])                 )                 permission_action_code = [permission_code_by_method[k] for k in permission_code_by_method if                                           k in permission_action and permission_code_by_method[k]]             else:                 permission_action_code = []             return self.query_permission(role_id=request.user.role_id, code=permission_code) & self.query_permission(                 role_id=request.user.role_id, code=permission_action_code             )         else:             return True
   |