From 96d4566111be2c7556aac4fbb83f163008cbaaba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Fri, 4 Jun 2021 18:09:20 +0200 Subject: [PATCH] crypto: Move the verification cache into a separate module --- matrix_sdk_crypto/src/verification/cache.rs | 118 ++++++++++++++++++ matrix_sdk_crypto/src/verification/machine.rs | 108 ++-------------- matrix_sdk_crypto/src/verification/mod.rs | 3 +- .../src/verification/requests.rs | 6 +- 4 files changed, 134 insertions(+), 101 deletions(-) create mode 100644 matrix_sdk_crypto/src/verification/cache.rs diff --git a/matrix_sdk_crypto/src/verification/cache.rs b/matrix_sdk_crypto/src/verification/cache.rs new file mode 100644 index 00000000..1d9ad673 --- /dev/null +++ b/matrix_sdk_crypto/src/verification/cache.rs @@ -0,0 +1,118 @@ +// Copyright 2021 The Matrix.org Foundation C.I.C. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use std::sync::Arc; + +use dashmap::DashMap; +use matrix_sdk_common::{ + identifiers::{DeviceId, UserId}, + uuid::Uuid, +}; + +use super::{event_enums::OutgoingContent, sas::content_to_request, Sas, Verification}; +use crate::{OutgoingRequest, RoomMessageRequest}; + +#[derive(Clone, Debug)] +pub struct VerificationCache { + verification: Arc>, + outgoing_requests: Arc>, +} + +impl VerificationCache { + pub fn new() -> Self { + Self { verification: DashMap::new().into(), outgoing_requests: DashMap::new().into() } + } + + #[cfg(test)] + pub fn is_empty(&self) -> bool { + self.verification.is_empty() + } + + pub fn insert_sas(&self, sas: Sas) { + self.verification.insert(sas.flow_id().as_str().to_string(), sas.into()); + } + + pub fn outgoing_requests(&self) -> Vec { + self.outgoing_requests.iter().map(|r| (*r).clone()).collect() + } + + pub fn garbage_collect(&self) -> Vec { + self.verification.retain(|_, s| !(s.is_done() || s.is_cancelled())); + + self.verification + .iter() + .filter_map(|s| { + #[allow(irrefutable_let_patterns)] + if let Verification::SasV1(s) = s.value() { + s.cancel_if_timed_out().map(|r| OutgoingRequest { + request_id: r.request_id(), + request: Arc::new(r.into()), + }) + } else { + None + } + }) + .collect() + } + + pub fn get_sas(&self, transaction_id: &str) -> Option { + self.verification.get(transaction_id).and_then(|v| { + #[allow(irrefutable_let_patterns)] + if let Verification::SasV1(sas) = v.value() { + Some(sas.clone()) + } else { + None + } + }) + } + + pub fn add_request(&self, request: OutgoingRequest) { + self.outgoing_requests.insert(request.request_id, request); + } + + pub fn queue_up_content( + &self, + recipient: &UserId, + recipient_device: &DeviceId, + content: OutgoingContent, + ) { + match content { + OutgoingContent::ToDevice(c) => { + let request = content_to_request(recipient, recipient_device.to_owned(), c); + let request_id = request.txn_id; + + let request = OutgoingRequest { request_id, request: Arc::new(request.into()) }; + + self.outgoing_requests.insert(request_id, request); + } + + OutgoingContent::Room(r, c) => { + let request_id = Uuid::new_v4(); + + let request = OutgoingRequest { + request: Arc::new( + RoomMessageRequest { room_id: r, txn_id: request_id, content: c }.into(), + ), + request_id, + }; + + self.outgoing_requests.insert(request_id, request); + } + } + } + + pub fn mark_request_as_sent(&self, uuid: &Uuid) { + self.outgoing_requests.remove(uuid); + } +} diff --git a/matrix_sdk_crypto/src/verification/machine.rs b/matrix_sdk_crypto/src/verification/machine.rs index 7bb65086..e12e92ad 100644 --- a/matrix_sdk_crypto/src/verification/machine.rs +++ b/matrix_sdk_crypto/src/verification/machine.rs @@ -23,10 +23,11 @@ use matrix_sdk_common::{ use tracing::{info, warn}; use super::{ + cache::VerificationCache, event_enums::{AnyEvent, AnyVerificationContent, OutgoingContent}, requests::VerificationRequest, sas::{content_to_request, Sas}, - FlowId, Verification, VerificationResult, + FlowId, VerificationResult, }; use crate::{ olm::PrivateCrossSigningIdentity, @@ -35,96 +36,6 @@ use crate::{ OutgoingVerificationRequest, ReadOnlyAccount, ReadOnlyDevice, RoomMessageRequest, }; -#[derive(Clone, Debug)] -pub struct VerificationCache { - verification: Arc>, - outgoing_requests: Arc>, -} - -impl VerificationCache { - pub fn new() -> Self { - Self { verification: DashMap::new().into(), outgoing_requests: DashMap::new().into() } - } - - #[cfg(test)] - fn is_empty(&self) -> bool { - self.verification.is_empty() - } - - pub fn insert_sas(&self, sas: Sas) { - self.verification.insert(sas.flow_id().as_str().to_string(), sas.into()); - } - - pub fn garbage_collect(&self) -> Vec { - self.verification.retain(|_, s| !(s.is_done() || s.is_cancelled())); - - self.verification - .iter() - .filter_map(|s| { - #[allow(irrefutable_let_patterns)] - if let Verification::SasV1(s) = s.value() { - s.cancel_if_timed_out().map(|r| OutgoingRequest { - request_id: r.request_id(), - request: Arc::new(r.into()), - }) - } else { - None - } - }) - .collect() - } - - pub fn get_sas(&self, transaction_id: &str) -> Option { - self.verification.get(transaction_id).and_then(|v| { - #[allow(irrefutable_let_patterns)] - if let Verification::SasV1(sas) = v.value() { - Some(sas.clone()) - } else { - None - } - }) - } - - pub fn add_request(&self, request: OutgoingRequest) { - self.outgoing_requests.insert(request.request_id, request); - } - - pub fn queue_up_content( - &self, - recipient: &UserId, - recipient_device: &DeviceId, - content: OutgoingContent, - ) { - match content { - OutgoingContent::ToDevice(c) => { - let request = content_to_request(recipient, recipient_device.to_owned(), c); - let request_id = request.txn_id; - - let request = OutgoingRequest { request_id, request: Arc::new(request.into()) }; - - self.outgoing_requests.insert(request_id, request); - } - - OutgoingContent::Room(r, c) => { - let request_id = Uuid::new_v4(); - - let request = OutgoingRequest { - request: Arc::new( - RoomMessageRequest { room_id: r, txn_id: request_id, content: c }.into(), - ), - request_id, - }; - - self.outgoing_requests.insert(request_id, request); - } - } - } - - pub fn mark_request_as_sent(&self, uuid: &Uuid) { - self.outgoing_requests.remove(uuid); - } -} - #[derive(Clone, Debug)] pub struct VerificationMachine { account: ReadOnlyAccount, @@ -204,7 +115,7 @@ impl VerificationMachine { } pub fn outgoing_messages(&self) -> Vec { - self.verifications.outgoing_requests.iter().map(|r| (*r).clone()).collect() + self.verifications.outgoing_requests() } pub fn garbage_collect(&self) { @@ -490,11 +401,12 @@ mod test { let event = wrap_any_to_device_content(bob.user_id(), content); - assert!(alice_machine.verifications.outgoing_requests.is_empty()); + assert!(alice_machine.verifications.outgoing_requests().is_empty()); alice_machine.receive_any_event(&event).await.unwrap(); - assert!(!alice_machine.verifications.outgoing_requests.is_empty()); + assert!(!alice_machine.verifications.outgoing_requests().is_empty()); - let request = alice_machine.verifications.outgoing_requests.iter().next().unwrap().clone(); + let request = + alice_machine.verifications.outgoing_requests().iter().next().unwrap().clone(); let txn_id = *request.request_id(); let content = OutgoingContent::try_from(request).unwrap(); let content = KeyContent::try_from(&content).unwrap().into(); @@ -528,14 +440,14 @@ mod test { let alice = alice_machine.get_sas(bob.flow_id().as_str()).unwrap(); assert!(!alice.timed_out()); - assert!(alice_machine.verifications.outgoing_requests.is_empty()); + assert!(alice_machine.verifications.outgoing_requests().is_empty()); // This line panics on macOS, so we're disabled for now. alice.set_creation_time(Instant::now() - Duration::from_secs(60 * 15)); assert!(alice.timed_out()); - assert!(alice_machine.verifications.outgoing_requests.is_empty()); + assert!(alice_machine.verifications.outgoing_requests().is_empty()); alice_machine.garbage_collect(); - assert!(!alice_machine.verifications.outgoing_requests.is_empty()); + assert!(!alice_machine.verifications.outgoing_requests().is_empty()); alice_machine.garbage_collect(); assert!(alice_machine.verifications.is_empty()); } diff --git a/matrix_sdk_crypto/src/verification/mod.rs b/matrix_sdk_crypto/src/verification/mod.rs index adb6f63c..3d74178e 100644 --- a/matrix_sdk_crypto/src/verification/mod.rs +++ b/matrix_sdk_crypto/src/verification/mod.rs @@ -12,6 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +mod cache; mod event_enums; mod machine; mod requests; @@ -20,7 +21,7 @@ mod sas; use std::sync::Arc; use event_enums::OutgoingContent; -pub use machine::{VerificationCache, VerificationMachine}; +pub use machine::VerificationMachine; use matrix_sdk_common::{ api::r0::keys::upload_signatures::Request as SignatureUploadRequest, events::{ diff --git a/matrix_sdk_crypto/src/verification/requests.rs b/matrix_sdk_crypto/src/verification/requests.rs index 01576585..a0ce3bba 100644 --- a/matrix_sdk_crypto/src/verification/requests.rs +++ b/matrix_sdk_crypto/src/verification/requests.rs @@ -36,11 +36,12 @@ use matrix_sdk_common::{ use tracing::{info, warn}; use super::{ + cache::VerificationCache, event_enums::{ CancelContent, DoneContent, OutgoingContent, ReadyContent, RequestContent, StartContent, }, sas::content_to_request, - Cancelled, FlowId, VerificationCache, + Cancelled, FlowId, }; use crate::{ olm::{PrivateCrossSigningIdentity, ReadOnlyAccount}, @@ -684,8 +685,9 @@ mod test { olm::{PrivateCrossSigningIdentity, ReadOnlyAccount}, store::{Changes, CryptoStore, MemoryStore}, verification::{ + cache::VerificationCache, event_enums::{OutgoingContent, ReadyContent, StartContent}, - FlowId, VerificationCache, + FlowId, }, ReadOnlyDevice, };