Files
Django/gvsdsdk/auth/permissions.py

117 lines
4.2 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
from gvsdsdk.models import User, UserRole, Role, RolePermission, Permission, UserABAC
from rest_framework.permissions import BasePermission
class IsAdminUser(BasePermission):
"""仅允许管理员IsStaff 或 IsSuperuser访问"""
def has_permission(self, request, view):
user = request.user
if not user or not user.is_authenticated:
return False
if not isinstance(user, User):
return False
return user.IsStaff or user.IsSuperuser
class IsCompanyMember(BasePermission):
"""验证用户当前角色属于目标数据所在公司"""
def has_object_permission(self, request, view, obj):
if not request.current_company_uuid:
return False
obj_company = getattr(obj, 'CompanyUUID_id', None) or getattr(obj, 'CompanyUUID', None)
if obj_company is None:
return True # 无公司归属的数据不做限制
return str(obj_company) == str(request.current_company_uuid)
class CompanyScopedMixin:
"""ViewSet Mixin自动按当前角色所属公司过滤 queryset"""
company_field = 'CompanyUUID' # 可在 ViewSet 中覆盖
def get_queryset(self):
qs = super().get_queryset()
company_uuid = getattr(self.request, 'current_company_uuid', None)
if company_uuid and hasattr(qs.model, self.company_field):
qs = qs.filter(**{self.company_field: company_uuid})
return qs
def perform_create(self, serializer):
company_uuid = getattr(self.request, 'current_company_uuid', None)
if company_uuid and hasattr(serializer.Meta.model, 'CompanyUUID'):
serializer.save(CompanyUUID=company_uuid)
else:
serializer.save()
def PermissionVerifier(permission, attributes, user=None, request=None):
"""权限验证器——混合 ABAC + RBAC 检查
RBAC 仅检查当前角色CurrentRoleUUID Cookie 指定的角色)的权限,
通过 RolePermission → Permission 链路查询,按当前公司过滤。
超级管理员/员工直接放行。
"""
if not permission:
return True
if user is None:
return False
if not isinstance(user, User):
return False
# 超级管理员和员工直接放行
if user.IsSuperuser or user.IsStaff:
return True
current_role = getattr(request, 'current_role', None) if request else None
current_company = getattr(request, 'current_company_uuid', None) if request else None
for attr in attributes:
# ABAC 检查
abac_match = UserABAC.objects.filter(
UserUUID=user.UserUUID,
HierarchicalPermissionIdentifiers=attr
).first()
if abac_match:
continue
# RBAC 检查:仅检查当前角色,按公司过滤权限
if current_role and isinstance(current_role, Role):
if current_role.RoleStatus != 1:
return False
rp_qs = RolePermission.objects.filter(
RoleUUID=current_role.RoleUUID
)
if current_company:
rp_qs = rp_qs.filter(CompanyUUID=current_company)
perm_uuids = rp_qs.values_list('PermUUID', flat=True)
rbac_result = Permission.objects.filter(
PermUUID__in=perm_uuids,
PermCode=attr,
PermStatus=1,
).exists()
else:
# 无 current_role 时回退到用户所有活跃角色
user_role_uuids = UserRole.objects.filter(
UserUUID=user.UserUUID
).values_list('RoleUUID', flat=True)
active_role_uuids = Role.objects.filter(
RoleUUID__in=user_role_uuids,
RoleStatus=1,
).values_list('RoleUUID', flat=True)
rp_qs = RolePermission.objects.filter(
RoleUUID__in=active_role_uuids
)
if current_company:
rp_qs = rp_qs.filter(CompanyUUID=current_company)
perm_uuids = rp_qs.values_list('PermUUID', flat=True)
rbac_result = Permission.objects.filter(
PermUUID__in=perm_uuids,
PermCode=attr,
PermStatus=1,
).exists()
if rbac_result:
continue
return False
return True