live-sfu-demo/internal/room/permission.go

212 lines
5.2 KiB
Go

package room
import (
"fmt"
"sort"
"strings"
)
type RoomPermission int
const (
PermSendChat RoomPermission = iota
PermViewChatHistory
PermViewMembers
PermSubscribe
PermWatchRoom
PermPublish
PermStopStream
PermBroadcast
PermManageMembers
PermAddMembers
PermRemoveMembers
PermManagePermissions
PermManageRoom
PermDeleteRoom
PermDeleteChatMessages
PermControlStream
_permCount
)
func (p RoomPermission) Bit() uint64 { return 1 << uint(p) }
func (p RoomPermission) String() string {
switch p {
case PermSendChat:
return "send_chat"
case PermViewChatHistory:
return "view_chat_history"
case PermViewMembers:
return "view_members"
case PermSubscribe:
return "subscribe"
case PermWatchRoom:
return "watch_room"
case PermPublish:
return "publish"
case PermStopStream:
return "stop_stream"
case PermBroadcast:
return "broadcast"
case PermManageMembers:
return "manage_members"
case PermAddMembers:
return "add_members"
case PermRemoveMembers:
return "remove_members"
case PermManagePermissions:
return "manage_permissions"
case PermManageRoom:
return "manage_room"
case PermDeleteRoom:
return "delete_room"
case PermDeleteChatMessages:
return "delete_chat_messages"
case PermControlStream:
return "control_stream"
default:
return fmt.Sprintf("perm_%d", int(p))
}
}
func ParsePermission(s string) (RoomPermission, error) {
switch strings.ToLower(strings.TrimSpace(s)) {
case "send_chat", "sendchat", "chat", "room:chat":
return PermSendChat, nil
case "view_chat_history", "viewchathistory":
return PermViewChatHistory, nil
case "view_members", "viewmembers", "members:view":
return PermViewMembers, nil
case "subscribe", "room:subscribe":
return PermSubscribe, nil
case "watch", "watch_room", "room:watch":
return PermWatchRoom, nil
case "publish", "room:publish":
return PermPublish, nil
case "stop", "stop_stream", "room:stop":
return PermStopStream, nil
case "broadcast", "room:broadcast":
return PermBroadcast, nil
case "manage_members", "managemembers":
return PermManageMembers, nil
case "add_members", "addmembers":
return PermAddMembers, nil
case "remove_members", "removemembers", "kick":
return PermRemoveMembers, nil
case "manage_permissions", "managepermissions":
return PermManagePermissions, nil
case "manage_room", "manageroom", "room:manage":
return PermManageRoom, nil
case "delete_room", "deleteroom", "room:delete":
return PermDeleteRoom, nil
case "delete_chat_messages", "deletechat":
return PermDeleteChatMessages, nil
case "control_stream", "controlstream":
return PermControlStream, nil
default:
return 0, fmt.Errorf("unknown permission %q", s)
}
}
type PermissionSet uint64
func (s PermissionSet) Has(p RoomPermission) bool { return uint64(s)&p.Bit() != 0 }
func (s PermissionSet) HasAll(o PermissionSet) bool { return uint64(s)&uint64(o) == uint64(o) }
func (s PermissionSet) HasAny(o PermissionSet) bool { return uint64(s)&uint64(o) != 0 }
func (s *PermissionSet) Grant(p RoomPermission) { *s |= PermissionSet(p.Bit()) }
func (s *PermissionSet) Revoke(p RoomPermission) { *s &^= PermissionSet(p.Bit()) }
func (s PermissionSet) Bits() uint64 { return uint64(s) }
func (s PermissionSet) List() []RoomPermission {
var out []RoomPermission
for i := 0; i < int(_permCount); i++ {
p := RoomPermission(i)
if s.Has(p) {
out = append(out, p)
}
}
return out
}
func (s PermissionSet) Names() []string {
list := s.List()
names := make([]string, len(list))
for i, p := range list {
names[i] = p.String()
}
sort.Strings(names)
return names
}
func (s PermissionSet) String() string { return strings.Join(s.Names(), ",") }
func AllPermissions() PermissionSet {
var all PermissionSet
for i := 0; i < int(_permCount); i++ {
all.Grant(RoomPermission(i))
}
return all
}
var (
PermAll = AllPermissions()
PermNone = PermissionSet(0)
PermDefaultCreator = PermAll
PermDefaultAdmin = func() PermissionSet {
var s PermissionSet
s.Grant(PermSendChat)
s.Grant(PermViewChatHistory)
s.Grant(PermViewMembers)
s.Grant(PermSubscribe)
s.Grant(PermWatchRoom)
s.Grant(PermPublish)
s.Grant(PermStopStream)
s.Grant(PermBroadcast)
s.Grant(PermManageMembers)
s.Grant(PermAddMembers)
s.Grant(PermRemoveMembers)
s.Grant(PermManagePermissions)
s.Grant(PermManageRoom)
s.Grant(PermDeleteChatMessages)
s.Grant(PermControlStream)
return s
}()
PermDefaultMember = func() PermissionSet {
var s PermissionSet
s.Grant(PermSendChat)
s.Grant(PermViewChatHistory)
s.Grant(PermViewMembers)
s.Grant(PermSubscribe)
s.Grant(PermWatchRoom)
s.Grant(PermPublish)
s.Grant(PermStopStream)
return s
}()
PermDefaultGuest = func() PermissionSet {
var s PermissionSet
s.Grant(PermViewChatHistory)
s.Grant(PermViewMembers)
s.Grant(PermSubscribe)
s.Grant(PermWatchRoom)
return s
}()
PermGuestAssignable = PermDefaultGuest | func() PermissionSet {
var s PermissionSet
s.Grant(PermSendChat)
return s
}()
)
func DefaultForRole(r RoomRole) PermissionSet {
switch r {
case RoleCreator:
return PermDefaultCreator
case RoleAdmin:
return PermDefaultAdmin
case RoleMember:
return PermDefaultMember
case RoleGuest:
return PermDefaultGuest
default:
return PermDefaultGuest
}
}