212 lines
5.2 KiB
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
|
|
}
|
|
}
|