From 113d291f75520692d28b87cd2301e00932dfd14f Mon Sep 17 00:00:00 2001 From: Aaron Date: Wed, 20 Sep 2023 23:16:24 +0200 Subject: [PATCH 1/6] Add ThreadMetadata store --- presage-store-sled/src/lib.rs | 62 ++++- presage/Cargo.toml | 2 +- presage/src/errors.rs | 2 + presage/src/lib.rs | 21 +- presage/src/manager.rs | 295 ++++++++++++++++++++++- presage/src/{serde.rs => serializers.rs} | 0 presage/src/store.rs | 19 +- 7 files changed, 395 insertions(+), 6 deletions(-) rename presage/src/{serde.rs => serializers.rs} (100%) diff --git a/presage-store-sled/src/lib.rs b/presage-store-sled/src/lib.rs index 4f2b47f51..6abc7efa4 100644 --- a/presage-store-sled/src/lib.rs +++ b/presage-store-sled/src/lib.rs @@ -30,7 +30,7 @@ use serde::{de::DeserializeOwned, Deserialize, Serialize}; use sha2::{Digest, Sha256}; use sled::{Batch, IVec}; -use presage::{GroupMasterKeyBytes, Registered, Store, Thread}; +use presage::{GroupMasterKeyBytes, Registered, Store, Thread, ThreadMetadata}; mod error; mod protobuf; @@ -47,6 +47,7 @@ const SLED_TREE_SIGNED_PRE_KEYS: &str = "signed_pre_keys"; const SLED_TREE_KYBER_PRE_KEYS: &str = "kyber_pre_keys"; const SLED_TREE_STATE: &str = "state"; const SLED_TREE_THREADS_PREFIX: &str = "threads"; +const SLED_TREE_THREADS_METADATA: &str = "threads_metadata"; const SLED_TREE_PROFILES: &str = "profiles"; const SLED_TREE_PROFILE_KEYS: &str = "profile_keys"; @@ -252,6 +253,13 @@ impl SledStore { hasher.update(key.collect::>()); format!("{:x}", hasher.finalize()) } + + fn thread_metadata_key(&self, thread: &Thread) -> Vec { + match thread { + Thread::Contact(contact) => contact.to_string().into_bytes(), + Thread::Group(group) => group.to_vec(), + } + } } fn migrate( @@ -335,6 +343,7 @@ impl Store for SledStore { type ContactsIter = SledContactsIter; type GroupsIter = SledGroupsIter; type MessagesIter = SledMessagesIter; + type ThreadMetadataIter = SledThreadMetadataIter; /// State @@ -442,6 +451,12 @@ impl Store for SledStore { Ok(()) } + fn save_contact(&mut self, contact: Contact) -> Result<(), Self::Error> { + self.insert(SLED_TREE_CONTACTS, contact.uuid, contact)?; + debug!("saved contact"); + Ok(()) + } + fn contacts(&self) -> Result { Ok(SledContactsIter { iter: self.read().open_tree(SLED_TREE_CONTACTS)?.iter(), @@ -606,6 +621,29 @@ impl Store for SledStore { let key = self.profile_key_for_uuid(uuid, key); self.get(SLED_TREE_PROFILES, key) } + /// Thread metadata + + fn save_thread_metadata(&mut self, metadata: ThreadMetadata) -> Result<(), Self::Error> { + let key = self.thread_metadata_key(&metadata.thread); + self.insert(SLED_TREE_THREADS_METADATA, key, metadata)?; + Ok(()) + } + + fn thread_metadata(&self, thread: &Thread) -> Result, Self::Error> { + let key = self.thread_metadata_key(thread); + self.get(SLED_TREE_THREADS_METADATA, key) + } + + fn thread_metadatas( + &self, + ) -> Result<::ThreadMetadataIter, ::Error> { + let tree = self.read().open_tree(SLED_TREE_THREADS_METADATA)?; + let iter = tree.iter(); + Ok(SledThreadMetadataIter { + cipher: self.cipher.clone(), + iter, + }) + } } pub struct SledContactsIter { @@ -1018,6 +1056,28 @@ impl DoubleEndedIterator for SledMessagesIter { } } +pub struct SledThreadMetadataIter { + cipher: Option>, + iter: sled::Iter, +} + +impl Iterator for SledThreadMetadataIter { + type Item = Result; + + fn next(&mut self) -> Option { + self.iter + .next()? + .map_err(SledStoreError::from) + .and_then(|(_key, value)| { + self.cipher.as_ref().map_or_else( + || serde_json::from_slice(&value).map_err(SledStoreError::from), + |c| c.decrypt_value(&value).map_err(SledStoreError::from), + ) + }) + .into() + } +} + #[cfg(test)] mod tests { use core::fmt; diff --git a/presage/Cargo.toml b/presage/Cargo.toml index d656fa88e..9a19850c6 100644 --- a/presage/Cargo.toml +++ b/presage/Cargo.toml @@ -13,7 +13,7 @@ base64 = "0.12" futures = "0.3" log = "0.4.8" rand = "0.8" -serde = "1.0" +serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" thiserror = "1.0" url = "2.2" diff --git a/presage/src/errors.rs b/presage/src/errors.rs index 2507b0c2a..acc35077b 100644 --- a/presage/src/errors.rs +++ b/presage/src/errors.rs @@ -54,6 +54,8 @@ pub enum Error { AttachmentCipherError(#[from] libsignal_service::attachment_cipher::AttachmentCipherError), #[error("unknown group")] UnknownGroup, + #[error("unknown contact")] + UnknownContact, #[error("unknown recipient")] UnknownRecipient, #[error("timeout: {0}")] diff --git a/presage/src/lib.rs b/presage/src/lib.rs index 308c34beb..31048c617 100644 --- a/presage/src/lib.rs +++ b/presage/src/lib.rs @@ -1,7 +1,8 @@ mod cache; mod errors; mod manager; -mod serde; +mod serializers; +use serde::{Deserialize, Serialize}; mod store; pub use errors::Error; @@ -34,3 +35,21 @@ const USER_AGENT: &str = concat!(env!("CARGO_PKG_NAME"), "-rs-", env!("CARGO_PKG // TODO: open a PR in libsignal and make sure the bytes can be read from `GroupMasterKey` instead of using this type pub type GroupMasterKeyBytes = [u8; 32]; + +#[derive(Deserialize, Serialize, Debug, Clone)] +pub struct ThreadMetadata { + pub thread: Thread, + pub last_message: Option, + pub unread_messages_count: usize, + pub title: Option, + pub archived: bool, + pub muted: bool, +} + +#[derive(Deserialize, Serialize, Debug, Clone)] +pub struct ThreadMetadataMessageContent { + pub sender: prelude::Uuid, + pub timestamp: u64, + pub message: Option, + +} \ No newline at end of file diff --git a/presage/src/manager.rs b/presage/src/manager.rs index 6755c4f88..64a1f5e30 100644 --- a/presage/src/manager.rs +++ b/presage/src/manager.rs @@ -26,9 +26,10 @@ use libsignal_service::{ messagepipe::ServiceCredentials, models::Contact, prelude::{phonenumber::PhoneNumber, Content, ProfileKey, PushService, Uuid}, + profile_name::ProfileName, proto::{ data_message::Delete, sync_message, AttachmentPointer, Envelope, GroupContextV2, - NullMessage, + NullMessage, Verified, }, protocol::{KeyPair, PrivateKey, PublicKey, SenderCertificate}, provisioning::{generate_registration_id, LinkingManager, SecondaryDeviceProvisioning}, @@ -49,7 +50,7 @@ use libsignal_service::{ use libsignal_service_hyper::push_service::HyperPushService; use crate::cache::CacheCell; -use crate::{serde::serde_profile_key, Thread}; +use crate::{serializers::serde_profile_key, Thread, ThreadMetadata}; use crate::{store::Store, Error}; type ServiceCipher = cipher::ServiceCipher; @@ -795,6 +796,11 @@ impl Manager { Ok(iter.map(|r| r.map_err(Into::into))) } + /// Save a contact to the [Store] + pub fn save_contact(&mut self, contact: Contact) -> Result<(), C::Error> { + self.config_store.save_contact(contact) + } + /// Get a group (either from the local cache, or fetch it remotely) using its master key pub fn group(&self, master_key_bytes: &[u8]) -> Result, Error> { Ok(self.config_store.group(master_key_bytes.try_into()?)?) @@ -953,6 +959,64 @@ impl Manager { log::trace!("{group:?}"); } } + let uuid = content.metadata.sender.uuid.clone(); + match state.config_store.contact_by_id(uuid) { + Ok(Some(_)) => {} + Ok(None) => { + // Fetch the profile of the contact + if let ContentBody::DataMessage(DataMessage { + profile_key: Some(profile_key), + .. + }) = &content.body + { + let contact = Contact { + uuid: uuid.clone(), + name: "".to_string(), + color: None, + phone_number: None, + verified: Verified { + identity_key: None, + state: None, + destination_uuid: None, + null_message: None, + }, + blocked: false, + expire_timer: 0, + inbox_position: 0, + archived: false, + avatar: None, + profile_key: profile_key.to_vec(), + }; + match state.config_store.save_contact(contact) { + Ok(_) => { + log::info!("Saved contact: {}", uuid); + } + Err(e) => { + log::error!("Error saving contact: {}", e); + } + } + } + } + Err(e) => { + log::error!("Error getting contact: {}", e); + } + } + + let thread = Thread::try_from(&content).unwrap(); + + let store = &mut state.config_store; + + match store.thread_metadata(&thread) { + Ok(metadata) => { + if metadata.is_none() { + // Create a new thread metadata and save it + create_thread_metadata(store, &thread).ok()?; + } + } + Err(e) => { + log::error!("Error getting thread metadata: {}", e); + } + }; if let Err(e) = save_message(&mut state.config_store, content.clone()) @@ -1263,6 +1327,192 @@ impl Manager { Ok(service_cipher) } + // Returns the title for a thread depending on the type of thread. + pub async fn get_title_for_thread(&self, thread: &Thread) -> Result> { + match thread { + Thread::Contact(uuid) => { + let contact = match self.contact_by_id(uuid) { + Ok(contact) => contact, + Err(e) => { + log::info!("Error getting contact by id: {}, {:?}", e, uuid); + None + } + }; + Ok(match contact { + Some(contact) => contact.name, + None => uuid.to_string(), + }) + } + Thread::Group(id) => match self.group(id)? { + Some(group) => Ok(group.title), + None => Ok("".to_string()), + }, + } + } + + pub async fn request_contacts_update_from_profile(&mut self) -> Result<(), Error> { + log::debug!("requesting contacts update from profile"); + for contact in self.contacts()? { + let mut contact = contact?; + let uuid = contact.uuid; + if contact.name.is_empty() { + let k = contact.profile_key.to_vec(); + let profile_key: [u8; 32] = match k.try_into() { + Ok(key) => key, + Err(_) => continue, + }; + let profile = match self + .retrieve_profile_by_uuid(contact.uuid, ProfileKey { bytes: profile_key }) + .await + { + Ok(profile) => profile, + Err(_) => continue, + }; + let name = profile.name.unwrap_or(ProfileName { + given_name: match contact.phone_number { + Some(_) => "".to_string(), + None => continue, + }, + family_name: None, + }); + contact.name = name.to_string(); + match self.save_contact(contact) { + Ok(_) => {} + Err(e) => { + println!("Error saving contact: {:?}", e); + } + }; + println!("Updating contact: {:?}", name); + } + let contact_thread = Thread::Contact(uuid); + + match self.thread_metadata(&contact_thread).await? { + Some(thread_metadata) => { + let title = self.get_title_for_thread(&contact_thread).await?; + if thread_metadata.title == Some(title.clone()) { + continue; + } + let mut thread_metadata = thread_metadata; + thread_metadata.title = Some(title); + self.save_thread_metadata(thread_metadata)?; + } + None => { + log::debug!("no thread metadata for contact {}", uuid); + let title = self.get_title_for_thread(&contact_thread).await?; + + self.save_thread_metadata(ThreadMetadata { + thread: contact_thread, + last_message: None, + unread_messages_count: 0, + title: Some(title), + archived: false, + muted: false, + })?; + continue; + } + }; + } + Ok(()) + } + pub async fn request_contact_update_from_profile( + &mut self, + uuid: Uuid, + ) -> Result> { + log::debug!("requesting contacts update from profile"); + let contact = self.contact_by_id(&uuid)?; + match contact { + Some(mut contact) => { + let k = contact.profile_key.to_vec(); + let profile_key: [u8; 32] = match k.try_into() { + Ok(key) => key, + Err(_) => { + log::debug!("Error converting profile key to bytes"); + return Err(Error::UnknownContact); + } + }; + let profile = match self + .retrieve_profile_by_uuid(contact.uuid, ProfileKey { bytes: profile_key }) + .await + { + Ok(profile) => profile, + Err(e) => { + log::debug!("Error retrieving profile {}", e); + return Err(Error::UnknownContact); + } + }; + let name = profile.name.unwrap_or(ProfileName { + given_name: match contact.phone_number { + Some(_) => "".to_string(), + None => "Unknown Contact".to_string(), + }, + family_name: None, + }); + contact.name = name.to_string(); + match self.save_contact(contact) { + Ok(_) => {} + Err(e) => { + println!("Error saving contact: {:?}", e); + } + }; + contact = self.contact_by_id(&uuid)?.unwrap(); + + println!("Updating contact: {:?}", name); + + let contact_thread = Thread::Contact(uuid); + + match self.thread_metadata(&contact_thread).await? { + Some(thread_metadata) => { + if thread_metadata.title != Some(name.to_string()) { + let mut thread_metadata = thread_metadata; + thread_metadata.title = Some(name.to_string()); + self.save_thread_metadata(thread_metadata)?; + } + } + None => { + log::debug!("no thread metadata for contact {}", uuid); + + self.save_thread_metadata(ThreadMetadata { + thread: contact_thread, + last_message: None, + unread_messages_count: 0, + title: Some(name.to_string()), + archived: false, + muted: false, + })?; + } + }; + return Ok(contact); + } + None => return Err(Error::UnknownContact), + } + } + + // Returns the metadatas for all threads. + pub async fn thread_metadatas( + &self, + ) -> Result>>, Error> + { + let iter = self.config_store.thread_metadatas()?; + Ok(iter.map(|r| r.map_err(Into::into))) + } + + // Returns the metadata for a thread. + pub async fn thread_metadata( + &self, + thread: &Thread, + ) -> Result, Error> { + let metadata = self.config_store.thread_metadata(&thread)?; + Ok(metadata) + } + + // Saves the metadata for a thread. + pub fn save_thread_metadata( + &mut self, + metadata: ThreadMetadata, + ) -> Result<(), Error> { + self.config_store.save_thread_metadata(metadata)?; + Ok(()) + } /// Returns the title of a thread (contact or group). pub async fn thread_title(&self, thread: &Thread) -> Result> { @@ -1413,7 +1663,48 @@ fn save_message(config_store: &mut C, message: Content) -> Result<(), let thread = Thread::try_from(&message)?; save_message_with_thread(config_store, message, thread) } +pub fn save_thread_metadata( + config_store: &mut C, + metadata: ThreadMetadata, +) -> Result<(), Error> { + config_store.save_thread_metadata(metadata)?; + Ok(()) +} +pub fn create_thread_metadata( + config_store: &mut C, + thread: &Thread, +) -> Result> { + let title = match thread { + Thread::Contact(uuid) => { + let contact = match config_store.contact_by_id(*uuid) { + Ok(contact) => contact, + Err(e) => { + log::info!("Error getting contact by id: {}, {:?}", e, uuid); + None + } + }; + match contact { + Some(contact) => contact.name, + None => uuid.to_string(), + } + } + Thread::Group(id) => match config_store.group(*id)? { + Some(group) => group.title, + None => "".to_string(), + }, + }; + let metadata = ThreadMetadata { + thread: thread.clone(), + unread_messages_count: 0, + last_message: None, + title: Some(title), + archived: false, + muted: false, + }; + save_thread_metadata(config_store, metadata.clone())?; + Ok(metadata) +} #[cfg(test)] mod tests { use libsignal_service::prelude::ProfileKey; diff --git a/presage/src/serde.rs b/presage/src/serializers.rs similarity index 100% rename from presage/src/serde.rs rename to presage/src/serializers.rs diff --git a/presage/src/store.rs b/presage/src/store.rs index 9315a9920..c8499700f 100644 --- a/presage/src/store.rs +++ b/presage/src/store.rs @@ -1,6 +1,6 @@ use std::{fmt, ops::RangeBounds}; -use crate::{manager::Registered, GroupMasterKeyBytes}; +use crate::{manager::Registered, GroupMasterKeyBytes, ThreadMetadata}; use libsignal_service::{ content::ContentBody, groups_v2::Group, @@ -21,6 +21,7 @@ pub trait Store: ProtocolStore + SenderKeyStore + SessionStoreExt + Sync + Clone type ContactsIter: Iterator>; type GroupsIter: Iterator>; type MessagesIter: Iterator>; + type ThreadMetadataIter: Iterator>; /// State @@ -99,6 +100,9 @@ pub trait Store: ProtocolStore + SenderKeyStore + SessionStoreExt + Sync + Clone fn save_contacts(&mut self, contacts: impl Iterator) -> Result<(), Self::Error>; + /// Save a single contact + fn save_contact(&mut self, contact: Contact) -> Result<(), Self::Error>; + /// Get an iterator on all stored (synchronized) contacts fn contacts(&self) -> Result; @@ -136,6 +140,19 @@ pub trait Store: ProtocolStore + SenderKeyStore + SessionStoreExt + Sync + Clone /// Retrieve a profile by [Uuid] and [ProfileKey]. fn profile(&self, uuid: Uuid, key: ProfileKey) -> Result, Self::Error>; + + /// Retrieve ThereadMetadata for all threads. + fn thread_metadatas(&self) -> Result; + + /// Retrieve ThereadMetadata for a single thread. + fn thread_metadata(&self, thread: &Thread) -> Result, Self::Error>; + + /// Save ThereadMetadata for a single thread. + /// This will overwrite any existing metadata for the thread. + /// + fn save_thread_metadata(&mut self, metadata: ThreadMetadata) -> Result<(), Self::Error>; + + } /// A thread specifies where a message was sent, either to or from a contact or in a group. From 8ec684d9f878b5f60d84fd885c9ca664f9985222 Mon Sep 17 00:00:00 2001 From: Aaron Date: Wed, 20 Sep 2023 23:22:49 +0200 Subject: [PATCH 2/6] Add some comments --- presage/src/manager.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/presage/src/manager.rs b/presage/src/manager.rs index 64a1f5e30..d0b5bb7eb 100644 --- a/presage/src/manager.rs +++ b/presage/src/manager.rs @@ -963,7 +963,7 @@ impl Manager { match state.config_store.contact_by_id(uuid) { Ok(Some(_)) => {} Ok(None) => { - // Fetch the profile of the contact + // Create a new contact if let ContentBody::DataMessage(DataMessage { profile_key: Some(profile_key), .. @@ -987,6 +987,7 @@ impl Manager { avatar: None, profile_key: profile_key.to_vec(), }; + // Todo: get the profile from the server match state.config_store.save_contact(contact) { Ok(_) => { log::info!("Saved contact: {}", uuid); @@ -1349,7 +1350,7 @@ impl Manager { }, } } - + // this checks for contacts that have no name and updates them from the profile pub async fn request_contacts_update_from_profile(&mut self) -> Result<(), Error> { log::debug!("requesting contacts update from profile"); for contact in self.contacts()? { @@ -1414,6 +1415,8 @@ impl Manager { } Ok(()) } + + // this updates a single contact from the profile pub async fn request_contact_update_from_profile( &mut self, uuid: Uuid, @@ -1679,6 +1682,7 @@ pub fn create_thread_metadata( Thread::Contact(uuid) => { let contact = match config_store.contact_by_id(*uuid) { Ok(contact) => contact, + // TODO: propably we should create the contact and update the profile here. Err(e) => { log::info!("Error getting contact by id: {}, {:?}", e, uuid); None From b806e925da080e7a033632aef339a5beba1d9b0b Mon Sep 17 00:00:00 2001 From: Aaron Date: Sat, 14 Oct 2023 21:44:15 +0200 Subject: [PATCH 3/6] solve merge conflicts --- presage-store-sled/src/lib.rs | 2 +- presage/src/manager.rs | 18 +++++------------- 2 files changed, 6 insertions(+), 14 deletions(-) diff --git a/presage-store-sled/src/lib.rs b/presage-store-sled/src/lib.rs index 4643f8d3e..3fa42da51 100644 --- a/presage-store-sled/src/lib.rs +++ b/presage-store-sled/src/lib.rs @@ -31,7 +31,7 @@ use protobuf::ContentProto; use serde::{de::DeserializeOwned, Deserialize, Serialize}; use sha2::{Digest, Sha256}; use sled::{Batch, IVec}; - +use presage_store_cipher::StoreCipher; use presage::{GroupMasterKeyBytes, Registered, Store, Thread, ThreadMetadata}; mod error; diff --git a/presage/src/manager.rs b/presage/src/manager.rs index 74805ab12..de6174a59 100644 --- a/presage/src/manager.rs +++ b/presage/src/manager.rs @@ -978,7 +978,7 @@ impl Manager { verified: Verified { identity_key: None, state: None, - destination_uuid: None, + destination_aci: None, null_message: None, }, blocked: false, @@ -1006,14 +1006,11 @@ impl Manager { let thread = Thread::try_from(&content).unwrap(); - let store = &mut state.config_store; - - match store.thread_metadata(&thread) { - Ok(metadata) => { - if metadata.is_none() { + match state.config_store.thread_metadata(&thread) { + Ok(Some(_)) => {}, + Ok(None) => { // Create a new thread metadata and save it - create_thread_metadata(store, &thread).ok()?; - } + create_thread_metadata(&mut state.config_store, &thread).ok()?; } Err(e) => { log::error!("Error getting thread metadata: {}", e); @@ -1714,11 +1711,6 @@ fn save_message(config_store: &mut C, message: Content) -> Result<(), Ok(()) } - -fn save_message(config_store: &mut C, message: Content) -> Result<(), Error> { - let thread = Thread::try_from(&message)?; - save_message_with_thread(config_store, message, thread) -} pub fn save_thread_metadata( config_store: &mut C, metadata: ThreadMetadata, From 1a1b9c86d23c3666cdc910078c08599545ac20c1 Mon Sep 17 00:00:00 2001 From: Aaron Date: Sat, 18 Nov 2023 00:40:34 +0100 Subject: [PATCH 4/6] make linter happy --- presage-store-sled/src/lib.rs | 20 ++++++++++-------- presage/src/lib.rs | 8 +++----- presage/src/manager/linking.rs | 7 +++++-- presage/src/manager/registration.rs | 7 +++++-- presage/src/store.rs | 32 ++++++++++++++++------------- 5 files changed, 43 insertions(+), 31 deletions(-) diff --git a/presage-store-sled/src/lib.rs b/presage-store-sled/src/lib.rs index c67d39b9e..088210ecf 100644 --- a/presage-store-sled/src/lib.rs +++ b/presage-store-sled/src/lib.rs @@ -5,6 +5,7 @@ use std::{ time::{SystemTime, UNIX_EPOCH}, }; +use crate::protobuf::ContentProto; use async_trait::async_trait; use log::{debug, error, trace, warn}; use presage::libsignal_service::zkgroup::GroupMasterKeyBytes; @@ -25,14 +26,13 @@ use presage::libsignal_service::{ Profile, ServiceAddress, }; use presage::store::{ContentExt, ContentsStore, PreKeyStoreExt, StateStore, Store, Thread}; +use presage::ThreadMetadata; use presage::{manager::RegistrationData, proto::verified}; +use presage_store_cipher::StoreCipher; use prost::Message; use serde::{de::DeserializeOwned, Deserialize, Serialize}; use sha2::{Digest, Sha256}; use sled::{Batch, IVec}; -use presage_store_cipher::StoreCipher; -use presage::{ThreadMetadata}; -use crate::protobuf::ContentProto; mod error; mod protobuf; @@ -626,20 +626,24 @@ impl ContentsStore for SledStore { } /// Thread metadata - fn save_thread_metadata(&mut self, metadata: ThreadMetadata) -> Result<(), Self::ContentsStoreError> { + fn save_thread_metadata( + &mut self, + metadata: ThreadMetadata, + ) -> Result<(), Self::ContentsStoreError> { let key = self.thread_metadata_key(&metadata.thread); self.insert(SLED_TREE_THREADS_METADATA, key, metadata)?; Ok(()) } - fn thread_metadata(&self, thread: &Thread) -> Result, Self::ContentsStoreError> { + fn thread_metadata( + &self, + thread: &Thread, + ) -> Result, Self::ContentsStoreError> { let key = self.thread_metadata_key(thread); self.get(SLED_TREE_THREADS_METADATA, key) } - fn thread_metadatas( - &self, - ) -> Result { + fn thread_metadatas(&self) -> Result { let tree = self.read().open_tree(SLED_TREE_THREADS_METADATA)?; let iter = tree.iter(); Ok(SledThreadMetadataIter { diff --git a/presage/src/lib.rs b/presage/src/lib.rs index 8a1eac275..d3634d343 100644 --- a/presage/src/lib.rs +++ b/presage/src/lib.rs @@ -5,14 +5,13 @@ use serde::{Deserialize, Serialize}; pub mod manager; pub mod store; +pub use crate::libsignal_service::prelude; +pub use errors::Error; pub use libsignal_service; /// Protobufs used in Signal protocol and service communication pub use libsignal_service::proto; - -pub use errors::Error; pub use manager::Manager; pub use store::Thread; -pub use crate::libsignal_service::prelude; const USER_AGENT: &str = concat!(env!("CARGO_PKG_NAME"), "-rs-", env!("CARGO_PKG_VERSION")); @@ -34,5 +33,4 @@ pub struct ThreadMetadataMessageContent { pub sender: prelude::Uuid, pub timestamp: u64, pub message: Option, - -} \ No newline at end of file +} diff --git a/presage/src/manager/linking.rs b/presage/src/manager/linking.rs index d761a72ab..5d3b9ce8c 100644 --- a/presage/src/manager/linking.rs +++ b/presage/src/manager/linking.rs @@ -32,8 +32,11 @@ impl Manager { /// /// #[tokio::main] /// async fn main() -> Result<(), Box> { - /// let store = - /// SledStore::open("/tmp/presage-example", MigrationConflictStrategy::Drop, OnNewIdentity::Trust)?; + /// let store = SledStore::open( + /// "/tmp/presage-example", + /// MigrationConflictStrategy::Drop, + /// OnNewIdentity::Trust, + /// )?; /// /// let (mut tx, mut rx) = oneshot::channel(); /// let (manager, err) = future::join( diff --git a/presage/src/manager/registration.rs b/presage/src/manager/registration.rs index e70b7ab83..9de26073a 100644 --- a/presage/src/manager/registration.rs +++ b/presage/src/manager/registration.rs @@ -43,8 +43,11 @@ impl Manager { /// /// #[tokio::main] /// async fn main() -> Result<(), Box> { - /// let store = - /// SledStore::open("/tmp/presage-example", MigrationConflictStrategy::Drop, OnNewIdentity::Trust)?; + /// let store = SledStore::open( + /// "/tmp/presage-example", + /// MigrationConflictStrategy::Drop, + /// OnNewIdentity::Trust, + /// )?; /// /// let manager = Manager::register( /// store, diff --git a/presage/src/store.rs b/presage/src/store.rs index c677fc591..ce60162af 100644 --- a/presage/src/store.rs +++ b/presage/src/store.rs @@ -2,7 +2,7 @@ use std::{fmt, ops::RangeBounds, time::SystemTime}; -use crate::{GroupMasterKeyBytes, ThreadMetadata, manager::RegistrationData}; +use crate::{manager::RegistrationData, GroupMasterKeyBytes, ThreadMetadata}; use libsignal_service::{ content::{ContentBody, Metadata}, groups_v2::Group, @@ -23,14 +23,14 @@ use serde::{Deserialize, Serialize}; pub trait StoreError: std::error::Error + Sync + Send + 'static {} // pub trait Store: ProtocolStore + SenderKeyStore + SessionStoreExt + Sync + Clone { - // type Error: StoreError; -// - // type ContactsIter: Iterator>; - // type GroupsIter: Iterator>; - // type MessagesIter: Iterator>; - // type ThreadMetadataIter: Iterator>; -// - /// State +// type Error: StoreError; +// +// type ContactsIter: Iterator>; +// type GroupsIter: Iterator>; +// type MessagesIter: Iterator>; +// type ThreadMetadataIter: Iterator>; +// +/// State /// Stores the registered state of the manager pub trait StateStore { type StateStoreError: StoreError; @@ -83,7 +83,7 @@ pub trait ContentsStore { type GroupsIter: Iterator>; /// Iterator over all stored thread metadata - /// + /// /// Each item is a tuple consisting of the thread and its corresponding metadata. type ThreadMetadataIter: Iterator>; @@ -245,13 +245,17 @@ pub trait ContentsStore { fn thread_metadatas(&self) -> Result; /// Retrieve ThereadMetadata for a single thread. - fn thread_metadata(&self, thread: &Thread) -> Result, Self::ContentsStoreError>; + fn thread_metadata( + &self, + thread: &Thread, + ) -> Result, Self::ContentsStoreError>; /// Save ThereadMetadata for a single thread. /// This will overwrite any existing metadata for the thread. - /// - fn save_thread_metadata(&mut self, metadata: ThreadMetadata) -> Result<(), Self::ContentsStoreError>; - + fn save_thread_metadata( + &mut self, + metadata: ThreadMetadata, + ) -> Result<(), Self::ContentsStoreError>; fn profile( &self, From da4ef190e70eeb7835e34f41a1d4b7f6928b216e Mon Sep 17 00:00:00 2001 From: Aaron Date: Sat, 18 Nov 2023 23:45:29 +0100 Subject: [PATCH 5/6] don't use pointers --- presage-store-sled/src/lib.rs | 6 +++--- presage/src/store.rs | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/presage-store-sled/src/lib.rs b/presage-store-sled/src/lib.rs index 088210ecf..4789c05aa 100644 --- a/presage-store-sled/src/lib.rs +++ b/presage-store-sled/src/lib.rs @@ -307,7 +307,7 @@ impl SledStore { format!("{:x}", hasher.finalize()) } - fn thread_metadata_key(&self, thread: &Thread) -> Vec { + fn thread_metadata_key(&self, thread: Thread) -> Vec { match thread { Thread::Contact(contact) => contact.to_string().into_bytes(), Thread::Group(group) => group.to_vec(), @@ -630,14 +630,14 @@ impl ContentsStore for SledStore { &mut self, metadata: ThreadMetadata, ) -> Result<(), Self::ContentsStoreError> { - let key = self.thread_metadata_key(&metadata.thread); + let key = self.thread_metadata_key(metadata.thread.clone()); self.insert(SLED_TREE_THREADS_METADATA, key, metadata)?; Ok(()) } fn thread_metadata( &self, - thread: &Thread, + thread: Thread, ) -> Result, Self::ContentsStoreError> { let key = self.thread_metadata_key(thread); self.get(SLED_TREE_THREADS_METADATA, key) diff --git a/presage/src/store.rs b/presage/src/store.rs index ce60162af..b6cbf64f7 100644 --- a/presage/src/store.rs +++ b/presage/src/store.rs @@ -247,7 +247,7 @@ pub trait ContentsStore { /// Retrieve ThereadMetadata for a single thread. fn thread_metadata( &self, - thread: &Thread, + thread: Thread, ) -> Result, Self::ContentsStoreError>; /// Save ThereadMetadata for a single thread. From ca8a9afbf390113810acd4d7a100cb6c4222dd74 Mon Sep 17 00:00:00 2001 From: Aaron Date: Wed, 27 Dec 2023 18:35:50 +0100 Subject: [PATCH 6/6] fix: don't duplicate save_contact --- presage-store-sled/src/lib.rs | 8 +------- presage/src/store.rs | 3 --- 2 files changed, 1 insertion(+), 10 deletions(-) diff --git a/presage-store-sled/src/lib.rs b/presage-store-sled/src/lib.rs index 4ee9d531f..4d1af74c0 100644 --- a/presage-store-sled/src/lib.rs +++ b/presage-store-sled/src/lib.rs @@ -26,7 +26,7 @@ use presage::libsignal_service::{ session_store::SessionStoreExt, Profile, ServiceAddress, }; -use presage::store::{ContentExt, ContentsStore, PreKeyStoreExt, StateStore, Store, Thread}; +use presage::store::{ContentExt, ContentsStore, StateStore, Store, Thread}; use presage::ThreadMetadata; use presage::{manager::RegistrationData, proto::verified}; use presage_store_cipher::StoreCipher; @@ -448,12 +448,6 @@ impl ContentsStore for SledStore { Ok(()) } - fn save_contact(&mut self, contact: Contact) -> Result<(), Self::ContentsStoreError> { - self.insert(SLED_TREE_CONTACTS, contact.uuid, contact)?; - debug!("saved contact"); - Ok(()) - } - fn contacts(&self) -> Result { Ok(SledContactsIter { iter: self.read().open_tree(SLED_TREE_CONTACTS)?.iter(), diff --git a/presage/src/store.rs b/presage/src/store.rs index b0b1e2ae9..2f991844f 100644 --- a/presage/src/store.rs +++ b/presage/src/store.rs @@ -200,9 +200,6 @@ pub trait ContentsStore { /// Save a contact fn save_contact(&mut self, contacts: &Contact) -> Result<(), Self::ContentsStoreError>; - /// Save a single contact - fn save_contact(&mut self, contact: Contact) -> Result<(), Self::ContentsStoreError>; - /// Get an iterator on all stored (synchronized) contacts fn contacts(&self) -> Result;