From f9d290746c8d8e5710a1af232d5f041d48f3fa2a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Thu, 15 Apr 2021 17:48:37 +0200 Subject: [PATCH] crypto: Load unsent outgoing key requests when we open a store --- matrix_sdk_crypto/src/key_request.rs | 49 +++++++++++++++++----- matrix_sdk_crypto/src/machine.rs | 7 ++-- matrix_sdk_crypto/src/store/memorystore.rs | 8 ++++ matrix_sdk_crypto/src/store/mod.rs | 3 ++ matrix_sdk_crypto/src/store/sled.rs | 12 ++++++ 5 files changed, 66 insertions(+), 13 deletions(-) diff --git a/matrix_sdk_crypto/src/key_request.rs b/matrix_sdk_crypto/src/key_request.rs index 34a3b8a3..b00e8fbb 100644 --- a/matrix_sdk_crypto/src/key_request.rs +++ b/matrix_sdk_crypto/src/key_request.rs @@ -149,6 +149,23 @@ pub struct OutgoingKeyRequest { pub sent_out: bool, } +impl OutgoingKeyRequest { + fn into_request( + &self, + recipient: &UserId, + own_device_id: &DeviceId, + ) -> Result { + let content = RoomKeyRequestToDeviceEventContent { + action: Action::Request, + request_id: self.request_id.to_string(), + requesting_device_id: own_device_id.to_owned(), + body: Some(self.info.clone()), + }; + + wrap_key_request_content(recipient.to_owned(), self.request_id, &content) + } +} + impl PartialEq for OutgoingKeyRequest { fn eq(&self, other: &Self) -> bool { self.request_id == other.request_id @@ -204,6 +221,25 @@ impl KeyRequestMachine { } } + /// Load stored non-sent out outgoing requests + pub async fn load_outgoing_requests(&mut self) -> Result<(), CryptoStoreError> { + let infos: Vec = vec![]; + let requests: DashMap = infos + .iter() + .filter(|i| !i.sent_out) + .filter_map(|info| { + Some(( + info.request_id, + info.into_request(self.user_id(), self.device_id()).ok()?, + )) + }) + .collect(); + + self.outgoing_to_device_requests = requests.into(); + + Ok(()) + } + /// Our own user id. pub fn user_id(&self) -> &UserId { &self.user_id @@ -542,21 +578,14 @@ impl KeyRequestMachine { let id = Uuid::new_v4(); - let content = RoomKeyRequestToDeviceEventContent { - action: Action::Request, - request_id: id.to_string(), - requesting_device_id: (&*self.device_id).clone(), - body: Some(key_info), - }; - - let request = wrap_key_request_content(self.user_id().clone(), id, &content)?; - let info = OutgoingKeyRequest { request_id: id, - info: content.body.unwrap(), + info: key_info, sent_out: false, }; + let request = info.into_request(self.user_id(), self.device_id())?; + self.save_outgoing_key_info(info).await?; self.outgoing_to_device_requests.insert(id, request); diff --git a/matrix_sdk_crypto/src/machine.rs b/matrix_sdk_crypto/src/machine.rs index 59a99457..746523f3 100644 --- a/matrix_sdk_crypto/src/machine.rs +++ b/matrix_sdk_crypto/src/machine.rs @@ -245,9 +245,10 @@ impl OlmMachine { } }; - Ok(OlmMachine::new_helper( - &user_id, device_id, store, account, identity, - )) + let mut machine = OlmMachine::new_helper(&user_id, device_id, store, account, identity); + machine.key_request_machine.load_outgoing_requests().await?; + + Ok(machine) } /// Create a new machine with the default crypto store. diff --git a/matrix_sdk_crypto/src/store/memorystore.rs b/matrix_sdk_crypto/src/store/memorystore.rs index 27993e25..150354ca 100644 --- a/matrix_sdk_crypto/src/store/memorystore.rs +++ b/matrix_sdk_crypto/src/store/memorystore.rs @@ -268,6 +268,14 @@ impl CryptoStore for MemoryStore { .and_then(|i| self.outgoing_key_requests.get(&i).map(|r| r.clone()))) } + async fn get_outgoing_key_requests(&self) -> Result> { + Ok(self + .outgoing_key_requests + .iter() + .map(|i| i.value().clone()) + .collect()) + } + async fn delete_outgoing_key_request(&self, request_id: Uuid) -> Result<()> { self.outgoing_key_requests .remove(&request_id) diff --git a/matrix_sdk_crypto/src/store/mod.rs b/matrix_sdk_crypto/src/store/mod.rs index 387bd610..6f5b1338 100644 --- a/matrix_sdk_crypto/src/store/mod.rs +++ b/matrix_sdk_crypto/src/store/mod.rs @@ -449,6 +449,9 @@ pub trait CryptoStore: AsyncTraitDeps { key_info: &RequestedKeyInfo, ) -> Result>; + /// Get all outgoing key requests that we have in the store. + async fn get_outgoing_key_requests(&self) -> Result>; + /// Delete an outoing key request that we created that matches the given /// request id. /// diff --git a/matrix_sdk_crypto/src/store/sled.rs b/matrix_sdk_crypto/src/store/sled.rs index f177f10d..0bda2de0 100644 --- a/matrix_sdk_crypto/src/store/sled.rs +++ b/matrix_sdk_crypto/src/store/sled.rs @@ -709,6 +709,16 @@ impl CryptoStore for SledStore { } } + async fn get_outgoing_key_requests(&self) -> Result> { + let requests: Result> = self + .outgoing_key_requests + .iter() + .map(|i| serde_json::from_slice(&i?.1).map_err(CryptoStoreError::from)) + .collect(); + + requests + } + async fn delete_outgoing_key_request(&self, request_id: Uuid) -> Result<()> { let ret: Result<(), TransactionError> = (&self.outgoing_key_requests, &self.key_requests_by_info).transaction( @@ -1318,6 +1328,7 @@ mod test { let stored_request = store.get_key_request_by_info(&info).await.unwrap(); assert_eq!(request, stored_request); + assert!(!store.get_outgoing_key_requests().await.unwrap().is_empty()); store.delete_outgoing_key_request(id).await.unwrap(); @@ -1326,5 +1337,6 @@ mod test { let stored_request = store.get_key_request_by_info(&info).await.unwrap(); assert_eq!(None, stored_request); + assert!(store.get_outgoing_key_requests().await.unwrap().is_empty()); } }