complete hub save endpoint
This commit is contained in:
@@ -7,6 +7,8 @@ import (
|
|||||||
"go-socket/packages/cache"
|
"go-socket/packages/cache"
|
||||||
"go-socket/packages/postgresql"
|
"go-socket/packages/postgresql"
|
||||||
"go-socket/packages/types"
|
"go-socket/packages/types"
|
||||||
|
|
||||||
|
"github.com/google/uuid"
|
||||||
)
|
)
|
||||||
|
|
||||||
func HandleHubCreate(response http.ResponseWriter, request *http.Request) {
|
func HandleHubCreate(response http.ResponseWriter, request *http.Request) {
|
||||||
@@ -33,9 +35,49 @@ func HandleHubCreate(response http.ResponseWriter, request *http.Request) {
|
|||||||
hub.Color = types.Rgba{}.GetRandom()
|
hub.Color = types.Rgba{}.GetRandom()
|
||||||
hub.CreatedAt = time.Now()
|
hub.CreatedAt = time.Now()
|
||||||
|
|
||||||
|
rootGrp := &types.HubChannelGroup{
|
||||||
|
Id: uuid.New(),
|
||||||
|
Name: "root",
|
||||||
|
Color: types.Rgba{6, 2, 1, 255},
|
||||||
|
Position: uint8(0),
|
||||||
|
}
|
||||||
|
hub.ChannelGroups[rootGrp.Id] = rootGrp
|
||||||
|
|
||||||
|
rootRole := &types.HubRole{
|
||||||
|
Id: 0,
|
||||||
|
Name: "root",
|
||||||
|
Color: types.Rgba{255, 0, 0, 255},
|
||||||
|
RolePermission: ^types.RolePermission(0),
|
||||||
|
}
|
||||||
|
hub.Roles[rootRole.Id] = rootRole
|
||||||
|
|
||||||
|
rootUser := &types.HubUser{
|
||||||
|
Id: user.Id,
|
||||||
|
Username: user.Name,
|
||||||
|
Roles: []uint8{rootRole.Id},
|
||||||
|
CreatedAt: hub.CreatedAt,
|
||||||
|
}
|
||||||
|
hub.Users[rootUser.Id] = rootUser
|
||||||
|
|
||||||
err = postgresql.HubSave(ctx, hub)
|
err = postgresql.HubSave(ctx, hub)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(response, "failed to save hub", http.StatusInternalServerError)
|
http.Error(response, "internal server error", http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if err = postgresql.HubRoleSave(ctx, hub.Id, rootRole); err != nil {
|
||||||
|
http.Error(response, "internal server error", http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if err = postgresql.HubChannelGroupSave(ctx, hub.Id, rootGrp); err != nil {
|
||||||
|
http.Error(response, "internal server error", http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if err = postgresql.HubUserAdd(ctx, hub.Id, rootUser); err != nil {
|
||||||
|
http.Error(response, "internal server error", http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if err = postgresql.HubUserRoleAdd(ctx, hub.Id, user.Id, rootRole.Id); err != nil {
|
||||||
|
http.Error(response, "internal server error", http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
cache.SaveHub(hub)
|
cache.SaveHub(hub)
|
||||||
|
|||||||
@@ -73,67 +73,81 @@ func Init(ctx context.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_, err = dbConn.Exec(ctx, `
|
_, err = dbConn.Exec(ctx, `
|
||||||
CREATE TABLE IF NOT EXISTS hubs ()
|
CREATE TABLE IF NOT EXISTS hubs (
|
||||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
id UUID PRIMARY KEY,
|
||||||
creator_id UUID NOT NULL REFERENCES users(id),
|
creator_id UUID NOT NULL REFERENCES users(id),
|
||||||
name TEXT NOT NULL,
|
name TEXT NOT NULL,
|
||||||
allow_user_color BOOLEAN DEFAULT TRUE,
|
allow_user_color BOOLEAN NOT NULL DEFAULT TRUE,
|
||||||
rgba BIGINT NOT NULL DEFAULT 0 CHECK (rgba BETWEEN 0 AND 4294967295),
|
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 {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = dbConn.Exec(ctx, `
|
_, err = dbConn.Exec(ctx, `
|
||||||
CREATE TABLE IF NOT EXISTS hub_channel_groups ()
|
CREATE TABLE IF NOT EXISTS hub_roles (
|
||||||
hub_id UUID PRIMARY KEY NOT NULL REFERENCES hubs(id) ON DELETE CASCADE,
|
hub_id UUID NOT NULL REFERENCES hubs(id) ON DELETE CASCADE,
|
||||||
channel_group_id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
role_id SMALLINT NOT NULL,
|
||||||
name TEXT NOT NULL,
|
|
||||||
rgba BIGINT NOT NULL DEFAULT 0 CHECK (rgba BETWEEN 0 AND 4294967295),
|
|
||||||
`)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err = dbConn.Exec(ctx, `
|
|
||||||
CREATE TABLE IF NOT EXISTS hub_channels ()
|
|
||||||
hub_id UUID PRIMARY KEY NOT NULL REFERENCES hubs(id) ON DELETE CASCADE,
|
|
||||||
channel_id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
||||||
name TEXT NOT NULL,
|
|
||||||
parent_group_id UUID REFERENCES hub_channel_groups(id) ON DELETE CASCADE,
|
|
||||||
`)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err = dbConn.Exec(ctx, `
|
|
||||||
CREATE TABLE IF NOT EXISTS hub_users ()
|
|
||||||
hub_id UUID PRIMARY KEY NOT NULL REFERENCES hubs(id) ON DELETE CASCADE,
|
|
||||||
user_id UUID PRIMARY KEY NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
|
||||||
name TEXT NOT NULL,
|
|
||||||
rgba BIGINT NOT NULL DEFAULT 0 CHECK (rgba BETWEEN 0 AND 4294967295),
|
|
||||||
created_at TIMESTAMP NOT NULL DEFAULT NOW()
|
|
||||||
`)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
_, err = dbConn.Exec(ctx, `
|
|
||||||
CREATE TABLE IF NOT EXISTS hub_user_roles ()
|
|
||||||
user_id UUID PRIMARY KEY NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
|
||||||
role_id SMALLINT NOT NULL REFERENCES hub_roles(role_id) ON DELETE CASCADE
|
|
||||||
`)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err = dbConn.Exec(ctx, `
|
|
||||||
CREATE TABLE IF NOT EXISTS hub_roles ()
|
|
||||||
hub_id UUID PRIMARY KEY NOT NULL REFERENCES hubs(id) ON DELETE CASCADE,
|
|
||||||
role_id SMALLINT NOT NULL DEFAULT 0,
|
|
||||||
name TEXT NOT NULL,
|
name TEXT NOT NULL,
|
||||||
permissions INTEGER NOT NULL DEFAULT 0,
|
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),
|
||||||
|
PRIMARY KEY (hub_id, role_id)
|
||||||
|
)
|
||||||
|
`)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = dbConn.Exec(ctx, `
|
||||||
|
CREATE TABLE IF NOT EXISTS hub_channel_groups (
|
||||||
|
channel_group_id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||||
|
hub_id UUID NOT NULL REFERENCES hubs(id) ON DELETE CASCADE,
|
||||||
|
name TEXT NOT NULL,
|
||||||
|
rgba BIGINT NOT NULL DEFAULT 0 CHECK (rgba BETWEEN 0 AND 4294967295),
|
||||||
|
position SMALLINT NOT NULL DEFAULT 0
|
||||||
|
)
|
||||||
|
`)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = dbConn.Exec(ctx, `
|
||||||
|
CREATE TABLE IF NOT EXISTS hub_channels (
|
||||||
|
channel_id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||||
|
hub_id UUID NOT NULL REFERENCES hubs(id) ON DELETE CASCADE,
|
||||||
|
name TEXT NOT NULL,
|
||||||
|
parent_group_id UUID REFERENCES hub_channel_groups(channel_group_id) ON DELETE CASCADE,
|
||||||
|
position SMALLINT NOT NULL DEFAULT 0
|
||||||
|
)
|
||||||
|
`)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = dbConn.Exec(ctx, `
|
||||||
|
CREATE TABLE IF NOT EXISTS hub_users (
|
||||||
|
hub_id UUID NOT NULL REFERENCES hubs(id) ON DELETE CASCADE,
|
||||||
|
user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
||||||
|
name TEXT NOT NULL,
|
||||||
|
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
||||||
|
PRIMARY KEY (hub_id, user_id)
|
||||||
|
)
|
||||||
|
`)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = dbConn.Exec(ctx, `
|
||||||
|
CREATE TABLE IF NOT EXISTS hub_user_roles (
|
||||||
|
hub_id UUID NOT NULL,
|
||||||
|
user_id UUID NOT NULL,
|
||||||
|
role_id SMALLINT NOT NULL,
|
||||||
|
PRIMARY KEY (hub_id, user_id, role_id),
|
||||||
|
FOREIGN KEY (hub_id, user_id) REFERENCES hub_users(hub_id, user_id) ON DELETE CASCADE,
|
||||||
|
FOREIGN KEY (hub_id, role_id) REFERENCES hub_roles(hub_id, role_id) ON DELETE CASCADE
|
||||||
|
)
|
||||||
`)
|
`)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
@@ -322,10 +336,10 @@ func ConnectionGetMessagesBefore(ctx context.Context, before time.Time, connecti
|
|||||||
}
|
}
|
||||||
|
|
||||||
func HubSave(ctx context.Context, hub *types.Hub) error {
|
func HubSave(ctx context.Context, hub *types.Hub) error {
|
||||||
return dbConn.QueryRow(ctx, `
|
_, err := dbConn.Exec(ctx, `
|
||||||
INSERT INTO hubs (creator_id, name, allow_user_color, rgba, created_at) VALUES ($1, $2, $3, $4, $5)
|
INSERT INTO hubs (id, creator_id, name, allow_user_color, rgba, created_at) VALUES ($1, $2, $3, $4, $5, $6)
|
||||||
RETURNING id
|
`, hub.Id, hub.Creator, hub.Name, hub.AllowUserColor, convertions.RgbaToUint32(hub.Color), hub.CreatedAt)
|
||||||
`, hub.Creator, hub.Name, hub.AllowUserColor, convertions.RgbaToUint32(hub.Color), hub.CreatedAt).Scan(&hub.Id)
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func HubDelete(ctx context.Context, hub *types.Hub) error {
|
func HubDelete(ctx context.Context, hub *types.Hub) error {
|
||||||
@@ -373,7 +387,7 @@ func HubGetUsers(ctx context.Context, hub *types.Hub) error {
|
|||||||
rows, err := dbConn.Query(ctx, `
|
rows, err := dbConn.Query(ctx, `
|
||||||
SELECT hu.user_id, hu.name, hu.created_at, COALESCE(array_agg(hur.role_id) FILTER (WHERE hur.role_id IS NOT NULL), '{}')
|
SELECT hu.user_id, hu.name, hu.created_at, COALESCE(array_agg(hur.role_id) FILTER (WHERE hur.role_id IS NOT NULL), '{}')
|
||||||
FROM hub_users hu
|
FROM hub_users hu
|
||||||
LEFT JOIN hub_user_roles hur ON hu.user_id = hur.user_id
|
LEFT JOIN hub_user_roles hur ON hu.hub_id = hur.hub_id AND hu.user_id = hur.user_id
|
||||||
WHERE hu.hub_id = $1
|
WHERE hu.hub_id = $1
|
||||||
GROUP BY hu.user_id, hu.name, hu.created_at
|
GROUP BY hu.user_id, hu.name, hu.created_at
|
||||||
`, hub.Id)
|
`, hub.Id)
|
||||||
@@ -442,17 +456,17 @@ func HubUserRemove(ctx context.Context, hubId uuid.UUID, userId uuid.UUID) error
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func HubUserRoleAdd(ctx context.Context, userId uuid.UUID, roleId uint8) error {
|
func HubUserRoleAdd(ctx context.Context, hubId uuid.UUID, userId uuid.UUID, roleId uint8) error {
|
||||||
_, err := dbConn.Exec(ctx, `
|
_, err := dbConn.Exec(ctx, `
|
||||||
INSERT INTO hub_user_roles (user_id, role_id) VALUES ($1, $2)
|
INSERT INTO hub_user_roles (hub_id, user_id, role_id) VALUES ($1, $2, $3)
|
||||||
`, userId, roleId)
|
`, hubId, userId, roleId)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func HubUserRoleRemove(ctx context.Context, userId uuid.UUID, roleId uint8) error {
|
func HubUserRoleRemove(ctx context.Context, hubId uuid.UUID, userId uuid.UUID, roleId uint8) error {
|
||||||
_, err := dbConn.Exec(ctx, `
|
_, err := dbConn.Exec(ctx, `
|
||||||
DELETE FROM hub_user_roles WHERE user_id = $1 AND role_id = $2
|
DELETE FROM hub_user_roles WHERE hub_id = $1 AND user_id = $2 AND role_id = $3
|
||||||
`, userId, roleId)
|
`, hubId, userId, roleId)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -478,10 +492,10 @@ func HubRoleUpdate(ctx context.Context, hubId uuid.UUID, role *types.HubRole) er
|
|||||||
}
|
}
|
||||||
|
|
||||||
func HubChannelGroupSave(ctx context.Context, hubId uuid.UUID, cg *types.HubChannelGroup) error {
|
func HubChannelGroupSave(ctx context.Context, hubId uuid.UUID, cg *types.HubChannelGroup) error {
|
||||||
return dbConn.QueryRow(ctx, `
|
_, err := dbConn.Exec(ctx, `
|
||||||
INSERT INTO hub_channel_groups (hub_id, name, rgba) VALUES ($1, $2, $3)
|
INSERT INTO hub_channel_groups (channel_group_id, hub_id, name, rgba, position) VALUES ($1, $2, $3, $4, $5)
|
||||||
RETURNING channel_group_id
|
`, cg.Id, hubId, cg.Name, convertions.RgbaToUint32(cg.Color), cg.Position)
|
||||||
`, hubId, cg.Name, convertions.RgbaToUint32(cg.Color)).Scan(&cg.Id)
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func HubChannelGroupDelete(ctx context.Context, cgId uuid.UUID) error {
|
func HubChannelGroupDelete(ctx context.Context, cgId uuid.UUID) error {
|
||||||
@@ -491,9 +505,9 @@ func HubChannelGroupDelete(ctx context.Context, cgId uuid.UUID) error {
|
|||||||
|
|
||||||
func HubChannelSave(ctx context.Context, hubId uuid.UUID, ch *types.HubChannel) error {
|
func HubChannelSave(ctx context.Context, hubId uuid.UUID, ch *types.HubChannel) error {
|
||||||
return dbConn.QueryRow(ctx, `
|
return dbConn.QueryRow(ctx, `
|
||||||
INSERT INTO hub_channels (hub_id, name, parent_group_id) VALUES ($1, $2, $3)
|
INSERT INTO hub_channels (hub_id, name, parent_group_id, position) VALUES ($1, $2, $3, $4)
|
||||||
RETURNING channel_id
|
RETURNING channel_id
|
||||||
`, hubId, ch.Name, ch.ParentGroupId).Scan(&ch.Id)
|
`, hubId, ch.Name, ch.ParentGroupId, ch.Position).Scan(&ch.Id)
|
||||||
}
|
}
|
||||||
|
|
||||||
func HubChannelDelete(ctx context.Context, chId uuid.UUID) error {
|
func HubChannelDelete(ctx context.Context, chId uuid.UUID) error {
|
||||||
|
|||||||
+29
-24
@@ -128,7 +128,7 @@ type RolePermission uint32
|
|||||||
|
|
||||||
const (
|
const (
|
||||||
// Hub permissions
|
// Hub permissions
|
||||||
PermissionSetHubName RolePermission = iota
|
PermissionSetHubName RolePermission = 1 << iota
|
||||||
PermissionSetHubBg
|
PermissionSetHubBg
|
||||||
PermissionSetHubColor
|
PermissionSetHubColor
|
||||||
PermissionRemoveHub
|
PermissionRemoveHub
|
||||||
@@ -165,38 +165,43 @@ 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 []*Message `json:"-"`
|
MessagesBuff []*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"`
|
ChannelGroups map[uuid.UUID]*HubChannelGroup `json:"-"`
|
||||||
Name string `json:"name"`
|
Creator uuid.UUID `json:"creator"`
|
||||||
Color Rgba `json:"color"`
|
Name string `json:"name"`
|
||||||
AllowUserColor bool `json:"allowUserColor"`
|
Color Rgba `json:"color"`
|
||||||
|
AllowUserColor bool `json:"allowUserColor"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewHub() *Hub {
|
func NewHub() *Hub {
|
||||||
return &Hub{
|
return &Hub{
|
||||||
MessagesBuff: make([]*Message, config.MaxHubMsgCache),
|
Id: uuid.New(),
|
||||||
Users: make(map[uuid.UUID]*HubUser),
|
MessagesBuff: make([]*Message, config.MaxHubMsgCache),
|
||||||
Roles: make(map[uint8]*HubRole),
|
Users: make(map[uuid.UUID]*HubUser),
|
||||||
|
Roles: make(map[uint8]*HubRole),
|
||||||
|
ChannelGroups: make(map[uuid.UUID]*HubChannelGroup),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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 Rgba `json:"color"`
|
Color Rgba `json:"color"`
|
||||||
|
Position uint8 `json:"position"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type HubChannel struct {
|
type HubChannel struct {
|
||||||
Id uuid.UUID `json:"id"`
|
Id uuid.UUID `json:"id"`
|
||||||
Name uuid.UUID `json:"name"`
|
Name uuid.UUID `json:"name"`
|
||||||
ParentGroupId uuid.UUID `json:"parentGroupId"`
|
ParentGroupId uuid.UUID `json:"parentGroupId"`
|
||||||
|
Position uint8 `json:"position"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type HubUser struct {
|
type HubUser struct {
|
||||||
@@ -213,22 +218,22 @@ type HubRole struct {
|
|||||||
Color Rgba `json:"color"`
|
Color Rgba `json:"color"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h HubRole) GrantPermission(r RolePermission) {
|
func (h *HubRole) GrantPermission(r RolePermission) {
|
||||||
h.RolePermission |= r
|
h.RolePermission |= r
|
||||||
}
|
}
|
||||||
func (h HubRole) GrantPermissions(rs []RolePermission) {
|
func (h *HubRole) GrantPermissions(rs []RolePermission) {
|
||||||
for _, r := range rs {
|
for _, r := range rs {
|
||||||
h.RolePermission |= r
|
h.RolePermission |= r
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
func (h HubRole) RevokePermission(r RolePermission) {
|
func (h *HubRole) RevokePermission(r RolePermission) {
|
||||||
h.RolePermission &^= r
|
h.RolePermission &^= r
|
||||||
}
|
}
|
||||||
func (h HubRole) RevokePermissions(rs []RolePermission) {
|
func (h *HubRole) RevokePermissions(rs []RolePermission) {
|
||||||
for _, r := range rs {
|
for _, r := range rs {
|
||||||
h.RolePermission &^= r
|
h.RolePermission &^= r
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
func (h HubRole) HasPermission(r RolePermission) bool {
|
func (h *HubRole) HasPermission(r RolePermission) bool {
|
||||||
return h.RolePermission&r != 0
|
return h.RolePermission&r != 0
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user