big batch

This commit is contained in:
Benjamin Kampmann
2021-11-17 13:08:58 +01:00
parent 8a2732ab5d
commit b8af613aef
5 changed files with 597 additions and 550 deletions

View File

@@ -20,14 +20,13 @@ default = []
encryption = ["matrix-sdk-crypto"]
qrcode = ["matrix-sdk-crypto/qrcode"]
sled_state_store = ["sled", "pbkdf2", "hmac", "sha2", "rand", "chacha20poly1305"]
indexeddb_state_store = ["indexed_db_futures", "pbkdf2", "hmac", "sha2", "rand", "chacha20poly1305"]
indexeddb_state_store = ["indexed_db_futures", "wasm-bindgen", "pbkdf2", "hmac", "sha2", "rand", "chacha20poly1305"]
sled_cryptostore = ["matrix-sdk-crypto/sled_cryptostore"]
docs = ["encryption", "sled_cryptostore"]
[dependencies]
chacha20poly1305 = { version = "0.9.0", optional = true }
indexed_db_futures = { version = "0.2.0", optional = true }
dashmap = "4.0.2"
futures-core = "0.3.15"
futures-util = { version = "0.3.15", default-features = false }
@@ -46,6 +45,10 @@ thiserror = "1.0.25"
tracing = "0.1.26"
zeroize = { version = "1.3.0", features = ["zeroize_derive"] }
## Feature indexeddb-state-store
indexed_db_futures = { version = "0.2.0", optional = true }
wasm-bindgen = { version = "0.2.74", features = ["serde-serialize"], optional = true }
[target.'cfg(not(target_arch = "wasm32"))'.dependencies.tokio]
version = "1.7.1"
default-features = false

View File

@@ -87,8 +87,8 @@ pub struct BaseClient {
olm: Arc<Mutex<Option<OlmMachine>>>,
#[cfg(feature = "encryption")]
cryptostore: Arc<Mutex<Option<Box<dyn CryptoStore>>>>,
#[cfg(feature = "encryption")]
store_path: Arc<Option<PathBuf>>,
#[cfg(feature = "sled_state_store")]
store_path: Option<PathBuf>,
#[cfg(feature = "sled_cryptostore")]
store_passphrase: Arc<Option<Zeroizing<String>>>,
}
@@ -118,7 +118,10 @@ impl fmt::Debug for BaseClient {
pub struct BaseClientConfig {
#[cfg(feature = "encryption")]
crypto_store: Option<Box<dyn CryptoStore>>,
#[cfg(feature = "sled_state_store")]
store_path: Option<PathBuf>,
#[cfg(feature = "indexeddb_state_store")]
name: String,
passphrase: Option<Zeroizing<String>>,
}
@@ -144,6 +147,18 @@ impl BaseClientConfig {
self
}
/// Set the indexeddb database name for storage.
///
/// # Arguments
///
/// * `name` - The name where the stores should save data in. Indexeddb
//// separates database through these nanmes
#[cfg(feature = "indexeddb_state_store")]
pub fn name<>(mut self, name: String) -> Self {
self.name = name;
self
}
/// Set the path for storage.
///
/// # Arguments
@@ -155,6 +170,7 @@ impl BaseClientConfig {
/// implementations for the crypto store and the state store. It will use
/// the given path to open the stores. If no path is provided no store will
/// be opened
#[cfg(feature = "sled_state_store")]
pub fn store_path<P: AsRef<Path>>(mut self, path: P) -> Self {
self.store_path = Some(path.as_ref().into());
self
@@ -176,8 +192,8 @@ impl BaseClientConfig {
impl BaseClient {
/// Create a new default client.
pub fn new() -> Result<Self> {
BaseClient::new_with_config(BaseClientConfig::default())
pub async fn new() -> Result<Self> {
BaseClient::new_with_config(BaseClientConfig::default()).await
}
/// Create a new client.
@@ -186,9 +202,9 @@ impl BaseClient {
///
/// * `config` - An optional session if the user already has one from a
/// previous login call.
pub fn new_with_config(config: BaseClientConfig) -> Result<Self> {
pub async fn new_with_config(config: BaseClientConfig) -> Result<Self> {
#[cfg_attr(
not(any(feature = "sled_state_store", feature = "sled_cryptostore")),
not(any(feature = "indexeddb_state_store", feature = "sled_state_store", feature = "sled_cryptostore")),
allow(unused_variables)
)]
let config = config;
@@ -204,7 +220,14 @@ impl BaseClient {
} else {
Store::open_temporary()?
};
#[cfg(not(feature = "sled_state_store"))]
#[cfg(feature = "indexeddb_state_store")]
let store = Store::open_default(
config.name.clone(),
config.passphrase.as_deref().map(|p| p.as_str())
).await?;
#[cfg(not(any(feature = "sled_state_store", feature = "indexeddb_state_store")))]
let stores = Store::open_memory_store();
#[cfg(all(feature = "encryption", feature = "sled_state_store"))]
@@ -229,7 +252,7 @@ impl BaseClient {
#[cfg(feature = "sled_state_store")]
let store = stores.0;
#[cfg(not(feature = "sled_state_store"))]
#[cfg(all(not(any(feature = "sled_state_store", feature = "indexeddb_state_store")), feature = "encryption"))]
let store = stores;
Ok(BaseClient {
@@ -240,7 +263,7 @@ impl BaseClient {
olm: Mutex::new(None).into(),
#[cfg(feature = "encryption")]
cryptostore: Mutex::new(crypto_store).into(),
#[cfg(feature = "encryption")]
#[cfg(feature = "sled_cryptostore")]
store_path: config.store_path.into(),
#[cfg(feature = "sled_cryptostore")]
store_passphrase: config.passphrase.into(),
@@ -308,27 +331,29 @@ impl BaseClient {
.await
.map_err(OlmError::from)?,
);
} else if let Some(path) = self.store_path.as_ref() {
} else {
#[cfg(feature = "sled_cryptostore")]
{
*olm = Some(
OlmMachine::new_with_default_store(
&session.user_id,
&session.device_id,
path,
self.store_passphrase.as_deref().map(|p| p.as_str()),
)
.await
.map_err(OlmError::from)?,
);
if let Some(path) = self.store_path.as_ref() {
*olm = Some(
OlmMachine::new_with_default_store(
&session.user_id,
&session.device_id,
path,
self.store_passphrase.as_deref().map(|p| p.as_str()),
)
.await
.map_err(OlmError::from)?,
);
} else {
*olm = Some(OlmMachine::new(&session.user_id, &session.device_id));
}
}
#[cfg(not(feature = "sled_cryptostore"))]
{
let _ = path;
*olm = Some(OlmMachine::new(&session.user_id, &session.device_id));
}
} else {
*olm = Some(OlmMachine::new(&session.user_id, &session.device_id));
}
}

View File

File diff suppressed because it is too large Load Diff

View File

@@ -70,11 +70,18 @@ pub enum StoreError {
Sled(#[from] sled::Error),
/// An error happened in the underlying sled database.
#[cfg(feature = "indexeddb_state_store")]
#[error(transparent)]
Indexeddb(#[from] indexed_db_futures::web_sys::DomException),
#[error("IndexDB error: {name} ({code}): {message}")]
Indexeddb {
/// DomException code
code: u16,
/// Specific name of the DomException
name: String,
/// Message given to the DomException
message: String
},
/// An error happened while serializing or deserializing some data.
#[error(transparent)]
Json(#[from] serde_json::Error),
Json(serde_json::Error),
/// An error happened while deserializing a Matrix identifier, e.g. an user
/// id.
#[error(transparent)]
@@ -89,12 +96,32 @@ pub enum StoreError {
/// The store failed to encrypt or decrypt some data.
#[error("Error encrypting or decrypting data from the store: {0}")]
Encryption(String),
/// The store failed to encode or decode some data.
#[error("Error encoding or decoding data from the store: {0}")]
Codec(String),
/// An error happened while running a tokio task.
#[cfg(feature = "sled_state_store")]
#[error(transparent)]
Task(#[from] tokio::task::JoinError),
}
#[cfg(target_arch = "wasm32")]
impl From<indexed_db_futures::web_sys::DomException> for StoreError {
fn from(frm: indexed_db_futures::web_sys::DomException) -> StoreError {
StoreError::Indexeddb {
name: frm.name(),
message: frm.message(),
code: frm.code(),
}
}
}
impl From<serde_json::Error> for StoreError {
fn from(frm: serde_json::Error) -> StoreError {
StoreError::Json(frm)
}
}
/// A `StateStore` specific result type.
pub type Result<T, E = StoreError> = std::result::Result<T, E>;
@@ -376,14 +403,14 @@ impl Store {
///
/// * `passphrase` - A passphrase that should be used to encrypt the state
/// store.
pub fn open_default(name: String, passphrase: Option<&str>) -> Result<(Self, IndexeddbStore)> {
pub async fn open_default(name: String, passphrase: Option<&str>) -> Result<Self> {
let inner = if let Some(passphrase) = passphrase {
IndexeddbStore::open_with_passphrase(name, passphrase)?
IndexeddbStore::open_with_passphrase(name, passphrase).await?
} else {
IndexeddbStore::open_with_name(name)?
IndexeddbStore::open_with_name(name).await?
};
Ok((Self::new(Box::new(inner.clone())), inner.inner))
Ok(Self::new(Box::new(inner)))
}
}

View File

@@ -249,7 +249,7 @@ pub mod identities;
pub mod verification;
use std::{
collections::{BTreeMap, HashSet},
io::{Read,Write},
io::{Read, Write},
path::PathBuf,
result::Result as StdResult,
};