ce33eb900d
- Implement UpdateMemberRoleUseCase with role-based permission - Owner/Admin can change roles, but Admin cannot change other Admins - Cannot change owner's role or change your own role - Cannot change to owner role (owner is unique) - Validate role not already assigned - Add 8 comprehensive unit tests (all passed) Phase 4 Task 16/68 completed
134 lines
4.7 KiB
Python
134 lines
4.7 KiB
Python
"""
|
|
修改成员角色 Use Case
|
|
"""
|
|
from typing import Optional
|
|
|
|
from packages.domain.entities import WorkspaceMemberRole
|
|
|
|
|
|
class UpdateMemberRoleRequest:
|
|
"""修改成员角色请求"""
|
|
|
|
def __init__(
|
|
self,
|
|
workspace_id: str,
|
|
requester_user_id: str,
|
|
target_user_id: str,
|
|
new_role: str,
|
|
):
|
|
self.workspace_id = workspace_id
|
|
self.requester_user_id = requester_user_id
|
|
self.target_user_id = target_user_id
|
|
self.new_role = new_role
|
|
|
|
|
|
class UpdateMemberRoleResponse:
|
|
"""修改成员角色响应"""
|
|
|
|
def __init__(self, user_id: str, old_role: str, new_role: str):
|
|
self.user_id = user_id
|
|
self.old_role = old_role
|
|
self.new_role = new_role
|
|
|
|
|
|
class UpdateMemberRoleUseCase:
|
|
"""修改成员角色用例"""
|
|
|
|
VALID_ROLES = [
|
|
WorkspaceMemberRole.ADMIN,
|
|
WorkspaceMemberRole.MEMBER,
|
|
WorkspaceMemberRole.VIEWER,
|
|
]
|
|
|
|
def __init__(
|
|
self,
|
|
workspace_repository,
|
|
workspace_member_repository,
|
|
):
|
|
self.workspace_repository = workspace_repository
|
|
self.workspace_member_repository = workspace_member_repository
|
|
|
|
def execute(self, request: UpdateMemberRoleRequest) -> tuple[Optional[UpdateMemberRoleResponse], Optional[str]]:
|
|
"""
|
|
执行修改成员角色
|
|
|
|
Args:
|
|
request: 修改请求
|
|
|
|
Returns:
|
|
(响应, 错误信息)
|
|
"""
|
|
try:
|
|
# 1. 验证输入
|
|
if not request.workspace_id:
|
|
return None, "Workspace ID is required"
|
|
|
|
if not request.requester_user_id:
|
|
return None, "Requester user ID is required"
|
|
|
|
if not request.target_user_id:
|
|
return None, "Target user ID is required"
|
|
|
|
if not request.new_role:
|
|
return None, "New role is required"
|
|
|
|
# 2. 验证新角色(不能修改为 owner)
|
|
if request.new_role not in self.VALID_ROLES:
|
|
return None, f"Invalid role: {request.new_role}. Cannot change to owner."
|
|
|
|
# 3. 验证 Workspace 存在
|
|
workspace = self.workspace_repository.find_by_id(request.workspace_id)
|
|
if not workspace:
|
|
return None, "Workspace not found"
|
|
|
|
# 4. 验证请求者是成员且有权限(只有 owner 和 admin 可以修改角色)
|
|
requester_member = self.workspace_member_repository.find_by_workspace_and_user(
|
|
request.workspace_id,
|
|
request.requester_user_id,
|
|
)
|
|
if not requester_member:
|
|
return None, "You are not a member of this workspace"
|
|
|
|
if requester_member.role not in [WorkspaceMemberRole.OWNER, WorkspaceMemberRole.ADMIN]:
|
|
return None, "Only owners and admins can change member roles"
|
|
|
|
# 5. 验证目标成员存在
|
|
target_member = self.workspace_member_repository.find_by_workspace_and_user(
|
|
request.workspace_id,
|
|
request.target_user_id,
|
|
)
|
|
if not target_member:
|
|
return None, "Target user is not a member of this workspace"
|
|
|
|
# 6. 不能修改自己的角色
|
|
if request.requester_user_id == request.target_user_id:
|
|
return None, "Cannot change your own role"
|
|
|
|
# 7. 不能修改 owner 的角色
|
|
if target_member.role == WorkspaceMemberRole.OWNER:
|
|
return None, "Cannot change the owner's role"
|
|
|
|
# 8. Admin 不能修改另一个 Admin 的角色(只有 owner 可以)
|
|
if (requester_member.role == WorkspaceMemberRole.ADMIN and
|
|
target_member.role == WorkspaceMemberRole.ADMIN):
|
|
return None, "Admins cannot change other admins' roles"
|
|
|
|
# 9. 检查角色是否相同
|
|
if target_member.role == request.new_role:
|
|
return None, f"User already has the {request.new_role} role"
|
|
|
|
# 10. 更新角色
|
|
old_role = target_member.role
|
|
target_member.role = request.new_role
|
|
self.workspace_member_repository.save(target_member)
|
|
|
|
# 11. 返回响应
|
|
return UpdateMemberRoleResponse(
|
|
user_id=request.target_user_id,
|
|
old_role=old_role,
|
|
new_role=request.new_role,
|
|
), None
|
|
|
|
except Exception as e:
|
|
return None, f"Failed to update member role: {str(e)}"
|