From 5f435a86ee1cef6f6854725116e5df7969219204 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Tue, 16 Jan 2024 12:57:18 +0000 Subject: [PATCH 1/3] Factor out `build_store_config` function --- crates/matrix-sdk/src/client/builder.rs | 32 +++++++++++++++---------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/crates/matrix-sdk/src/client/builder.rs b/crates/matrix-sdk/src/client/builder.rs index fcb1a2a08..597d31d10 100644 --- a/crates/matrix-sdk/src/client/builder.rs +++ b/crates/matrix-sdk/src/client/builder.rs @@ -368,19 +368,7 @@ impl ClientBuilder { let base_client = if let Some(base_client) = self.base_client { base_client } else { - #[allow(clippy::infallible_destructuring_match)] - let store_config = match self.store_config { - #[cfg(feature = "sqlite")] - BuilderStoreConfig::Sqlite { path, passphrase } => { - matrix_sdk_sqlite::make_store_config(&path, passphrase.as_deref()).await? - } - #[cfg(feature = "indexeddb")] - BuilderStoreConfig::IndexedDb { name, passphrase } => { - matrix_sdk_indexeddb::make_store_config(&name, passphrase.as_deref()).await? - } - BuilderStoreConfig::Custom(config) => config, - }; - BaseClient::with_store_config(store_config) + BaseClient::with_store_config(build_store_config(self.store_config).await?) }; let http_client = HttpClient::new(inner_http_client.clone(), self.request_config); @@ -483,6 +471,24 @@ impl ClientBuilder { } } +async fn build_store_config( + builder_config: BuilderStoreConfig, +) -> Result { + #[allow(clippy::infallible_destructuring_match)] + let store_config = match builder_config { + #[cfg(feature = "sqlite")] + BuilderStoreConfig::Sqlite { path, passphrase } => { + matrix_sdk_sqlite::make_store_config(&path, passphrase.as_deref()).await? + } + #[cfg(feature = "indexeddb")] + BuilderStoreConfig::IndexedDb { name, passphrase } => { + matrix_sdk_indexeddb::make_store_config(&name, passphrase.as_deref()).await? + } + BuilderStoreConfig::Custom(config) => config, + }; + Ok(store_config) +} + #[derive(Clone, Copy, Debug)] enum UrlScheme { Http, From 8ef09b4044528abd32682c43700e85d497bb5d8c Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Tue, 16 Jan 2024 12:59:17 +0000 Subject: [PATCH 2/3] indexeddb: Replace `make_store_config` Replace `make_store_config` with a pair of funtions `open_stores_with_name` and `open_state_store`. This allows us to remove a dependency on `matrix-sdk-base/e2e-encryption`, and generally simplifies things. --- crates/matrix-sdk-indexeddb/Cargo.toml | 2 +- crates/matrix-sdk-indexeddb/src/lib.rs | 42 ++++++++----------------- crates/matrix-sdk/src/client/builder.rs | 38 ++++++++++++++++++---- 3 files changed, 46 insertions(+), 36 deletions(-) diff --git a/crates/matrix-sdk-indexeddb/Cargo.toml b/crates/matrix-sdk-indexeddb/Cargo.toml index c5c6355e0..fd185233b 100644 --- a/crates/matrix-sdk-indexeddb/Cargo.toml +++ b/crates/matrix-sdk-indexeddb/Cargo.toml @@ -16,7 +16,7 @@ rustdoc-args = ["--cfg", "docsrs"] [features] default = ["e2e-encryption", "state-store"] state-store = ["dep:matrix-sdk-base"] -e2e-encryption = ["matrix-sdk-base?/e2e-encryption", "dep:matrix-sdk-crypto"] +e2e-encryption = ["dep:matrix-sdk-crypto"] testing = ["matrix-sdk-crypto?/testing"] [dependencies] diff --git a/crates/matrix-sdk-indexeddb/src/lib.rs b/crates/matrix-sdk-indexeddb/src/lib.rs index faf24f9f8..a828ac675 100644 --- a/crates/matrix-sdk-indexeddb/src/lib.rs +++ b/crates/matrix-sdk-indexeddb/src/lib.rs @@ -1,7 +1,7 @@ #![cfg_attr(not(target_arch = "wasm32"), allow(unused))] #[cfg(feature = "state-store")] -use matrix_sdk_base::store::{StoreConfig, StoreError}; +use matrix_sdk_base::store::StoreError; use thiserror::Error; #[cfg(feature = "e2e-encryption")] @@ -23,7 +23,7 @@ pub use state_store::{ /// Create a [`IndexeddbStateStore`] and a [`IndexeddbCryptoStore`] that use the /// same name and passphrase. #[cfg(all(feature = "e2e-encryption", feature = "state-store"))] -async fn open_stores_with_name( +pub async fn open_stores_with_name( name: &str, passphrase: Option<&str>, ) -> Result<(IndexeddbStateStore, IndexeddbCryptoStore), OpenStoreError> { @@ -40,38 +40,22 @@ async fn open_stores_with_name( Ok((state_store, crypto_store)) } -/// Create a [`StoreConfig`] with an opened indexeddb [`IndexeddbStateStore`] -/// that uses the given name and passphrase. If `encryption` is enabled, a -/// [`IndexeddbCryptoStore`] with the same parameters is also opened. +/// Create an [`IndexeddbStateStore`]. +/// +/// If a `passphrase` is given, the store will be encrypted using a key derived +/// from that passphrase. #[cfg(feature = "state-store")] -pub async fn make_store_config( +pub async fn open_state_store( name: &str, passphrase: Option<&str>, -) -> Result { - #[cfg(target_arch = "wasm32")] - { - #[cfg(feature = "e2e-encryption")] - { - let (state_store, crypto_store) = open_stores_with_name(name, passphrase).await?; - Ok(StoreConfig::new().state_store(state_store).crypto_store(crypto_store)) - } - - #[cfg(not(feature = "e2e-encryption"))] - { - let mut builder = IndexeddbStateStore::builder().name(name.to_owned()); - - if let Some(passphrase) = passphrase { - builder = builder.passphrase(passphrase.to_owned()); - } - - let state_store = builder.build().await.map_err(StoreError::from)?; - - Ok(StoreConfig::new().state_store(state_store)) - } +) -> Result { + let mut builder = IndexeddbStateStore::builder().name(name.to_owned()); + if let Some(passphrase) = passphrase { + builder = builder.passphrase(passphrase.to_owned()); } + let state_store = builder.build().await.map_err(StoreError::from)?; - #[cfg(not(target_arch = "wasm32"))] - panic!("the IndexedDB is only available on the 'wasm32' arch") + Ok(state_store) } /// All the errors that can occur when opening an IndexedDB store. diff --git a/crates/matrix-sdk/src/client/builder.rs b/crates/matrix-sdk/src/client/builder.rs index 597d31d10..be02f2c78 100644 --- a/crates/matrix-sdk/src/client/builder.rs +++ b/crates/matrix-sdk/src/client/builder.rs @@ -184,11 +184,6 @@ impl ClientBuilder { } /// Set up the store configuration for a IndexedDB store. - /// - /// This is the same as - /// .[store_config](Self::store_config)([matrix_sdk_indexeddb]::[make_store_config](matrix_sdk_indexeddb::make_store_config)(path, passphrase).await?), - /// except it delegates the actual store config creation to when - /// `.build().await` is called. #[cfg(feature = "indexeddb")] pub fn indexeddb_store(mut self, name: &str, passphrase: Option<&str>) -> Self { self.store_config = BuilderStoreConfig::IndexedDb { @@ -480,15 +475,46 @@ async fn build_store_config( BuilderStoreConfig::Sqlite { path, passphrase } => { matrix_sdk_sqlite::make_store_config(&path, passphrase.as_deref()).await? } + #[cfg(feature = "indexeddb")] BuilderStoreConfig::IndexedDb { name, passphrase } => { - matrix_sdk_indexeddb::make_store_config(&name, passphrase.as_deref()).await? + build_indexeddb_store_config(&name, passphrase.as_deref()).await? } + BuilderStoreConfig::Custom(config) => config, }; Ok(store_config) } +// The indexeddb stores only implement `IntoStateStore` and `IntoCryptoStore` on +// wasm32, so this only compiles there. +#[cfg(all(target_arch = "wasm32", feature = "indexeddb"))] +async fn build_indexeddb_store_config( + name: &str, + passphrase: Option<&str>, +) -> Result { + #[cfg(feature = "e2e-encryption")] + { + let (state_store, crypto_store) = + matrix_sdk_indexeddb::open_stores_with_name(name, passphrase).await?; + Ok(StoreConfig::new().state_store(state_store).crypto_store(crypto_store)) + } + + #[cfg(not(feature = "e2e-encryption"))] + { + let state_store = matrix_sdk_indexeddb::open_state_store(name, passphrase).await?; + Ok(StoreConfig::new().state_store(state_store)) + } +} + +#[cfg(all(not(target_arch = "wasm32"), feature = "indexeddb"))] +async fn build_indexeddb_store_config( + _name: &str, + _passphrase: Option<&str>, +) -> Result { + panic!("the IndexedDB is only available on the 'wasm32' arch") +} + #[derive(Clone, Copy, Debug)] enum UrlScheme { Http, From 79bb7162982055656f4f38e64404c8a56b2ec0e6 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Tue, 16 Jan 2024 13:11:34 +0000 Subject: [PATCH 3/3] Inline `matrix_sdk_sqlite::make_store_config` ... mostly for parity with `matrix_sdk_indexeddb::make_store_config`, but again, simplifying the dependency graph. --- crates/matrix-sdk-sqlite/Cargo.toml | 9 +++------ crates/matrix-sdk-sqlite/src/lib.rs | 26 ------------------------- crates/matrix-sdk/src/client/builder.rs | 16 +++++++++------ 3 files changed, 13 insertions(+), 38 deletions(-) diff --git a/crates/matrix-sdk-sqlite/Cargo.toml b/crates/matrix-sdk-sqlite/Cargo.toml index 79265a705..eede3850e 100644 --- a/crates/matrix-sdk-sqlite/Cargo.toml +++ b/crates/matrix-sdk-sqlite/Cargo.toml @@ -12,17 +12,14 @@ default = ["state-store"] testing = ["matrix-sdk-crypto?/testing"] bundled = ["rusqlite/bundled"] -crypto-store = [ - "dep:matrix-sdk-crypto", - "matrix-sdk-base/e2e-encryption", -] -state-store = [] +crypto-store = ["dep:matrix-sdk-crypto"] +state-store = ["dep:matrix-sdk-base"] [dependencies] async-trait = { workspace = true } deadpool-sqlite = "0.7.0" itertools = { workspace = true } -matrix-sdk-base = { workspace = true } +matrix-sdk-base = { workspace = true, optional = true } matrix-sdk-crypto = { workspace = true, optional = true } matrix-sdk-store-encryption = { workspace = true } rmp-serde = "1.1.1" diff --git a/crates/matrix-sdk-sqlite/src/lib.rs b/crates/matrix-sdk-sqlite/src/lib.rs index 9e92a3895..e04c6f290 100644 --- a/crates/matrix-sdk-sqlite/src/lib.rs +++ b/crates/matrix-sdk-sqlite/src/lib.rs @@ -16,10 +16,7 @@ allow(dead_code, unused_imports) )] -use std::path::Path; - use deadpool_sqlite::Object as SqliteConn; -use matrix_sdk_base::store::StoreConfig; use matrix_sdk_store_encryption::StoreCipher; #[cfg(feature = "crypto-store")] @@ -59,26 +56,3 @@ async fn get_or_create_store_cipher( #[cfg(test)] matrix_sdk_test::init_tracing_for_tests!(); - -/// Create a [`StoreConfig`] with an opened [`SqliteStateStore`] in the given -/// directory and using the given passphrase. If the `crypto-store` feature is -/// enabled, a [`SqliteCryptoStore`] with the same parameters is also opened. -#[cfg(feature = "state-store")] -pub async fn make_store_config( - path: &Path, - passphrase: Option<&str>, -) -> Result { - let state_store = SqliteStateStore::open(path, passphrase).await?; - let config = StoreConfig::new().state_store(state_store); - - #[cfg(feature = "crypto-store")] - { - let crypto_store = SqliteCryptoStore::open(path, passphrase).await?; - Ok(config.crypto_store(crypto_store)) - } - - #[cfg(not(feature = "crypto-store"))] - { - Ok(config) - } -} diff --git a/crates/matrix-sdk/src/client/builder.rs b/crates/matrix-sdk/src/client/builder.rs index be02f2c78..7e64aea72 100644 --- a/crates/matrix-sdk/src/client/builder.rs +++ b/crates/matrix-sdk/src/client/builder.rs @@ -165,11 +165,6 @@ impl ClientBuilder { } /// Set up the store configuration for a SQLite store. - /// - /// This is the same as - /// .[store_config](Self::store_config)([matrix_sdk_sqlite]::[make_store_config](matrix_sdk_sqlite::make_store_config)(path, passphrase)?). - /// except it delegates the actual store config creation to when - /// `.build().await` is called. #[cfg(feature = "sqlite")] pub fn sqlite_store( mut self, @@ -473,7 +468,16 @@ async fn build_store_config( let store_config = match builder_config { #[cfg(feature = "sqlite")] BuilderStoreConfig::Sqlite { path, passphrase } => { - matrix_sdk_sqlite::make_store_config(&path, passphrase.as_deref()).await? + let store_config = StoreConfig::new().state_store( + matrix_sdk_sqlite::SqliteStateStore::open(&path, passphrase.as_deref()).await?, + ); + + #[cfg(feature = "e2e-encryption")] + let store_config = store_config.crypto_store( + matrix_sdk_sqlite::SqliteCryptoStore::open(&path, passphrase.as_deref()).await?, + ); + + store_config } #[cfg(feature = "indexeddb")]