package service import ( "hyapp/pkg/xerr" "hyapp/services/room-service/internal/room/state" ) // roomRole 是权限矩阵内部使用的收敛角色,不直接信任客户端 JoinRoom.role。 type roomRole string const ( // roleOwner 来自 RoomState.OwnerUserID,拥有房间内最高管理权限。 roleOwner roomRole = "owner" // roleAdmin 来自 RoomState.AdminUsers,权限低于 owner。 roleAdmin roomRole = "admin" // roleAudience 是默认兜底角色,包含未登录、未在房间和普通观众。 roleAudience roomRole = "audience" ) func actorRole(current *state.RoomState, actorUserID int64) roomRole { // 角色权威顺序按当前房间状态固定:owner > admin > audience,不能只看 RoomUser.role 展示字段。 switch { case current == nil || actorUserID <= 0: return roleAudience case actorUserID == current.OwnerUserID: return roleOwner case current.AdminUsers[actorUserID]: return roleAdmin default: return roleAudience } } func requireActiveRoom(current *state.RoomState) error { // 当前只有 active 房间可执行管理和麦位命令;CloseRoom 语义后续单独扩展。 if current == nil || current.Status != state.RoomStatusActive { return xerr.New(xerr.Conflict, "room is not active") } return nil } func requireActorPresent(current *state.RoomState, actorUserID int64) error { // 管理动作必须来自房间业务 presence;离房后的 admin 不能远程管理房间。 if _, exists := current.OnlineUsers[actorUserID]; !exists { return xerr.New(xerr.PermissionDenied, "permission denied") } return nil } func requireManagerPresent(current *state.RoomState, actorUserID int64) error { // 先校验 presence,再校验角色,避免房间外用户凭持久 admin 身份直接操作。 if err := requireActorPresent(current, actorUserID); err != nil { return err } if !isManagerRole(actorRole(current, actorUserID)) { return xerr.New(xerr.PermissionDenied, "permission denied") } return nil } func isManagerRole(role roomRole) bool { // 管理角色集合只包含 owner/admin,普通观众只能做自助动作。 return role == roleOwner || role == roleAdmin } func canManageTarget(current *state.RoomState, actorUserID int64, targetUserID int64) error { // 目标用户同样按权威状态判定角色,防止客户端伪造 role 绕过管理层级。 actor := actorRole(current, actorUserID) target := actorRole(current, targetUserID) if !isManagerRole(actor) { return xerr.New(xerr.PermissionDenied, "permission denied") } if target == roleOwner && actor != roleOwner { // admin 不能管理 owner,owner 自操作由具体命令的 self check 再收紧。 return xerr.New(xerr.PermissionDenied, "permission denied") } return nil } func canSelfOrManageTarget(current *state.RoomState, actorUserID int64, targetUserID int64) error { // 自助动作例如自己下麦允许 audience 执行,代操作才进入管理权限矩阵。 if actorUserID == targetUserID { return nil } return canManageTarget(current, actorUserID, targetUserID) } func requireOwnerPresent(current *state.RoomState, actorUserID int64) error { // owner 专属命令仍要求 owner 当前在房间业务 presence 内。 if err := requireActorPresent(current, actorUserID); err != nil { return err } if actorRole(current, actorUserID) != roleOwner { return xerr.New(xerr.PermissionDenied, "permission denied") } return nil }