111 lines
		
	
	
		
			3.4 KiB
		
	
	
	
		
			Python
		
	
	
	
			
		
		
	
	
			111 lines
		
	
	
		
			3.4 KiB
		
	
	
	
		
			Python
		
	
	
	
| from django.core.cache import cache
 | |
| from rest_framework.permissions import BasePermission
 | |
| from utils.queryset import get_child_queryset2
 | |
| from .models import Permission
 | |
| from django.db.models import Q
 | |
| 
 | |
| def get_permission_list(user):
 | |
|     """
 | |
|     获取权限列表,可用redis存取
 | |
|     """
 | |
|     if user.is_superuser:
 | |
|         perms_list = ['admin']
 | |
|     else:
 | |
|         perms = Permission.objects.none()
 | |
|         roles = user.roles.all()
 | |
|         if roles:
 | |
|             for i in roles:
 | |
|                 perms = perms | i.perms.all()
 | |
|         perms_list = perms.values_list('method', flat=True)
 | |
|         perms_list = list(set(perms_list))
 | |
|     cache.set(user.username + '__perms', perms_list, 60*60*24)
 | |
|     return perms_list
 | |
| 
 | |
| def has_permission(action, user):
 | |
|     """
 | |
|     判断有无权限
 | |
|     action为操作权限
 | |
|     """
 | |
|     if user.is_superuser:
 | |
|         return True
 | |
|     else:
 | |
|         perms = cache.get(user.username + '__perms')
 | |
|         if not perms:
 | |
|             perms = get_permission_list(user)
 | |
|         if action in perms:
 | |
|             return True
 | |
|     return False
 | |
| 
 | |
| class RbacPermission(BasePermission):
 | |
|     """
 | |
|     基于角色的权限校验类
 | |
|     """
 | |
| 
 | |
|     def has_permission(self, request, view):
 | |
|         """
 | |
|         权限校验逻辑
 | |
|         :param request:
 | |
|         :param view:
 | |
|         :return:
 | |
|         """
 | |
|         if not request.user:
 | |
|             perms = ['visitor'] # 如果没有经过认证,视为游客
 | |
|         else:
 | |
|             perms = cache.get(request.user.username + '__perms')
 | |
|         if not perms:
 | |
|             perms = get_permission_list(request.user)
 | |
|         if perms:
 | |
|             if 'admin' in perms:
 | |
|                 return True
 | |
|             elif not hasattr(view, 'perms_map'):
 | |
|                 return True
 | |
|             else:
 | |
|                 perms_map = view.perms_map
 | |
|                 _method = request._request.method.lower()
 | |
|                 if perms_map:
 | |
|                     for key in perms_map:
 | |
|                         if key == _method or key == '*':
 | |
|                             if perms_map[key] in perms or perms_map[key] == '*':
 | |
|                                 return True
 | |
|                 return False
 | |
|         else:
 | |
|             return False
 | |
|     
 | |
|     def has_object_permission(self, request, view, obj):
 | |
|         """
 | |
|         Return `True` if permission is granted, `False` otherwise.
 | |
|         """
 | |
|         # if not request.user:
 | |
|         #     return False
 | |
|         # if hasattr(obj, 'belong_dept'):
 | |
|         #     has_obj_perm(request.user, obj)
 | |
|         return True
 | |
| 
 | |
| def has_obj_perm(user, obj):
 | |
|     """
 | |
|     数据权限控权
 | |
|     返回对象的是否可以操作
 | |
|     需要控数据权限的表需有belong_dept, create_by, update_by字段(部门, 创建人, 编辑人)
 | |
|     传入user, obj实例
 | |
|     """
 | |
|     roles = user.roles
 | |
|     data_range = roles.values_list('datas', flat=True)
 | |
|     if '全部' in data_range:
 | |
|         return True
 | |
|     elif '自定义' in data_range:
 | |
|         if roles.depts.exists():
 | |
|             if obj.belong_dept not in roles.depts:
 | |
|                 return False
 | |
|     elif '同级及以下' in data_range:
 | |
|         if user.dept.parent:
 | |
|             belong_depts = get_child_queryset2(user.dept.parent)
 | |
|             if obj.belong_dept not in belong_depts:
 | |
|                 return False
 | |
|     elif '本级及以下' in data_range:
 | |
|         belong_depts = get_child_queryset2(user.dept)
 | |
|         if obj.belong_dept not in belong_depts:
 | |
|             return False
 | |
|     elif '本级' in data_range:
 | |
|         if obj.belong_dept is not user.dept:
 | |
|             return False
 | |
|     return True |