Files
Django/gvsdsdk/auth/permissions.py
T

118 lines
4.3 KiB
Python

from gvsds.apps.core.models import User
from gvsdsdk.models import 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