98 lines
3.4 KiB
Go
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.

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 不能管理 ownerowner 自操作由具体命令的 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
}