fix: 集团可给各俱乐部分配不同功能角色,按俱乐部隔离权限校验
This commit is contained in:
@@ -144,8 +144,8 @@ class GetRolePermissionView(APIView):
|
||||
if kefu is None:
|
||||
return permissions # 直接返回错误响应
|
||||
|
||||
# 2. 检查是否有 000001 权限
|
||||
if '000001' not in permissions:
|
||||
from jituan.services.admin_context import can_access_admin_user_management
|
||||
if not can_access_admin_user_management(request.user, permissions):
|
||||
return Response({'code': 403, 'msg': '您无权访问此页面'})
|
||||
|
||||
# 3. 获取所有权限
|
||||
@@ -410,7 +410,8 @@ class GetAdminUserListView(APIView):
|
||||
kefu, permissions = verify_kefu_permission(request, username)
|
||||
if kefu is None:
|
||||
return permissions
|
||||
if '000001' not in permissions:
|
||||
from jituan.services.admin_context import can_access_admin_user_management
|
||||
if not can_access_admin_user_management(request.user, permissions):
|
||||
return Response({'code': 403, 'msg': '您无权访问此页面'})
|
||||
|
||||
phone = request.data.get('phone', '').strip()
|
||||
@@ -541,7 +542,8 @@ class GetAdminRolesView(APIView):
|
||||
kefu, permissions = verify_kefu_permission(request, username)
|
||||
if kefu is None:
|
||||
return permissions
|
||||
if '000001' not in permissions:
|
||||
from jituan.services.admin_context import can_access_admin_user_management
|
||||
if not can_access_admin_user_management(request.user, permissions):
|
||||
return Response({'code': 403, 'msg': '您无权访问此页面'})
|
||||
|
||||
from jituan.services.admin_context import can_manage_admin_assignments, get_manageable_club_ids
|
||||
@@ -588,7 +590,8 @@ class GetAdminRolesView(APIView):
|
||||
kefu, permissions = verify_kefu_permission(request, username)
|
||||
if kefu is None:
|
||||
return permissions
|
||||
if '000001' not in permissions:
|
||||
from jituan.services.admin_context import can_access_admin_user_management
|
||||
if not can_access_admin_user_management(request.user, permissions):
|
||||
return Response({'code': 403, 'msg': '您无权访问此页面'})
|
||||
|
||||
# 筛选条件
|
||||
@@ -659,7 +662,11 @@ class ModifyAdminUserView(APIView):
|
||||
if kefu is None:
|
||||
return permissions
|
||||
|
||||
from jituan.services.admin_context import can_manage_admin_assignments, can_manage_roles_for_club
|
||||
from jituan.services.admin_context import (
|
||||
can_manage_admin_assignments,
|
||||
can_manage_roles_for_club,
|
||||
can_access_admin_user_management,
|
||||
)
|
||||
|
||||
club_assign_actions = {'add_club_assignment', 'remove_club_assignment'}
|
||||
role_manage_actions = {'add_user_roles', 'remove_user_role'}
|
||||
@@ -667,8 +674,9 @@ class ModifyAdminUserView(APIView):
|
||||
if not can_manage_admin_assignments(request.user, permissions):
|
||||
return Response({'code': 403, 'msg': '无权分配俱乐部任职'})
|
||||
elif action in role_manage_actions:
|
||||
pass
|
||||
elif '000001' not in permissions:
|
||||
if not can_access_admin_user_management(request.user, permissions):
|
||||
return Response({'code': 403, 'msg': '您无权管理角色分配'})
|
||||
elif not can_manage_admin_assignments(request.user, permissions) and '000001' not in permissions:
|
||||
return Response({'code': 403, 'msg': '您无权进行此操作'})
|
||||
|
||||
target_yonghuid = request.data.get('yonghuid', '').strip()
|
||||
@@ -726,6 +734,10 @@ class ModifyAdminUserView(APIView):
|
||||
if not role:
|
||||
missing.append(rc)
|
||||
continue
|
||||
role_club = (getattr(role, 'ClubID', None) or '').strip()
|
||||
if role_club and role_club != bind_club_id:
|
||||
missing.append(rc)
|
||||
continue
|
||||
_, created = UserRole.objects.get_or_create(
|
||||
UserUUID=target_user.UserUUID,
|
||||
RoleUUID=role.RoleUUID,
|
||||
@@ -822,8 +834,19 @@ class AddAdminUserView(APIView):
|
||||
kefu, permissions = verify_kefu_permission(request, username)
|
||||
if kefu is None:
|
||||
return permissions
|
||||
if '000001' not in permissions:
|
||||
return Response({'code': 403, 'msg': '您无权进行此操作'})
|
||||
|
||||
from jituan.services.admin_context import (
|
||||
can_manage_admin_assignments,
|
||||
can_manage_roles_for_club,
|
||||
)
|
||||
from jituan.services.club_context import resolve_club_id_from_request
|
||||
|
||||
target_club_id = resolve_club_id_from_request(request)
|
||||
if not (
|
||||
can_manage_admin_assignments(request.user, permissions)
|
||||
or can_manage_roles_for_club(request.user, permissions, target_club_id)
|
||||
):
|
||||
return Response({'code': 403, 'msg': '您无权在该俱乐部添加用户'})
|
||||
|
||||
phone = request.data.get('phone', '').strip()
|
||||
password = request.data.get('password', '').strip()
|
||||
@@ -836,11 +859,8 @@ class AddAdminUserView(APIView):
|
||||
if len(password) < 6 or len(erjimima) < 6:
|
||||
return Response({'code': 400, 'msg': '密码和二级密码至少6位'})
|
||||
|
||||
from jituan.services.club_context import resolve_club_id_from_request
|
||||
from jituan.services.club_rbac import resolve_roles_for_binding
|
||||
|
||||
target_club_id = resolve_club_id_from_request(request)
|
||||
|
||||
# 校验手机号是否已被后台客服占用(同俱乐部优先)
|
||||
existing_kefu = User.query.filter(
|
||||
Phone=phone, KefuProfile__isnull=False
|
||||
|
||||
@@ -213,6 +213,20 @@ def get_manageable_club_ids(user, permissions=None):
|
||||
}
|
||||
|
||||
|
||||
def can_access_admin_user_management(user, permissions=None):
|
||||
"""
|
||||
是否可访问「后台用户」页(列表、按俱乐部分配功能角色)。
|
||||
系统超管 / 000001 / 集团高管 / 任一俱乐部超管均可。
|
||||
"""
|
||||
if is_system_super_admin(user):
|
||||
return True
|
||||
if permissions and '000001' in permissions:
|
||||
return True
|
||||
if can_manage_admin_assignments(user, permissions):
|
||||
return True
|
||||
return bool(get_manageable_club_ids(user, permissions))
|
||||
|
||||
|
||||
def _pack(scope, club_id, is_group_admin, assignments, clubs, can_switch_club,
|
||||
role_code, role_name):
|
||||
allowed_club_ids = sorted({
|
||||
|
||||
@@ -94,10 +94,8 @@ def resolve_role_by_name(role_name, club_id=None):
|
||||
qs = Role.objects.filter(RoleName=name, RoleStatus=1)
|
||||
cid = (club_id or '').strip()
|
||||
if cid:
|
||||
hit = qs.filter(ClubID=cid).first()
|
||||
if hit:
|
||||
return hit
|
||||
return qs.filter(ClubID='').first() or qs.first()
|
||||
return qs.filter(ClubID=cid).first()
|
||||
return qs.filter(ClubID='').first()
|
||||
|
||||
|
||||
def role_uuid_bytes(role_uuid):
|
||||
@@ -192,10 +190,23 @@ def resolve_permission_codes_for_club(user, club_id, allowed_club_ids=None, scop
|
||||
|
||||
|
||||
def resolve_effective_permission_codes(user, club_id, scope, allowed_club_ids=None):
|
||||
"""菜单与各业务接口统一权限码:仅当前俱乐部 gvsdsdk 角色,不串其他俱乐部。"""
|
||||
return resolve_permission_codes_for_club(
|
||||
"""
|
||||
菜单与各业务接口统一权限码:当前俱乐部 gvsdsdk 角色。
|
||||
单俱乐部任职且 gvsdsdk 为空时,兜底合并旧 user_role 表(兼容未迁移账号)。
|
||||
"""
|
||||
from backend.utils import _legacy_backend_role_permissions
|
||||
|
||||
codes = resolve_permission_codes_for_club(
|
||||
user, club_id, allowed_club_ids, scope=scope,
|
||||
)
|
||||
if codes:
|
||||
return codes
|
||||
allowed = {c for c in (allowed_club_ids or []) if c}
|
||||
if len(allowed) <= 1:
|
||||
legacy_codes, _ = _legacy_backend_role_permissions(getattr(user, 'Phone', ''))
|
||||
if legacy_codes:
|
||||
return list(legacy_codes)
|
||||
return []
|
||||
|
||||
|
||||
def user_bound_role_names(user, club_id=None, scope=None, allowed_club_ids=None):
|
||||
|
||||
@@ -6,6 +6,7 @@ from backend.utils import _AllPermissions, verify_kefu_permission
|
||||
from jituan.models import KefuMenuPage
|
||||
from jituan.services.admin_context import (
|
||||
build_admin_club_context,
|
||||
can_access_admin_user_management,
|
||||
can_manage_admin_assignments,
|
||||
get_allowed_club_ids,
|
||||
is_system_super_admin,
|
||||
@@ -32,6 +33,9 @@ def _page_visible(page, permissions, user):
|
||||
if page.require_group_manage:
|
||||
return can_manage_admin_assignments(user)
|
||||
|
||||
if getattr(page, 'require_admin_user_manage', False):
|
||||
return can_access_admin_user_management(user, permissions)
|
||||
|
||||
if page.require_super:
|
||||
return _has_super_perm(permissions) or is_system_super_admin(user)
|
||||
|
||||
@@ -46,8 +50,8 @@ def _page_visible(page, permissions, user):
|
||||
|
||||
|
||||
def _permission_codes_list(permissions):
|
||||
if _is_super_permissions(permissions):
|
||||
return ['000001']
|
||||
if isinstance(permissions, _AllPermissions):
|
||||
return list(dict.fromkeys(permissions)) if len(permissions) else ['000001']
|
||||
return list(permissions) if permissions else []
|
||||
|
||||
|
||||
@@ -64,6 +68,7 @@ def _builtin_menu_pages():
|
||||
perm_codes=row.get('perm_codes', []),
|
||||
require_super=row.get('require_super', False),
|
||||
require_group_manage=row.get('require_group_manage', False),
|
||||
require_admin_user_manage=row.get('require_admin_user_manage', False),
|
||||
))
|
||||
return pages
|
||||
|
||||
@@ -145,6 +150,7 @@ def build_menu_access_payload(request, username=None):
|
||||
'yonghuid': getattr(request.user, 'UserUID', '') or '',
|
||||
'club_id': club_id,
|
||||
'club_scope': scope,
|
||||
'effective_club_id': club_id,
|
||||
'can_switch_club': bool(club_ctx.get('can_switch_club')),
|
||||
'is_group_admin': bool(club_ctx.get('is_group_admin')),
|
||||
'menu_ready': True,
|
||||
|
||||
@@ -55,7 +55,7 @@ KEFU_MENU_ROW_DEFS = [
|
||||
{'page_id': 'admin.club-config', 'name': '俱乐部密钥配置', 'path': '/admin/club-config', 'parent_id': 'admin', 'sort_order': 73,
|
||||
'require_group_manage': True},
|
||||
{'page_id': 'admin.user', 'name': '后台用户', 'path': '/admin/user', 'parent_id': 'admin', 'sort_order': 74,
|
||||
'require_super': True},
|
||||
'require_admin_user_manage': True},
|
||||
{'page_id': 'admin.operation-log', 'name': '操作日志', 'path': '/admin/operation-log', 'parent_id': 'admin', 'sort_order': 75,
|
||||
'perm_codes': ['czrz666']},
|
||||
{'page_id': 'punishment', 'name': '处罚管理', 'path': '/punishment', 'parent_id': '', 'sort_order': 80,
|
||||
|
||||
@@ -131,11 +131,10 @@ class KefuGetOrderListView(APIView):
|
||||
return Response({'code': 400, 'msg': '缺少username'})
|
||||
|
||||
# 2. 公共权限校验
|
||||
kefu, permissions = verify_kefu_permission(request, username)
|
||||
kefu, permissions = verify_kefu_permission(request, None)
|
||||
if kefu is None:
|
||||
return permissions
|
||||
|
||||
# 3. 检查平台订单管理权限(002ab)
|
||||
if not has_perm_code(permissions, '002ab'):
|
||||
return Response({'code': 403, 'msg': '您无权查看平台订单列表'})
|
||||
|
||||
@@ -299,10 +298,8 @@ class KefuGetShangjiaOrderListView(APIView):
|
||||
if not username:
|
||||
return Response({'code': 400, 'msg': '缺少username'})
|
||||
|
||||
# 2. 权限校验(与 menu-access 完全一致:须 002ac)
|
||||
kefu, permissions = verify_kefu_permission(
|
||||
request, getattr(request.user, 'Phone', '') or None,
|
||||
)
|
||||
# 2. 权限校验(与 menu-access 同一算法、同一用户)
|
||||
kefu, permissions = verify_kefu_permission(request, None)
|
||||
if kefu is None:
|
||||
return permissions
|
||||
|
||||
|
||||
Reference in New Issue
Block a user