meowlib/client/server.go

187 lines
6.2 KiB
Go
Raw Normal View History

2022-09-06 09:30:45 +02:00
package client
import (
"fmt"
"time"
"forge.redroom.link/yves/meowlib"
"github.com/google/uuid"
"google.golang.org/protobuf/proto"
2022-09-06 09:30:45 +02:00
)
2023-11-08 22:01:44 +01:00
// Server manages server related operations
2023-11-08 21:52:09 +01:00
// - Sending messages for server usage
// - Two first steps of an invitation
// - User message sending with UserKp identification
2023-11-08 21:52:09 +01:00
// - Messages lookup requests
// - Utility functions for packing/unpacking, encrypting/decrypting messages for server communication
// - Server remote management if ManagerKp is available for that server
2023-11-08 22:01:44 +01:00
type Server struct {
2023-11-08 21:52:09 +01:00
ServerData meowlib.ServerCard `json:"server_data,omitempty"`
Presence bool `json:"presence,omitempty"`
LastCheck time.Time `json:"last_check,omitempty"`
Uptime time.Duration `json:"uptime,omitempty"`
UserKp meowlib.KeyPair `json:"user_kp,omitempty"`
ManagerKp meowlib.KeyPair `json:"manager_kp,omitempty"`
2023-11-08 21:52:09 +01:00
Country string `json:"country,omitempty"`
AllowedDelay int `json:"allowed_delay,omitempty"`
2023-12-09 20:09:55 +01:00
Backup bool `json:"backup,omitempty"`
2022-09-06 09:30:45 +02:00
}
// CreateServerFromUrl creates a server from a basic url, ex : https://my.meowserver.example:8443/meow/
func CreateServerFromUrl(url string) *Server {
2023-11-08 22:01:44 +01:00
var is Server
2022-09-06 09:30:45 +02:00
is.ServerData.Url = url
return &is
}
// Create a server from a server card
2023-11-08 22:01:44 +01:00
func CreateServerFromServerCard(server *meowlib.ServerCard) *Server {
var is Server
2022-09-19 13:26:27 +02:00
is.ServerData = *server
is.UserKp = meowlib.NewKeyPair()
2022-09-19 13:26:27 +02:00
return &is
}
2022-09-06 17:07:35 +02:00
// AsymEncryptMessage prepares a message to send to a specific internal server
2023-11-08 22:01:44 +01:00
func (ints *Server) AsymEncryptMessage(Message []byte) (*meowlib.EncryptedMessage, error) {
var enc *meowlib.EncryptedMessage
enc, err := meowlib.AsymEncryptAndSign(ints.ServerData.PublicKey, ints.UserKp.Private, Message)
2022-09-06 09:30:45 +02:00
if err != nil {
fmt.Println(err.Error())
return nil, err
2022-09-06 09:30:45 +02:00
}
return enc, err
2022-09-06 09:30:45 +02:00
}
2022-09-06 17:07:35 +02:00
// AsymDecryptMessage reads a message from a specific internal server
2023-11-08 22:01:44 +01:00
func (ints *Server) AsymDecryptMessage(Message []byte, Signature []byte) (DecryptedMessage []byte, err error) {
DecryptedMessage, err = meowlib.AsymDecryptAndCheck(ints.UserKp.Private, ints.ServerData.PublicKey, Message, Signature)
2022-09-06 09:30:45 +02:00
if err != nil {
fmt.Println(err.Error())
return nil, err
}
2022-09-06 17:07:35 +02:00
return DecryptedMessage, err
2022-09-06 09:30:45 +02:00
}
2023-11-06 22:44:21 +01:00
// BuildToServerMessageFromUserMessage creates a basic message to server from a single packed user message and returns a meowlib.ToServerMessage
2023-11-08 22:01:44 +01:00
func (ints *Server) BuildToServerMessageFromUserMessage(usermsg *meowlib.PackedUserMessage) *meowlib.ToServerMessage {
var msg meowlib.ToServerMessage
msg.Uuid = uuid.New().String()
msg.Type = "1"
msg.From = ints.UserKp.Public
msg.Messages = append(msg.Messages, usermsg)
2022-12-18 20:37:26 +01:00
return &msg
}
2023-11-06 22:44:21 +01:00
// BuildMessageSendingMessage creates a basic message to server from a single packed user message and returns it as protobuf serialized byte array
2023-11-08 22:01:44 +01:00
func (ints *Server) BuildMessageSendingMessage(usermsg *meowlib.PackedUserMessage) ([]byte, error) {
2022-12-18 20:37:26 +01:00
msg := ints.BuildToServerMessageFromUserMessage(usermsg)
out, err := proto.Marshal(msg)
if err != nil {
return nil, err
}
return out, nil
}
2023-11-06 22:44:21 +01:00
// BuildMessageRequestMessage creates a message lookup message to server and returns it as protobuf serialized byte array
2023-11-08 22:01:44 +01:00
func (ints *Server) BuildMessageRequestMessage(lookupKeys []string) ([]byte, error) {
var msg meowlib.ToServerMessage
msg.Uuid = uuid.New().String()
msg.Type = "1"
msg.From = ints.UserKp.Public
out, err := proto.Marshal(&msg)
if err != nil {
return nil, err
}
return out, nil
}
2022-09-19 13:26:27 +02:00
2023-11-08 21:52:09 +01:00
// BuildToServerMessageInvitation creates an invitation message to server and returns it as a meowlib.ToServerMessage
2023-11-14 16:32:50 +01:00
// it takes as input a contactcard generated by Identity.InvitePeer
func (ints *Server) BuildToServerMessageInvitationCreation(invitation *meowlib.ContactCard, password string, timeout int, invitationIdLen int) (*meowlib.ToServerMessage, error) {
var msg meowlib.ToServerMessage
var inv meowlib.Invitation
payload, err := invitation.Compress()
if err != nil {
return nil, err
}
msg.Type = "1"
msg.From = ints.UserKp.Public
2023-11-08 21:52:09 +01:00
inv.Step = 1
inv.Password = password
inv.Timeout = int32(timeout)
2023-11-14 16:32:50 +01:00
inv.ShortcodeLen = int32(invitationIdLen)
inv.Payload = payload
msg.Invitation = &inv
return &msg, nil
}
2023-11-08 21:52:09 +01:00
// BuildToServerMessageInvitationRequest requests invitation with provided id from server and returns it as a meowlib.ToServerMessage
2023-11-14 16:32:50 +01:00
func (ints *Server) BuildToServerMessageInvitationRequest(shortcode string, password string) (*meowlib.ToServerMessage, error) {
2023-11-08 21:52:09 +01:00
var msg meowlib.ToServerMessage
var inv meowlib.Invitation
msg.Type = "1"
msg.From = ints.UserKp.Public
2023-11-08 21:52:09 +01:00
inv.Step = 2
inv.Password = password
2023-11-14 16:32:50 +01:00
inv.Shortcode = shortcode
2023-11-08 21:52:09 +01:00
msg.Invitation = &inv
return &msg, nil
}
// PackServerMessage
2023-11-08 22:01:44 +01:00
func (ints *Server) PackServerMessage(payload []byte, signature []byte) (protoPackedMessage []byte, err error) {
2022-09-19 13:26:27 +02:00
var msg meowlib.PackedServerMessage
msg.From = ints.UserKp.Public
2022-09-19 13:26:27 +02:00
msg.Payload = payload
msg.Signature = signature
out, err := proto.Marshal(&msg)
if err != nil {
return nil, err
}
return out, nil
}
2023-11-08 22:01:44 +01:00
func (ints *Server) UnPackServerMessage(protoPackedMessage []byte) (payload []byte, signature []byte, err error) {
msg := &meowlib.PackedServerMessage{}
if err := proto.Unmarshal(protoPackedMessage, msg); err != nil {
return nil, nil, err
}
return msg.Payload, msg.Signature, nil
}
2022-12-18 20:59:27 +01:00
2023-11-08 22:01:44 +01:00
func (srv *Server) ProcessOutboundMessage(toServerMessage *meowlib.ToServerMessage) ([]byte, error) {
2022-12-18 20:59:27 +01:00
byteToServerMessage, err := proto.Marshal(toServerMessage)
if err != nil {
return nil, err
}
// Encrypting it
encToServer, err := srv.AsymEncryptMessage(byteToServerMessage)
2022-12-18 20:59:27 +01:00
if err != nil {
return nil, err
}
// Packing it
protoPackedServerMsg, err := srv.PackServerMessage(encToServer.Data, encToServer.Signature)
2022-12-18 20:59:27 +01:00
if err != nil {
return nil, err
}
return protoPackedServerMsg, nil
}
2023-11-08 22:01:44 +01:00
func (srv *Server) ProcessInboundServerResponse(msg []byte) (*meowlib.FromServerMessage, error) {
2022-12-18 20:59:27 +01:00
fsmsg := &meowlib.FromServerMessage{}
payload, signature, err := srv.UnPackServerMessage(msg)
if err != nil {
return nil, err
}
decrypted, err := srv.AsymDecryptMessage(payload, signature)
if err != nil {
return nil, err
}
if err := proto.Unmarshal(decrypted, fsmsg); err != nil {
return nil, err
}
return fsmsg, nil
}