diff --git a/crates/matrix-sdk-crypto/src/store/mod.rs b/crates/matrix-sdk-crypto/src/store/mod.rs index 9967f8709..eed2662e9 100644 --- a/crates/matrix-sdk-crypto/src/store/mod.rs +++ b/crates/matrix-sdk-crypto/src/store/mod.rs @@ -38,14 +38,6 @@ //! [`OlmMachine`]: /matrix_sdk_crypto/struct.OlmMachine.html //! [`CryptoStore`]: trait.Cryptostore.html -pub mod caches; -mod memorystore; - -#[cfg(any(test, feature = "testing"))] -#[macro_use] -#[allow(missing_docs)] -pub mod integration_tests; - use std::{ collections::{HashMap, HashSet}, fmt::Debug, @@ -54,14 +46,11 @@ use std::{ sync::{atomic::AtomicBool, Arc}, }; -use async_trait::async_trait; use atomic::Ordering; use dashmap::DashSet; -use matrix_sdk_common::{locks::Mutex, AsyncTraitDeps}; -pub use memorystore::MemoryStore; +use matrix_sdk_common::locks::Mutex; use ruma::{ - events::secret::request::SecretName, DeviceId, IdParseError, OwnedDeviceId, OwnedUserId, - RoomId, TransactionId, UserId, + events::secret::request::SecretName, DeviceId, IdParseError, OwnedDeviceId, OwnedUserId, UserId, }; use serde::{Deserialize, Serialize}; use serde_json::Error as SerdeError; @@ -70,6 +59,18 @@ use tracing::{info, warn}; use vodozemac::{megolm::SessionOrdering, Curve25519PublicKey}; use zeroize::Zeroize; +pub mod caches; +mod memorystore; +mod traits; + +#[cfg(any(test, feature = "testing"))] +#[macro_use] +#[allow(missing_docs)] +pub mod integration_tests; + +pub use memorystore::MemoryStore; +pub use traits::{CryptoStore, IntoCryptoStore}; + use crate::{ identities::{ user::{OwnUserIdentity, UserIdentities, UserIdentity}, @@ -786,179 +787,3 @@ impl CryptoStoreError { Self::Backend(Box::new(error)) } } - -/// Represents a store that the `OlmMachine` uses to store E2EE data (such as -/// cryptographic keys). -#[cfg_attr(target_arch = "wasm32", async_trait(?Send))] -#[cfg_attr(not(target_arch = "wasm32"), async_trait)] -pub trait CryptoStore: AsyncTraitDeps { - /// Load an account that was previously stored. - async fn load_account(&self) -> Result>; - - /// Save the given account in the store. - /// - /// # Arguments - /// - /// * `account` - The account that should be stored. - async fn save_account(&self, account: ReadOnlyAccount) -> Result<()>; - - /// Try to load a private cross signing identity, if one is stored. - async fn load_identity(&self) -> Result>; - - /// Save the set of changes to the store. - /// - /// # Arguments - /// - /// * `changes` - The set of changes that should be stored. - async fn save_changes(&self, changes: Changes) -> Result<()>; - - /// Get all the sessions that belong to the given sender key. - /// - /// # Arguments - /// - /// * `sender_key` - The sender key that was used to establish the sessions. - async fn get_sessions(&self, sender_key: &str) -> Result>>>>; - - /// Get the inbound group session from our store. - /// - /// # Arguments - /// * `room_id` - The room id of the room that the session belongs to. - /// - /// * `sender_key` - The sender key that sent us the session. - /// - /// * `session_id` - The unique id of the session. - async fn get_inbound_group_session( - &self, - room_id: &RoomId, - session_id: &str, - ) -> Result>; - - /// Get all the inbound group sessions we have stored. - async fn get_inbound_group_sessions(&self) -> Result>; - - /// Get the number inbound group sessions we have and how many of them are - /// backed up. - async fn inbound_group_session_counts(&self) -> Result; - - /// Get all the inbound group sessions we have not backed up yet. - async fn inbound_group_sessions_for_backup( - &self, - limit: usize, - ) -> Result>; - - /// Reset the backup state of all the stored inbound group sessions. - async fn reset_backup_state(&self) -> Result<()>; - - /// Get the backup keys we have stored. - async fn load_backup_keys(&self) -> Result; - - /// Get the outbound group session we have stored that is used for the - /// given room. - async fn get_outbound_group_session( - &self, - room_id: &RoomId, - ) -> Result>; - - /// Load the list of users whose devices we are keeping track of. - async fn load_tracked_users(&self) -> Result>; - - /// Save a list of users and their respective dirty/outdated flags to the - /// store. - async fn save_tracked_users(&self, users: &[(&UserId, bool)]) -> Result<()>; - - /// Get the device for the given user with the given device ID. - /// - /// # Arguments - /// - /// * `user_id` - The user that the device belongs to. - /// - /// * `device_id` - The unique id of the device. - async fn get_device( - &self, - user_id: &UserId, - device_id: &DeviceId, - ) -> Result>; - - /// Get all the devices of the given user. - /// - /// # Arguments - /// - /// * `user_id` - The user for which we should get all the devices. - async fn get_user_devices( - &self, - user_id: &UserId, - ) -> Result>; - - /// Get the user identity that is attached to the given user id. - /// - /// # Arguments - /// - /// * `user_id` - The user for which we should get the identity. - async fn get_user_identity(&self, user_id: &UserId) -> Result>; - - /// Check if a hash for an Olm message stored in the database. - async fn is_message_known(&self, message_hash: &OlmMessageHash) -> Result; - - /// Get an outgoing secret request that we created that matches the given - /// request id. - /// - /// # Arguments - /// - /// * `request_id` - The unique request id that identifies this outgoing - /// secret request. - async fn get_outgoing_secret_requests( - &self, - request_id: &TransactionId, - ) -> Result>; - - /// Get an outgoing key request that we created that matches the given - /// requested key info. - /// - /// # Arguments - /// - /// * `key_info` - The key info of an outgoing secret request. - async fn get_secret_request_by_info( - &self, - secret_info: &SecretInfo, - ) -> Result>; - - /// Get all outgoing secret requests that we have in the store. - async fn get_unsent_secret_requests(&self) -> Result>; - - /// Delete an outgoing key request that we created that matches the given - /// request id. - /// - /// # Arguments - /// - /// * `request_id` - The unique request id that identifies this outgoing key - /// request. - async fn delete_outgoing_secret_requests(&self, request_id: &TransactionId) -> Result<()>; -} - -/// A type that can be type-erased into `Arc`. -/// -/// This trait is not meant to be implemented directly outside -/// `matrix-sdk-crypto`, but it is automatically implemented for everything that -/// implements `CryptoStore`. -pub trait IntoCryptoStore { - #[doc(hidden)] - fn into_crypto_store(self) -> Arc; -} - -impl IntoCryptoStore for T -where - T: CryptoStore + Sized + 'static, -{ - fn into_crypto_store(self) -> Arc { - Arc::new(self) - } -} - -impl IntoCryptoStore for Arc -where - T: CryptoStore + 'static, -{ - fn into_crypto_store(self) -> Arc { - self - } -} diff --git a/crates/matrix-sdk-crypto/src/store/traits.rs b/crates/matrix-sdk-crypto/src/store/traits.rs new file mode 100644 index 000000000..709309012 --- /dev/null +++ b/crates/matrix-sdk-crypto/src/store/traits.rs @@ -0,0 +1,191 @@ +use std::{collections::HashMap, sync::Arc}; + +use async_trait::async_trait; +use matrix_sdk_common::{locks::Mutex, AsyncTraitDeps}; +use ruma::{DeviceId, OwnedDeviceId, RoomId, TransactionId, UserId}; + +use super::{BackupKeys, Changes, Result, RoomKeyCounts}; +use crate::{ + olm::{ + InboundGroupSession, OlmMessageHash, OutboundGroupSession, PrivateCrossSigningIdentity, + Session, + }, + GossipRequest, ReadOnlyAccount, ReadOnlyDevice, ReadOnlyUserIdentities, SecretInfo, + TrackedUser, +}; + +/// Represents a store that the `OlmMachine` uses to store E2EE data (such as +/// cryptographic keys). +#[cfg_attr(target_arch = "wasm32", async_trait(?Send))] +#[cfg_attr(not(target_arch = "wasm32"), async_trait)] +pub trait CryptoStore: AsyncTraitDeps { + /// Load an account that was previously stored. + async fn load_account(&self) -> Result>; + + /// Save the given account in the store. + /// + /// # Arguments + /// + /// * `account` - The account that should be stored. + async fn save_account(&self, account: ReadOnlyAccount) -> Result<()>; + + /// Try to load a private cross signing identity, if one is stored. + async fn load_identity(&self) -> Result>; + + /// Save the set of changes to the store. + /// + /// # Arguments + /// + /// * `changes` - The set of changes that should be stored. + async fn save_changes(&self, changes: Changes) -> Result<()>; + + /// Get all the sessions that belong to the given sender key. + /// + /// # Arguments + /// + /// * `sender_key` - The sender key that was used to establish the sessions. + async fn get_sessions(&self, sender_key: &str) -> Result>>>>; + + /// Get the inbound group session from our store. + /// + /// # Arguments + /// * `room_id` - The room id of the room that the session belongs to. + /// + /// * `sender_key` - The sender key that sent us the session. + /// + /// * `session_id` - The unique id of the session. + async fn get_inbound_group_session( + &self, + room_id: &RoomId, + session_id: &str, + ) -> Result>; + + /// Get all the inbound group sessions we have stored. + async fn get_inbound_group_sessions(&self) -> Result>; + + /// Get the number inbound group sessions we have and how many of them are + /// backed up. + async fn inbound_group_session_counts(&self) -> Result; + + /// Get all the inbound group sessions we have not backed up yet. + async fn inbound_group_sessions_for_backup( + &self, + limit: usize, + ) -> Result>; + + /// Reset the backup state of all the stored inbound group sessions. + async fn reset_backup_state(&self) -> Result<()>; + + /// Get the backup keys we have stored. + async fn load_backup_keys(&self) -> Result; + + /// Get the outbound group session we have stored that is used for the + /// given room. + async fn get_outbound_group_session( + &self, + room_id: &RoomId, + ) -> Result>; + + /// Load the list of users whose devices we are keeping track of. + async fn load_tracked_users(&self) -> Result>; + + /// Save a list of users and their respective dirty/outdated flags to the + /// store. + async fn save_tracked_users(&self, users: &[(&UserId, bool)]) -> Result<()>; + + /// Get the device for the given user with the given device ID. + /// + /// # Arguments + /// + /// * `user_id` - The user that the device belongs to. + /// + /// * `device_id` - The unique id of the device. + async fn get_device( + &self, + user_id: &UserId, + device_id: &DeviceId, + ) -> Result>; + + /// Get all the devices of the given user. + /// + /// # Arguments + /// + /// * `user_id` - The user for which we should get all the devices. + async fn get_user_devices( + &self, + user_id: &UserId, + ) -> Result>; + + /// Get the user identity that is attached to the given user id. + /// + /// # Arguments + /// + /// * `user_id` - The user for which we should get the identity. + async fn get_user_identity(&self, user_id: &UserId) -> Result>; + + /// Check if a hash for an Olm message stored in the database. + async fn is_message_known(&self, message_hash: &OlmMessageHash) -> Result; + + /// Get an outgoing secret request that we created that matches the given + /// request id. + /// + /// # Arguments + /// + /// * `request_id` - The unique request id that identifies this outgoing + /// secret request. + async fn get_outgoing_secret_requests( + &self, + request_id: &TransactionId, + ) -> Result>; + + /// Get an outgoing key request that we created that matches the given + /// requested key info. + /// + /// # Arguments + /// + /// * `key_info` - The key info of an outgoing secret request. + async fn get_secret_request_by_info( + &self, + secret_info: &SecretInfo, + ) -> Result>; + + /// Get all outgoing secret requests that we have in the store. + async fn get_unsent_secret_requests(&self) -> Result>; + + /// Delete an outgoing key request that we created that matches the given + /// request id. + /// + /// # Arguments + /// + /// * `request_id` - The unique request id that identifies this outgoing key + /// request. + async fn delete_outgoing_secret_requests(&self, request_id: &TransactionId) -> Result<()>; +} + +/// A type that can be type-erased into `Arc`. +/// +/// This trait is not meant to be implemented directly outside +/// `matrix-sdk-crypto`, but it is automatically implemented for everything that +/// implements `CryptoStore`. +pub trait IntoCryptoStore { + #[doc(hidden)] + fn into_crypto_store(self) -> Arc; +} + +impl IntoCryptoStore for T +where + T: CryptoStore + Sized + 'static, +{ + fn into_crypto_store(self) -> Arc { + Arc::new(self) + } +} + +impl IntoCryptoStore for Arc +where + T: CryptoStore + 'static, +{ + fn into_crypto_store(self) -> Arc { + self + } +}