summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKyren223 <Kyren223@proton.me>2024-11-27 07:47:30 +0200
committerKyren223 <Kyren223@proton.me>2024-11-27 07:47:30 +0200
commit8ed2527a8879e01f4f3f741feebaf86fee2bf18d (patch)
treea8b426c2f78745c3e4c475b5baf14c95cd27db17
parent195a2912b7c67393b806dedb058590d8bc201186 (diff)
Started working on refactoring packet types and some changes to the SQL
schema
-rw-r--r--internal/client/api/api.go36
-rw-r--r--internal/data/models.go12
-rw-r--r--internal/data/networks.sql.go19
-rw-r--r--internal/data/users.sql.go2
-rw-r--r--internal/packet/messages.go67
-rw-r--r--internal/packet/packet.go101
-rw-r--r--internal/packet/types.go162
-rw-r--r--migrations/20241026174345_init.sql31
-rw-r--r--query/networks.sql11
9 files changed, 282 insertions, 159 deletions
diff --git a/internal/client/api/api.go b/internal/client/api/api.go
index d91de46..cfc4ce9 100644
--- a/internal/client/api/api.go
+++ b/internal/client/api/api.go
@@ -92,3 +92,39 @@ func GetUserById(id snowflake.ID) tea.Cmd {
}
}
+func CreateServer(
+ name string,
+ icon string,
+ bgHexColor string,
+ fgHexColor string,
+ isPublic bool,
+) tea.Cmd {
+ return func() tea.Msg {
+ requestName := "CreateServer"
+ log.Println("request", requestName, "sent")
+ request := packet.CreateNetwork{
+ Name: name,
+ Icon: icon,
+ BgHexColor: bgHexColor,
+ FgHexColor: fgHexColor,
+ IsPublic: isPublic,
+ }
+ response, ok := <-gateway.Send(&request)
+ if !ok {
+ return fmt.Errorf("request %s timeout", requestName)
+ }
+ log.Println("request", requestName, "received response")
+
+ switch response := response.(type) {
+ case *packet.ErrorMessage:
+ return errors.New(response.Error)
+ case *packet.Users:
+ if len(response.Users) == 0 {
+ return fmt.Errorf("requested user id %v not found", id)
+ }
+ assert.Assert(len(response.Users) == 1, "server must return only one user with the matching id")
+ return UserProfileUpdate(response.Users[0])
+ }
+ return fmt.Errorf("received invalid response from server: %v", response.Type())
+ }
+}
diff --git a/internal/data/models.go b/internal/data/models.go
index 4bfb7a5..e6fac50 100644
--- a/internal/data/models.go
+++ b/internal/data/models.go
@@ -37,18 +37,11 @@ type Network struct {
IsPublic bool
}
-type NetworkBannedUser struct {
- NetworkID snowflake.ID
- BannedUserID snowflake.ID
- BannedAt string
- Reason *string
-}
-
type User struct {
ID snowflake.ID
Name string
PublicKey ed25519.PublicKey
- Description *string
+ Description string
IsPublicDM bool
IsDeleted bool
}
@@ -68,6 +61,9 @@ type UsersNetwork struct {
UserID snowflake.ID
NetworkID snowflake.ID
JoinedAt string
+ IsMember bool
IsAdmin bool
IsMuted bool
+ IsBanned bool
+ BanReason *string
}
diff --git a/internal/data/networks.sql.go b/internal/data/networks.sql.go
index d690b7b..8064fa9 100644
--- a/internal/data/networks.sql.go
+++ b/internal/data/networks.sql.go
@@ -67,17 +67,15 @@ func (q *Queries) DeleteNetwork(ctx context.Context, id snowflake.ID) error {
const getBannedUsersInNetwork = `-- name: GetBannedUsersInNetwork :many
SELECT
users.id, users.name, users.public_key, users.description, users.is_public_dm, users.is_deleted,
- network_banned_users.banned_at,
- network_banned_users.reason
-FROM network_banned_users
-JOIN users ON users.id = network_banned_users.banned_user_id
-WHERE network_banned_users.network_id = ?
+ users_networks.ban_reason
+FROM users_networks
+JOIN users ON users.id = users_networks.user_id
+WHERE users_networks.network_id = ?
`
type GetBannedUsersInNetworkRow struct {
- User User
- BannedAt string
- Reason *string
+ User User
+ BanReason *string
}
func (q *Queries) GetBannedUsersInNetwork(ctx context.Context, networkID snowflake.ID) ([]GetBannedUsersInNetworkRow, error) {
@@ -96,8 +94,7 @@ func (q *Queries) GetBannedUsersInNetwork(ctx context.Context, networkID snowfla
&i.User.Description,
&i.User.IsPublicDM,
&i.User.IsDeleted,
- &i.BannedAt,
- &i.Reason,
+ &i.BanReason,
); err != nil {
return nil, err
}
@@ -176,7 +173,7 @@ SELECT
users_networks.is_muted
FROM users_networks
JOIN users ON users.id = users_networks.user_id
-WHERE users_networks.network_id = ?
+WHERE users_networks.network_id = ? AND is_member = true
`
type GetUsersInNetworkRow struct {
diff --git a/internal/data/users.sql.go b/internal/data/users.sql.go
index 4411a80..33eab3f 100644
--- a/internal/data/users.sql.go
+++ b/internal/data/users.sql.go
@@ -117,7 +117,7 @@ RETURNING id, name, public_key, description, is_public_dm, is_deleted
`
type SetUserDescriptionParams struct {
- Description *string
+ Description string
ID snowflake.ID
}
diff --git a/internal/packet/messages.go b/internal/packet/messages.go
deleted file mode 100644
index 58d12e9..0000000
--- a/internal/packet/messages.go
+++ /dev/null
@@ -1,67 +0,0 @@
-package packet
-
-import (
- "github.com/kyren223/eko/internal/data"
- "github.com/kyren223/eko/pkg/snowflake"
-)
-
-type ErrorMessage struct {
- Error string `msgpack:"error"`
-}
-
-func (m *ErrorMessage) Type() PacketType {
- return PacketError
-}
-
-type SendMessage struct {
- ReceiverID *snowflake.ID
- FrequencyID *snowflake.ID
- Content string
-}
-
-func (m *SendMessage) Type() PacketType {
- return PacketSendMessage
-}
-
-type PushedMessages struct {
- Messages []data.Message
-}
-
-func (m *PushedMessages) Type() PacketType {
- return PacketPushedMessages
-}
-
-type Messages struct {
- Messages []data.Message
-}
-
-func (m *Messages) Type() PacketType {
- return PacketMessages
-}
-
-type GetMessagesRange struct {
- FrequencyID *snowflake.ID
- ReceiverID *snowflake.ID
- From *int64
- To *int64
-}
-
-func (m *GetMessagesRange) Type() PacketType {
- return PacketGetMessageRange
-}
-
-type GetUserByID struct {
- UserID snowflake.ID
-}
-
-func (m *GetUserByID) Type() PacketType {
- return PacketGetUserById
-}
-
-type Users struct {
- Users []data.User
-}
-
-func (m *Users) Type() PacketType {
- return PacketUsers
-}
diff --git a/internal/packet/packet.go b/internal/packet/packet.go
index 58e83b4..8eb1a86 100644
--- a/internal/packet/packet.go
+++ b/internal/packet/packet.go
@@ -51,47 +51,34 @@ type PacketType uint8
const (
PacketError PacketType = iota
+
+ PacketCreateNetwork
+ PacketUpdateNetwork
+ PacketTransferNetwork
+ PacketDeleteNetwork
+ PacketSetNetworkUser
+ PacketNetworksInfo
+
+ PacketCreateFrequency
+ PacketUpdateFrequency
+ PacketDeleteFrequency
+ PacketSwapFrequencies
+
PacketSendMessage
- PacketPushedMessages
- PacketGetMessageRange
- PacketMessages
- PacketGetUserById
- PacketUsers
+ PacketEditMessage
+ PacketDeleteMessage
+ PacketRequestMessages
+ PacketMessagesInfo
+
+ PacketMax
)
-func (t PacketType) String() string {
- switch t {
- case PacketError:
- return "PacketError"
- case PacketSendMessage:
- return "PacketSendMessage"
- case PacketPushedMessages:
- return "PacketPushedMessages"
- case PacketGetMessageRange:
- return "PacketGetMessageRange"
- case PacketMessages:
- return "PacketMessages"
- case PacketGetUserById:
- return "PacketGetUserById"
- case PacketUsers:
- return "PacketUsers"
- default:
- return fmt.Sprintf("PacketInvalidType(%v)", byte(t))
- }
+func Init() {
+ assert.Assert(PacketMax <= 64, "packet types exceeded allowed limit of 64 types")
}
func (e PacketType) IsSupported() bool {
- return e <= PacketUsers
-}
-
-// True for all packets that a server may push passively to the client.
-func (e PacketType) IsPush() bool {
- switch e {
- case PacketPushedMessages:
- return true
- default:
- return false
- }
+ return e < PacketMax
}
const (
@@ -166,7 +153,7 @@ func (p Packet) Payload() []byte {
}
func (p Packet) String() string {
- return fmt.Sprintf("Packet(v%v %v %v [%v bytes...])", p.Version(), p.Encoding().String(), p.Type().String(), p.PayloadLength())
+ return fmt.Sprintf("Packet(v%v t%v %v [%v bytes...])", p.Version(), p.Encoding().String(), p.Type(), p.PayloadLength())
}
func (p Packet) Into(writer io.Writer) (int, error) {
@@ -196,21 +183,39 @@ func (p Packet) DecodedPayload() (Payload, error) {
var payload Payload
switch p.Type() {
case PacketError:
- payload = &ErrorMessage{}
- case PacketPushedMessages:
- payload = &PushedMessages{}
+ payload = &Error{}
+ case PacketCreateFrequency:
+ payload = &CreateFrequency{}
+ case PacketCreateNetwork:
+ payload = &CreateNetwork{}
+ case PacketDeleteFrequency:
+ payload = &DeleteFrequency{}
+ case PacketDeleteMessage:
+ payload = &DeleteMessage{}
+ case PacketDeleteNetwork:
+ payload = &DeleteNetwork{}
+ case PacketEditMessage:
+ payload = &EditMessage{}
+ case PacketMessagesInfo:
+ payload = &MessagesInfo{}
+ case PacketNetworksInfo:
+ payload = &NetworksInfo{}
+ case PacketRequestMessages:
+ payload = &RequestMessages{}
case PacketSendMessage:
payload = &SendMessage{}
- case PacketGetMessageRange:
- payload = &GetMessagesRange{}
- case PacketMessages:
- payload = &Messages{}
- case PacketGetUserById:
- payload = &GetUserByID{}
- case PacketUsers:
- payload = &Users{}
+ case PacketSetNetworkUser:
+ payload = &SetNetworkUser{}
+ case PacketSwapFrequencies:
+ payload = &SwapFrequencies{}
+ case PacketTransferNetwork:
+ payload = &TransferNetwork{}
+ case PacketUpdateFrequency:
+ payload = &UpdateFrequency{}
+ case PacketUpdateNetwork:
+ payload = &UpdateNetwork{}
default:
- assert.Never("packet type of a packet struct must always be valid")
+ assert.Never("unexpected packet.PacketType", "type", p.Type())
}
err := p.DecodePayloadInto(payload)
return payload, err
diff --git a/internal/packet/types.go b/internal/packet/types.go
new file mode 100644
index 0000000..405513e
--- /dev/null
+++ b/internal/packet/types.go
@@ -0,0 +1,162 @@
+package packet
+
+import (
+ "github.com/kyren223/eko/internal/data"
+ "github.com/kyren223/eko/pkg/snowflake"
+)
+
+type Error struct {
+ Error string
+}
+
+func (m *Error) Type() PacketType {
+ return PacketError
+}
+
+type CreateNetwork struct {
+ Name string
+ Icon string
+ BgHexColor string
+ FgHexColor string
+ IsPublic bool
+}
+
+func (m *CreateNetwork) Type() PacketType {
+ return PacketCreateNetwork
+}
+
+type UpdateNetwork struct {
+ Network snowflake.ID
+ CreateNetwork
+}
+
+func (m *UpdateNetwork) Type() PacketType {
+ return PacketUpdateNetwork
+}
+
+type TransferNetwork struct {
+ Network snowflake.ID
+ User snowflake.ID
+}
+
+func (m *TransferNetwork) Type() PacketType {
+ return PacketTransferNetwork
+}
+
+type DeleteNetwork struct {
+ Network snowflake.ID
+}
+
+func (m *DeleteNetwork) Type() PacketType {
+ return PacketDeleteNetwork
+}
+
+type SetNetworkUser struct {
+ Network snowflake.ID
+ User snowflake.ID
+ Member *bool
+ Admin *bool
+ Muted *bool
+ Banned *bool
+ BanReason *string
+}
+
+func (m *SetNetworkUser) Type() PacketType {
+ return PacketSetNetworkUser
+}
+
+type NetworksInfo struct {
+ Networks []struct {
+ Network data.Network
+ Frequencies []data.Frequency
+ Members []data.User
+ }
+}
+
+func (m *NetworksInfo) Type() PacketType {
+ return PacketNetworksInfo
+}
+
+type CreateFrequency struct {
+ Network snowflake.ID
+ Name string
+ HexColor string
+ Perms int
+}
+
+func (m *CreateFrequency) Type() PacketType {
+ return PacketCreateFrequency
+}
+
+type UpdateFrequency struct {
+ Frequency snowflake.ID
+ Name string
+ HexColor string
+ Perms byte
+}
+
+func (m *UpdateFrequency) Type() PacketType {
+ return PacketUpdateFrequency
+}
+
+type DeleteFrequency struct {
+ Frequency snowflake.ID
+}
+
+func (m *DeleteFrequency) Type() PacketType {
+ return PacketDeleteFrequency
+}
+
+type SwapFrequencies struct {
+ Network snowflake.ID
+ Pos1 int
+ Pos2 int
+}
+
+func (m *SwapFrequencies) Type() PacketType {
+ return PacketSwapFrequencies
+}
+
+type SendMessage struct {
+ ReceiverID *snowflake.ID
+ FrequencyID *snowflake.ID
+ Content string
+}
+
+func (m *SendMessage) Type() PacketType {
+ return PacketSendMessage
+}
+
+type EditMessage struct {
+ Message snowflake.ID
+ Content string
+}
+
+func (m *EditMessage) Type() PacketType {
+ return PacketEditMessage
+}
+
+type DeleteMessage struct {
+ Message snowflake.ID
+}
+
+func (m *DeleteMessage) Type() PacketType {
+ return PacketDeleteMessage
+}
+
+type RequestMessages struct {
+ ReceiverID *snowflake.ID
+ FrequencyID *snowflake.ID
+}
+
+func (m *RequestMessages) Type() PacketType {
+ return PacketRequestMessages
+}
+
+type MessagesInfo struct {
+ Messages []data.Message
+}
+
+func (m *MessagesInfo) Type() PacketType {
+ return PacketMessagesInfo
+}
diff --git a/migrations/20241026174345_init.sql b/migrations/20241026174345_init.sql
index d20898a..f7cedd8 100644
--- a/migrations/20241026174345_init.sql
+++ b/migrations/20241026174345_init.sql
@@ -3,7 +3,7 @@ CREATE TABLE messages (
id INTEGER PRIMARY KEY,
sender_id INT NOT NULL REFERENCES users (id),
content TEXT NOT NULL,
- edited BOOLEAN NOT NULL CHECK (edited IN (0, 1)) DEFAULT 0,
+ edited BOOLEAN NOT NULL CHECK (edited IN (false, true)) DEFAULT false,
frequency_id INT REFERENCES frequencies (id) ON DELETE CASCADE,
receiver_id INT REFERENCES users (id),
@@ -18,9 +18,9 @@ CREATE TABLE users (
id INTEGER PRIMARY KEY,
name TEXT NOT NULL,
public_key BLOB NOT NULL UNIQUE,
- description TEXT,
- is_public_dm BOOLEAN NOT NULL CHECK (is_public_dm IN (0, 1)) DEFAULT 1,
- is_deleted BOOLEAN NOT NULL CHECK (is_deleted IN (0, 1)) DEFAULT 0
+ description TEXT NOT NULL,
+ is_public_dm BOOLEAN NOT NULL CHECK (is_public_dm IN (false, true)) DEFAULT true,
+ is_deleted BOOLEAN NOT NULL CHECK (is_deleted IN (false, true)) DEFAULT false
);
CREATE TABLE networks (
@@ -30,7 +30,7 @@ CREATE TABLE networks (
icon TEXT NOT NULL,
bg_hex_color TEXT NOT NULL,
fg_hex_color TEXT NOT NULL,
- is_public BOOLEAN NOT NULL CHECK (is_public IN (0, 1))
+ is_public BOOLEAN NOT NULL CHECK (is_public IN (false, true))
);
CREATE TABLE frequencies (
@@ -39,7 +39,7 @@ CREATE TABLE frequencies (
name TEXT NOT NULL,
hex_color TEXT,
perms INT NOT NULL CHECK (perms IN (0, 1, 2)),
- -- 0 rw admin | 1 r all w admin | 2 rw all
+ -- 0 no access | 1 read | 2 read & write
position INT NOT NULL
);
@@ -47,8 +47,11 @@ CREATE TABLE users_networks (
user_id INT NOT NULL REFERENCES users (id),
network_id INT NOT NULL REFERENCES networks (id) ON DELETE CASCADE,
joined_at TEXT NOT NULL DEFAULT current_timestamp,
- is_admin BOOLEAN NOT NULL CHECK (is_admin IN (0, 1)) DEFAULT 0,
- is_muted BOOLEAN NOT NULL CHECK (is_muted IN (0, 1)) DEFAULT 0,
+ is_member BOOLEAN NOT NULL CHECK (is_member IN (false, true)) DEFAULT true,
+ is_admin BOOLEAN NOT NULL CHECK (is_admin IN (false, true)) DEFAULT false,
+ is_muted BOOLEAN NOT NULL CHECK (is_muted IN (false, true)) DEFAULT false,
+ is_banned BOOLEAN NOT NULL CHECK (is_banned IN (false, true)) DEFAULT false,
+ ban_reason TEXT,
PRIMARY KEY (user_id, network_id)
);
@@ -65,18 +68,10 @@ CREATE TABLE user_blocked_users (
PRIMARY KEY (blocker_user_id, blocked_user_id)
);
-CREATE TABLE network_banned_users (
- network_id INT NOT NULL REFERENCES networks (id) ON DELETE CASCADE,
- banned_user_id INT NOT NULL REFERENCES users (id),
- banned_at TEXT NOT NULL DEFAULT current_timestamp,
- reason TEXT,
- PRIMARY KEY (network_id, banned_user_id)
-);
-
-CREATE INDEX idx_network_name ON networks (name) WHERE is_public = 1;
+CREATE INDEX idx_network_name ON networks (name) WHERE is_public = true;
CREATE INDEX idx_frequency_network ON frequencies (network_id);
CREATE INDEX idx_blocked_by_user ON user_blocked_users (blocker_user_id);
-CREATE INDEX idx_banned_by_network ON network_banned_users (network_id);
+CREATE INDEX idx_banned_by_network ON users_networks (network_id) WHERE is_banned = true;
CREATE INDEX idx_direct_messages ON messages (sender_id, receiver_id);
CREATE INDEX idx_frequency_messages ON messages (frequency_id);
diff --git a/query/networks.sql b/query/networks.sql
index 9ff350e..dfa7b6b 100644
--- a/query/networks.sql
+++ b/query/networks.sql
@@ -19,11 +19,10 @@ RETURNING *;
-- name: GetBannedUsersInNetwork :many
SELECT
sqlc.embed(users),
- network_banned_users.banned_at,
- network_banned_users.reason
-FROM network_banned_users
-JOIN users ON users.id = network_banned_users.banned_user_id
-WHERE network_banned_users.network_id = ?;
+ users_networks.ban_reason
+FROM users_networks
+JOIN users ON users.id = users_networks.user_id
+WHERE users_networks.network_id = ?;
-- name: GetUsersInNetwork :many
SELECT
@@ -33,7 +32,7 @@ SELECT
users_networks.is_muted
FROM users_networks
JOIN users ON users.id = users_networks.user_id
-WHERE users_networks.network_id = ?;
+WHERE users_networks.network_id = ? AND is_member = true;
-- name: SetNetworkName :one
UPDATE networks SET