base: Allow using the same sled database for the state and cryptostore

master
Damir Jelić 2021-01-22 11:33:06 +01:00
parent 9cd217fc5d
commit c034de470b
6 changed files with 50 additions and 13 deletions

View File

@ -247,7 +247,7 @@ impl Printer {
impl Inspector { impl Inspector {
fn new(database_path: &str, json: bool, color: bool) -> Self { fn new(database_path: &str, json: bool, color: bool) -> Self {
let printer = Printer::new(json, color); let printer = Printer::new(json, color);
let store = Store::open_default(database_path, None).unwrap(); let (store, _) = Store::open_default(database_path, None).unwrap();
Self { store, printer } Self { store, printer }
} }

View File

@ -279,7 +279,8 @@ impl BaseClient {
/// * `config` - 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. /// previous login call.
pub fn new_with_config(config: BaseClientConfig) -> Result<Self> { pub fn new_with_config(config: BaseClientConfig) -> Result<Self> {
let store = if let Some(path) = &config.store_path { #[cfg(not(target_arch = "wasm32"))]
let (store, sled_store) = if let Some(path) = &config.store_path {
if config.passphrase.is_some() { if config.passphrase.is_some() {
info!("Opening an encrypted store in path {}", path.display()); info!("Opening an encrypted store in path {}", path.display());
} else { } else {
@ -289,6 +290,28 @@ impl BaseClient {
} else { } else {
Store::open_temporrary()? Store::open_temporrary()?
}; };
#[cfg(target_arch = "wasm32")]
let store = Store::open_memory_store();
#[cfg(not(target_arch = "wasm32"))]
let crypto_store = if config.crypto_store.is_none() {
#[cfg(feature = "sled_cryptostore")]
let store: Option<Box<dyn CryptoStore>> = Some(Box::new(
matrix_sdk_crypto::store::SledStore::open_with_database(
sled_store,
config.passphrase.as_deref().map(|p| p.as_str()),
)
.map_err(OlmError::Store)?,
));
#[cfg(not(feature = "sled_cryptostore"))]
let store = config.crypto_store;
store
} else {
config.crypto_store
};
#[cfg(target_arch = "wasm32")]
let crypto_store = config.crypto_store;
Ok(BaseClient { Ok(BaseClient {
session: store.session.clone(), session: store.session.clone(),
@ -297,7 +320,7 @@ impl BaseClient {
#[cfg(feature = "encryption")] #[cfg(feature = "encryption")]
olm: Mutex::new(None).into(), olm: Mutex::new(None).into(),
#[cfg(feature = "encryption")] #[cfg(feature = "encryption")]
cryptostore: Mutex::new(config.crypto_store).into(), cryptostore: Mutex::new(crypto_store).into(),
store_path: config.store_path.into(), store_path: config.store_path.into(),
store_passphrase: config.passphrase.into(), store_passphrase: config.passphrase.into(),
event_emitter: RwLock::new(None).into(), event_emitter: RwLock::new(None).into(),

View File

@ -25,6 +25,7 @@ use matrix_sdk_common::{
locks::RwLock, locks::RwLock,
AsyncTraitDeps, AsyncTraitDeps,
}; };
use sled::Db;
use crate::{ use crate::{
deserialized_responses::{MemberEvent, StrippedMemberEvent}, deserialized_responses::{MemberEvent, StrippedMemberEvent},
@ -33,9 +34,12 @@ use crate::{
}; };
mod memory_store; mod memory_store;
#[cfg(not(target_arch = "wasm32"))]
mod sled_store; mod sled_store;
use self::{memory_store::MemoryStore, sled_store::SledStore}; use self::memory_store::MemoryStore;
#[cfg(not(target_arch = "wasm32"))]
use self::sled_store::SledStore;
#[derive(Debug, thiserror::Error)] #[derive(Debug, thiserror::Error)]
pub enum StoreError { pub enum StoreError {
@ -138,20 +142,20 @@ impl Store {
Self::new(inner) Self::new(inner)
} }
pub fn open_default(path: impl AsRef<Path>, passphrase: Option<&str>) -> Result<Self> { pub fn open_default(path: impl AsRef<Path>, passphrase: Option<&str>) -> Result<(Self, Db)> {
let inner = if let Some(passphrase) = passphrase { let inner = if let Some(passphrase) = passphrase {
Box::new(SledStore::open_with_passphrase(path, passphrase)?) SledStore::open_with_passphrase(path, passphrase)?
} else { } else {
Box::new(SledStore::open_with_path(path)?) SledStore::open_with_path(path)?
}; };
Ok(Self::new(inner)) Ok((Self::new(Box::new(inner.clone())), inner.inner))
} }
pub fn open_temporrary() -> Result<Self> { pub fn open_temporrary() -> Result<(Self, Db)> {
let inner = Box::new(SledStore::open()?); let inner = SledStore::open()?;
Ok(Self::new(inner)) Ok((Self::new(Box::new(inner.clone())), inner.inner))
} }
pub(crate) fn get_bare_room(&self, room_id: &RoomId) -> Option<Room> { pub(crate) fn get_bare_room(&self, room_id: &RoomId) -> Option<Room> {

View File

@ -81,7 +81,7 @@ impl From<SerializationError> for StoreError {
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct SledStore { pub struct SledStore {
inner: Db, pub(crate) inner: Db,
store_key: Arc<Option<StoreKey>>, store_key: Arc<Option<StoreKey>>,
session: Tree, session: Tree,
account_data: Tree, account_data: Tree,

View File

@ -46,6 +46,8 @@ pub(crate) mod sled;
#[cfg(feature = "sqlite_cryptostore")] #[cfg(feature = "sqlite_cryptostore")]
pub(crate) mod sqlite; pub(crate) mod sqlite;
#[cfg(feature = "sled_cryptostore")]
pub use self::sled::SledStore;
pub use memorystore::MemoryStore; pub use memorystore::MemoryStore;
pub use pickle_key::{EncryptedPickleKey, PickleKey}; pub use pickle_key::{EncryptedPickleKey, PickleKey};
#[cfg(not(target_arch = "wasm32"))] #[cfg(not(target_arch = "wasm32"))]

View File

@ -81,6 +81,8 @@ impl From<TransactionError<serde_json::Error>> for CryptoStoreError {
} }
impl SledStore { impl SledStore {
/// Open the sled based cryptostore at the given path using the given
/// passphrase to encrypt private data.
pub fn open_with_passphrase(path: impl AsRef<Path>, passphrase: Option<&str>) -> Result<Self> { pub fn open_with_passphrase(path: impl AsRef<Path>, passphrase: Option<&str>) -> Result<Self> {
let path = path.as_ref().join("matrix-sdk-crypto"); let path = path.as_ref().join("matrix-sdk-crypto");
let db = Config::new().temporary(false).path(path).open()?; let db = Config::new().temporary(false).path(path).open()?;
@ -88,6 +90,12 @@ impl SledStore {
SledStore::open_helper(db, passphrase) SledStore::open_helper(db, passphrase)
} }
/// Create a sled based cryptostore using the given sled database.
/// The given passphrase will be used to encrypt private data.
pub fn open_with_database(db: Db, passphrase: Option<&str>) -> Result<Self> {
SledStore::open_helper(db, passphrase)
}
fn open_helper(db: Db, passphrase: Option<&str>) -> Result<Self> { fn open_helper(db: Db, passphrase: Option<&str>) -> Result<Self> {
let account = db.open_tree("account")?; let account = db.open_tree("account")?;
let private_identity = db.open_tree("private_identity")?; let private_identity = db.open_tree("private_identity")?;
@ -171,7 +179,7 @@ impl SledStore {
Ok(()) Ok(())
} }
pub async fn save_changes(&self, changes: Changes) -> Result<()> { async fn save_changes(&self, changes: Changes) -> Result<()> {
let account_pickle = if let Some(a) = changes.account { let account_pickle = if let Some(a) = changes.account {
Some(a.pickle(self.get_pickle_mode()).await) Some(a.pickle(self.get_pickle_mode()).await)
} else { } else {