ready to switch to peer DB
Some checks failed
continuous-integration/drone/push Build is failing

This commit is contained in:
ycc 2024-05-28 14:28:10 +02:00
parent c284b15788
commit c1883f1524
5 changed files with 154 additions and 51 deletions

View File

@ -14,7 +14,7 @@ func DbMessageToInternalUserMessage(id int64, dbFile string, dbm *meowlib.DbMess
ium.Outbound = false ium.Outbound = false
} }
ium.Message = string(dbm.Data) ium.Message = string(dbm.Data)
ium.ConversationStatus = dbm.Status ium.Status = dbm.Status
ium.Contact = dbm.Contact ium.Contact = dbm.Contact
ium.CurrentLocation = dbm.CurrentLocation ium.CurrentLocation = dbm.CurrentLocation
ium.Messagetype = dbm.Type ium.Messagetype = dbm.Type
@ -23,6 +23,19 @@ func DbMessageToInternalUserMessage(id int64, dbFile string, dbm *meowlib.DbMess
return &ium return &ium
} }
func InternalUserMessageToDbMessage(ium *InternalUserMessage) *meowlib.DbMessage {
var dbm meowlib.DbMessage
dbm.Outbound = ium.Outbound
dbm.Type = ium.Messagetype
dbm.Data = []byte(ium.Message)
dbm.Appdata = ium.Appdata
dbm.Contact = ium.Contact
dbm.CurrentLocation = ium.CurrentLocation
dbm.Status = ium.Status
dbm.FilePaths = ium.FilePaths
return &dbm
}
func UserMessageToDbMessage(outbound bool, um *meowlib.UserMessage, filepaths []string) *meowlib.DbMessage { func UserMessageToDbMessage(outbound bool, um *meowlib.UserMessage, filepaths []string) *meowlib.DbMessage {
var dbm meowlib.DbMessage var dbm meowlib.DbMessage
dbm.Outbound = outbound dbm.Outbound = outbound

View File

@ -51,7 +51,7 @@ func PrepareUserMessage(message string, srvuid string, peer_idx int, replyToUid
} }
func SendAck(messageUid string, srvuid string, peer_idx int, received int64, processed int64) ([]byte, string, error) { func BuildAckMessage(messageUid string, srvuid string, peer_idx int, received int64, processed int64) ([]byte, string, error) {
peer := client.GetConfig().GetIdentity().Peers[peer_idx] peer := client.GetConfig().GetIdentity().Peers[peer_idx]
srv, err := client.GetConfig().GetIdentity().MessageServers.LoadServer(srvuid) srv, err := client.GetConfig().GetIdentity().MessageServers.LoadServer(srvuid)
@ -77,10 +77,10 @@ func SendAck(messageUid string, srvuid string, peer_idx int, received int64, pro
if err != nil { if err != nil {
return nil, "PrepareServerMessage : ProcessOutboundMessage", err return nil, "PrepareServerMessage : ProcessOutboundMessage", err
} }
// Store message
err = peer.StoreMessage(usermessage, nil)
if err != nil {
return nil, "PrepareServerMessage : StoreMessage", err
}
return data, "", nil return data, "", nil
} }
func ReadAckMessageResponse() {
//! update the status in message store
}

View File

@ -6,7 +6,7 @@ type InternalUserMessage struct {
Outbound bool `json:"outbound"` Outbound bool `json:"outbound"`
Messagetype string `json:"messagetype,omitempty"` Messagetype string `json:"messagetype,omitempty"`
Message string `json:"message,omitempty"` Message string `json:"message,omitempty"`
ConversationStatus *meowlib.ConversationStatus `json:"conversation_status,omitempty"` Status *meowlib.ConversationStatus `json:"conversation_status,omitempty"`
Contact *meowlib.ContactCard `json:"contact,omitempty"` Contact *meowlib.ContactCard `json:"contact,omitempty"`
ServerDeliveryUuid string `json:"server_delivery_uuid,omitempty"` ServerDeliveryUuid string `json:"server_delivery_uuid,omitempty"`
ServerDeliveryTimestamp int64 `json:"server_delivery_timestamp,omitempty"` ServerDeliveryTimestamp int64 `json:"server_delivery_timestamp,omitempty"`
@ -28,7 +28,7 @@ func InternalUserMessageFromUserMessage(peer *Peer, msg *meowlib.UserMessage) *I
} }
iu.Messagetype = msg.Type iu.Messagetype = msg.Type
iu.Message = string(msg.Data) iu.Message = string(msg.Data)
iu.ConversationStatus = msg.Status iu.Status = msg.Status
iu.Contact = msg.Contact iu.Contact = msg.Contact
return iu return iu
} }

View File

@ -225,9 +225,7 @@ func GetMessagesHistory(peer *Peer, inAppMsgCount int, lastDbId int, wantMore in
return messages, nil return messages, nil
} }
// Get old messages from a peer func GetDbMessage(dbFile string, dbId int64, password string) (*meowlib.DbMessage, error) {
func GetMessagePreview(peer *Peer, dbFile string, dbId int64, password string) ([]byte, error) {
// There fileidx should provide the db that we need (unless wantMore overlaps the next DB) // There fileidx should provide the db that we need (unless wantMore overlaps the next DB)
db, _ := sql.Open("sqlite3", filepath.Join(GetConfig().StoragePath, GetConfig().GetIdentity().Uuid, dbFile+GetConfig().DbSuffix)) // Open the created SQLite File db, _ := sql.Open("sqlite3", filepath.Join(GetConfig().StoragePath, GetConfig().GetIdentity().Uuid, dbFile+GetConfig().DbSuffix)) // Open the created SQLite File
defer db.Close() defer db.Close()
@ -261,9 +259,44 @@ func GetMessagePreview(peer *Peer, dbFile string, dbId int64, password string) (
} }
} }
return &dbm, nil
}
func UpdateDbMessage(dbm *meowlib.DbMessage, dbFile string, dbId int64, password string) error {
db, _ := sql.Open("sqlite3", filepath.Join(GetConfig().StoragePath, GetConfig().GetIdentity().Uuid, dbFile+GetConfig().DbSuffix)) // Open the created SQLite File
defer db.Close()
// Encrypt message
out, err := proto.Marshal(dbm)
if err != nil {
return err
}
encData, err := meowlib.SymEncrypt(password, out)
if err != nil {
return err
}
// Insert message
updateMessageSQL := `UPDATE message SET m=? WHERE id=?`
statement, err := db.Prepare(updateMessageSQL) // Prepare statement.
if err != nil {
return err
}
_, err = statement.Exec(encData, dbId)
if err != nil {
return err
}
return nil
}
// Get old messages from a peer
func GetMessagePreview(dbFile string, dbId int64, password string) ([]byte, error) {
dbm, err := GetDbMessage(dbFile, dbId, password)
if err != nil {
return nil, err
}
return FilePreview(dbm.FilePaths[0], password) return FilePreview(dbm.FilePaths[0], password)
} }
// decrypt the a file and returns the raw content
func FilePreview(filename string, password string) ([]byte, error) { func FilePreview(filename string, password string) ([]byte, error) {
// get the hidden file // get the hidden file
encData, err := os.ReadFile(filename) encData, err := os.ReadFile(filename)
@ -278,7 +311,7 @@ func FilePreview(filename string, password string) ([]byte, error) {
return data, nil return data, nil
} }
// make an image from the files content (loads the first image, or build a more complex view) // return the raw content from the files content (loads the first image, or build a more complex view)
func InternalUserMessagePreview(msg *InternalUserMessage, password string) ([]byte, error) { func InternalUserMessagePreview(msg *InternalUserMessage, password string) ([]byte, error) {
// get the hidden file name // get the hidden file name
if len(msg.FilePaths) == 0 { if len(msg.FilePaths) == 0 {
@ -296,7 +329,6 @@ func getMessageCount(dbid string) (int, error) {
if err != nil { if err != nil {
return 0, err return 0, err
} }
return count, nil return count, nil
} }

View File

@ -6,7 +6,9 @@ package client
import ( import (
"crypto/sha256" "crypto/sha256"
"encoding/json" "encoding/json"
"errors"
"path/filepath" "path/filepath"
"sort"
"forge.redroom.link/yves/meowlib" "forge.redroom.link/yves/meowlib"
"github.com/dgraph-io/badger" "github.com/dgraph-io/badger"
@ -18,7 +20,7 @@ type PeerStorage struct {
cache map[string]*Peer cache map[string]*Peer
} }
// Open a badger database from struct PeerStorage // Open the badger database from struct PeerStorage
func (ps *PeerStorage) open() error { func (ps *PeerStorage) open() error {
opts := badger.DefaultOptions(filepath.Join(GetConfig().StoragePath, GetConfig().GetIdentity().Uuid, ps.DbFile)) opts := badger.DefaultOptions(filepath.Join(GetConfig().StoragePath, GetConfig().GetIdentity().Uuid, ps.DbFile))
@ -31,7 +33,7 @@ func (ps *PeerStorage) open() error {
return nil return nil
} }
// Store function StorePeer stores a peer in a badger database with Peer.Uid as key // Store function StorePeer stores a peer in the badger database with Peer.Uid as key
func (ps *PeerStorage) StorePeer(peer *Peer) error { func (ps *PeerStorage) StorePeer(peer *Peer) error {
err := ps.open() err := ps.open()
if err != nil { if err != nil {
@ -60,7 +62,7 @@ func (ps *PeerStorage) StorePeer(peer *Peer) error {
} }
// LoadPeer function loads a Peer from a badger database with Peer.GetUid() as key // LoadPeer function loads a Peer from the badger database with Peer.GetUid() as key
func (ps *PeerStorage) LoadPeer(uid string, password string) (*Peer, error) { func (ps *PeerStorage) LoadPeer(uid string, password string) (*Peer, error) {
var peer Peer var peer Peer
err := ps.open() err := ps.open()
@ -86,7 +88,7 @@ func (ps *PeerStorage) LoadPeer(uid string, password string) (*Peer, error) {
return &peer, err return &peer, err
} }
// DeletePeer function deletes a Peer from a badger database with Peer.GetUid() as key // DeletePeer function deletes a Peer from the badger database with Peer.GetUid() as key
func (ps *PeerStorage) DeletePeer(uid string) error { func (ps *PeerStorage) DeletePeer(uid string) error {
err := ps.open() err := ps.open()
if err != nil { if err != nil {
@ -100,8 +102,8 @@ func (ps *PeerStorage) DeletePeer(uid string) error {
}) })
} }
// LoadAllPeers function loads all Peers from a badger database // LoadPeers function loads Peers from the badger database with a specific password
func (ps *PeerStorage) LoadAllPeers(password string) ([]*Peer, error) { func (ps *PeerStorage) LoadPeers(password string) ([]*Peer, error) {
var peers []*Peer var peers []*Peer
err := ps.open() err := ps.open()
if err != nil { if err != nil {
@ -125,48 +127,104 @@ func (ps *PeerStorage) LoadAllPeers(password string) ([]*Peer, error) {
}) })
if err != nil { if err != nil {
peers = append(peers, &sc) peers = append(peers, &sc)
ps.cache[sc.Uid] = &sc
} }
} }
return nil return nil
}) })
return peers, err // Sort peers based on peer.Name
} sort.Slice(peers, func(i, j int) bool {
return peers[i].Name < peers[j].Name
// LoadPeersFromUids function loads Peers with id in []Uid parameter from a badger database
func (ps *PeerStorage) LoadPeersFromUids(uids []string, password string) ([]*Peer, error) {
var peers []*Peer
err := ps.open()
if err != nil {
return nil, err
}
defer ps.close()
err = ps.db.View(func(txn *badger.Txn) error {
for _, uid := range uids {
shakey := sha256.Sum256([]byte(uid))
key := shakey[:]
item, err := txn.Get(key)
if err != nil {
return err
}
var sc Peer
err = item.Value(func(val []byte) error {
jsonsrv, err := meowlib.SymDecrypt(password, val)
if err != nil {
return err
}
return json.Unmarshal(jsonsrv, &sc)
})
if err == nil {
peers = append(peers, &sc)
}
}
return nil
}) })
return peers, err return peers, err
} }
// close a badger database // GetPeers function returns all peers from the cache as a sorted array
func (ps *PeerStorage) GetPeers() ([]*Peer, error) {
peers := make([]*Peer, 0, len(ps.cache))
for _, peer := range ps.cache {
peers = append(peers, peer)
}
// Sort peers based on peer.Name
sort.Slice(peers, func(i, j int) bool {
return peers[i].Name < peers[j].Name
})
return peers, nil
}
// close the badger database
func (ps *PeerStorage) close() { func (ps *PeerStorage) close() {
ps.db.Close() ps.db.Close()
} }
func (ps *PeerStorage) GetFromPublicKey(publickey string) *Peer {
for _, peer := range ps.cache {
if peer.ContactPublicKey == publickey {
return peer
}
}
return nil
}
func (ps *PeerStorage) GetFromInvitationId(invitationId string) *Peer {
for _, peer := range ps.cache {
if peer.InvitationId == invitationId {
return peer
}
}
return nil
}
func (ps *PeerStorage) GetFromMyLookupKey(publickey string) *Peer {
for _, peer := range ps.cache {
if peer.MyLookupKp.Public == publickey {
return peer
}
}
return nil
}
func (ps *PeerStorage) GetFromName(name string) *Peer {
for _, peer := range ps.cache {
if peer.Name == name {
return peer
}
}
return nil
}
func (ps *PeerStorage) GetFromUid(uid string) *Peer {
return ps.cache[uid]
}
// Checks if the received contact card is an answer to an invitation, returns true if it is, and the proposed and received nicknames
func (ps *PeerStorage) CheckInvitation(ReceivedContact *meowlib.ContactCard) (isAnswer bool, proposedNick string, receivedNick string, invitationMessage string) {
// invitation Id found, this is an answer to an invitation
for _, p := range ps.cache {
if p.InvitationId == ReceivedContact.InvitationId {
return true, p.Name, ReceivedContact.Name, ReceivedContact.InvitationMessage
}
}
// it's an invitation
return false, "", ReceivedContact.Name, ReceivedContact.InvitationMessage
}
// Finalizes an invitation, returns nil if successful
func (ps *PeerStorage) FinalizeInvitation(ReceivedContact *meowlib.ContactCard) error {
for i, p := range ps.cache {
if p.InvitationId == ReceivedContact.InvitationId {
//id.Peers[i].Name = ReceivedContact.Name
ps.cache[i].ContactEncryption = ReceivedContact.EncryptionPublicKey
ps.cache[i].ContactLookupKey = ReceivedContact.LookupPublicKey
ps.cache[i].ContactPublicKey = ReceivedContact.ContactPublicKey
srvs := []string{}
for srv := range ReceivedContact.PullServers {
srvs = append(srvs, ReceivedContact.PullServers[srv].GetUid())
}
ps.cache[i].ContactPullServers = srvs
ps.StorePeer(ps.cache[i])
return nil
}
}
return errors.New("no matching contact found for invitationId " + ReceivedContact.InvitationId)
}