revork structures for hub
This commit is contained in:
@@ -1,58 +0,0 @@
|
|||||||
package permission
|
|
||||||
|
|
||||||
type Global uint32
|
|
||||||
|
|
||||||
const (
|
|
||||||
// Hub permissions
|
|
||||||
GlobalSetHubName Global = 1 << iota
|
|
||||||
GlobalSetHubBg
|
|
||||||
GlobalSetHubColor
|
|
||||||
GlobalRemoveHub
|
|
||||||
GlobalSetUserColorAllowed
|
|
||||||
|
|
||||||
// User permissions
|
|
||||||
GlobalAddUser
|
|
||||||
GlobalRemoveUser
|
|
||||||
GlobalRenameUser
|
|
||||||
GlobalMuteUser
|
|
||||||
|
|
||||||
// Role permissions
|
|
||||||
GlobalAddRole
|
|
||||||
GlobalRemoveRole
|
|
||||||
GlobalChangeRoleName
|
|
||||||
GlobalChangeRoleColor
|
|
||||||
GlobalChangeRoleGlobals
|
|
||||||
GlobalOnlySelfRoleRemove
|
|
||||||
|
|
||||||
// Channel group permissions
|
|
||||||
GlobalAddChannelGroup
|
|
||||||
GlobalRemoveChannelGroup
|
|
||||||
GlobalSetChannelGroupName
|
|
||||||
GlobalSetChannelGroupColor
|
|
||||||
GlobalSetChannelGroupPermittedVisibleRoles
|
|
||||||
|
|
||||||
// Channel permissions
|
|
||||||
GlobalAddChannel
|
|
||||||
GlobalRemoveChannel
|
|
||||||
GlobalSetChannelName
|
|
||||||
GlobalSetChannelPermittedVisibleRoles
|
|
||||||
GlobalSetChannelPermittedSendMessageRoles
|
|
||||||
GlobalSetChannelPermittedReadHistoryRoles
|
|
||||||
)
|
|
||||||
|
|
||||||
type ChannelGroup uint16
|
|
||||||
|
|
||||||
const (
|
|
||||||
// Channel group permission
|
|
||||||
ChannelGroupSetName ChannelGroup = 1 << iota
|
|
||||||
ChannelGroupSetColor
|
|
||||||
ChannelGroupSetPermittedVisibleRoles
|
|
||||||
|
|
||||||
// Channel permission
|
|
||||||
ChannelGroupAddChannel
|
|
||||||
ChannelGroupRemoveChannel
|
|
||||||
ChannelGroupSetChannelName
|
|
||||||
ChannelGroupSetChannelPermittedVisibleRoles
|
|
||||||
ChannelGroupSetChannelPermittedSendMessageRoles
|
|
||||||
ChannelGroupSetChannelPermittedReadHistoryRoles
|
|
||||||
)
|
|
||||||
@@ -12,28 +12,30 @@ import (
|
|||||||
var (
|
var (
|
||||||
Port uint32 = 8080
|
Port uint32 = 8080
|
||||||
MaxDirectMsgCache uint32 = 32
|
MaxDirectMsgCache uint32 = 32
|
||||||
MaxHubMsgCache uint32 = 32
|
MaxHubChannelMsgCache uint32 = 16
|
||||||
|
MaxUserHubRoles uint8 = 64
|
||||||
FileStorageBucketName string = "communicator"
|
FileStorageBucketName string = "communicator"
|
||||||
MaxRequestBytes uint32 = 4 << 10
|
MaxRequestBytes uint32 = 4 << 10
|
||||||
MaxRequestWithFileBytes uint32 = 1 << 30
|
MaxRequestWithFileBytes uint32 = 1 << 30
|
||||||
MaxRequestWithAvatarBytes uint = 1 << 20
|
MaxRequestWithAvatarBytes uint32 = 1 << 20
|
||||||
MaxRequestWithProfileBgBytes uint = 4 << 20
|
MaxRequestWithProfileBgBytes uint32 = 4 << 20
|
||||||
FileProcessingPartBytes uint64 = 12 << 20
|
FileProcessingPartBytes uint64 = 12 << 20
|
||||||
FileProcessingThreads uint = 3
|
FileProcessingThreads uint32 = 3
|
||||||
FileDownloadLinkTtl time.Duration = 24 * time.Hour
|
FileDownloadLinkTtl time.Duration = 24 * time.Hour
|
||||||
)
|
)
|
||||||
|
|
||||||
type configFile struct {
|
type configFile struct {
|
||||||
Port uint32 `toml:"port"`
|
Port uint32 `toml:"port"`
|
||||||
MaxDirectMsgCache uint32 `toml:"max_direct_messages_cache"`
|
MaxDirectMsgCache uint32 `toml:"max_direct_messages_cache"`
|
||||||
MaxHubMsgCache uint32 `toml:"max_hub_msg_cache"`
|
MaxHubChannelMsgCache uint32 `toml:"max_hub_channel_msg_cache"`
|
||||||
|
MaxUserHubRoles uint8 `toml:"max_hub_roles"`
|
||||||
FileStorageBucketName string `toml:"file_storage_bucket_name"`
|
FileStorageBucketName string `toml:"file_storage_bucket_name"`
|
||||||
MaxRequestBytes uint32 `toml:"max_request_bytes"`
|
MaxRequestBytes uint32 `toml:"max_request_bytes"`
|
||||||
MaxRequestWithFileBytes uint32 `toml:"max_request_with_file_bytes"`
|
MaxRequestWithFileBytes uint32 `toml:"max_request_with_file_bytes"`
|
||||||
MaxRequestWithAvatarBytes uint `toml:"max_request_with_avatar_bytes"`
|
MaxRequestWithAvatarBytes uint32 `toml:"max_request_with_avatar_bytes"`
|
||||||
MaxRequestWithProfileBgBytes uint `toml:"max_request_with_profile_bg_bytes"`
|
MaxRequestWithProfileBgBytes uint32 `toml:"max_request_with_profile_bg_bytes"`
|
||||||
FileProcessingPartBytes uint64 `toml:"file_processing_part_bytes"`
|
FileProcessingPartBytes uint64 `toml:"file_processing_part_bytes"`
|
||||||
FileProcessingThreads uint `toml:"file_processing_threads"`
|
FileProcessingThreads uint32 `toml:"file_processing_threads"`
|
||||||
FileDownloadLinkTtl time.Duration `toml:"file_download_link_ttl"`
|
FileDownloadLinkTtl time.Duration `toml:"file_download_link_ttl"`
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -51,7 +53,7 @@ func LoadConfFile() {
|
|||||||
|
|
||||||
Port = cfg.Port
|
Port = cfg.Port
|
||||||
MaxDirectMsgCache = cfg.MaxDirectMsgCache
|
MaxDirectMsgCache = cfg.MaxDirectMsgCache
|
||||||
MaxHubMsgCache = cfg.MaxHubMsgCache
|
MaxHubChannelMsgCache = cfg.MaxHubChannelMsgCache
|
||||||
FileStorageBucketName = cfg.FileStorageBucketName
|
FileStorageBucketName = cfg.FileStorageBucketName
|
||||||
MaxRequestBytes = cfg.MaxRequestBytes
|
MaxRequestBytes = cfg.MaxRequestBytes
|
||||||
MaxRequestWithFileBytes = cfg.MaxRequestWithFileBytes
|
MaxRequestWithFileBytes = cfg.MaxRequestWithFileBytes
|
||||||
|
|||||||
@@ -241,7 +241,7 @@ func HandleUserNewConnection(response http.ResponseWriter, request *http.Request
|
|||||||
}
|
}
|
||||||
requestor.Mu.RUnlock()
|
requestor.Mu.RUnlock()
|
||||||
|
|
||||||
connection := types.CreateConn()
|
connection := types.NewConn()
|
||||||
connection.CreatedAt = time.Now()
|
connection.CreatedAt = time.Now()
|
||||||
connection.RequestorId = requestor.Id
|
connection.RequestorId = requestor.Id
|
||||||
connection.RecipientId = recipient.Id
|
connection.RecipientId = recipient.Id
|
||||||
|
|||||||
@@ -84,12 +84,12 @@ func HandleGetUserAvatar(response http.ResponseWriter, request *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if target.Avatar == "" {
|
if target.AvatarUrl == "" {
|
||||||
http.Error(response, "no avatar", http.StatusNotFound)
|
http.Error(response, "no avatar", http.StatusNotFound)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
url, _, err := minio.GetDownloadUrlAndMetadata(ctx, target.Avatar)
|
url, _, err := minio.GetDownloadUrlAndMetadata(ctx, target.AvatarUrl)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(response, "internal server error", http.StatusInternalServerError)
|
http.Error(response, "internal server error", http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
@@ -122,12 +122,12 @@ func HandleGetUserProfileBg(response http.ResponseWriter, request *http.Request)
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if target.ProfileBg == "" {
|
if target.ProfileBgUrl == "" {
|
||||||
http.Error(response, "no profile background", http.StatusNotFound)
|
http.Error(response, "no profile background", http.StatusNotFound)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
url, _, err := minio.GetDownloadUrlAndMetadata(ctx, target.ProfileBg)
|
url, _, err := minio.GetDownloadUrlAndMetadata(ctx, target.ProfileBgUrl)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(response, "internal server error", http.StatusInternalServerError)
|
http.Error(response, "internal server error", http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -62,11 +62,11 @@ func HandleHubCreate(response http.ResponseWriter, request *http.Request) {
|
|||||||
}
|
}
|
||||||
hub.ChannelGroups[rootGrp.Id] = rootGrp
|
hub.ChannelGroups[rootGrp.Id] = rootGrp
|
||||||
|
|
||||||
rootRole := &types.HubGlobalRole{
|
rootRole := &types.HubRole{
|
||||||
Id: 0,
|
Id: 0,
|
||||||
Name: "root",
|
Name: "root",
|
||||||
Color: types.Rgba{255, 0, 0, 255},
|
Color: types.Rgba{255, 0, 0, 255},
|
||||||
RolePermission: ^permission.Global(0),
|
Permissions: ^permission.Global(0),
|
||||||
}
|
}
|
||||||
hub.GlobalRoles[rootRole.Id] = rootRole
|
hub.GlobalRoles[rootRole.Id] = rootRole
|
||||||
|
|
||||||
|
|||||||
@@ -222,8 +222,8 @@ func HandleUserModAvatar(response http.ResponseWriter, request *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if user.Avatar != "" {
|
if user.AvatarUrl != "" {
|
||||||
err = minio.Delete(ctx, user.Avatar)
|
err = minio.Delete(ctx, user.AvatarUrl)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(response, "internal server error", http.StatusInternalServerError)
|
http.Error(response, "internal server error", http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
@@ -243,7 +243,7 @@ func HandleUserModAvatar(response http.ResponseWriter, request *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
user.Avatar = key
|
user.AvatarUrl = key
|
||||||
err = postgresql.UserUpdateProfile(ctx, user, types.UserProfileUpdateList{Avatar: true})
|
err = postgresql.UserUpdateProfile(ctx, user, types.UserProfileUpdateList{Avatar: true})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(response, "internal server error", http.StatusInternalServerError)
|
http.Error(response, "internal server error", http.StatusInternalServerError)
|
||||||
@@ -285,8 +285,8 @@ func HandleUserModProfileBg(response http.ResponseWriter, request *http.Request)
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if user.ProfileBg != "" {
|
if user.ProfileBgUrl != "" {
|
||||||
err = minio.Delete(ctx, user.ProfileBg)
|
err = minio.Delete(ctx, user.ProfileBgUrl)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(response, "internal server error", http.StatusInternalServerError)
|
http.Error(response, "internal server error", http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
@@ -306,7 +306,7 @@ func HandleUserModProfileBg(response http.ResponseWriter, request *http.Request)
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
user.ProfileBg = key
|
user.ProfileBgUrl = key
|
||||||
err = postgresql.UserUpdateProfile(ctx, user, types.UserProfileUpdateList{ProfileBg: true})
|
err = postgresql.UserUpdateProfile(ctx, user, types.UserProfileUpdateList{ProfileBg: true})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(response, "internal server error", http.StatusInternalServerError)
|
http.Error(response, "internal server error", http.StatusInternalServerError)
|
||||||
|
|||||||
@@ -95,7 +95,7 @@ func UserGetStandardInfoByName(ctx context.Context, user *types.User) error {
|
|||||||
var rgba int64
|
var rgba int64
|
||||||
err := dbConn.QueryRow(ctx, `
|
err := dbConn.QueryRow(ctx, `
|
||||||
SELECT id, name, pass_hash, COALESCE(pronouns, ''), rgba, created_at, COALESCE(avatar, ''), COALESCE(profile_bg, '') FROM users WHERE name = $1
|
SELECT id, name, pass_hash, COALESCE(pronouns, ''), rgba, created_at, COALESCE(avatar, ''), COALESCE(profile_bg, '') FROM users WHERE name = $1
|
||||||
`, user.Name).Scan(&user.Id, &user.Name, &user.PasswordHash, &user.Pronouns, &rgba, &user.CreatedAt, &user.Avatar, &user.ProfileBg)
|
`, user.Name).Scan(&user.Id, &user.Name, &user.PasswordHash, &user.Pronouns, &rgba, &user.CreatedAt, &user.AvatarUrl, &user.ProfileBgUrl)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
user.Color = convertions.Uint32ToRgba(uint32(rgba))
|
user.Color = convertions.Uint32ToRgba(uint32(rgba))
|
||||||
}
|
}
|
||||||
@@ -106,7 +106,7 @@ func UserGetById(ctx context.Context, user *types.User) error {
|
|||||||
var rgba int64
|
var rgba int64
|
||||||
err := dbConn.QueryRow(ctx, `
|
err := dbConn.QueryRow(ctx, `
|
||||||
SELECT name, pass_hash, COALESCE(pronouns, ''), rgba, created_at, COALESCE(avatar, ''), COALESCE(profile_bg, '') FROM users WHERE id = $1
|
SELECT name, pass_hash, COALESCE(pronouns, ''), rgba, created_at, COALESCE(avatar, ''), COALESCE(profile_bg, '') FROM users WHERE id = $1
|
||||||
`, user.Id).Scan(&user.Name, &user.PasswordHash, &user.Pronouns, &rgba, &user.CreatedAt, &user.Avatar, &user.ProfileBg)
|
`, user.Id).Scan(&user.Name, &user.PasswordHash, &user.Pronouns, &rgba, &user.CreatedAt, &user.AvatarUrl, &user.ProfileBgUrl)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
user.Color = convertions.Uint32ToRgba(uint32(rgba))
|
user.Color = convertions.Uint32ToRgba(uint32(rgba))
|
||||||
}
|
}
|
||||||
@@ -135,12 +135,12 @@ func UserUpdateProfile(ctx context.Context, user *types.User, updateList types.U
|
|||||||
}
|
}
|
||||||
if updateList.Avatar {
|
if updateList.Avatar {
|
||||||
setClauses = append(setClauses, fmt.Sprintf("avatar = $%d", argIdx))
|
setClauses = append(setClauses, fmt.Sprintf("avatar = $%d", argIdx))
|
||||||
args = append(args, user.Avatar)
|
args = append(args, user.AvatarUrl)
|
||||||
argIdx++
|
argIdx++
|
||||||
}
|
}
|
||||||
if updateList.ProfileBg {
|
if updateList.ProfileBg {
|
||||||
setClauses = append(setClauses, fmt.Sprintf("profile_bg = $%d", argIdx))
|
setClauses = append(setClauses, fmt.Sprintf("profile_bg = $%d", argIdx))
|
||||||
args = append(args, user.ProfileBg)
|
args = append(args, user.ProfileBgUrl)
|
||||||
argIdx++
|
argIdx++
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -197,7 +197,7 @@ func ConnectionsGetBelongingToUser(ctx context.Context, user *types.User) error
|
|||||||
}
|
}
|
||||||
|
|
||||||
for rows.Next() {
|
for rows.Next() {
|
||||||
conn := types.CreateConn()
|
conn := types.NewConn()
|
||||||
if err = rows.Scan(&conn.Id, &conn.RequestorId, &conn.RecipientId, &conn.State, &conn.CreatedAt); err != nil {
|
if err = rows.Scan(&conn.Id, &conn.RequestorId, &conn.RecipientId, &conn.State, &conn.CreatedAt); err != nil {
|
||||||
return fmt.Errorf("scanning connection row: %w", err)
|
return fmt.Errorf("scanning connection row: %w", err)
|
||||||
}
|
}
|
||||||
@@ -254,4 +254,3 @@ func ConnectionGetMessagesBefore(ctx context.Context, before time.Time, connecti
|
|||||||
}
|
}
|
||||||
return messages, rows.Err()
|
return messages, rows.Err()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+125
-61
@@ -2,7 +2,6 @@ package types
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/sha256"
|
"crypto/sha256"
|
||||||
"go-socket/packages/Enums/permission"
|
|
||||||
"math/rand/v2"
|
"math/rand/v2"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
@@ -25,18 +24,13 @@ func (r Rgba) GetRandom() Rgba {
|
|||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
|
|
||||||
type pairUuidHubChannelGroupRole struct {
|
|
||||||
first uuid.UUID
|
|
||||||
second *HubChannelGroupRole
|
|
||||||
}
|
|
||||||
|
|
||||||
type User struct {
|
type User struct {
|
||||||
Mu sync.RWMutex `json:"-"`
|
Mu sync.RWMutex `json:"-"`
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
Pronouns string `json:"pronouns"`
|
Pronouns string `json:"pronouns"`
|
||||||
Description string `json:"description"`
|
Description string `json:"description"`
|
||||||
Avatar string `json:"avatar"`
|
AvatarUrl string `json:"avatarUrl"`
|
||||||
ProfileBg string `json:"profileBackground"`
|
ProfileBgUrl string `json:"profileBackgroundUrl"`
|
||||||
PasswordHash string `json:"-"`
|
PasswordHash string `json:"-"`
|
||||||
CreatedAt time.Time `json:"createdAt"`
|
CreatedAt time.Time `json:"createdAt"`
|
||||||
WsConn *websocket.Conn `json:"-"`
|
WsConn *websocket.Conn `json:"-"`
|
||||||
@@ -66,12 +60,11 @@ type Connection struct {
|
|||||||
State ConnectionState.ConnectionState `json:"state"`
|
State ConnectionState.ConnectionState `json:"state"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func CreateConn() *Connection {
|
func NewConn() *Connection {
|
||||||
return &Connection{
|
return &Connection{
|
||||||
MessagesBuff: make([]*Message, config.MaxDirectMsgCache),
|
MessagesBuff: make([]*Message, config.MaxDirectMsgCache),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (conn *Connection) AddMessageToBuff(message *Message) {
|
func (conn *Connection) AddMessageToBuff(message *Message) {
|
||||||
conn.Mu.Lock()
|
conn.Mu.Lock()
|
||||||
defer conn.Mu.Unlock()
|
defer conn.Mu.Unlock()
|
||||||
@@ -130,82 +123,153 @@ type WsAuthMessage struct {
|
|||||||
Error string `json:"error"`
|
Error string `json:"error"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Permissions uint32
|
||||||
|
|
||||||
|
const (
|
||||||
|
// Hub permissions
|
||||||
|
PermissionSetHubName Permissions = 1 << iota
|
||||||
|
PermissionSetHubIcon
|
||||||
|
PermissionSetHubBg
|
||||||
|
PermissionSetHubColor
|
||||||
|
PermissionRemoveHub
|
||||||
|
PermissionSetUserColorAllowed
|
||||||
|
|
||||||
|
// User permissions
|
||||||
|
PermissionAddUser
|
||||||
|
PermissionRemoveUser
|
||||||
|
PermissionRenameUser
|
||||||
|
PermissionMuteUser
|
||||||
|
|
||||||
|
// Role permissions
|
||||||
|
PermissionAddRole
|
||||||
|
PermissionRemoveRole
|
||||||
|
PermissionChangeRoleName
|
||||||
|
PermissionChangeRoleColor
|
||||||
|
PermissionChangeRoleGlobals
|
||||||
|
PermissionOnlySelfRoleRemove
|
||||||
|
|
||||||
|
// Channel group permissions
|
||||||
|
PermissionAddChannelGroup
|
||||||
|
PermissionRemoveChannelGroup
|
||||||
|
PermissionSetChannelGroupName
|
||||||
|
PermissionSetChannelGroupColor
|
||||||
|
PermissionSetChannelGroupPermittedVisibleRoles
|
||||||
|
|
||||||
|
// Channel permissions
|
||||||
|
PermissionAddChannel
|
||||||
|
PermissionRemoveChannel
|
||||||
|
PermissionSetChannelName
|
||||||
|
PermissionSetChannelIcon
|
||||||
|
PermissionSetChannelPermittedVisibleRoles
|
||||||
|
PermissionSetChannelPermittedSendMessageRoles
|
||||||
|
PermissionSetChannelPermittedReadHistoryRoles
|
||||||
|
)
|
||||||
|
|
||||||
type Hub struct {
|
type Hub struct {
|
||||||
Mu sync.RWMutex `json:"-"`
|
Mu sync.RWMutex `json:"-"`
|
||||||
Id uuid.UUID `json:"id"`
|
Roles []*HubRole `json:"-"`
|
||||||
CreatedAt time.Time `json:"createdAt"`
|
Users []*HubUser `json:"-"`
|
||||||
Users map[uuid.UUID]*HubUser `json:"-"`
|
Groups []*HubGroup `json:"-"`
|
||||||
GlobalRoles map[uint8]*HubGlobalRole `json:"-"`
|
Channels []*HubChannel `json:"-"`
|
||||||
ChannelGroupRoles map[uint8]*HubChannelGroupRole `json:"-"`
|
|
||||||
ChannelGroups map[uuid.UUID]*HubChannelGroup `json:"-"`
|
|
||||||
Creator uuid.UUID `json:"creator"`
|
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
|
IconUrl string `json:"iconUrl"`
|
||||||
|
BgUrl string `json:"bgUrl"`
|
||||||
|
Id uuid.UUID `json:"id"`
|
||||||
Color Rgba `json:"color"`
|
Color Rgba `json:"color"`
|
||||||
AllowUserColor bool `json:"allowUserColor"`
|
UserColorAllowed bool `json:"userColorAllowed"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func CreateHub() *Hub {
|
func NewHub() *Hub {
|
||||||
return &Hub{
|
return &Hub{
|
||||||
Id: uuid.New(),
|
Roles: make([]*HubRole, 0, 255),
|
||||||
Users: make(map[uuid.UUID]*HubUser),
|
Users: make([]*HubUser, 0, 255),
|
||||||
GlobalRoles: make(map[uint8]*HubGlobalRole),
|
Groups: make([]*HubGroup, 0, 255),
|
||||||
ChannelGroupRoles: make(map[uint8]*HubChannelGroupRole),
|
Channels: make([]*HubChannel, 0, 255),
|
||||||
ChannelGroups: make(map[uuid.UUID]*HubChannelGroup),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type HubChannelGroup struct {
|
type HubRole struct {
|
||||||
Id uuid.UUID `json:"id"`
|
Name string `json:"role"`
|
||||||
Name string `json:"name"`
|
CreatedAt time.Time `json:"createdAt"`
|
||||||
|
Permissions Permissions `json:"permissions"`
|
||||||
Color Rgba `json:"color"`
|
Color Rgba `json:"color"`
|
||||||
Position uint8 `json:"position"`
|
Id uint8 `json:"id"`
|
||||||
|
BoundedGroup uint8 `json:"boundedGroup"` // BoundedGroup 0 for global
|
||||||
}
|
}
|
||||||
|
|
||||||
type HubChannel struct {
|
func (h *HubRole) GrantPermission(r Permissions) {
|
||||||
Id uuid.UUID `json:"id"`
|
h.Permissions |= r
|
||||||
Name uuid.UUID `json:"name"`
|
}
|
||||||
ParentGroupId uuid.UUID `json:"parentGroupId"`
|
func (h *HubRole) RevokePermission(r Permissions) {
|
||||||
Position uint8 `json:"position"`
|
h.Permissions &^= r
|
||||||
|
}
|
||||||
|
func (h *HubRole) HasPermission(r Permissions) bool {
|
||||||
|
return h.Permissions&r != 0
|
||||||
|
}
|
||||||
|
|
||||||
|
type HubGroup struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
CreatedAt time.Time `json:"createdAt"`
|
||||||
|
Color Rgba `json:"color"`
|
||||||
|
Id uint8 `json:"id"` // Id 0 for unused
|
||||||
}
|
}
|
||||||
|
|
||||||
type HubUser struct {
|
type HubUser struct {
|
||||||
Id uuid.UUID `json:"id"`
|
Mu sync.RWMutex `json:"mu"`
|
||||||
Username string `json:"username"`
|
Roles []*HubRole `json:"roles"`
|
||||||
GlobalRoles []uint8 `json:"globalRoles"`
|
Name string `json:"name"`
|
||||||
ChannelGroupRoles map[uint8]pairUuidHubChannelGroupRole `json:"ChannelGroupRoles"`
|
OriginalId uuid.UUID `json:"originalId"`
|
||||||
|
IsMuted bool `json:"isMuted"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewHubUser() *HubUser {
|
||||||
|
return &HubUser{
|
||||||
|
Roles: make([]*HubRole, 0, config.MaxUserHubRoles),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type HubChannel struct {
|
||||||
|
Mu sync.RWMutex `json:"-"`
|
||||||
|
MessagesBuff []*Message `json:"-"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
Description string `json:"description"`
|
||||||
|
IconUrl string `json:"iconUrl"`
|
||||||
CreatedAt time.Time `json:"createdAt"`
|
CreatedAt time.Time `json:"createdAt"`
|
||||||
}
|
NextBuffIdx uint32 `json:"-"`
|
||||||
|
|
||||||
type HubGlobalRole struct {
|
|
||||||
Name string `json:"role"`
|
|
||||||
Id uint8 `json:"id"`
|
Id uint8 `json:"id"`
|
||||||
RolePermission permission.Global `json:"rolePermission"`
|
HaveOverflowed bool `json:"-"`
|
||||||
Color Rgba `json:"color"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *HubGlobalRole) GrantPermission(r permission.Global) {
|
func NewHubChannel() *HubChannel {
|
||||||
h.RolePermission |= r
|
return &HubChannel{
|
||||||
|
MessagesBuff: make([]*Message, config.MaxHubChannelMsgCache),
|
||||||
}
|
}
|
||||||
func (h *HubGlobalRole) RevokePermission(r permission.Global) {
|
|
||||||
h.RolePermission &^= r
|
|
||||||
}
|
}
|
||||||
func (h *HubGlobalRole) HasPermission(r permission.Global) bool {
|
func (conn *HubChannel) AddMessageToBuff(message *Message) {
|
||||||
return h.RolePermission&r != 0
|
conn.Mu.Lock()
|
||||||
|
defer conn.Mu.Unlock()
|
||||||
|
|
||||||
|
size := uint32(len(conn.MessagesBuff))
|
||||||
|
conn.MessagesBuff[conn.NextBuffIdx%size] = message
|
||||||
|
conn.NextBuffIdx++
|
||||||
|
if conn.NextBuffIdx >= size {
|
||||||
|
conn.HaveOverflowed = true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type HubChannelGroupRole struct {
|
// GetSortedMessagesBuff returns slice and its valid length.
|
||||||
Name string `json:"role"`
|
func (conn *HubChannel) GetSortedMessagesBuff() ([]*Message, uint32) {
|
||||||
Id uint8 `json:"id"`
|
conn.Mu.RLock()
|
||||||
RolePermission permission.ChannelGroup `json:"rolePermission"`
|
defer conn.Mu.RUnlock()
|
||||||
Color Rgba `json:"color"`
|
|
||||||
|
size := uint32(len(conn.MessagesBuff))
|
||||||
|
if !conn.HaveOverflowed {
|
||||||
|
return conn.MessagesBuff, conn.NextBuffIdx
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *HubChannelGroupRole) GrantPermission(r permission.ChannelGroup) {
|
sorted := make([]*Message, size)
|
||||||
h.RolePermission |= r
|
for i := uint32(0); i < size; i++ {
|
||||||
|
sorted[i] = conn.MessagesBuff[(conn.NextBuffIdx+i)%size]
|
||||||
}
|
}
|
||||||
func (h *HubChannelGroupRole) RevokePermission(r permission.ChannelGroup) {
|
return sorted, size
|
||||||
h.RolePermission &^= r
|
|
||||||
}
|
|
||||||
func (h *HubChannelGroupRole) HasPermission(r permission.ChannelGroup) bool {
|
|
||||||
return h.RolePermission&r != 0
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
when user not ws connected collect count of unread messages for each conn (add db table in future)
|
when user not ws connected collect count of unread messages for each conn (add db table in future)
|
||||||
|
|
||||||
add hubs
|
add hubs
|
||||||
|
check when mutex needed
|
||||||
|
|
||||||
user banners
|
user banners
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user