matrix-sdk: Move most of the configuration to the base client.
parent
7edb42b75c
commit
ba66ee214f
|
@ -20,7 +20,7 @@ sqlite-cryptostore = ["matrix-sdk-base/sqlite-cryptostore"]
|
|||
http = "0.2.1"
|
||||
reqwest = "0.10.4"
|
||||
serde_json = "1.0.53"
|
||||
thiserror = "1.0.18"
|
||||
thiserror = "1.0.19"
|
||||
tracing = "0.1.14"
|
||||
url = "2.1.1"
|
||||
futures-timer = { version = "3.0.2", features = ["wasm-bindgen"] }
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
use std::collections::BTreeMap;
|
||||
use std::collections::HashMap;
|
||||
use std::convert::{TryFrom, TryInto};
|
||||
use std::path::Path;
|
||||
use std::result::Result as StdResult;
|
||||
use std::sync::Arc;
|
||||
|
||||
|
@ -47,10 +48,7 @@ use crate::api;
|
|||
#[cfg(not(target_arch = "wasm32"))]
|
||||
use crate::VERSION;
|
||||
use crate::{Error, EventEmitter, Result};
|
||||
use matrix_sdk_base::BaseClient;
|
||||
use matrix_sdk_base::Room;
|
||||
use matrix_sdk_base::Session;
|
||||
use matrix_sdk_base::StateStore;
|
||||
use matrix_sdk_base::{BaseClient, BaseClientConfig, Room, Session, StateStore};
|
||||
|
||||
const DEFAULT_SYNC_TIMEOUT: Duration = Duration::from_secs(30);
|
||||
|
||||
|
@ -104,7 +102,7 @@ pub struct ClientConfig {
|
|||
proxy: Option<reqwest::Proxy>,
|
||||
user_agent: Option<HeaderValue>,
|
||||
disable_ssl_verification: bool,
|
||||
state_store: Option<Box<dyn StateStore>>,
|
||||
base_config: BaseClientConfig,
|
||||
}
|
||||
|
||||
#[cfg_attr(tarpaulin, skip)]
|
||||
|
@ -166,7 +164,36 @@ impl ClientConfig {
|
|||
///
|
||||
/// The state store should be opened before being set.
|
||||
pub fn state_store(mut self, store: Box<dyn StateStore>) -> Self {
|
||||
self.state_store = Some(store);
|
||||
self.base_config = self.base_config.state_store(store);
|
||||
self
|
||||
}
|
||||
|
||||
/// Set the path for storage.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `path` - The path where the stores should save data in. It is the
|
||||
/// callers responsibility to make sure that the path exists.
|
||||
///
|
||||
/// In the default configuration the client will open default
|
||||
/// 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
|
||||
pub fn store_path<P: AsRef<Path>>(mut self, path: P) -> Self {
|
||||
self.base_config = self.base_config.store_path(path);
|
||||
self
|
||||
}
|
||||
|
||||
/// Set the passphrase to encrypt the crypto store.
|
||||
///
|
||||
/// # Argument
|
||||
///
|
||||
/// * `passphrase` - The passphrase that will be used to encrypt the data in
|
||||
/// the cryptostore.
|
||||
///
|
||||
/// This is only used if no custom cryptostore is set.
|
||||
pub fn passphrase(mut self, passphrase: String) -> Self {
|
||||
self.base_config = self.base_config.passphrase(passphrase);
|
||||
self
|
||||
}
|
||||
}
|
||||
|
@ -293,11 +320,7 @@ impl Client {
|
|||
|
||||
let http_client = http_client.build()?;
|
||||
|
||||
let base_client = if let Some(store) = config.state_store {
|
||||
BaseClient::new_with_state_store(store)?
|
||||
} else {
|
||||
BaseClient::new()?
|
||||
};
|
||||
let base_client = BaseClient::new_with_config(config.base_config)?;
|
||||
|
||||
Ok(Self {
|
||||
homeserver,
|
||||
|
@ -371,38 +394,6 @@ impl Client {
|
|||
self.base_client.get_left_room(room_id).await
|
||||
}
|
||||
|
||||
/// This allows `Client` to manually sync state with the provided `StateStore`.
|
||||
///
|
||||
/// Returns true when a successful `StateStore` sync has completed.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```no_run
|
||||
/// use matrix_sdk::{Client, ClientConfig, JsonStore, RoomBuilder};
|
||||
/// # use matrix_sdk::api::r0::room::Visibility;
|
||||
/// # use url::Url;
|
||||
///
|
||||
/// # let homeserver = Url::parse("http://example.com").unwrap();
|
||||
/// let store = JsonStore::open("path/to/store").unwrap();
|
||||
/// let config = ClientConfig::new().state_store(Box::new(store));
|
||||
/// let mut client = Client::new(homeserver).unwrap();
|
||||
/// # use futures::executor::block_on;
|
||||
/// # block_on(async {
|
||||
/// let _ = client.login("name", "password", None, None).await.unwrap();
|
||||
/// // returns true when a state store sync is successful
|
||||
/// assert!(client.sync_with_state_store().await.unwrap());
|
||||
/// // now state is restored without a request to the server
|
||||
/// let mut names = vec![];
|
||||
/// for r in client.joined_rooms().read().await.values() {
|
||||
/// names.push(r.read().await.display_name());
|
||||
/// }
|
||||
/// assert_eq!(vec!["room".to_string(), "names".to_string()], names)
|
||||
/// # });
|
||||
/// ```
|
||||
pub async fn sync_with_state_store(&self) -> Result<bool> {
|
||||
Ok(self.base_client.sync_with_state_store().await?)
|
||||
}
|
||||
|
||||
/// This allows `Client` to manually store `Room` state with the provided
|
||||
/// `StateStore`.
|
||||
///
|
||||
|
@ -477,8 +468,6 @@ impl Client {
|
|||
self.send(request).await
|
||||
}
|
||||
|
||||
// TODO enable this once Ruma supports proper serialization of the query
|
||||
// string.
|
||||
/// Join a room by `RoomId`.
|
||||
///
|
||||
/// Returns a `join_room_by_id_or_alias::Response` consisting of the
|
||||
|
@ -1441,8 +1430,6 @@ mod test {
|
|||
);
|
||||
}
|
||||
|
||||
// TODO enable this once Ruma supports proper serialization of the query
|
||||
// string.
|
||||
#[tokio::test]
|
||||
async fn join_room_by_id_or_alias() {
|
||||
let homeserver = Url::from_str(&mockito::server_url()).unwrap();
|
||||
|
@ -1798,7 +1785,7 @@ mod test {
|
|||
.unwrap();
|
||||
|
||||
assert_eq!(
|
||||
EventId::try_from("$h29iv0s8:example.com").ok(),
|
||||
EventId::try_from("$h29iv0s8:example.com").unwrap(),
|
||||
response.event_id
|
||||
)
|
||||
}
|
||||
|
|
|
@ -20,12 +20,13 @@ sqlite-cryptostore = ["matrix-sdk-crypto/sqlite-cryptostore"]
|
|||
async-trait = "0.1.31"
|
||||
serde = "1.0.110"
|
||||
serde_json = "1.0.53"
|
||||
zeroize = "1.1.0"
|
||||
|
||||
matrix-sdk-common = { version = "0.1.0", path = "../matrix_sdk_common" }
|
||||
matrix-sdk-crypto = { version = "0.1.0", path = "../matrix_sdk_crypto", optional = true }
|
||||
|
||||
# Misc dependencies
|
||||
thiserror = "1.0.18"
|
||||
thiserror = "1.0.19"
|
||||
|
||||
[target.'cfg(not(target_arch = "wasm32"))'.dependencies.tokio]
|
||||
version = "0.2.21"
|
||||
|
|
|
@ -17,10 +17,10 @@ use std::collections::HashMap;
|
|||
#[cfg(feature = "encryption")]
|
||||
use std::collections::{BTreeMap, HashSet};
|
||||
use std::fmt;
|
||||
use std::sync::atomic::{AtomicBool, Ordering};
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::sync::Arc;
|
||||
use zeroize::Zeroizing;
|
||||
|
||||
#[cfg(feature = "encryption")]
|
||||
use std::result::Result as StdResult;
|
||||
|
||||
use crate::api::r0 as api;
|
||||
|
@ -55,8 +55,10 @@ use crate::api::r0::to_device::send_event_to_device;
|
|||
use crate::events::room::{encrypted::EncryptedEventContent, message::MessageEventContent};
|
||||
#[cfg(feature = "encryption")]
|
||||
use crate::identifiers::DeviceId;
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
use crate::JsonStore;
|
||||
#[cfg(feature = "encryption")]
|
||||
use matrix_sdk_crypto::{OlmMachine, OneTimeKeys};
|
||||
use matrix_sdk_crypto::{CryptoStore, OlmMachine, OneTimeKeys};
|
||||
|
||||
pub type Token = String;
|
||||
|
||||
|
@ -115,11 +117,13 @@ pub struct BaseClient {
|
|||
///
|
||||
/// There is a default implementation `JsonStore` that saves JSON to disk.
|
||||
state_store: Arc<RwLock<Option<Box<dyn StateStore>>>>,
|
||||
/// Does the `Client` need to sync with the state store.
|
||||
needs_state_store_sync: Arc<AtomicBool>,
|
||||
|
||||
#[cfg(feature = "encryption")]
|
||||
olm: Arc<Mutex<Option<OlmMachine>>>,
|
||||
#[cfg(feature = "encryption")]
|
||||
cryptostore: Arc<Mutex<Option<Box<dyn CryptoStore>>>>,
|
||||
store_path: Arc<Option<PathBuf>>,
|
||||
store_passphrase: Arc<Zeroizing<String>>,
|
||||
}
|
||||
|
||||
#[cfg_attr(tarpaulin, skip)]
|
||||
|
@ -136,31 +140,99 @@ impl fmt::Debug for BaseClient {
|
|||
}
|
||||
}
|
||||
|
||||
/// Configuration for the creation of the `BaseClient`.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// # use matrix_sdk_base::BaseClientConfig;
|
||||
///
|
||||
/// let client_config = BaseClientConfig::new()
|
||||
/// .store_path("/home/example/matrix-sdk-client")
|
||||
/// .passphrase("test-passphrase".to_owned());
|
||||
/// ```
|
||||
#[derive(Default)]
|
||||
pub struct BaseClientConfig {
|
||||
state_store: Option<Box<dyn StateStore>>,
|
||||
#[cfg(feature = "encryption")]
|
||||
crypto_store: Option<Box<dyn CryptoStore>>,
|
||||
store_path: Option<PathBuf>,
|
||||
passphrase: Option<Zeroizing<String>>,
|
||||
}
|
||||
|
||||
#[cfg_attr(tarpaulin, skip)]
|
||||
impl std::fmt::Debug for BaseClientConfig {
|
||||
fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> StdResult<(), std::fmt::Error> {
|
||||
fmt.debug_struct("BaseClientConfig").finish()
|
||||
}
|
||||
}
|
||||
|
||||
impl BaseClientConfig {
|
||||
/// Create a new default `BaseClientConfig`.
|
||||
pub fn new() -> Self {
|
||||
Default::default()
|
||||
}
|
||||
|
||||
/// Set a custom implementation of a `StateStore`.
|
||||
///
|
||||
/// The state store should be opened before being set.
|
||||
pub fn state_store(mut self, store: Box<dyn StateStore>) -> Self {
|
||||
self.state_store = Some(store);
|
||||
self
|
||||
}
|
||||
|
||||
/// Set a custom implementation of a `CryptoStore`.
|
||||
///
|
||||
/// The crypto store should be opened before being set.
|
||||
#[cfg(feature = "encryption")]
|
||||
pub fn crypto_store(mut self, store: Box<dyn CryptoStore>) -> Self {
|
||||
self.crypto_store = Some(store);
|
||||
self
|
||||
}
|
||||
|
||||
/// Set the path for storage.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `path` - The path where the stores should save data in. It is the
|
||||
/// callers responsibility to make sure that the path exists.
|
||||
///
|
||||
/// In the default configuration the client will open default
|
||||
/// 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
|
||||
pub fn store_path<P: AsRef<Path>>(mut self, path: P) -> Self {
|
||||
self.store_path = Some(path.as_ref().into());
|
||||
self
|
||||
}
|
||||
|
||||
/// Set the passphrase to encrypt the crypto store.
|
||||
///
|
||||
/// # Argument
|
||||
///
|
||||
/// * `passphrase` - The passphrase that will be used to encrypt the data in
|
||||
/// the cryptostore.
|
||||
///
|
||||
/// This is only used if no custom cryptostore is set.
|
||||
pub fn passphrase(mut self, passphrase: String) -> Self {
|
||||
self.passphrase = Some(Zeroizing::new(passphrase));
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl BaseClient {
|
||||
/// Create a new client.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `session` - An optional session if the user already has one from a
|
||||
/// previous login call.
|
||||
/// Create a new default client.
|
||||
pub fn new() -> Result<Self> {
|
||||
BaseClient::new_helper(None)
|
||||
BaseClient::new_with_config(BaseClientConfig::default())
|
||||
}
|
||||
|
||||
/// Create a new client.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `session` - An optional session if the user already has one from a
|
||||
/// * `config` - An optional session if the user already has one from a
|
||||
/// previous login call.
|
||||
///
|
||||
/// * `store` - An open state store implementation that will be used through
|
||||
/// the lifetime of the client.
|
||||
pub fn new_with_state_store(store: Box<dyn StateStore>) -> Result<Self> {
|
||||
BaseClient::new_helper(Some(store))
|
||||
}
|
||||
|
||||
fn new_helper(store: Option<Box<dyn StateStore>>) -> Result<Self> {
|
||||
pub fn new_with_config(config: BaseClientConfig) -> Result<Self> {
|
||||
Ok(BaseClient {
|
||||
session: Arc::new(RwLock::new(None)),
|
||||
sync_token: Arc::new(RwLock::new(None)),
|
||||
|
@ -170,10 +242,17 @@ impl BaseClient {
|
|||
ignored_users: Arc::new(RwLock::new(Vec::new())),
|
||||
push_ruleset: Arc::new(RwLock::new(None)),
|
||||
event_emitter: Arc::new(RwLock::new(None)),
|
||||
state_store: Arc::new(RwLock::new(store)),
|
||||
needs_state_store_sync: Arc::new(AtomicBool::from(true)),
|
||||
state_store: Arc::new(RwLock::new(config.state_store)),
|
||||
#[cfg(feature = "encryption")]
|
||||
olm: Arc::new(Mutex::new(None)),
|
||||
#[cfg(feature = "encryption")]
|
||||
cryptostore: Arc::new(Mutex::new(config.crypto_store)),
|
||||
store_path: Arc::new(config.store_path),
|
||||
store_passphrase: Arc::new(
|
||||
config
|
||||
.passphrase
|
||||
.unwrap_or_else(|| Zeroizing::new("DEFAULT_PASSPHRASE".to_owned())),
|
||||
),
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -197,55 +276,55 @@ impl BaseClient {
|
|||
*self.event_emitter.write().await = Some(emitter);
|
||||
}
|
||||
|
||||
/// Returns true if the state store has been loaded into the client.
|
||||
pub fn is_state_store_synced(&self) -> bool {
|
||||
!self.needs_state_store_sync.load(Ordering::Relaxed)
|
||||
}
|
||||
|
||||
/// When a client is provided the state store will load state from the `StateStore`.
|
||||
///
|
||||
/// Returns `true` when a state store sync has successfully completed.
|
||||
pub async fn sync_with_state_store(&self) -> Result<bool> {
|
||||
async fn sync_with_state_store(&self, session: &Session) -> Result<bool> {
|
||||
let store = self.state_store.read().await;
|
||||
if let Some(store) = store.as_ref() {
|
||||
if let Some(sess) = self.session.read().await.as_ref() {
|
||||
if let Some(client_state) = store.load_client_state(sess).await? {
|
||||
let ClientState {
|
||||
sync_token,
|
||||
ignored_users,
|
||||
push_ruleset,
|
||||
} = client_state;
|
||||
*self.sync_token.write().await = sync_token;
|
||||
*self.ignored_users.write().await = ignored_users;
|
||||
*self.push_ruleset.write().await = push_ruleset;
|
||||
} else {
|
||||
// return false and continues with a sync request then save the state and create
|
||||
// and populate the files during the sync
|
||||
return Ok(false);
|
||||
}
|
||||
|
||||
let AllRooms {
|
||||
mut joined,
|
||||
mut invited,
|
||||
mut left,
|
||||
} = store.load_all_rooms().await?;
|
||||
*self.joined_rooms.write().await = joined
|
||||
.drain()
|
||||
.map(|(k, room)| (k, Arc::new(RwLock::new(room))))
|
||||
.collect();
|
||||
*self.invited_rooms.write().await = invited
|
||||
.drain()
|
||||
.map(|(k, room)| (k, Arc::new(RwLock::new(room))))
|
||||
.collect();
|
||||
*self.left_rooms.write().await = left
|
||||
.drain()
|
||||
.map(|(k, room)| (k, Arc::new(RwLock::new(room))))
|
||||
.collect();
|
||||
|
||||
self.needs_state_store_sync.store(false, Ordering::Relaxed);
|
||||
let loaded = if let Some(store) = store.as_ref() {
|
||||
if let Some(client_state) = store.load_client_state(session).await? {
|
||||
let ClientState {
|
||||
sync_token,
|
||||
ignored_users,
|
||||
push_ruleset,
|
||||
} = client_state;
|
||||
*self.sync_token.write().await = sync_token;
|
||||
*self.ignored_users.write().await = ignored_users;
|
||||
*self.push_ruleset.write().await = push_ruleset;
|
||||
} else {
|
||||
// return false and continues with a sync request then save the state and create
|
||||
// and populate the files during the sync
|
||||
return Ok(false);
|
||||
}
|
||||
}
|
||||
Ok(!self.needs_state_store_sync.load(Ordering::Relaxed))
|
||||
|
||||
let AllRooms {
|
||||
mut joined,
|
||||
mut invited,
|
||||
mut left,
|
||||
} = store.load_all_rooms().await?;
|
||||
|
||||
*self.joined_rooms.write().await = joined
|
||||
.drain()
|
||||
.map(|(k, room)| (k, Arc::new(RwLock::new(room))))
|
||||
.collect();
|
||||
|
||||
*self.invited_rooms.write().await = invited
|
||||
.drain()
|
||||
.map(|(k, room)| (k, Arc::new(RwLock::new(room))))
|
||||
.collect();
|
||||
|
||||
*self.left_rooms.write().await = left
|
||||
.drain()
|
||||
.map(|(k, room)| (k, Arc::new(RwLock::new(room))))
|
||||
.collect();
|
||||
|
||||
true
|
||||
} else {
|
||||
false
|
||||
};
|
||||
|
||||
Ok(loaded)
|
||||
}
|
||||
|
||||
/// When a client is provided the state store will load state from the `StateStore`.
|
||||
|
@ -303,9 +382,54 @@ impl BaseClient {
|
|||
#[cfg(feature = "encryption")]
|
||||
{
|
||||
let mut olm = self.olm.lock().await;
|
||||
*olm = Some(OlmMachine::new(&session.user_id, &session.device_id));
|
||||
let store = self.cryptostore.lock().await.take();
|
||||
|
||||
if let Some(store) = store {
|
||||
*olm = Some(
|
||||
OlmMachine::new_with_store(
|
||||
session.user_id.to_owned(),
|
||||
session.device_id.to_owned(),
|
||||
store,
|
||||
)
|
||||
.await
|
||||
.unwrap(),
|
||||
);
|
||||
} else if let Some(path) = self.store_path.as_ref() {
|
||||
#[cfg(feature = "sqlite-cryptostore")]
|
||||
{
|
||||
*olm = Some(
|
||||
OlmMachine::new_with_default_store(
|
||||
&session.user_id,
|
||||
&session.device_id,
|
||||
path,
|
||||
&self.store_passphrase,
|
||||
)
|
||||
.await
|
||||
.unwrap(),
|
||||
);
|
||||
}
|
||||
#[cfg(not(feature = "sqlite-cryptostore"))]
|
||||
{
|
||||
*olm = Some(OlmMachine::new(&session.user_id, &session.device_id));
|
||||
}
|
||||
} else {
|
||||
*olm = Some(OlmMachine::new(&session.user_id, &session.device_id));
|
||||
}
|
||||
}
|
||||
self.sync_with_state_store().await?;
|
||||
|
||||
// If there wasn't a state store opened, try to open the default one if
|
||||
// a store path was provided.
|
||||
if self.state_store.read().await.is_none() {
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
{
|
||||
if let Some(path) = &*self.store_path {
|
||||
let store = JsonStore::open(path)?;
|
||||
*self.state_store.write().await = Some(Box::new(store));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
self.sync_with_state_store(&session).await?;
|
||||
|
||||
*self.session.write().await = Some(session);
|
||||
|
||||
|
@ -713,8 +837,6 @@ impl BaseClient {
|
|||
/// # Arguments
|
||||
///
|
||||
/// * `response` - The response that we received after a successful sync.
|
||||
///
|
||||
/// * `did_update` - Signals to the `StateStore` if the client state needs updating.
|
||||
pub async fn receive_sync_response(
|
||||
&self,
|
||||
response: &mut api::sync::sync_events::Response,
|
||||
|
|
|
@ -45,7 +45,7 @@ mod models;
|
|||
mod session;
|
||||
mod state;
|
||||
|
||||
pub use client::{BaseClient, RoomState, RoomStateType};
|
||||
pub use client::{BaseClient, BaseClientConfig, RoomState, RoomStateType};
|
||||
pub use event_emitter::{EventEmitter, SyncRoom};
|
||||
#[cfg(feature = "encryption")]
|
||||
pub use matrix_sdk_crypto::{Device, TrustState};
|
||||
|
|
|
@ -205,7 +205,7 @@ mod test {
|
|||
|
||||
use crate::api::r0::sync::sync_events::Response as SyncResponse;
|
||||
use crate::identifiers::{RoomId, UserId};
|
||||
use crate::{BaseClient, Session};
|
||||
use crate::{BaseClient, BaseClientConfig, Session};
|
||||
|
||||
fn sync_response(file: &str) -> SyncResponse {
|
||||
let mut file = File::open(file).unwrap();
|
||||
|
@ -360,7 +360,8 @@ mod test {
|
|||
|
||||
// a sync response to populate our JSON store
|
||||
let store = Box::new(JsonStore::open(path).unwrap());
|
||||
let client = BaseClient::new_with_state_store(store).unwrap();
|
||||
let client =
|
||||
BaseClient::new_with_config(BaseClientConfig::new().state_store(store)).unwrap();
|
||||
client.restore_login(session.clone()).await.unwrap();
|
||||
|
||||
let mut response = sync_response("../test_data/sync.json");
|
||||
|
@ -370,9 +371,9 @@ mod test {
|
|||
|
||||
// now syncing the client will update from the state store
|
||||
let store = Box::new(JsonStore::open(path).unwrap());
|
||||
let client = BaseClient::new_with_state_store(store).unwrap();
|
||||
let client =
|
||||
BaseClient::new_with_config(BaseClientConfig::new().state_store(store)).unwrap();
|
||||
client.restore_login(session.clone()).await.unwrap();
|
||||
client.sync_with_state_store().await.unwrap();
|
||||
|
||||
// assert the synced client and the logged in client are equal
|
||||
assert_eq!(*client.session().read().await, Some(session));
|
||||
|
|
|
@ -13,7 +13,7 @@ version = "0.1.0"
|
|||
[dependencies]
|
||||
js_int = "0.1.5"
|
||||
ruma-api = "0.16.1"
|
||||
ruma-client-api = "0.8.0"
|
||||
ruma-client-api = "0.9.0"
|
||||
ruma-events = "0.21.2"
|
||||
ruma-identifiers = "0.16.1"
|
||||
instant = { version = "0.1.4", features = ["wasm-bindgen", "now"] }
|
||||
|
|
|
@ -27,10 +27,10 @@ zeroize = { version = "1.1.0", features = ["zeroize_derive"] }
|
|||
url = "2.1.1"
|
||||
|
||||
# Misc dependencies
|
||||
thiserror = "1.0.18"
|
||||
thiserror = "1.0.19"
|
||||
tracing = "0.1.14"
|
||||
atomic = "0.4.5"
|
||||
dashmap = "3.11.1"
|
||||
dashmap = "3.11.2"
|
||||
|
||||
[dependencies.tracing-futures]
|
||||
version = "0.2.4"
|
||||
|
|
|
@ -141,9 +141,9 @@ impl OlmMachine {
|
|||
/// * `store` - A `Cryptostore` implementation that will be used to store
|
||||
/// the encryption keys.
|
||||
pub async fn new_with_store(
|
||||
user_id: &UserId,
|
||||
device_id: &str,
|
||||
mut store: impl CryptoStore + 'static,
|
||||
user_id: UserId,
|
||||
device_id: String,
|
||||
mut store: Box<dyn CryptoStore>,
|
||||
) -> StoreError<Self> {
|
||||
let account = match store.load_account().await? {
|
||||
Some(a) => {
|
||||
|
@ -161,7 +161,7 @@ impl OlmMachine {
|
|||
device_id: device_id.to_owned(),
|
||||
account,
|
||||
uploaded_signed_key_count: None,
|
||||
store: Box::new(store),
|
||||
store,
|
||||
outbound_group_sessions: HashMap::new(),
|
||||
})
|
||||
}
|
||||
|
@ -181,12 +181,12 @@ impl OlmMachine {
|
|||
user_id: &UserId,
|
||||
device_id: &str,
|
||||
path: P,
|
||||
passphrase: String,
|
||||
passphrase: &str,
|
||||
) -> StoreError<Self> {
|
||||
let store =
|
||||
SqliteStore::open_with_passphrase(&user_id, device_id, path, passphrase).await?;
|
||||
|
||||
OlmMachine::new_with_store(user_id, device_id, store).await
|
||||
OlmMachine::new_with_store(user_id.to_owned(), device_id.to_owned(), Box::new(store)).await
|
||||
}
|
||||
|
||||
/// The unique user id that owns this identity.
|
||||
|
|
|
@ -91,9 +91,15 @@ impl SqliteStore {
|
|||
user_id: &UserId,
|
||||
device_id: &str,
|
||||
path: P,
|
||||
passphrase: String,
|
||||
passphrase: &str,
|
||||
) -> Result<SqliteStore> {
|
||||
SqliteStore::open_helper(user_id, device_id, path, Some(Zeroizing::new(passphrase))).await
|
||||
SqliteStore::open_helper(
|
||||
user_id,
|
||||
device_id,
|
||||
path,
|
||||
Some(Zeroizing::new(passphrase.to_owned())),
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
fn path_to_url(path: &Path) -> Result<Url> {
|
||||
|
@ -801,14 +807,9 @@ mod test {
|
|||
let user_id = &UserId::try_from(USER_ID).unwrap();
|
||||
|
||||
let store = if let Some(passphrase) = passphrase {
|
||||
SqliteStore::open_with_passphrase(
|
||||
&user_id,
|
||||
DEVICE_ID,
|
||||
tmpdir_path,
|
||||
passphrase.to_owned(),
|
||||
)
|
||||
.await
|
||||
.expect("Can't create a passphrase protected store")
|
||||
SqliteStore::open_with_passphrase(&user_id, DEVICE_ID, tmpdir_path, passphrase)
|
||||
.await
|
||||
.expect("Can't create a passphrase protected store")
|
||||
} else {
|
||||
SqliteStore::open(&user_id, DEVICE_ID, tmpdir_path)
|
||||
.await
|
||||
|
|
Loading…
Reference in New Issue