use uuid for everything
This commit is contained in:
@@ -9,17 +9,17 @@ import (
|
|||||||
|
|
||||||
var (
|
var (
|
||||||
mu sync.RWMutex
|
mu sync.RWMutex
|
||||||
CacheUsers = make(map[uint32]*User)
|
CacheUsers = make(map[uuid.UUID]*User)
|
||||||
CacheGroups = make(map[uint32]*Group)
|
CacheGroups = make(map[uuid.UUID]*Group)
|
||||||
)
|
)
|
||||||
|
|
||||||
func CacheGetUserById(id uint32) (*User, error) {
|
func CacheGetUserById(id uuid.UUID) (*User, error) {
|
||||||
mu.RLock()
|
mu.RLock()
|
||||||
defer mu.RUnlock()
|
defer mu.RUnlock()
|
||||||
|
|
||||||
user, ok := CacheUsers[id]
|
user, ok := CacheUsers[id]
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, fmt.Errorf("user %d not found", id)
|
return nil, fmt.Errorf("user %s not found", id)
|
||||||
}
|
}
|
||||||
return user, nil
|
return user, nil
|
||||||
}
|
}
|
||||||
@@ -43,7 +43,7 @@ func CacheSaveUser(user *User) {
|
|||||||
CacheUsers[user.Id] = user
|
CacheUsers[user.Id] = user
|
||||||
}
|
}
|
||||||
|
|
||||||
func CacheDeleteUser(id uint32) {
|
func CacheDeleteUser(id uuid.UUID) {
|
||||||
mu.Lock()
|
mu.Lock()
|
||||||
defer mu.Unlock()
|
defer mu.Unlock()
|
||||||
|
|
||||||
@@ -57,7 +57,7 @@ func CacheSaveGroup(group *Group) {
|
|||||||
CacheGroups[group.Id] = group
|
CacheGroups[group.Id] = group
|
||||||
}
|
}
|
||||||
|
|
||||||
func CacheDeleteGroup(id uint32) {
|
func CacheDeleteGroup(id uuid.UUID) {
|
||||||
mu.Lock()
|
mu.Lock()
|
||||||
defer mu.Unlock()
|
defer mu.Unlock()
|
||||||
delete(CacheGroups, id)
|
delete(CacheGroups, id)
|
||||||
@@ -65,7 +65,7 @@ func CacheDeleteGroup(id uint32) {
|
|||||||
|
|
||||||
func CacheAddConnection(a, b *User, conn *Connection) {
|
func CacheAddConnection(a, b *User, conn *Connection) {
|
||||||
first, second := a, b
|
first, second := a, b
|
||||||
if a.Id > b.Id {
|
if a.Id.String() > b.Id.String() {
|
||||||
first, second = b, a
|
first, second = b, a
|
||||||
}
|
}
|
||||||
first.Mu.Lock()
|
first.Mu.Lock()
|
||||||
@@ -78,7 +78,7 @@ func CacheAddConnection(a, b *User, conn *Connection) {
|
|||||||
|
|
||||||
func CacheDeleteConnection(a, b *User, id uuid.UUID) {
|
func CacheDeleteConnection(a, b *User, id uuid.UUID) {
|
||||||
first, second := a, b
|
first, second := a, b
|
||||||
if a.Id > b.Id {
|
if a.Id.String() > b.Id.String() {
|
||||||
first, second = b, a
|
first, second = b, a
|
||||||
}
|
}
|
||||||
first.Mu.Lock()
|
first.Mu.Lock()
|
||||||
@@ -96,13 +96,13 @@ func CacheGetConnection(user *User, id uuid.UUID) (*Connection, bool) {
|
|||||||
return conn, ok
|
return conn, ok
|
||||||
}
|
}
|
||||||
|
|
||||||
func CacheGetGroup(id uint32) (*Group, error) {
|
func CacheGetGroup(id uuid.UUID) (*Group, error) {
|
||||||
mu.RLock()
|
mu.RLock()
|
||||||
defer mu.RUnlock()
|
defer mu.RUnlock()
|
||||||
|
|
||||||
group, ok := CacheGroups[id]
|
group, ok := CacheGroups[id]
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, fmt.Errorf("group %d not found", id)
|
return nil, fmt.Errorf("group %s not found", id)
|
||||||
}
|
}
|
||||||
|
|
||||||
return group, nil
|
return group, nil
|
||||||
|
|||||||
+18
-18
@@ -26,7 +26,7 @@ func DbInit(ctx context.Context) {
|
|||||||
|
|
||||||
_, err = dbConn.Exec(ctx, `
|
_, err = dbConn.Exec(ctx, `
|
||||||
CREATE TABLE IF NOT EXISTS users (
|
CREATE TABLE IF NOT EXISTS users (
|
||||||
id SERIAL PRIMARY KEY,
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||||
name TEXT UNIQUE NOT NULL,
|
name TEXT UNIQUE NOT NULL,
|
||||||
pass_hash TEXT NOT NULL,
|
pass_hash TEXT NOT NULL,
|
||||||
pronouns TEXT DEFAULT NULL,
|
pronouns TEXT DEFAULT NULL,
|
||||||
@@ -43,8 +43,8 @@ func DbInit(ctx context.Context) {
|
|||||||
_, err = dbConn.Exec(ctx, `
|
_, err = dbConn.Exec(ctx, `
|
||||||
CREATE TABLE IF NOT EXISTS user_connections (
|
CREATE TABLE IF NOT EXISTS user_connections (
|
||||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||||
requestor_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
requestor_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
||||||
recipient_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
recipient_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
||||||
state SMALLINT NOT NULL DEFAULT 0,
|
state SMALLINT NOT NULL DEFAULT 0,
|
||||||
created_at TIMESTAMP NOT NULL DEFAULT NOW()
|
created_at TIMESTAMP NOT NULL DEFAULT NOW()
|
||||||
)
|
)
|
||||||
@@ -56,7 +56,7 @@ func DbInit(ctx context.Context) {
|
|||||||
_, err = dbConn.Exec(ctx, `
|
_, err = dbConn.Exec(ctx, `
|
||||||
CREATE TABLE IF NOT EXISTS direct_messages (
|
CREATE TABLE IF NOT EXISTS direct_messages (
|
||||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||||
sender_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
sender_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
||||||
receiver_id UUID NOT NULL REFERENCES user_connections(id) ON DELETE CASCADE,
|
receiver_id UUID NOT NULL REFERENCES user_connections(id) ON DELETE CASCADE,
|
||||||
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
||||||
content TEXT NOT NULL
|
content TEXT NOT NULL
|
||||||
@@ -68,10 +68,10 @@ func DbInit(ctx context.Context) {
|
|||||||
|
|
||||||
_, err = dbConn.Exec(ctx, `
|
_, err = dbConn.Exec(ctx, `
|
||||||
CREATE TABLE IF NOT EXISTS chat_groups (
|
CREATE TABLE IF NOT EXISTS chat_groups (
|
||||||
id SERIAL PRIMARY KEY,
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||||
name TEXT NOT NULL,
|
name TEXT NOT NULL,
|
||||||
creator_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
creator_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
||||||
owner_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
owner_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
||||||
enable_client_colors BOOLEAN NOT NULL DEFAULT true,
|
enable_client_colors BOOLEAN NOT NULL DEFAULT true,
|
||||||
color_red SMALLINT DEFAULT NULL,
|
color_red SMALLINT DEFAULT NULL,
|
||||||
color_green SMALLINT DEFAULT NULL,
|
color_green SMALLINT DEFAULT NULL,
|
||||||
@@ -85,8 +85,8 @@ func DbInit(ctx context.Context) {
|
|||||||
|
|
||||||
_, err = dbConn.Exec(ctx, `
|
_, err = dbConn.Exec(ctx, `
|
||||||
CREATE TABLE IF NOT EXISTS chat_group_members (
|
CREATE TABLE IF NOT EXISTS chat_group_members (
|
||||||
group_id INTEGER NOT NULL REFERENCES chat_groups(id) ON DELETE CASCADE,
|
group_id UUID NOT NULL REFERENCES chat_groups(id) ON DELETE CASCADE,
|
||||||
user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
||||||
joined_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
joined_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
||||||
PRIMARY KEY (group_id, user_id)
|
PRIMARY KEY (group_id, user_id)
|
||||||
)
|
)
|
||||||
@@ -106,7 +106,7 @@ func DbUserSave(ctx context.Context, user *User) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func DbUserDelete(ctx context.Context, id uint32) error {
|
func DbUserDelete(ctx context.Context, id uuid.UUID) error {
|
||||||
_, err := dbConn.Exec(ctx, `
|
_, err := dbConn.Exec(ctx, `
|
||||||
DELETE FROM users WHERE id = $1
|
DELETE FROM users WHERE id = $1
|
||||||
`, id)
|
`, id)
|
||||||
@@ -136,9 +136,9 @@ func DbUserGetGroups(ctx context.Context, user *User) error {
|
|||||||
}
|
}
|
||||||
defer rows.Close()
|
defer rows.Close()
|
||||||
|
|
||||||
user.Groups = make(map[uint32]struct{})
|
user.Groups = make(map[uuid.UUID]struct{})
|
||||||
for rows.Next() {
|
for rows.Next() {
|
||||||
var groupId uint32
|
var groupId uuid.UUID
|
||||||
if err := rows.Scan(&groupId); err != nil {
|
if err := rows.Scan(&groupId); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -312,9 +312,9 @@ func DbGroupGetMembers(ctx context.Context, group *Group) error {
|
|||||||
}
|
}
|
||||||
defer rows.Close()
|
defer rows.Close()
|
||||||
|
|
||||||
group.Users = make(map[uint32]struct{})
|
group.Users = make(map[uuid.UUID]struct{})
|
||||||
for rows.Next() {
|
for rows.Next() {
|
||||||
var userId uint32
|
var userId uuid.UUID
|
||||||
if err := rows.Scan(&userId); err != nil {
|
if err := rows.Scan(&userId); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -323,12 +323,12 @@ func DbGroupGetMembers(ctx context.Context, group *Group) error {
|
|||||||
return rows.Err()
|
return rows.Err()
|
||||||
}
|
}
|
||||||
|
|
||||||
func DbGroupAddUsers(ctx context.Context, groupId uint32, userIds *[MaxUsersInGroup]uint32) error {
|
func DbGroupAddUsers(ctx context.Context, groupId uuid.UUID, userIds *[MaxUsersInGroup]uuid.UUID) error {
|
||||||
batch := &pgx.Batch{}
|
batch := &pgx.Batch{}
|
||||||
now := time.Now()
|
now := time.Now()
|
||||||
var count int
|
var count int
|
||||||
for _, uid := range userIds {
|
for _, uid := range userIds {
|
||||||
if uid == 0 {
|
if uid == (uuid.UUID{}) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
batch.Queue(`
|
batch.Queue(`
|
||||||
@@ -348,11 +348,11 @@ func DbGroupAddUsers(ctx context.Context, groupId uint32, userIds *[MaxUsersInGr
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func DbGroupRemoveUsers(ctx context.Context, groupId uint32, userIds *[MaxUsersInGroup]uint32) (int, error) {
|
func DbGroupRemoveUsers(ctx context.Context, groupId uuid.UUID, userIds *[MaxUsersInGroup]uuid.UUID) (int, error) {
|
||||||
batch := &pgx.Batch{}
|
batch := &pgx.Batch{}
|
||||||
var count int
|
var count int
|
||||||
for _, uid := range userIds {
|
for _, uid := range userIds {
|
||||||
if uid == 0 {
|
if uid == (uuid.UUID{}) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
batch.Queue(`
|
batch.Queue(`
|
||||||
|
|||||||
@@ -1,8 +1,12 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import "context"
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
func GetUserById(ctx context.Context, userId uint32) (*User, error) {
|
"github.com/google/uuid"
|
||||||
|
)
|
||||||
|
|
||||||
|
func GetUserById(ctx context.Context, userId uuid.UUID) (*User, error) {
|
||||||
user, err := CacheGetUserById(userId)
|
user, err := CacheGetUserById(userId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
user = &User{Id: userId}
|
user = &User{Id: userId}
|
||||||
@@ -23,7 +27,7 @@ func GetUserByToken(ctx context.Context, token string) (*User, error) {
|
|||||||
return GetUserById(ctx, userId)
|
return GetUserById(ctx, userId)
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetGroup(ctx context.Context, groupId uint32) (*Group, error) {
|
func GetGroup(ctx context.Context, groupId uuid.UUID) (*Group, error) {
|
||||||
group, err := CacheGetGroup(groupId)
|
group, err := CacheGetGroup(groupId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
group = &Group{Id: groupId}
|
group = &Group{Id: groupId}
|
||||||
|
|||||||
@@ -165,7 +165,7 @@ func HttpHandleUserNewConnection(response http.ResponseWriter, request *http.Req
|
|||||||
http.Error(response, "invalid token", http.StatusUnauthorized)
|
http.Error(response, "invalid token", http.StatusUnauthorized)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
recipientId, err := ConvertStringUint32(request.FormValue("recipient"))
|
recipientId, err := ConvertStringUuid(request.FormValue("recipient"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(response, "no such user", http.StatusUnauthorized)
|
http.Error(response, "no such user", http.StatusUnauthorized)
|
||||||
return
|
return
|
||||||
@@ -296,8 +296,7 @@ func HttpHandleUserElevateConnection(response http.ResponseWriter, request *http
|
|||||||
|
|
||||||
response.WriteHeader(http.StatusAccepted)
|
response.WriteHeader(http.StatusAccepted)
|
||||||
|
|
||||||
// TODO change to != "" after user id via uuid
|
if conn.UserWantingToElevate != (uuid.UUID{}) && conn.UserWantingToElevate != user.Id {
|
||||||
if conn.UserWantingToElevate != 0 && conn.UserWantingToElevate != user.Id {
|
|
||||||
switch conn.State {
|
switch conn.State {
|
||||||
case ConnectionState.Stranger:
|
case ConnectionState.Stranger:
|
||||||
conn.State = ConnectionState.Friend
|
conn.State = ConnectionState.Friend
|
||||||
|
|||||||
+13
-11
@@ -11,6 +11,8 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/google/uuid"
|
||||||
)
|
)
|
||||||
|
|
||||||
func isOwnerOfGroup(user *User, group *Group) bool {
|
func isOwnerOfGroup(user *User, group *Group) bool {
|
||||||
@@ -27,7 +29,7 @@ func getIfOwnerUserAndGroup(ctx context.Context, response *http.ResponseWriter,
|
|||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
affectedGroupId, err := ConvertStringUint32(request.FormValue("groupid"))
|
affectedGroupId, err := ConvertStringUuid(request.FormValue("groupid"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(*response, "no such group", http.StatusUnauthorized)
|
http.Error(*response, "no such group", http.StatusUnauthorized)
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
@@ -77,7 +79,7 @@ func HttpHandeGroupCreate(response http.ResponseWriter, request *http.Request) {
|
|||||||
OwnerId: user.Id,
|
OwnerId: user.Id,
|
||||||
CreatorId: user.Id,
|
CreatorId: user.Id,
|
||||||
Color: color,
|
Color: color,
|
||||||
Users: map[uint32]struct{}{user.Id: {}},
|
Users: map[uuid.UUID]struct{}{user.Id: {}},
|
||||||
}
|
}
|
||||||
|
|
||||||
enableUserColors := request.FormValue("enableUserColors")
|
enableUserColors := request.FormValue("enableUserColors")
|
||||||
@@ -91,7 +93,7 @@ func HttpHandeGroupCreate(response http.ResponseWriter, request *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
response.WriteHeader(http.StatusCreated)
|
response.WriteHeader(http.StatusCreated)
|
||||||
fmt.Fprintf(response, "%d", group.Id)
|
fmt.Fprintf(response, "%s", group.Id)
|
||||||
}
|
}
|
||||||
|
|
||||||
func HttpHandleGroupDelete(response http.ResponseWriter, request *http.Request) {
|
func HttpHandleGroupDelete(response http.ResponseWriter, request *http.Request) {
|
||||||
@@ -140,13 +142,13 @@ func HttpHandleGroupAddUsers(response http.ResponseWriter, request *http.Request
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
var ids [MaxUsersInGroup]uint32
|
var ids [MaxUsersInGroup]uuid.UUID
|
||||||
var idx uint32 = 0
|
var idx uint32 = 0
|
||||||
for _, s := range usersStringSlice {
|
for _, s := range usersStringSlice {
|
||||||
if idx >= MaxUsersInGroup {
|
if idx >= MaxUsersInGroup {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
id, err := ConvertStringUint32(strings.TrimSpace(s))
|
id, err := ConvertStringUuid(strings.TrimSpace(s))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@@ -192,13 +194,13 @@ func HttpHandleGroupRemoveUser(response http.ResponseWriter, request *http.Reque
|
|||||||
|
|
||||||
usersStringSlice := strings.SplitN(usersString, ",", int(MaxUsersInGroup)+1)
|
usersStringSlice := strings.SplitN(usersString, ",", int(MaxUsersInGroup)+1)
|
||||||
|
|
||||||
var ids [MaxUsersInGroup]uint32
|
var ids [MaxUsersInGroup]uuid.UUID
|
||||||
var idx uint32 = 0
|
var idx uint32 = 0
|
||||||
for _, s := range usersStringSlice {
|
for _, s := range usersStringSlice {
|
||||||
if idx >= MaxUsersInGroup {
|
if idx >= MaxUsersInGroup {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
id, err := ConvertStringUint32(strings.TrimSpace(s))
|
id, err := ConvertStringUuid(strings.TrimSpace(s))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@@ -314,7 +316,7 @@ func HttpHandleGroupMessage(response http.ResponseWriter, request *http.Request)
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
groupIdStr := request.FormValue("groupid")
|
groupIdStr := request.FormValue("groupid")
|
||||||
groupId, err := ConvertStringUint32(groupIdStr)
|
groupId, err := ConvertStringUuid(groupIdStr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(response, "no such group", http.StatusUnauthorized)
|
http.Error(response, "no such group", http.StatusUnauthorized)
|
||||||
return
|
return
|
||||||
@@ -360,13 +362,13 @@ func HttpHandleGroupsGetWithoutMembers(response http.ResponseWriter, request *ht
|
|||||||
}
|
}
|
||||||
|
|
||||||
user.Mu.RLock()
|
user.Mu.RLock()
|
||||||
groupIds := make([]uint32, 0, len(user.Groups))
|
groupIds := make([]uuid.UUID, 0, len(user.Groups))
|
||||||
for groupId := range user.Groups {
|
for groupId := range user.Groups {
|
||||||
groupIds = append(groupIds, groupId)
|
groupIds = append(groupIds, groupId)
|
||||||
}
|
}
|
||||||
user.Mu.RUnlock()
|
user.Mu.RUnlock()
|
||||||
|
|
||||||
groups := make(map[uint32]*Group, len(groupIds))
|
groups := make(map[uuid.UUID]*Group, len(groupIds))
|
||||||
for _, groupId := range groupIds {
|
for _, groupId := range groupIds {
|
||||||
group, err := GetGroup(ctx, groupId)
|
group, err := GetGroup(ctx, groupId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -398,7 +400,7 @@ func HttpHandleGroupMembersGet(response http.ResponseWriter, request *http.Reque
|
|||||||
}
|
}
|
||||||
|
|
||||||
groupStr := request.FormValue("group")
|
groupStr := request.FormValue("group")
|
||||||
groupId, err := ConvertStringUint32(groupStr)
|
groupId, err := ConvertStringUuid(groupStr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(response, "invalid group", http.StatusBadRequest)
|
http.Error(response, "invalid group", http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
|
|||||||
+11
-11
@@ -18,8 +18,8 @@ type User struct {
|
|||||||
PasswordHash string
|
PasswordHash string
|
||||||
CreatedAt time.Time
|
CreatedAt time.Time
|
||||||
WsConn *websocket.Conn
|
WsConn *websocket.Conn
|
||||||
Id uint32
|
Id uuid.UUID
|
||||||
Groups map[uint32]struct{}
|
Groups map[uuid.UUID]struct{}
|
||||||
Connections map[uuid.UUID]*Connection
|
Connections map[uuid.UUID]*Connection
|
||||||
Color [3]uint8
|
Color [3]uint8
|
||||||
}
|
}
|
||||||
@@ -30,9 +30,9 @@ type Connection struct {
|
|||||||
CreatedAt time.Time `json:"createdAt"`
|
CreatedAt time.Time `json:"createdAt"`
|
||||||
MessagesBuff [MaxDirectMsgCache]*Message `json:"-"`
|
MessagesBuff [MaxDirectMsgCache]*Message `json:"-"`
|
||||||
NextBuffIdx uint32 `json:"-"`
|
NextBuffIdx uint32 `json:"-"`
|
||||||
RequestorId uint32 `json:"requestorId"`
|
RequestorId uuid.UUID `json:"requestorId"`
|
||||||
RecipientId uint32 `json:"recipientId"`
|
RecipientId uuid.UUID `json:"recipientId"`
|
||||||
UserWantingToElevate uint32 `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"`
|
||||||
}
|
}
|
||||||
@@ -73,7 +73,7 @@ type Message struct {
|
|||||||
Id uuid.UUID `json:"id"`
|
Id uuid.UUID `json:"id"`
|
||||||
Content string `json:"content"`
|
Content string `json:"content"`
|
||||||
CreatedAt time.Time `json:"createdAt"`
|
CreatedAt time.Time `json:"createdAt"`
|
||||||
Sender uint32 `json:"sender"`
|
Sender uuid.UUID `json:"sender"`
|
||||||
Receiver uuid.UUID `json:"receiver"`
|
Receiver uuid.UUID `json:"receiver"`
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -83,10 +83,10 @@ type Group struct {
|
|||||||
CreatedAt time.Time `json:"createdAt"`
|
CreatedAt time.Time `json:"createdAt"`
|
||||||
MessagesBuff [MaxDirectMsgCache]*Message `json:"-"`
|
MessagesBuff [MaxDirectMsgCache]*Message `json:"-"`
|
||||||
NextBuffIdx uint32 `json:"-"`
|
NextBuffIdx uint32 `json:"-"`
|
||||||
Id uint32 `json:"-"`
|
Id uuid.UUID `json:"-"`
|
||||||
CreatorId uint32 `json:"creatorId"`
|
CreatorId uuid.UUID `json:"creatorId"`
|
||||||
OwnerId uint32 `json:"ownerId"`
|
OwnerId uuid.UUID `json:"ownerId"`
|
||||||
Users map[uint32]struct{} `json:"-"`
|
Users map[uuid.UUID]struct{} `json:"-"`
|
||||||
Color [3]uint8 `json:"color"`
|
Color [3]uint8 `json:"color"`
|
||||||
EnableUserColors bool `json:"enableUserColors"`
|
EnableUserColors bool `json:"enableUserColors"`
|
||||||
HaveMessageBuffOverflowed bool `json:"-"`
|
HaveMessageBuffOverflowed bool `json:"-"`
|
||||||
@@ -94,7 +94,7 @@ type Group struct {
|
|||||||
|
|
||||||
type LoginReturn struct {
|
type LoginReturn struct {
|
||||||
Token string `json:"token"`
|
Token string `json:"token"`
|
||||||
UserId uint32 `json:"userId"`
|
UserId uuid.UUID `json:"userId"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type WsEventMessage struct {
|
type WsEventMessage struct {
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
group messages history
|
group messages history
|
||||||
rewrite to use uuid
|
|
||||||
media support
|
media support
|
||||||
|
|
||||||
fix color saving to use INT (002255255035) rgba
|
fix color saving to use INT (002255255035) rgba
|
||||||
|
|||||||
@@ -2,26 +2,26 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"strconv"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/golang-jwt/jwt/v5"
|
"github.com/golang-jwt/jwt/v5"
|
||||||
|
"github.com/google/uuid"
|
||||||
)
|
)
|
||||||
|
|
||||||
const tokenSecret = "tmp" // TODO delete in production
|
const tokenSecret = "tmp" // TODO delete in production
|
||||||
const tokenExpiration = time.Hour
|
const tokenExpiration = time.Hour
|
||||||
|
|
||||||
func TokenCreate(userId uint32) (string, error) {
|
func TokenCreate(userId uuid.UUID) (string, error) {
|
||||||
now := time.Now()
|
now := time.Now()
|
||||||
signedToken, err := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.RegisteredClaims{
|
signedToken, err := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.RegisteredClaims{
|
||||||
Subject: strconv.FormatUint(uint64(userId), 10),
|
Subject: userId.String(),
|
||||||
IssuedAt: jwt.NewNumericDate(now),
|
IssuedAt: jwt.NewNumericDate(now),
|
||||||
ExpiresAt: jwt.NewNumericDate(now.Add(tokenExpiration)),
|
ExpiresAt: jwt.NewNumericDate(now.Add(tokenExpiration)),
|
||||||
}).SignedString([]byte(tokenSecret))
|
}).SignedString([]byte(tokenSecret))
|
||||||
return signedToken, err
|
return signedToken, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func TokenValidateGetId(tokenString string) (uint32, error) {
|
func TokenValidateGetId(tokenString string) (uuid.UUID, error) {
|
||||||
token, err := jwt.Parse(tokenString, func(t *jwt.Token) (interface{}, error) {
|
token, err := jwt.Parse(tokenString, func(t *jwt.Token) (interface{}, error) {
|
||||||
if _, ok := t.Method.(*jwt.SigningMethodHMAC); !ok {
|
if _, ok := t.Method.(*jwt.SigningMethodHMAC); !ok {
|
||||||
return nil, fmt.Errorf("unexpected signing method: %v", t.Header["alg"])
|
return nil, fmt.Errorf("unexpected signing method: %v", t.Header["alg"])
|
||||||
@@ -29,28 +29,28 @@ func TokenValidateGetId(tokenString string) (uint32, error) {
|
|||||||
return []byte(tokenSecret), nil
|
return []byte(tokenSecret), nil
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return uuid.UUID{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
claims, ok := token.Claims.(jwt.MapClaims)
|
claims, ok := token.Claims.(jwt.MapClaims)
|
||||||
if !ok || !token.Valid {
|
if !ok || !token.Valid {
|
||||||
return 0, fmt.Errorf("invalid token")
|
return uuid.UUID{}, fmt.Errorf("invalid token")
|
||||||
}
|
}
|
||||||
|
|
||||||
exp, ok := claims["exp"].(float64)
|
exp, ok := claims["exp"].(float64)
|
||||||
if !ok || time.Now().Unix() > int64(exp) {
|
if !ok || time.Now().Unix() > int64(exp) {
|
||||||
return 0, fmt.Errorf("token expired")
|
return uuid.UUID{}, fmt.Errorf("token expired")
|
||||||
}
|
}
|
||||||
|
|
||||||
sub, ok := claims["sub"].(string)
|
sub, ok := claims["sub"].(string)
|
||||||
if !ok {
|
if !ok {
|
||||||
return 0, fmt.Errorf("invalid subject claim")
|
return uuid.UUID{}, fmt.Errorf("invalid subject claim")
|
||||||
}
|
}
|
||||||
|
|
||||||
id, err := strconv.ParseUint(sub, 10, 32)
|
id, err := uuid.Parse(sub)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, fmt.Errorf("invalid subject claim")
|
return uuid.UUID{}, fmt.Errorf("invalid subject claim")
|
||||||
}
|
}
|
||||||
|
|
||||||
return uint32(id), nil
|
return id, nil
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user