matrix_sdk/encryption/secret_storage/
futures.rs1use std::{future::IntoFuture, pin::Pin};
16
17use futures_core::Future;
18use matrix_sdk_base::crypto::secret_storage::SecretStorageKey;
19use ruma::events::secret_storage::default_key::SecretStorageDefaultKeyEventContent;
20
21use super::{Result, SecretStorage, SecretStore};
22
23#[derive(Debug)]
24pub(crate) enum KeyOrPassphrase<'a> {
25 None,
26 Key(&'a SecretStorageKey),
27 Passphrase(&'a str),
28}
29
30#[derive(Debug)]
32pub struct CreateStore<'a> {
33 pub(super) secret_storage: &'a SecretStorage,
34 pub(super) key: KeyOrPassphrase<'a>,
35}
36
37impl<'a> CreateStore<'a> {
38 pub fn with_passphrase(mut self, passphrase: &'a str) -> Self {
43 self.key = KeyOrPassphrase::Passphrase(passphrase);
44
45 self
46 }
47
48 pub fn with_key(mut self, key: &'a SecretStorageKey) -> Self {
53 self.key = KeyOrPassphrase::Key(key);
54
55 self
56 }
57}
58
59impl<'a> IntoFuture for CreateStore<'a> {
60 type Output = Result<SecretStore>;
61 #[cfg(target_family = "wasm")]
62 type IntoFuture = Pin<Box<dyn Future<Output = Self::Output> + 'a>>;
63 #[cfg(not(target_family = "wasm"))]
64 type IntoFuture = Pin<Box<dyn Future<Output = Self::Output> + Send + 'a>>;
65
66 fn into_future(self) -> Self::IntoFuture {
67 let Self { secret_storage, key } = self;
68
69 Box::pin(async move {
70 let client_copy = secret_storage.client.to_owned();
75 let _guard = client_copy.locks().open_secret_store_lock.lock().await;
76
77 let new_key = match key {
78 KeyOrPassphrase::None => SecretStorageKey::new(),
79 KeyOrPassphrase::Key(k) => k.clone(),
80 KeyOrPassphrase::Passphrase(p) => SecretStorageKey::new_from_passphrase(p),
81 };
82
83 let content = new_key.event_content().to_owned();
84
85 secret_storage.client.account().set_account_data(content).await?;
86
87 let store = SecretStore { client: secret_storage.client.to_owned(), key: new_key };
88 store.export_secrets().await?;
89
90 let default_key_content =
91 SecretStorageDefaultKeyEventContent::new(store.key.key_id().to_owned());
92
93 store.client.account().set_account_data(default_key_content).await?;
94
95 Ok(store)
96 })
97 }
98}