Encrypted channels

This commit is contained in:
LittleSheep 2024-05-12 22:00:22 +08:00
parent 13fcc64f79
commit 18af7eae81
5 changed files with 27 additions and 36 deletions

View File

@ -19,6 +19,7 @@ type Channel struct {
Type ChannelType `json:"type"` Type ChannelType `json:"type"`
Account Account `json:"account"` Account Account `json:"account"`
AccountID uint `json:"account_id"` AccountID uint `json:"account_id"`
IsEncrypted bool `json:"is_encrypted"`
Realm Realm `json:"realm"` Realm Realm `json:"realm"`
RealmID *uint `json:"realm_id"` RealmID *uint `json:"realm_id"`

View File

@ -1,18 +1,15 @@
package models package models
import "gorm.io/datatypes"
type Message struct { type Message struct {
BaseModel BaseModel
Content []byte `json:"content"` Content []byte `json:"content"`
Metadata datatypes.JSONMap `json:"metadata"` Type string `json:"type"`
Type string `json:"type"` Attachments []Attachment `json:"attachments"`
Attachments []Attachment `json:"attachments"` Channel Channel `json:"channel"`
Channel Channel `json:"channel"` Sender ChannelMember `json:"sender"`
Sender ChannelMember `json:"sender"` ReplyID *uint `json:"reply_id"`
ReplyID *uint `json:"reply_id"` ReplyTo *Message `json:"reply_to" gorm:"foreignKey:ReplyID"`
ReplyTo *Message `json:"reply_to" gorm:"foreignKey:ReplyID"` ChannelID uint `json:"channel_id"`
ChannelID uint `json:"channel_id"` SenderID uint `json:"sender_id"`
SenderID uint `json:"sender_id"`
} }

View File

@ -99,6 +99,7 @@ func createChannel(c *fiber.Ctx) error {
Alias string `json:"alias" validate:"required,lowercase,min=4,max=32"` Alias string `json:"alias" validate:"required,lowercase,min=4,max=32"`
Name string `json:"name" validate:"required"` Name string `json:"name" validate:"required"`
Description string `json:"description"` Description string `json:"description"`
IsEncrypted bool `json:"is_encrypted"`
} }
if err := BindAndValidate(c, &data); err != nil { if err := BindAndValidate(c, &data); err != nil {
@ -121,9 +122,9 @@ func createChannel(c *fiber.Ctx) error {
var err error var err error
var channel models.Channel var channel models.Channel
if realm != nil { if realm != nil {
channel, err = services.NewChannel(user, data.Alias, data.Name, data.Description, realm.ID) channel, err = services.NewChannel(user, data.Alias, data.Name, data.Description, data.IsEncrypted, realm.ID)
} else { } else {
channel, err = services.NewChannel(user, data.Alias, data.Name, data.Description) channel, err = services.NewChannel(user, data.Alias, data.Name, data.Description, data.IsEncrypted)
} }
if err != nil { if err != nil {
@ -141,6 +142,7 @@ func editChannel(c *fiber.Ctx) error {
Alias string `json:"alias" validate:"required,min=4,max=32"` Alias string `json:"alias" validate:"required,min=4,max=32"`
Name string `json:"name" validate:"required"` Name string `json:"name" validate:"required"`
Description string `json:"description"` Description string `json:"description"`
IsEncrypted bool `json:"is_encrypted"`
} }
if err := BindAndValidate(c, &data); err != nil { if err := BindAndValidate(c, &data); err != nil {
@ -166,7 +168,7 @@ func editChannel(c *fiber.Ctx) error {
return fiber.NewError(fiber.StatusNotFound, err.Error()) return fiber.NewError(fiber.StatusNotFound, err.Error())
} }
channel, err := services.EditChannel(channel, data.Alias, data.Name, data.Description) channel, err := services.EditChannel(channel, data.Alias, data.Name, data.Description, data.IsEncrypted)
if err != nil { if err != nil {
return fiber.NewError(fiber.StatusBadRequest, err.Error()) return fiber.NewError(fiber.StatusBadRequest, err.Error())
} }

View File

@ -1,7 +1,6 @@
package server package server
import ( import (
"encoding/base64"
"encoding/json" "encoding/json"
"fmt" "fmt"
"git.solsynth.dev/hydrogen/messaging/pkg/database" "git.solsynth.dev/hydrogen/messaging/pkg/database"
@ -48,7 +47,6 @@ func newMessage(c *fiber.Ctx) error {
var data struct { var data struct {
Type string `json:"type" validate:"required"` Type string `json:"type" validate:"required"`
Content map[string]any `json:"content"` Content map[string]any `json:"content"`
Metadata map[string]any `json:"metadata"`
Attachments []models.Attachment `json:"attachments"` Attachments []models.Attachment `json:"attachments"`
ReplyTo *uint `json:"reply_to"` ReplyTo *uint `json:"reply_to"`
} }
@ -74,22 +72,17 @@ func newMessage(c *fiber.Ctx) error {
} }
} }
var encodedContent []byte rawContent, err := json.Marshal(data.Content)
if raw, err := json.Marshal(data.Content); err != nil { if err != nil {
return fiber.NewError(fiber.StatusBadRequest, fmt.Sprintf("invalid message content, unable to encode: %v", err)) return fiber.NewError(fiber.StatusBadRequest, fmt.Sprintf("invalid message content, unable to encode: %v", err))
} else {
encoder := base64.StdEncoding
encodedContent = make([]byte, encoder.EncodedLen(len(raw)))
encoder.Encode(encodedContent, raw)
} }
message := models.Message{ message := models.Message{
Content: encodedContent, Content: rawContent,
Sender: member, Sender: member,
Channel: channel, Channel: channel,
ChannelID: channel.ID, ChannelID: channel.ID,
SenderID: member.ID, SenderID: member.ID,
Metadata: data.Metadata,
Attachments: data.Attachments, Attachments: data.Attachments,
Type: data.Type, Type: data.Type,
} }
@ -119,7 +112,6 @@ func editMessage(c *fiber.Ctx) error {
var data struct { var data struct {
Type string `json:"type" validate:"required"` Type string `json:"type" validate:"required"`
Content map[string]any `json:"content"` Content map[string]any `json:"content"`
Metadata map[string]any `json:"metadata"`
Attachments []models.Attachment `json:"attachments"` Attachments []models.Attachment `json:"attachments"`
ReplyTo *uint `json:"reply_to"` ReplyTo *uint `json:"reply_to"`
} }
@ -148,18 +140,13 @@ func editMessage(c *fiber.Ctx) error {
return fiber.NewError(fiber.StatusNotFound, err.Error()) return fiber.NewError(fiber.StatusNotFound, err.Error())
} }
var encodedContent []byte rawContent, err := json.Marshal(data.Content)
if raw, err := json.Marshal(data.Content); err != nil { if err != nil {
return fiber.NewError(fiber.StatusBadRequest, fmt.Sprintf("invalid message content, unable to encode: %v", err)) return fiber.NewError(fiber.StatusBadRequest, fmt.Sprintf("invalid message content, unable to encode: %v", err))
} else {
encoder := base64.StdEncoding
encodedContent = make([]byte, encoder.EncodedLen(len(raw)))
encoder.Encode(encodedContent, raw)
} }
message.Attachments = data.Attachments message.Attachments = data.Attachments
message.Metadata = data.Metadata message.Content = rawContent
message.Content = encodedContent
message.Type = data.Type message.Type = data.Type
message, err = services.EditMessage(message) message, err = services.EditMessage(message)

View File

@ -134,11 +134,12 @@ func ListAvailableChannel(user models.Account, realmId ...uint) ([]models.Channe
return channels, nil return channels, nil
} }
func NewChannel(user models.Account, alias, name, description string, realmId ...uint) (models.Channel, error) { func NewChannel(user models.Account, alias, name, description string, isEncrypted bool, realmId ...uint) (models.Channel, error) {
channel := models.Channel{ channel := models.Channel{
Alias: alias, Alias: alias,
Name: name, Name: name,
Description: description, Description: description,
IsEncrypted: isEncrypted,
AccountID: user.ID, AccountID: user.ID,
Members: []models.ChannelMember{ Members: []models.ChannelMember{
{AccountID: user.ID}, {AccountID: user.ID},
@ -153,10 +154,13 @@ func NewChannel(user models.Account, alias, name, description string, realmId ..
return channel, err return channel, err
} }
func EditChannel(channel models.Channel, alias, name, description string) (models.Channel, error) { func EditChannel(channel models.Channel, alias, name, description string, isEncrypted bool) (models.Channel, error) {
channel.Alias = alias channel.Alias = alias
channel.Name = name channel.Name = name
channel.Description = description channel.Description = description
if !channel.IsEncrypted {
channel.IsEncrypted = isEncrypted
}
err := database.C.Save(&channel).Error err := database.C.Save(&channel).Error