seekia/internal/messaging/chatMessageStorage/chatMessageStorage.go

142 lines
5.1 KiB
Go

// chatMessageStorage provides functions for storing and retrieving raw chat messages.
// This package stores encrypted messages. The myChatMessages package is where decrypted messages are stored.
package chatMessageStorage
import "seekia/internal/badgerDatabase"
import "seekia/internal/messaging/myInbox"
import "seekia/internal/messaging/readMessages"
import "seekia/internal/moderation/reportStorage"
import "seekia/internal/moderation/reviewStorage"
import "seekia/internal/mySettings"
import "errors"
func GetNumberOfStoredMessages()(int64, error){
numberOfMessages, err := badgerDatabase.GetNumberOfChatMessages()
if (err != nil) { return 0, err }
return numberOfMessages, nil
}
// Returns all downloaded raw message hashes
// These are different from myChatMessages, which are decrypted
func GetAllDownloadedMessageHashes()([][26]byte, error){
messageHashes, err := badgerDatabase.GetAllChatMessageHashes()
if (err != nil) { return nil, err }
return messageHashes, nil
}
//Outputs:
// -bool: Message is well formed
// -error
func AddMessage(inputMessage []byte)(bool, error){
ableToRead, messageHash, _, messageNetworkType, recipientInbox, _, _, _, _, _, _, err := readMessages.ReadChatMessagePublicDataAndHash(true, inputMessage)
if (err != nil) { return false, err }
if (ableToRead == false){
// Message is malformed, do nothing.
// This means that the other host is malicious
return false, nil
}
exists, _, err := badgerDatabase.GetChatMessage(messageHash)
if (err != nil) { return false, err }
if (exists == true){
// Message already exists in the database.
return true, nil
}
err = badgerDatabase.AddChatInboxMessage(recipientInbox, messageHash)
if (err != nil) { return false, err }
err = badgerDatabase.AddChatMessage(messageHash, inputMessage)
if (err != nil) { return false, err }
err = mySettings.SetSetting("ViewedContentNeedsRefreshYesNo", "Yes")
if (err != nil) { return false, err }
inboxIsMine, inboxIdentityType, err := myInbox.CheckIfInboxIsMine(recipientInbox, messageNetworkType)
if (err != nil) { return false, err }
if (inboxIsMine == true){
err = mySettings.SetSetting(inboxIdentityType + "ChatConversationsNeedRefreshYesNo", "Yes")
if (err != nil) { return false, err }
}
return true, nil
}
// This function will attempt to decrypt a message and return the communication
// We attempt to find a cipher key for the message from any downloaded reviews/reports
//Outputs:
// -bool: Message exists (in storage)
// -bool: Cipher key found
// -bool: Message is decryptable
// -[32]byte: Message Cipher Key
// -[16]byte: Message sender
// -string: Message communication
// -error
func GetDecryptedMessageForModeration(messageHash [26]byte)(bool, bool, bool, [32]byte, [16]byte, string, error){
messageExists, messageBytes, err := badgerDatabase.GetChatMessage(messageHash)
if (err != nil) { return false, false, false, [32]byte{}, [16]byte{}, "", err }
if (messageExists == false){
return false, false, false, [32]byte{}, [16]byte{}, "", nil
}
ableToRead, _, messageNetworkType, _, _, _, _, messageCipherKeyHash, _, _, err := readMessages.ReadChatMessagePublicData(false, messageBytes)
if (err != nil) { return false, false, false, [32]byte{}, [16]byte{}, "", err }
if (ableToRead == false){
return false, false, false, [32]byte{}, [16]byte{}, "", errors.New("Database corrupt: Contains invalid message.")
}
getMessageCipherKey := func()(bool, [32]byte, error){
cipherKeyFound, cipherKey, err := reportStorage.GetMessageCipherKeyFromAnyReport(messageHash, messageNetworkType, messageCipherKeyHash)
if (err != nil) { return false, [32]byte{}, err }
if (cipherKeyFound == true){
return true, cipherKey, nil
}
cipherKeyFound, cipherKey, err = reviewStorage.GetMessageCipherKeyFromAnyReview(messageHash, messageNetworkType, messageCipherKeyHash)
if (err != nil) { return false, [32]byte{}, err }
if (cipherKeyFound == true){
return true, cipherKey, nil
}
return false, [32]byte{}, nil
}
cipherKeyFound, messageCipherKey, err := getMessageCipherKey()
if (err != nil) { return false, false, false, [32]byte{}, [16]byte{}, "", err }
if (cipherKeyFound == false){
return true, false, false, [32]byte{}, [16]byte{}, "", nil
}
ableToRead, messageHash_Received, _, messageNetworkType_Received, senderIdentityHash, messageCommunication, err := readMessages.ReadChatMessageWithCipherKey(messageBytes, messageCipherKey)
if (err != nil) { return false, false, false, [32]byte{}, [16]byte{}, "", err }
if (ableToRead == false){
// Message is malformed
// It must have been created by a malicious author.
return true, true, false, [32]byte{}, [16]byte{}, "", nil
}
if (messageHash_Received != messageHash){
return false, false, false, [32]byte{}, [16]byte{}, "", errors.New("ReadChatMessageWithCipherKey returning different messageHash than ReadChatMessagePublicData")
}
if (messageNetworkType_Received != messageNetworkType){
return false, false, false, [32]byte{}, [16]byte{}, "", errors.New("Database corrupt: Contains message with different message hash than entry key.")
}
return true, true, true, messageCipherKey, senderIdentityHash, messageCommunication, nil
}