mirror of
https://github.com/Kyren223/eko.git
synced 2026-07-17 09:01:03 +00:00
Fixed everything on the server-side
This commit is contained in:
6
.github/workflows/cd.yml
vendored
6
.github/workflows/cd.yml
vendored
@@ -39,6 +39,12 @@ jobs:
|
||||
run: gosec ./...
|
||||
|
||||
# Starts deployment
|
||||
- name: Install goose
|
||||
run: go install github.com/pressly/goose/v3/cmd/goose@latest
|
||||
|
||||
- name: Convert migrations from timestmaps to indices
|
||||
run: goose fix -dir internal/server/api/migrations
|
||||
|
||||
- name: Build executable
|
||||
run: GOOS=linux GOARCH=amd64 go build -o ./eko-server ./cmd/server
|
||||
|
||||
|
||||
@@ -82,7 +82,7 @@ func (q *Queries) GetMemberById(ctx context.Context, arg GetMemberByIdParams) (M
|
||||
return i, err
|
||||
}
|
||||
|
||||
const getMembers = `-- name: GetMembers :many
|
||||
const getNetworkMembers = `-- name: GetNetworkMembers :many
|
||||
SELECT
|
||||
users.id, users.name, users.public_key, users.description, users.is_public_dm, users.is_deleted,
|
||||
members.user_id, members.network_id, members.joined_at, members.is_member, members.is_admin, members.is_muted, members.is_banned, members.ban_reason
|
||||
@@ -91,20 +91,20 @@ JOIN users ON users.id = members.user_id
|
||||
WHERE network_id = ? AND is_member = true
|
||||
`
|
||||
|
||||
type GetMembersRow struct {
|
||||
type GetNetworkMembersRow struct {
|
||||
User User
|
||||
Member Member
|
||||
}
|
||||
|
||||
func (q *Queries) GetMembers(ctx context.Context, networkID snowflake.ID) ([]GetMembersRow, error) {
|
||||
rows, err := q.db.QueryContext(ctx, getMembers, networkID)
|
||||
func (q *Queries) GetNetworkMembers(ctx context.Context, networkID snowflake.ID) ([]GetNetworkMembersRow, error) {
|
||||
rows, err := q.db.QueryContext(ctx, getNetworkMembers, networkID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
var items []GetMembersRow
|
||||
var items []GetNetworkMembersRow
|
||||
for rows.Next() {
|
||||
var i GetMembersRow
|
||||
var i GetNetworkMembersRow
|
||||
if err := rows.Scan(
|
||||
&i.User.ID,
|
||||
&i.User.Name,
|
||||
|
||||
@@ -67,3 +67,8 @@ type User struct {
|
||||
IsPublicDM bool
|
||||
IsDeleted bool
|
||||
}
|
||||
|
||||
type UserData struct {
|
||||
UserID snowflake.ID
|
||||
Data string
|
||||
}
|
||||
|
||||
@@ -89,3 +89,40 @@ func (q *Queries) GetUserByPublicKey(ctx context.Context, publicKey ed25519.Publ
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
|
||||
const getUserData = `-- name: GetUserData :one
|
||||
SELECT data FROM user_data
|
||||
WHERE user_id = ?
|
||||
`
|
||||
|
||||
func (q *Queries) GetUserData(ctx context.Context, userID snowflake.ID) (string, error) {
|
||||
row := q.db.QueryRowContext(ctx, getUserData, userID)
|
||||
var data string
|
||||
err := row.Scan(&data)
|
||||
return data, err
|
||||
}
|
||||
|
||||
const setUserData = `-- name: SetUserData :one
|
||||
INSERT INTO user_data (
|
||||
user_id, data
|
||||
) VALUES (
|
||||
?1, ?2
|
||||
)
|
||||
ON CONFLICT DO
|
||||
UPDATE SET
|
||||
user_id = EXCLUDED.user_id, data = EXCLUDED.data
|
||||
WHERE user_id = EXCLUDED.user_id
|
||||
RETURNING user_id, data
|
||||
`
|
||||
|
||||
type SetUserDataParams struct {
|
||||
UserID snowflake.ID
|
||||
Data string
|
||||
}
|
||||
|
||||
func (q *Queries) SetUserData(ctx context.Context, arg SetUserDataParams) (UserData, error) {
|
||||
row := q.db.QueryRowContext(ctx, setUserData, arg.UserID, arg.Data)
|
||||
var i UserData
|
||||
err := row.Scan(&i.UserID, &i.Data)
|
||||
return i, err
|
||||
}
|
||||
|
||||
@@ -1,329 +0,0 @@
|
||||
// Code generated by sqlc. DO NOT EDIT.
|
||||
// versions:
|
||||
// sqlc v1.27.0
|
||||
// source: users_networks.sql
|
||||
|
||||
package data
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strings"
|
||||
|
||||
"github.com/kyren223/eko/pkg/snowflake"
|
||||
)
|
||||
|
||||
const filterUsersInNetwork = `-- name: FilterUsersInNetwork :many
|
||||
SELECT user_id FROM users_networks
|
||||
WHERE network_id = ? AND user_id IN (/*SLICE:users*/?)
|
||||
`
|
||||
|
||||
type FilterUsersInNetworkParams struct {
|
||||
NetworkID snowflake.ID
|
||||
Users []snowflake.ID
|
||||
}
|
||||
|
||||
func (q *Queries) FilterUsersInNetwork(ctx context.Context, arg FilterUsersInNetworkParams) ([]snowflake.ID, error) {
|
||||
query := filterUsersInNetwork
|
||||
var queryParams []interface{}
|
||||
queryParams = append(queryParams, arg.NetworkID)
|
||||
if len(arg.Users) > 0 {
|
||||
for _, v := range arg.Users {
|
||||
queryParams = append(queryParams, v)
|
||||
}
|
||||
query = strings.Replace(query, "/*SLICE:users*/?", strings.Repeat(",?", len(arg.Users))[1:], 1)
|
||||
} else {
|
||||
query = strings.Replace(query, "/*SLICE:users*/?", "NULL", 1)
|
||||
}
|
||||
rows, err := q.db.QueryContext(ctx, query, queryParams...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
var items []snowflake.ID
|
||||
for rows.Next() {
|
||||
var user_id snowflake.ID
|
||||
if err := rows.Scan(&user_id); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
items = append(items, user_id)
|
||||
}
|
||||
if err := rows.Close(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return items, nil
|
||||
}
|
||||
|
||||
const getNetworkBannedUsers = `-- name: GetNetworkBannedUsers :many
|
||||
SELECT
|
||||
users.id, users.name, users.public_key, users.description, users.is_public_dm, users.is_deleted,
|
||||
users_networks.ban_reason
|
||||
FROM users_networks
|
||||
JOIN users ON users.id = users_networks.user_id
|
||||
WHERE users_networks.network_id = ?
|
||||
`
|
||||
|
||||
type GetNetworkBannedUsersRow struct {
|
||||
User User
|
||||
BanReason *string
|
||||
}
|
||||
|
||||
func (q *Queries) GetNetworkBannedUsers(ctx context.Context, networkID snowflake.ID) ([]GetNetworkBannedUsersRow, error) {
|
||||
rows, err := q.db.QueryContext(ctx, getNetworkBannedUsers, networkID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
var items []GetNetworkBannedUsersRow
|
||||
for rows.Next() {
|
||||
var i GetNetworkBannedUsersRow
|
||||
if err := rows.Scan(
|
||||
&i.User.ID,
|
||||
&i.User.Name,
|
||||
&i.User.PublicKey,
|
||||
&i.User.Description,
|
||||
&i.User.IsPublicDM,
|
||||
&i.User.IsDeleted,
|
||||
&i.BanReason,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
items = append(items, i)
|
||||
}
|
||||
if err := rows.Close(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return items, nil
|
||||
}
|
||||
|
||||
const getNetworkMemberById = `-- name: GetNetworkMemberById :one
|
||||
SELECT user_id, network_id, joined_at, is_member, is_admin, is_muted, is_banned, ban_reason, position
|
||||
FROM users_networks
|
||||
WHERE users_networks.network_id = ? AND users_networks.user_id = ?
|
||||
`
|
||||
|
||||
type GetNetworkMemberByIdParams struct {
|
||||
NetworkID snowflake.ID
|
||||
UserID snowflake.ID
|
||||
}
|
||||
|
||||
func (q *Queries) GetNetworkMemberById(ctx context.Context, arg GetNetworkMemberByIdParams) (UserNetwork, error) {
|
||||
row := q.db.QueryRowContext(ctx, getNetworkMemberById, arg.NetworkID, arg.UserID)
|
||||
var i UserNetwork
|
||||
err := row.Scan(
|
||||
&i.UserID,
|
||||
&i.NetworkID,
|
||||
&i.JoinedAt,
|
||||
&i.IsMember,
|
||||
&i.IsAdmin,
|
||||
&i.IsMuted,
|
||||
&i.IsBanned,
|
||||
&i.BanReason,
|
||||
&i.Position,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
|
||||
const getNetworkMembers = `-- name: GetNetworkMembers :many
|
||||
SELECT
|
||||
users.id, users.name, users.public_key, users.description, users.is_public_dm, users.is_deleted,
|
||||
users_networks.joined_at,
|
||||
users_networks.is_admin,
|
||||
users_networks.is_muted
|
||||
FROM users_networks
|
||||
JOIN users ON users.id = users_networks.user_id
|
||||
WHERE users_networks.network_id = ? AND is_member = true
|
||||
`
|
||||
|
||||
type GetNetworkMembersRow struct {
|
||||
User User
|
||||
JoinedAt string
|
||||
IsAdmin bool
|
||||
IsMuted bool
|
||||
}
|
||||
|
||||
func (q *Queries) GetNetworkMembers(ctx context.Context, networkID snowflake.ID) ([]GetNetworkMembersRow, error) {
|
||||
rows, err := q.db.QueryContext(ctx, getNetworkMembers, networkID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
var items []GetNetworkMembersRow
|
||||
for rows.Next() {
|
||||
var i GetNetworkMembersRow
|
||||
if err := rows.Scan(
|
||||
&i.User.ID,
|
||||
&i.User.Name,
|
||||
&i.User.PublicKey,
|
||||
&i.User.Description,
|
||||
&i.User.IsPublicDM,
|
||||
&i.User.IsDeleted,
|
||||
&i.JoinedAt,
|
||||
&i.IsAdmin,
|
||||
&i.IsMuted,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
items = append(items, i)
|
||||
}
|
||||
if err := rows.Close(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return items, nil
|
||||
}
|
||||
|
||||
const getUserNetwork = `-- name: GetUserNetwork :one
|
||||
SELECT user_id, network_id, joined_at, is_member, is_admin, is_muted, is_banned, ban_reason, position FROM users_networks
|
||||
WHERE user_id = ? AND network_id = ?
|
||||
`
|
||||
|
||||
type GetUserNetworkParams struct {
|
||||
UserID snowflake.ID
|
||||
NetworkID snowflake.ID
|
||||
}
|
||||
|
||||
func (q *Queries) GetUserNetwork(ctx context.Context, arg GetUserNetworkParams) (UserNetwork, error) {
|
||||
row := q.db.QueryRowContext(ctx, getUserNetwork, arg.UserID, arg.NetworkID)
|
||||
var i UserNetwork
|
||||
err := row.Scan(
|
||||
&i.UserID,
|
||||
&i.NetworkID,
|
||||
&i.JoinedAt,
|
||||
&i.IsMember,
|
||||
&i.IsAdmin,
|
||||
&i.IsMuted,
|
||||
&i.IsBanned,
|
||||
&i.BanReason,
|
||||
&i.Position,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
|
||||
const getUserNetworks = `-- name: GetUserNetworks :many
|
||||
SELECT networks.id, networks.owner_id, networks.name, networks.icon, networks.bg_hex_color, networks.fg_hex_color, networks.is_public, users_networks.position FROM networks
|
||||
JOIN users_networks ON networks.id = users_networks.network_id
|
||||
WHERE users_networks.user_id = ?
|
||||
ORDER BY users_networks.position
|
||||
`
|
||||
|
||||
type GetUserNetworksRow struct {
|
||||
Network Network
|
||||
Position *int64
|
||||
}
|
||||
|
||||
func (q *Queries) GetUserNetworks(ctx context.Context, userID snowflake.ID) ([]GetUserNetworksRow, error) {
|
||||
rows, err := q.db.QueryContext(ctx, getUserNetworks, userID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
var items []GetUserNetworksRow
|
||||
for rows.Next() {
|
||||
var i GetUserNetworksRow
|
||||
if err := rows.Scan(
|
||||
&i.Network.ID,
|
||||
&i.Network.OwnerID,
|
||||
&i.Network.Name,
|
||||
&i.Network.Icon,
|
||||
&i.Network.BgHexColor,
|
||||
&i.Network.FgHexColor,
|
||||
&i.Network.IsPublic,
|
||||
&i.Position,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
items = append(items, i)
|
||||
}
|
||||
if err := rows.Close(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return items, nil
|
||||
}
|
||||
|
||||
const setMember = `-- name: SetMember :one
|
||||
INSERT INTO users_networks (
|
||||
user_id, network_id,
|
||||
is_member, is_admin, is_muted,
|
||||
is_banned, ban_reason, position
|
||||
) VALUES (
|
||||
?1, ?2,
|
||||
?3, ?4, ?5,
|
||||
?6, ?7,
|
||||
CASE
|
||||
WHEN ?3 = false THEN NULL
|
||||
ELSE (SELECT COUNT(*) FROM users_networks WHERE user_id = ?1)
|
||||
END
|
||||
)
|
||||
ON CONFLICT DO
|
||||
UPDATE SET
|
||||
is_member = EXCLUDED.is_member, is_admin = EXCLUDED.is_admin, is_muted = EXCLUDED.is_muted,
|
||||
is_banned = EXCLUDED.is_banned, ban_reason = EXCLUDED.ban_reason, position = EXCLUDED.position
|
||||
WHERE user_id = EXCLUDED.user_id AND network_id = EXCLUDED.network_id
|
||||
RETURNING user_id, network_id, joined_at, is_member, is_admin, is_muted, is_banned, ban_reason, position
|
||||
`
|
||||
|
||||
type SetMemberParams struct {
|
||||
UserID snowflake.ID
|
||||
NetworkID snowflake.ID
|
||||
IsMember bool
|
||||
IsAdmin bool
|
||||
IsMuted bool
|
||||
IsBanned bool
|
||||
BanReason *string
|
||||
}
|
||||
|
||||
func (q *Queries) SetMember(ctx context.Context, arg SetMemberParams) (UserNetwork, error) {
|
||||
row := q.db.QueryRowContext(ctx, setMember,
|
||||
arg.UserID,
|
||||
arg.NetworkID,
|
||||
arg.IsMember,
|
||||
arg.IsAdmin,
|
||||
arg.IsMuted,
|
||||
arg.IsBanned,
|
||||
arg.BanReason,
|
||||
)
|
||||
var i UserNetwork
|
||||
err := row.Scan(
|
||||
&i.UserID,
|
||||
&i.NetworkID,
|
||||
&i.JoinedAt,
|
||||
&i.IsMember,
|
||||
&i.IsAdmin,
|
||||
&i.IsMuted,
|
||||
&i.IsBanned,
|
||||
&i.BanReason,
|
||||
&i.Position,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
|
||||
const swapUserNetworks = `-- name: SwapUserNetworks :exec
|
||||
UPDATE users_networks SET
|
||||
position = CASE
|
||||
WHEN position = ?1 THEN ?2
|
||||
WHEN position = ?2 THEN ?1
|
||||
END
|
||||
WHERE user_id = ?3 AND position IN (?1, ?2)
|
||||
`
|
||||
|
||||
type SwapUserNetworksParams struct {
|
||||
Pos1 *int64
|
||||
Pos2 *int64
|
||||
UserID snowflake.ID
|
||||
}
|
||||
|
||||
func (q *Queries) SwapUserNetworks(ctx context.Context, arg SwapUserNetworksParams) error {
|
||||
_, err := q.db.ExecContext(ctx, swapUserNetworks, arg.Pos1, arg.Pos2, arg.UserID)
|
||||
return err
|
||||
}
|
||||
@@ -5,6 +5,7 @@ const (
|
||||
DefaultFrequencyName = "main"
|
||||
DefaultFrequencyColor = "#FFFFFF"
|
||||
MaxFrequencyName = 32
|
||||
MaxUserDataBytes = 8192
|
||||
)
|
||||
|
||||
const (
|
||||
|
||||
@@ -52,16 +52,15 @@ type PacketType uint8
|
||||
const (
|
||||
PacketError PacketType = iota
|
||||
|
||||
PacketSetUserData
|
||||
PacketGetUserData
|
||||
|
||||
PacketCreateNetwork
|
||||
PacketUpdateNetwork
|
||||
PacketTransferNetwork
|
||||
PacketDeleteNetwork
|
||||
PacketSwapUserNetworks
|
||||
PacketNetworksInfo
|
||||
|
||||
PacketSetMember
|
||||
PacketMembersInfo
|
||||
|
||||
PacketCreateFrequency
|
||||
PacketUpdateFrequency
|
||||
PacketDeleteFrequency
|
||||
@@ -74,6 +73,9 @@ const (
|
||||
PacketRequestMessages
|
||||
PacketMessagesInfo
|
||||
|
||||
PacketSetMember
|
||||
PacketMembersInfo
|
||||
|
||||
PacketMax
|
||||
)
|
||||
|
||||
@@ -189,6 +191,11 @@ func (p Packet) DecodedPayload() (Payload, error) {
|
||||
case PacketError:
|
||||
payload = &Error{}
|
||||
|
||||
case PacketSetUserData:
|
||||
payload = &SetUserData{}
|
||||
case PacketGetUserData:
|
||||
payload = &GetUserData{}
|
||||
|
||||
case PacketCreateNetwork:
|
||||
payload = &CreateNetwork{}
|
||||
case PacketUpdateNetwork:
|
||||
@@ -197,10 +204,6 @@ func (p Packet) DecodedPayload() (Payload, error) {
|
||||
payload = &TransferNetwork{}
|
||||
case PacketDeleteNetwork:
|
||||
payload = &DeleteNetwork{}
|
||||
case PacketSwapUserNetworks:
|
||||
payload = &SwapUserNetworks{}
|
||||
case PacketSetMember:
|
||||
payload = &SetMember{}
|
||||
case PacketNetworksInfo:
|
||||
payload = &NetworksInfo{}
|
||||
|
||||
@@ -226,6 +229,11 @@ func (p Packet) DecodedPayload() (Payload, error) {
|
||||
case PacketMessagesInfo:
|
||||
payload = &MessagesInfo{}
|
||||
|
||||
case PacketSetMember:
|
||||
payload = &SetMember{}
|
||||
case PacketMembersInfo:
|
||||
payload = &MembersInfo{}
|
||||
|
||||
default:
|
||||
assert.Never("unexpected packet.PacketType", "type", p.Type())
|
||||
}
|
||||
|
||||
@@ -52,15 +52,6 @@ func (m *DeleteNetwork) Type() PacketType {
|
||||
return PacketDeleteNetwork
|
||||
}
|
||||
|
||||
type SwapUserNetworks struct {
|
||||
Pos1 int
|
||||
Pos2 int
|
||||
}
|
||||
|
||||
func (m *SwapUserNetworks) Type() PacketType {
|
||||
return PacketSwapUserNetworks
|
||||
}
|
||||
|
||||
type SetMember struct {
|
||||
Member *bool
|
||||
Admin *bool
|
||||
@@ -78,8 +69,8 @@ func (m *SetMember) Type() PacketType {
|
||||
type FullNetwork struct {
|
||||
data.Network
|
||||
Frequencies []data.Frequency
|
||||
Members []data.GetNetworkMembersRow
|
||||
Position int
|
||||
Members []data.Member
|
||||
Users []data.User
|
||||
}
|
||||
|
||||
type NetworksInfo struct {
|
||||
@@ -189,10 +180,27 @@ func (m *MessagesInfo) Type() PacketType {
|
||||
|
||||
type MembersInfo struct {
|
||||
RemovedMembers []snowflake.ID
|
||||
Members []data.GetNetworkMembersRow
|
||||
Members []data.Member
|
||||
Users []data.User
|
||||
Network snowflake.ID
|
||||
}
|
||||
|
||||
func (m *MembersInfo) Type() PacketType {
|
||||
return PacketMessagesInfo
|
||||
}
|
||||
|
||||
type SetUserData struct{
|
||||
Data string
|
||||
}
|
||||
|
||||
func (m *SetUserData) Type() PacketType {
|
||||
return PacketSetUserData
|
||||
}
|
||||
|
||||
type GetUserData struct{
|
||||
Data string
|
||||
}
|
||||
|
||||
func (m *GetUserData) Type() PacketType {
|
||||
return PacketGetUserData
|
||||
}
|
||||
|
||||
@@ -43,7 +43,10 @@ func SendMessage(ctx context.Context, sess *session.Session, request *packet.Sen
|
||||
return &ErrInternalError
|
||||
}
|
||||
|
||||
return &packet.MessagesInfo{Messages: []data.Message{message}}
|
||||
return &packet.MessagesInfo{
|
||||
Messages: []data.Message{message},
|
||||
RemovedMessages: nil,
|
||||
}
|
||||
}
|
||||
|
||||
func RequestMessages(ctx context.Context, sess *session.Session, request *packet.RequestMessages) packet.Payload {
|
||||
@@ -59,14 +62,27 @@ func RequestMessages(ctx context.Context, sess *session.Session, request *packet
|
||||
User2: request.ReceiverID,
|
||||
})
|
||||
} else {
|
||||
return &packet.Error{Error: "either receiver id or frequency id must exist"}
|
||||
return &packet.Error{Error: "either receiver id or frequency id must be specified"}
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
log.Println("database error when retrieving messages:", err)
|
||||
return &packet.Error{Error: "internal server error"}
|
||||
}
|
||||
return &packet.MessagesInfo{Messages: messages}
|
||||
|
||||
// TODO:
|
||||
// FIXME: If an attacker knows the frequency ID of a private frequency
|
||||
// Such in a case where they used to have access to it but no longer do
|
||||
// Then it's possible to view all messages including current ones
|
||||
// Add a check to make sure the user is inside the network of this
|
||||
// Frequency, and even if it is, if the frequency is "no access" then
|
||||
// an admin-check needs to happen, and if he's not an admin it needs to be
|
||||
// denied
|
||||
|
||||
return &packet.MessagesInfo{
|
||||
Messages: messages,
|
||||
RemovedMessages: nil,
|
||||
}
|
||||
}
|
||||
|
||||
func CreateOrGetUser(ctx context.Context, node *snowflake.Node, pubKey ed25519.PublicKey) (data.User, error) {
|
||||
@@ -107,7 +123,7 @@ func CreateNetwork(ctx context.Context, sess *session.Session, request *packet.C
|
||||
log.Println("database error:", err)
|
||||
return &ErrInternalError
|
||||
}
|
||||
defer tx.Rollback() //nolint
|
||||
defer tx.Rollback()
|
||||
|
||||
queries := data.New(db)
|
||||
qtx := queries.WithTx(tx)
|
||||
@@ -138,7 +154,7 @@ func CreateNetwork(ctx context.Context, sess *session.Session, request *packet.C
|
||||
return &ErrInternalError
|
||||
}
|
||||
|
||||
networkUser, err := qtx.SetMember(ctx, data.SetMemberParams{
|
||||
member, err := qtx.SetMember(ctx, data.SetMemberParams{
|
||||
UserID: network.OwnerID,
|
||||
NetworkID: network.ID,
|
||||
IsMember: true,
|
||||
@@ -167,13 +183,8 @@ func CreateNetwork(ctx context.Context, sess *session.Session, request *packet.C
|
||||
fullNetwork := packet.FullNetwork{
|
||||
Network: network,
|
||||
Frequencies: []data.Frequency{frequency},
|
||||
Members: []data.GetNetworkMembersRow{{
|
||||
JoinedAt: networkUser.JoinedAt,
|
||||
User: user,
|
||||
IsAdmin: networkUser.IsAdmin,
|
||||
IsMuted: networkUser.IsMuted,
|
||||
}},
|
||||
Position: int(*networkUser.Position),
|
||||
Members: []data.Member{member},
|
||||
Users: []data.User{user},
|
||||
}
|
||||
return &packet.NetworksInfo{
|
||||
Networks: []packet.FullNetwork{fullNetwork},
|
||||
@@ -189,40 +200,33 @@ func GetNetworksInfo(ctx context.Context, sess *session.Session) (packet.Payload
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer tx.Rollback() //nolint
|
||||
defer tx.Rollback()
|
||||
|
||||
queries := data.New(db)
|
||||
qtx := queries.WithTx(tx)
|
||||
|
||||
networks, err := qtx.GetUserNetworks(ctx, sess.ID())
|
||||
networks, err := qtx.GetNetworksOfUser(ctx, sess.ID())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, userNetwork := range networks {
|
||||
network := userNetwork.Network
|
||||
|
||||
// User was in this network but is no longer there (left/kicked/banned)
|
||||
if userNetwork.Position == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
position := int(*userNetwork.Position)
|
||||
for _, network := range networks {
|
||||
frequencies, err := qtx.GetNetworkFrequencies(ctx, network.ID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
members, err := qtx.GetNetworkMembers(ctx, network.ID)
|
||||
membersAndUsers, err := qtx.GetNetworkMembers(ctx, network.ID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
members, users := SplitMembersAndUsers(membersAndUsers)
|
||||
|
||||
fullNetworks = append(fullNetworks, packet.FullNetwork{
|
||||
Network: network,
|
||||
Frequencies: frequencies,
|
||||
Members: members,
|
||||
Position: position,
|
||||
Users: users,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -238,22 +242,6 @@ func GetNetworksInfo(ctx context.Context, sess *session.Session) (packet.Payload
|
||||
}, nil
|
||||
}
|
||||
|
||||
func SwapUserNetworks(ctx context.Context, sess *session.Session, request *packet.SwapUserNetworks) packet.Payload {
|
||||
queries := data.New(db)
|
||||
pos1, pos2 := int64(request.Pos1), int64(request.Pos2)
|
||||
err := queries.SwapUserNetworks(ctx, data.SwapUserNetworksParams{
|
||||
Pos1: &pos1,
|
||||
Pos2: &pos2,
|
||||
UserID: sess.ID(),
|
||||
})
|
||||
if err != nil {
|
||||
log.Println("database error:", err)
|
||||
return &ErrInternalError
|
||||
}
|
||||
|
||||
return request
|
||||
}
|
||||
|
||||
func CreateFrequency(ctx context.Context, sess *session.Session, request *packet.CreateFrequency) packet.Payload {
|
||||
queries := data.New(db)
|
||||
|
||||
@@ -425,7 +413,7 @@ func SetMember(ctx context.Context, sess *session.Session, request *packet.SetMe
|
||||
return &ErrInternalError
|
||||
}
|
||||
|
||||
member, err := queries.GetNetworkMemberById(ctx, data.GetNetworkMemberByIdParams{
|
||||
member, err := queries.GetMemberById(ctx, data.GetMemberByIdParams{
|
||||
NetworkID: request.Network,
|
||||
UserID: request.User,
|
||||
})
|
||||
@@ -454,13 +442,9 @@ func SetMember(ctx context.Context, sess *session.Session, request *packet.SetMe
|
||||
|
||||
NetworkPropagate(ctx, sess, request.Network, &packet.MembersInfo{
|
||||
RemovedMembers: nil,
|
||||
Members: []data.GetNetworkMembersRow{{
|
||||
User: user,
|
||||
JoinedAt: newMember.JoinedAt,
|
||||
IsAdmin: newMember.IsAdmin,
|
||||
IsMuted: newMember.IsMuted,
|
||||
}},
|
||||
Network: request.Network,
|
||||
Members: []data.Member{newMember},
|
||||
Users: []data.User{user},
|
||||
Network: request.Network,
|
||||
})
|
||||
|
||||
frequencies, err := queries.GetNetworkFrequencies(ctx, network.ID)
|
||||
@@ -469,18 +453,19 @@ func SetMember(ctx context.Context, sess *session.Session, request *packet.SetMe
|
||||
return &ErrInternalError
|
||||
}
|
||||
|
||||
members, err := queries.GetNetworkMembers(ctx, network.ID)
|
||||
membersAndUsers, err := queries.GetNetworkMembers(ctx, network.ID)
|
||||
if err != nil {
|
||||
log.Println("database error 5:", err)
|
||||
return &ErrInternalError
|
||||
}
|
||||
members, users := SplitMembersAndUsers(membersAndUsers)
|
||||
|
||||
return &packet.NetworksInfo{
|
||||
Networks: []packet.FullNetwork{{
|
||||
Network: network,
|
||||
Frequencies: frequencies,
|
||||
Members: members,
|
||||
Position: int(*newMember.Position),
|
||||
Users: users,
|
||||
}},
|
||||
RemovedNetworks: nil,
|
||||
Set: false,
|
||||
@@ -553,6 +538,7 @@ func SetMember(ctx context.Context, sess *session.Session, request *packet.SetMe
|
||||
return NetworkPropagate(ctx, sess, request.Network, &packet.MembersInfo{
|
||||
RemovedMembers: []snowflake.ID{newMember.UserID},
|
||||
Members: nil,
|
||||
Users: nil,
|
||||
Network: request.Network,
|
||||
})
|
||||
}
|
||||
@@ -565,13 +551,9 @@ func SetMember(ctx context.Context, sess *session.Session, request *packet.SetMe
|
||||
|
||||
payload := NetworkPropagate(ctx, sess, request.Network, &packet.MembersInfo{
|
||||
RemovedMembers: nil,
|
||||
Members: []data.GetNetworkMembersRow{{
|
||||
User: user,
|
||||
JoinedAt: newMember.JoinedAt,
|
||||
IsAdmin: newMember.IsAdmin,
|
||||
IsMuted: newMember.IsMuted,
|
||||
}},
|
||||
Network: request.Network,
|
||||
Members: []data.Member{newMember},
|
||||
Users: []data.User{user},
|
||||
Network: request.Network,
|
||||
})
|
||||
|
||||
// Joined
|
||||
@@ -582,18 +564,19 @@ func SetMember(ctx context.Context, sess *session.Session, request *packet.SetMe
|
||||
return &ErrInternalError
|
||||
}
|
||||
|
||||
members, err := queries.GetNetworkMembers(ctx, network.ID)
|
||||
membersAndUsers, err := queries.GetNetworkMembers(ctx, network.ID)
|
||||
if err != nil {
|
||||
log.Println("database error 11:", err)
|
||||
return &ErrInternalError
|
||||
}
|
||||
members, users := SplitMembersAndUsers(membersAndUsers)
|
||||
|
||||
return &packet.NetworksInfo{
|
||||
Networks: []packet.FullNetwork{{
|
||||
Network: network,
|
||||
Frequencies: frequencies,
|
||||
Members: members,
|
||||
Position: int(*newMember.Position),
|
||||
Users: users,
|
||||
}},
|
||||
RemovedNetworks: nil,
|
||||
Set: false,
|
||||
@@ -603,3 +586,41 @@ func SetMember(ctx context.Context, sess *session.Session, request *packet.SetMe
|
||||
// Normal case, was already in the server
|
||||
return payload
|
||||
}
|
||||
|
||||
func SetUserData(ctx context.Context, sess *session.Session, request *packet.SetUserData) packet.Payload {
|
||||
queries := data.New(db)
|
||||
|
||||
if len(request.Data) > packet.MaxUserDataBytes {
|
||||
return &packet.Error{
|
||||
Error: "data bytes may not exceed " +
|
||||
strconv.FormatInt(packet.MaxUserDataBytes, 10) + " bytes",
|
||||
}
|
||||
}
|
||||
|
||||
_, err := queries.SetUserData(ctx, data.SetUserDataParams{
|
||||
UserID: sess.ID(),
|
||||
Data: request.Data,
|
||||
})
|
||||
if err != nil {
|
||||
log.Println("database error:", err)
|
||||
return &ErrInternalError
|
||||
}
|
||||
|
||||
return &packet.GetUserData{
|
||||
Data: request.Data,
|
||||
}
|
||||
}
|
||||
|
||||
func GetUserData(ctx context.Context, sess *session.Session, request *packet.GetUserData) packet.Payload {
|
||||
queries := data.New(db)
|
||||
|
||||
data, err := queries.GetUserData(ctx, sess.ID())
|
||||
if err != nil {
|
||||
log.Println("database error:", err)
|
||||
return &ErrInternalError
|
||||
}
|
||||
|
||||
return &packet.GetUserData{
|
||||
Data: data,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,7 +46,6 @@ func ConnectToDatabase() {
|
||||
db.Close()
|
||||
log.Fatalln("error running up migrations:", err)
|
||||
}
|
||||
log.Println("database up migrations applied successfully")
|
||||
|
||||
log.Println("database connection ready to be used")
|
||||
}
|
||||
|
||||
@@ -33,9 +33,9 @@ func isValidHexColor(color string) (bool, string) {
|
||||
}
|
||||
|
||||
func IsNetworkAdmin(ctx context.Context, queries *data.Queries, userId, networkId snowflake.ID) (bool, error) {
|
||||
userNetwork, err := queries.GetUserNetwork(ctx, data.GetUserNetworkParams{
|
||||
UserID: userId,
|
||||
userNetwork, err := queries.GetMemberById(ctx, data.GetMemberByIdParams{
|
||||
NetworkID: networkId,
|
||||
UserID: userId,
|
||||
})
|
||||
if err != nil {
|
||||
return false, err
|
||||
@@ -87,3 +87,14 @@ func NetworkPropagate(
|
||||
|
||||
return payload
|
||||
}
|
||||
|
||||
func SplitMembersAndUsers(membersAndUsers []data.GetNetworkMembersRow) ([]data.Member, []data.User) {
|
||||
members := make([]data.Member, 0, len(membersAndUsers))
|
||||
users := make([]data.User, 0, len(membersAndUsers))
|
||||
for _, memberAndUser := range membersAndUsers {
|
||||
members = append(members, memberAndUser.Member)
|
||||
users = append(users, memberAndUser.User)
|
||||
}
|
||||
|
||||
return members, users
|
||||
}
|
||||
|
||||
@@ -8,5 +8,11 @@ CREATE TABLE IF NOT EXISTS users (
|
||||
is_deleted BOOLEAN NOT NULL CHECK (is_deleted IN (false, true)) DEFAULT false
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS user_data (
|
||||
user_id INTEGER PRIMARY KEY REFERENCES users(id),
|
||||
data TEXT NOT NULL
|
||||
);
|
||||
|
||||
-- +goose Down
|
||||
DROP TABLE IF EXISTS users;
|
||||
DROP TABLE IF EXISTS user_data;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
-- +goose Up
|
||||
-- +goose StatementBegin
|
||||
CREATE TRIGGER on_user_delete
|
||||
CREATE TRIGGER IF NOT EXISTS on_user_delete
|
||||
AFTER UPDATE OF is_deleted ON users
|
||||
WHEN NEW.is_deleted = true
|
||||
BEGIN
|
||||
|
||||
@@ -332,14 +332,16 @@ func processRequest(ctx context.Context, sess *session.Session, request packet.P
|
||||
// Potentially even separate time for code vs DB operations
|
||||
var response packet.Payload
|
||||
switch request := request.(type) {
|
||||
|
||||
case *packet.SetUserData:
|
||||
response = timeout(5*time.Millisecond, api.SetUserData, ctx, sess, request)
|
||||
case *packet.GetUserData:
|
||||
response = timeout(5*time.Millisecond, api.GetUserData, ctx, sess, request)
|
||||
|
||||
case *packet.CreateNetwork:
|
||||
response = timeout(10*time.Millisecond, api.CreateNetwork, ctx, sess, request)
|
||||
case *packet.DeleteNetwork:
|
||||
response = timeout(500*time.Millisecond, api.DeleteNetwork, ctx, sess, request)
|
||||
case *packet.SwapUserNetworks:
|
||||
response = timeout(5*time.Millisecond, api.SwapUserNetworks, ctx, sess, request)
|
||||
case *packet.SetMember:
|
||||
response = timeout(50*time.Millisecond, api.SetMember, ctx, sess, request)
|
||||
|
||||
case *packet.CreateFrequency:
|
||||
response = timeout(5*time.Millisecond, api.CreateFrequency, ctx, sess, request)
|
||||
@@ -353,6 +355,9 @@ func processRequest(ctx context.Context, sess *session.Session, request packet.P
|
||||
case *packet.RequestMessages:
|
||||
response = timeout(50*time.Millisecond, api.RequestMessages, ctx, sess, request)
|
||||
|
||||
case *packet.SetMember:
|
||||
response = timeout(50*time.Millisecond, api.SetMember, ctx, sess, request)
|
||||
|
||||
default:
|
||||
response = &packet.Error{Error: "use of disallowed packet type for request"}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
-- name: GetMembers :many
|
||||
-- name: GetNetworkMembers :many
|
||||
SELECT
|
||||
sqlc.embed(users),
|
||||
sqlc.embed(members)
|
||||
|
||||
@@ -18,3 +18,19 @@ RETURNING *;
|
||||
UPDATE users SET
|
||||
is_deleted = true
|
||||
WHERE id = ? AND is_deleted = false;
|
||||
|
||||
-- name: SetUserData :one
|
||||
INSERT INTO user_data (
|
||||
user_id, data
|
||||
) VALUES (
|
||||
@user_id, @data
|
||||
)
|
||||
ON CONFLICT DO
|
||||
UPDATE SET
|
||||
user_id = EXCLUDED.user_id, data = EXCLUDED.data
|
||||
WHERE user_id = EXCLUDED.user_id
|
||||
RETURNING *;
|
||||
|
||||
-- name: GetUserData :one
|
||||
SELECT data FROM user_data
|
||||
WHERE user_id = ?;
|
||||
|
||||
Reference in New Issue
Block a user