add configs from file, continue develpoment on hubs
This commit is contained in:
@@ -9,6 +9,7 @@ require (
|
|||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
github.com/BurntSushi/toml v1.6.0 // indirect
|
||||||
github.com/dustin/go-humanize v1.0.1 // indirect
|
github.com/dustin/go-humanize v1.0.1 // indirect
|
||||||
github.com/go-ini/ini v1.67.0 // indirect
|
github.com/go-ini/ini v1.67.0 // indirect
|
||||||
github.com/google/uuid v1.6.0 // indirect
|
github.com/google/uuid v1.6.0 // indirect
|
||||||
|
|||||||
@@ -4,7 +4,9 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
"go-socket/packages/config"
|
||||||
"go-socket/packages/httpRequest"
|
"go-socket/packages/httpRequest"
|
||||||
"go-socket/packages/minio"
|
"go-socket/packages/minio"
|
||||||
"go-socket/packages/postgresql"
|
"go-socket/packages/postgresql"
|
||||||
@@ -21,6 +23,7 @@ func withCORS(h http.HandlerFunc) http.HandlerFunc {
|
|||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
|
config.LoadConfFile()
|
||||||
postgresql.Init(ctx)
|
postgresql.Init(ctx)
|
||||||
minio.Init(ctx)
|
minio.Init(ctx)
|
||||||
|
|
||||||
@@ -57,5 +60,5 @@ func main() {
|
|||||||
http.HandleFunc("GET /ws", wsServer.ServeWsConnection)
|
http.HandleFunc("GET /ws", wsServer.ServeWsConnection)
|
||||||
|
|
||||||
log.Println("beep boop; server server started")
|
log.Println("beep boop; server server started")
|
||||||
log.Fatal(http.ListenAndServe(":8080", nil))
|
log.Fatal(http.ListenAndServe(":"+strconv.Itoa(int(config.Port)), nil))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,65 @@
|
|||||||
|
package config
|
||||||
|
|
||||||
|
import (
|
||||||
|
"log/slog"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/BurntSushi/toml"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Array-size constants — must be compile-time values; cannot be overridden via config file.
|
||||||
|
const (
|
||||||
|
MaxDirectMsgCache uint32 = 32
|
||||||
|
MaxHubMsgCache uint32 = 32
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
Port uint32 = 8080
|
||||||
|
FileStorageBucketName string = "communicator"
|
||||||
|
MaxRequestBytes uint32 = 4 << 10
|
||||||
|
MaxRequestWithFileBytes uint32 = 1 << 30
|
||||||
|
MaxRequestWithAvatarBytes uint = 1 << 20
|
||||||
|
MaxRequestWithProfileBgBytes uint = 4 << 20
|
||||||
|
FileProcessingPartBytes uint64 = 12 << 20
|
||||||
|
FileProcessingThreads uint = 3
|
||||||
|
FileDownloadLinkTtl time.Duration = 24 * time.Hour
|
||||||
|
)
|
||||||
|
|
||||||
|
type configFile struct {
|
||||||
|
Port uint32 `toml:"port"`
|
||||||
|
MaxDirectMsgCache uint32 `toml:"max_direct_messages_cache"`
|
||||||
|
MaxHubMsgCache uint32 `toml:"max_hub_msg_cache"`
|
||||||
|
FileStorageBucketName string `toml:"file_storage_bucket_name"`
|
||||||
|
MaxRequestBytes uint32 `toml:"max_request_bytes"`
|
||||||
|
MaxRequestWithFileBytes uint32 `toml:"max_request_with_file_bytes"`
|
||||||
|
MaxRequestWithAvatarBytes uint `toml:"max_request_with_avatar_bytes"`
|
||||||
|
MaxRequestWithProfileBgBytes uint `toml:"max_request_with_profile_bg_bytes"`
|
||||||
|
FileProcessingPartBytes uint64 `toml:"file_processing_part_bytes"`
|
||||||
|
FileProcessingThreads uint `toml:"file_processing_threads"`
|
||||||
|
FileDownloadLinkTtl time.Duration `toml:"file_download_link_ttl"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func LoadConfFile() {
|
||||||
|
path, err := os.Executable()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
var cfg configFile
|
||||||
|
if _, err := toml.DecodeFile("config.toml", &cfg); err != nil {
|
||||||
|
slog.Warn("Failed to load config.toml. Default values will be used", "path", filepath.Dir(path)+"/config.toml")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
Port = cfg.Port
|
||||||
|
FileStorageBucketName = cfg.FileStorageBucketName
|
||||||
|
MaxRequestBytes = cfg.MaxRequestBytes
|
||||||
|
MaxRequestWithFileBytes = cfg.MaxRequestWithFileBytes
|
||||||
|
MaxRequestWithAvatarBytes = cfg.MaxRequestWithAvatarBytes
|
||||||
|
MaxRequestWithProfileBgBytes = cfg.MaxRequestWithProfileBgBytes
|
||||||
|
FileProcessingPartBytes = cfg.FileProcessingPartBytes
|
||||||
|
FileProcessingThreads = cfg.FileProcessingThreads
|
||||||
|
FileDownloadLinkTtl = cfg.FileDownloadLinkTtl
|
||||||
|
}
|
||||||
@@ -17,28 +17,28 @@ func StringToUint32(s string) (uint32, error) {
|
|||||||
return uint32(v), err
|
return uint32(v), err
|
||||||
}
|
}
|
||||||
|
|
||||||
func StringToRgba(str string) (*types.Rgba, error) {
|
func StringToRgba(str string) (types.Rgba, error) {
|
||||||
parts := strings.SplitN(str, ",", 5)
|
parts := strings.SplitN(str, ",", 5)
|
||||||
if len(parts) != 4 {
|
if len(parts) != 4 {
|
||||||
return nil, fmt.Errorf("invalid rgba")
|
return types.Rgba{}, fmt.Errorf("invalid rgba")
|
||||||
}
|
}
|
||||||
rgba := &types.Rgba{}
|
rgba := types.Rgba{}
|
||||||
for i, p := range parts {
|
for i, p := range parts {
|
||||||
n, err := strconv.ParseUint(strings.TrimSpace(p), 10, 8)
|
n, err := strconv.ParseUint(strings.TrimSpace(p), 10, 8)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("invalid component %d: %w", i, err)
|
return types.Rgba{}, fmt.Errorf("invalid component %d: %w", i, err)
|
||||||
}
|
}
|
||||||
rgba[i] = uint8(n)
|
rgba[i] = uint8(n)
|
||||||
}
|
}
|
||||||
return rgba, nil
|
return rgba, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func RgbaToUint32(r *types.Rgba) uint32 {
|
func RgbaToUint32(r types.Rgba) uint32 {
|
||||||
return uint32(r[0])<<24 | uint32(r[1])<<16 | uint32(r[2])<<8 | uint32(r[3])
|
return uint32(r[0])<<24 | uint32(r[1])<<16 | uint32(r[2])<<8 | uint32(r[3])
|
||||||
}
|
}
|
||||||
|
|
||||||
func Uint32ToRgba(v uint32) *types.Rgba {
|
func Uint32ToRgba(v uint32) types.Rgba {
|
||||||
return &types.Rgba{uint8(v >> 24), uint8(v >> 16), uint8(v >> 8), uint8(v)}
|
return types.Rgba{uint8(v >> 24), uint8(v >> 16), uint8(v >> 8), uint8(v)}
|
||||||
}
|
}
|
||||||
|
|
||||||
func StringToUuid(str string) (uuid.UUID, error) {
|
func StringToUuid(str string) (uuid.UUID, error) {
|
||||||
|
|||||||
@@ -1,16 +0,0 @@
|
|||||||
package globals
|
|
||||||
|
|
||||||
import "time"
|
|
||||||
|
|
||||||
const (
|
|
||||||
MaxDirectMsgCache uint32 = 32
|
|
||||||
MaxHubMsgCache
|
|
||||||
FileStorageBucketName string = "communicator"
|
|
||||||
MaxRequestBytes uint32 = 4 << 10
|
|
||||||
MaxRequestWithFileBytes uint32 = 1 << 30
|
|
||||||
MaxRequestWithAvatarBytes uint = 1 << 20
|
|
||||||
MaxRequestWithProfileBgBytes uint = 4 << 20
|
|
||||||
FileProcessingPartBytes uint64 = 12 << 20
|
|
||||||
FileProcessingThreads uint = 3
|
|
||||||
FileDownloadLinkTtl time.Duration = 24 * time.Hour
|
|
||||||
)
|
|
||||||
@@ -11,8 +11,8 @@ import (
|
|||||||
"go-socket/packages/Enums/ConnectionState"
|
"go-socket/packages/Enums/ConnectionState"
|
||||||
"go-socket/packages/Enums/WsEventType"
|
"go-socket/packages/Enums/WsEventType"
|
||||||
"go-socket/packages/cache"
|
"go-socket/packages/cache"
|
||||||
|
"go-socket/packages/config"
|
||||||
"go-socket/packages/convertions"
|
"go-socket/packages/convertions"
|
||||||
"go-socket/packages/globals"
|
|
||||||
"go-socket/packages/postgresql"
|
"go-socket/packages/postgresql"
|
||||||
"go-socket/packages/types"
|
"go-socket/packages/types"
|
||||||
"go-socket/packages/wsServer"
|
"go-socket/packages/wsServer"
|
||||||
@@ -158,7 +158,7 @@ func HandleUserGetConnectionMessages(response http.ResponseWriter, request *http
|
|||||||
|
|
||||||
messagesCap, err := convertions.StringToUint32(request.URL.Query().Get("messages"))
|
messagesCap, err := convertions.StringToUint32(request.URL.Query().Get("messages"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
messagesCap = globals.MaxDirectMsgCache
|
messagesCap = config.MaxDirectMsgCache
|
||||||
}
|
}
|
||||||
|
|
||||||
buffer, bufferSize := conn.GetSortedMessagesBuff()
|
buffer, bufferSize := conn.GetSortedMessagesBuff()
|
||||||
|
|||||||
@@ -5,8 +5,8 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"go-socket/packages/config"
|
||||||
"go-socket/packages/convertions"
|
"go-socket/packages/convertions"
|
||||||
"go-socket/packages/globals"
|
|
||||||
"go-socket/packages/minio"
|
"go-socket/packages/minio"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -22,9 +22,9 @@ func HandleAttachmentFileUpload(response http.ResponseWriter, request *http.Requ
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
request.Body = http.MaxBytesReader(response, request.Body, int64(globals.MaxRequestWithFileBytes))
|
request.Body = http.MaxBytesReader(response, request.Body, int64(config.MaxRequestWithFileBytes))
|
||||||
|
|
||||||
if err = request.ParseMultipartForm(int64(globals.MaxRequestBytes)); err != nil {
|
if err = request.ParseMultipartForm(int64(config.MaxRequestBytes)); err != nil {
|
||||||
http.Error(response, "invalid multipart form", http.StatusBadRequest)
|
http.Error(response, "invalid multipart form", http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"go-socket/packages/globals"
|
"go-socket/packages/config"
|
||||||
)
|
)
|
||||||
|
|
||||||
type postType uint8
|
type postType uint8
|
||||||
@@ -21,13 +21,13 @@ func validCheckWithResponseOnFail(response *http.ResponseWriter, request *http.R
|
|||||||
var maxSize int64
|
var maxSize int64
|
||||||
switch pt {
|
switch pt {
|
||||||
case file:
|
case file:
|
||||||
maxSize = int64(globals.MaxRequestWithFileBytes)
|
maxSize = int64(config.MaxRequestWithFileBytes)
|
||||||
case avatar:
|
case avatar:
|
||||||
maxSize = int64(globals.MaxRequestWithAvatarBytes)
|
maxSize = int64(config.MaxRequestWithAvatarBytes)
|
||||||
case profileBg:
|
case profileBg:
|
||||||
maxSize = int64(globals.MaxRequestWithProfileBgBytes)
|
maxSize = int64(config.MaxRequestWithProfileBgBytes)
|
||||||
default:
|
default:
|
||||||
maxSize = int64(globals.MaxRequestBytes)
|
maxSize = int64(config.MaxRequestBytes)
|
||||||
}
|
}
|
||||||
|
|
||||||
if request.ContentLength > maxSize {
|
if request.ContentLength > maxSize {
|
||||||
|
|||||||
@@ -5,8 +5,8 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"go-socket/packages/config"
|
||||||
"go-socket/packages/convertions"
|
"go-socket/packages/convertions"
|
||||||
"go-socket/packages/globals"
|
|
||||||
"go-socket/packages/minio"
|
"go-socket/packages/minio"
|
||||||
|
|
||||||
"go-socket/packages/cache"
|
"go-socket/packages/cache"
|
||||||
@@ -202,9 +202,9 @@ func HandleUserModAvatar(response http.ResponseWriter, request *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
request.Body = http.MaxBytesReader(response, request.Body, int64(globals.MaxRequestWithAvatarBytes))
|
request.Body = http.MaxBytesReader(response, request.Body, int64(config.MaxRequestWithAvatarBytes))
|
||||||
|
|
||||||
if err = request.ParseMultipartForm(int64(globals.MaxRequestBytes)); err != nil {
|
if err = request.ParseMultipartForm(int64(config.MaxRequestBytes)); err != nil {
|
||||||
http.Error(response, "invalid multipart form", http.StatusBadRequest)
|
http.Error(response, "invalid multipart form", http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -265,9 +265,9 @@ func HandleUserModProfileBg(response http.ResponseWriter, request *http.Request)
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
request.Body = http.MaxBytesReader(response, request.Body, int64(globals.MaxRequestWithProfileBgBytes))
|
request.Body = http.MaxBytesReader(response, request.Body, int64(config.MaxRequestWithProfileBgBytes))
|
||||||
|
|
||||||
if err = request.ParseMultipartForm(int64(globals.MaxRequestBytes)); err != nil {
|
if err = request.ParseMultipartForm(int64(config.MaxRequestBytes)); err != nil {
|
||||||
http.Error(response, "invalid multipart form", http.StatusBadRequest)
|
http.Error(response, "invalid multipart form", http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
+11
-11
@@ -8,7 +8,7 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"go-socket/packages/globals"
|
"go-socket/packages/config"
|
||||||
|
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
"github.com/minio/minio-go/v7"
|
"github.com/minio/minio-go/v7"
|
||||||
@@ -68,15 +68,15 @@ func Init(ctx context.Context) {
|
|||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
exists, err := minClient.BucketExists(ctx, globals.FileStorageBucketName)
|
exists, err := minClient.BucketExists(ctx, config.FileStorageBucketName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if !exists {
|
if !exists {
|
||||||
err = minClient.MakeBucket(ctx, globals.FileStorageBucketName, minio.MakeBucketOptions{})
|
err = minClient.MakeBucket(ctx, config.FileStorageBucketName, minio.MakeBucketOptions{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
exists, checkErr := minClient.BucketExists(ctx, globals.FileStorageBucketName)
|
exists, checkErr := minClient.BucketExists(ctx, config.FileStorageBucketName)
|
||||||
if checkErr != nil || !exists {
|
if checkErr != nil || !exists {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
@@ -87,22 +87,22 @@ func Init(ctx context.Context) {
|
|||||||
func Upload(ctx context.Context, key string, body io.Reader, size int64, contentType string, metadata map[string]string) error {
|
func Upload(ctx context.Context, key string, body io.Reader, size int64, contentType string, metadata map[string]string) error {
|
||||||
opt := minio.PutObjectOptions{
|
opt := minio.PutObjectOptions{
|
||||||
ContentType: contentType,
|
ContentType: contentType,
|
||||||
PartSize: globals.FileProcessingPartBytes,
|
PartSize: config.FileProcessingPartBytes,
|
||||||
NumThreads: globals.FileProcessingThreads,
|
NumThreads: config.FileProcessingThreads,
|
||||||
UserMetadata: metadata,
|
UserMetadata: metadata,
|
||||||
}
|
}
|
||||||
opt.SetMatchETagExcept("*")
|
opt.SetMatchETagExcept("*")
|
||||||
|
|
||||||
_, err := minClient.PutObject(ctx, globals.FileStorageBucketName, key, body, size, opt)
|
_, err := minClient.PutObject(ctx, config.FileStorageBucketName, key, body, size, opt)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetDownloadUrlAndMetadata(ctx context.Context, key string) (*url.URL, map[string]string, error) {
|
func GetDownloadUrlAndMetadata(ctx context.Context, key string) (*url.URL, map[string]string, error) {
|
||||||
info, err := minClient.StatObject(ctx, globals.FileStorageBucketName, key, minio.StatObjectOptions{})
|
info, err := minClient.StatObject(ctx, config.FileStorageBucketName, key, minio.StatObjectOptions{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
u, err := minClient.PresignedGetObject(ctx, globals.FileStorageBucketName, key, globals.FileDownloadLinkTtl, nil)
|
u, err := minClient.PresignedGetObject(ctx, config.FileStorageBucketName, key, config.FileDownloadLinkTtl, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
@@ -110,11 +110,11 @@ func GetDownloadUrlAndMetadata(ctx context.Context, key string) (*url.URL, map[s
|
|||||||
}
|
}
|
||||||
|
|
||||||
func DoesExist(ctx context.Context, key string) bool {
|
func DoesExist(ctx context.Context, key string) bool {
|
||||||
_, err := minClient.StatObject(ctx, globals.FileStorageBucketName, key, minio.StatObjectOptions{})
|
_, err := minClient.StatObject(ctx, config.FileStorageBucketName, key, minio.StatObjectOptions{})
|
||||||
return err == nil
|
return err == nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func Delete(ctx context.Context, key string) error {
|
func Delete(ctx context.Context, key string) error {
|
||||||
err := minClient.RemoveObject(ctx, globals.FileStorageBucketName, key, minio.RemoveObjectOptions{})
|
err := minClient.RemoveObject(ctx, config.FileStorageBucketName, key, minio.RemoveObjectOptions{})
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -76,6 +76,9 @@ func Init(ctx context.Context) {
|
|||||||
CREATE TABLE IF NOT EXISTS hubs ()
|
CREATE TABLE IF NOT EXISTS hubs ()
|
||||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||||
creator_id UUID NOT NULL REFERENCES users(id),
|
creator_id UUID NOT NULL REFERENCES users(id),
|
||||||
|
name TEXT NOT NULL,
|
||||||
|
allow_user_color BOOLEAN DEFAULT TRUE,
|
||||||
|
rgba BIGINT NOT NULL DEFAULT 0 CHECK (rgba BETWEEN 0 AND 4294967295),
|
||||||
created_at TIMESTAMP NOT NULL DEFAULT NOW()
|
created_at TIMESTAMP NOT NULL DEFAULT NOW()
|
||||||
`)
|
`)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -118,7 +121,7 @@ func Init(ctx context.Context) {
|
|||||||
_, err = dbConn.Exec(ctx, `
|
_, err = dbConn.Exec(ctx, `
|
||||||
CREATE TABLE IF NOT EXISTS hub_user_roles ()
|
CREATE TABLE IF NOT EXISTS hub_user_roles ()
|
||||||
user_id UUID PRIMARY KEY NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
user_id UUID PRIMARY KEY NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
||||||
role_id SMALLINT NOT NULL REFERENCES hub_roles(role_id)
|
role_id SMALLINT NOT NULL REFERENCES hub_roles(role_id) ON DELETE CASCADE
|
||||||
`)
|
`)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
@@ -129,6 +132,7 @@ func Init(ctx context.Context) {
|
|||||||
hub_id UUID PRIMARY KEY NOT NULL REFERENCES hubs(id) ON DELETE CASCADE,
|
hub_id UUID PRIMARY KEY NOT NULL REFERENCES hubs(id) ON DELETE CASCADE,
|
||||||
role_id SMALLINT NOT NULL DEFAULT 0,
|
role_id SMALLINT NOT NULL DEFAULT 0,
|
||||||
name TEXT NOT NULL,
|
name TEXT NOT NULL,
|
||||||
|
permissions INTEGER NOT NULL DEFAULT 0,
|
||||||
rgba BIGINT NOT NULL DEFAULT 0 CHECK (rgba BETWEEN 0 AND 4294967295),
|
rgba BIGINT NOT NULL DEFAULT 0 CHECK (rgba BETWEEN 0 AND 4294967295),
|
||||||
`)
|
`)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -316,3 +320,10 @@ func ConnectionGetMessagesBefore(ctx context.Context, before time.Time, connecti
|
|||||||
}
|
}
|
||||||
return messages, rows.Err()
|
return messages, rows.Err()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func HubCreate(ctx context.Context, hub *types.Hub, creator *types.User) error {
|
||||||
|
_, err := dbConn.Exec(ctx, `
|
||||||
|
INSERT INTO hubs (id, creator_id, name, allow_user_color, rgba, created_at) VALUES ($1, $2, $3, $4, $5)
|
||||||
|
`, hub.Id, creator.Id, hub.Name, hub.AllowUserColor, convertions.RgbaToUint32(hub.Color), hub.CreatedAt)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|||||||
+36
-31
@@ -8,7 +8,7 @@ import (
|
|||||||
|
|
||||||
"go-socket/packages/Enums/ConnectionState"
|
"go-socket/packages/Enums/ConnectionState"
|
||||||
"go-socket/packages/Enums/WsEventType"
|
"go-socket/packages/Enums/WsEventType"
|
||||||
"go-socket/packages/globals"
|
"go-socket/packages/config"
|
||||||
|
|
||||||
"github.com/coder/websocket"
|
"github.com/coder/websocket"
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
@@ -17,11 +17,11 @@ import (
|
|||||||
type Rgba [4]uint8
|
type Rgba [4]uint8
|
||||||
type Sha256Hash [sha256.Size]byte
|
type Sha256Hash [sha256.Size]byte
|
||||||
|
|
||||||
func (r Rgba) GetRandom() *Rgba {
|
func (r Rgba) GetRandom() Rgba {
|
||||||
for i := range r {
|
for i := range r {
|
||||||
r[i] = uint8(rand.IntN(256))
|
r[i] = uint8(rand.IntN(256))
|
||||||
}
|
}
|
||||||
return &r
|
return r
|
||||||
}
|
}
|
||||||
|
|
||||||
type User struct {
|
type User struct {
|
||||||
@@ -36,7 +36,7 @@ type User struct {
|
|||||||
WsConn *websocket.Conn `json:"-"`
|
WsConn *websocket.Conn `json:"-"`
|
||||||
Id uuid.UUID `json:"-"`
|
Id uuid.UUID `json:"-"`
|
||||||
Connections map[uuid.UUID]*Connection `json:"-"`
|
Connections map[uuid.UUID]*Connection `json:"-"`
|
||||||
Color *Rgba `json:"color"`
|
Color Rgba `json:"color"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type UserProfileUpdateList struct {
|
type UserProfileUpdateList struct {
|
||||||
@@ -48,31 +48,31 @@ type UserProfileUpdateList struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type Connection struct {
|
type Connection struct {
|
||||||
Mu sync.RWMutex `json:"-"`
|
Mu sync.RWMutex `json:"-"`
|
||||||
Id uuid.UUID `json:"id"`
|
Id uuid.UUID `json:"id"`
|
||||||
CreatedAt time.Time `json:"createdAt"`
|
CreatedAt time.Time `json:"createdAt"`
|
||||||
MessagesBuff [globals.MaxDirectMsgCache]*Message `json:"-"`
|
MessagesBuff [config.MaxDirectMsgCache]*Message `json:"-"`
|
||||||
NextBuffIdx uint32 `json:"-"`
|
NextBuffIdx uint32 `json:"-"`
|
||||||
RequestorId uuid.UUID `json:"requestorId"`
|
RequestorId uuid.UUID `json:"requestorId"`
|
||||||
RecipientId uuid.UUID `json:"recipientId"`
|
RecipientId uuid.UUID `json:"recipientId"`
|
||||||
UserWantingToElevate uuid.UUID `json:"userWantingToElevate"` // TODO add to database
|
UserWantingToElevate uuid.UUID `json:"userWantingToElevate"` // TODO add to database
|
||||||
HaveOverflowed bool `json:"-"`
|
HaveOverflowed bool `json:"-"`
|
||||||
State ConnectionState.ConnectionState `json:"state"`
|
State ConnectionState.ConnectionState `json:"state"`
|
||||||
}
|
}
|
||||||
|
|
||||||
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()
|
||||||
|
|
||||||
conn.MessagesBuff[conn.NextBuffIdx%globals.MaxDirectMsgCache] = message
|
conn.MessagesBuff[conn.NextBuffIdx%config.MaxDirectMsgCache] = message
|
||||||
conn.NextBuffIdx++
|
conn.NextBuffIdx++
|
||||||
if conn.NextBuffIdx >= globals.MaxDirectMsgCache {
|
if conn.NextBuffIdx >= config.MaxDirectMsgCache {
|
||||||
conn.HaveOverflowed = true
|
conn.HaveOverflowed = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetSortedMessagesBuff returns arr, length
|
// GetSortedMessagesBuff returns arr, length
|
||||||
func (conn *Connection) GetSortedMessagesBuff() (*[globals.MaxDirectMsgCache]*Message, uint32) {
|
func (conn *Connection) GetSortedMessagesBuff() (*[config.MaxDirectMsgCache]*Message, uint32) {
|
||||||
conn.Mu.RLock()
|
conn.Mu.RLock()
|
||||||
defer conn.Mu.RUnlock()
|
defer conn.Mu.RUnlock()
|
||||||
|
|
||||||
@@ -80,11 +80,11 @@ func (conn *Connection) GetSortedMessagesBuff() (*[globals.MaxDirectMsgCache]*Me
|
|||||||
return &conn.MessagesBuff, conn.NextBuffIdx
|
return &conn.MessagesBuff, conn.NextBuffIdx
|
||||||
}
|
}
|
||||||
|
|
||||||
sorted := new([globals.MaxDirectMsgCache]*Message)
|
sorted := new([config.MaxDirectMsgCache]*Message)
|
||||||
for i := uint32(0); i < globals.MaxDirectMsgCache; i++ {
|
for i := uint32(0); i < config.MaxDirectMsgCache; i++ {
|
||||||
sorted[i] = conn.MessagesBuff[(conn.NextBuffIdx+i)%globals.MaxDirectMsgCache]
|
sorted[i] = conn.MessagesBuff[(conn.NextBuffIdx+i)%config.MaxDirectMsgCache]
|
||||||
}
|
}
|
||||||
return sorted, globals.MaxDirectMsgCache
|
return sorted, config.MaxDirectMsgCache
|
||||||
}
|
}
|
||||||
|
|
||||||
type ConnectionStatusSetData struct {
|
type ConnectionStatusSetData struct {
|
||||||
@@ -138,6 +138,7 @@ const (
|
|||||||
PermissionChangeRoleName
|
PermissionChangeRoleName
|
||||||
PermissionChangeRoleColor
|
PermissionChangeRoleColor
|
||||||
PermissionChangeRolePermissions
|
PermissionChangeRolePermissions
|
||||||
|
PermissionOnlySelfRoleRemove
|
||||||
|
|
||||||
// Channel group permissions
|
// Channel group permissions
|
||||||
PermissionAddChannelGroup
|
PermissionAddChannelGroup
|
||||||
@@ -156,21 +157,24 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type Hub struct {
|
type Hub struct {
|
||||||
Mu sync.RWMutex `json:"-"`
|
Mu sync.RWMutex `json:"-"`
|
||||||
Id uuid.UUID `json:"id"`
|
Id uuid.UUID `json:"id"`
|
||||||
CreatedAt time.Time `json:"createdAt"`
|
CreatedAt time.Time `json:"createdAt"`
|
||||||
MessagesBuff [globals.MaxHubMsgCache]*Message `json:"-"`
|
MessagesBuff [config.MaxHubMsgCache]*Message `json:"-"`
|
||||||
NextBuffIdx uint32 `json:"-"`
|
NextBuffIdx uint32 `json:"-"`
|
||||||
HaveOverflowed bool `json:"-"`
|
HaveOverflowed bool `json:"-"`
|
||||||
Users map[uuid.UUID]*HubUser `json:"-"`
|
Users map[uuid.UUID]*HubUser `json:"-"`
|
||||||
Roles map[uint8]*HubRole `json:"-"`
|
Roles map[uint8]*HubRole `json:"-"`
|
||||||
Creator uuid.UUID `json:"creator"`
|
Creator uuid.UUID `json:"creator"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
Color Rgba `json:"color"`
|
||||||
|
AllowUserColor bool `json:"allowUserColor"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type HubChannelGroup struct {
|
type HubChannelGroup struct {
|
||||||
Id uuid.UUID `json:"id"`
|
Id uuid.UUID `json:"id"`
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
Color string `json:"color"`
|
Color Rgba `json:"color"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type HubChannel struct {
|
type HubChannel struct {
|
||||||
@@ -190,6 +194,7 @@ type HubRole struct {
|
|||||||
Name string `json:"role"`
|
Name string `json:"role"`
|
||||||
Id uint8 `json:"id"`
|
Id uint8 `json:"id"`
|
||||||
RolePermission RolePermission `json:"rolePermission"`
|
RolePermission RolePermission `json:"rolePermission"`
|
||||||
|
Color Rgba `json:"color"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h HubRole) GrantPermission(r RolePermission) {
|
func (h HubRole) GrantPermission(r RolePermission) {
|
||||||
|
|||||||
Reference in New Issue
Block a user