[fractal/fractal-next] verification: Only allocate FlowId on insert



commit 62da8d1589fbb6f44a92951db34162ba4d74a9ff
Author: Julian Sparber <julian sparber net>
Date:   Tue Jan 18 15:11:57 2022 +0100

    verification: Only allocate FlowId on insert

 src/session/room/timeline.rs                  | 21 +++++-----
 src/session/verification/mod.rs               |  2 +-
 src/session/verification/verification_list.rs | 59 +++++++++++++++++++--------
 3 files changed, 55 insertions(+), 27 deletions(-)
---
diff --git a/src/session/room/timeline.rs b/src/session/room/timeline.rs
index 0db7e2cf..f88527d4 100644
--- a/src/session/room/timeline.rs
+++ b/src/session/room/timeline.rs
@@ -17,7 +17,7 @@ use matrix_sdk::{
 use crate::session::{
     room::{Event, Item, ItemType, Room},
     user::UserExt,
-    verification::{FlowId, IdentityVerification, VERIFICATION_CREATION_TIMEOUT},
+    verification::{IdentityVerification, VERIFICATION_CREATION_TIMEOUT},
 };
 use crate::{spawn, spawn_tokio};
 
@@ -694,8 +694,9 @@ impl Timeline {
         };
 
         let session = self.room().session();
+        let verification_list = session.verification_list();
 
-        let flow_id = match message {
+        let request = match message {
             AnySyncMessageEvent::RoomMessage(message) => {
                 if let MessageType::VerificationRequest(request) = message.content.msgtype {
                     // Ignore request that are too old
@@ -745,32 +746,32 @@ impl Timeline {
                 return;
             }
             AnySyncMessageEvent::KeyVerificationReady(e) => {
-                FlowId::new(e.sender.into(), e.content.relates_to.event_id.to_string())
+                verification_list.get_by_id(&e.sender, &e.content.relates_to.event_id)
             }
             AnySyncMessageEvent::KeyVerificationStart(e) => {
-                FlowId::new(e.sender.into(), e.content.relates_to.event_id.to_string())
+                verification_list.get_by_id(&e.sender, &e.content.relates_to.event_id)
             }
             AnySyncMessageEvent::KeyVerificationCancel(e) => {
-                FlowId::new(e.sender.into(), e.content.relates_to.event_id.to_string())
+                verification_list.get_by_id(&e.sender, &e.content.relates_to.event_id)
             }
             AnySyncMessageEvent::KeyVerificationAccept(e) => {
-                FlowId::new(e.sender.into(), e.content.relates_to.event_id.to_string())
+                verification_list.get_by_id(&e.sender, &e.content.relates_to.event_id)
             }
             AnySyncMessageEvent::KeyVerificationKey(e) => {
-                FlowId::new(e.sender.into(), e.content.relates_to.event_id.to_string())
+                verification_list.get_by_id(&e.sender, &e.content.relates_to.event_id)
             }
             AnySyncMessageEvent::KeyVerificationMac(e) => {
-                FlowId::new(e.sender.into(), e.content.relates_to.event_id.to_string())
+                verification_list.get_by_id(&e.sender, &e.content.relates_to.event_id)
             }
             AnySyncMessageEvent::KeyVerificationDone(e) => {
-                FlowId::new(e.sender.into(), e.content.relates_to.event_id.to_string())
+                verification_list.get_by_id(&e.sender, &e.content.relates_to.event_id)
             }
             _ => {
                 return;
             }
         };
 
-        if let Some(request) = session.verification_list().get_by_id(&flow_id) {
+        if let Some(request) = request {
             request.notify_state();
         }
     }
diff --git a/src/session/verification/mod.rs b/src/session/verification/mod.rs
index 8cf011f3..1c1cfa14 100644
--- a/src/session/verification/mod.rs
+++ b/src/session/verification/mod.rs
@@ -4,7 +4,7 @@ mod verification_list;
 pub use self::identity_verification::{
     IdentityVerification, Mode as VerificationMode, SasData, State as VerificationState,
 };
-pub use self::verification_list::{FlowId, VerificationList};
+pub use self::verification_list::VerificationList;
 
 use std::time::Duration;
 /// The time a verification is valid after it's creation.
diff --git a/src/session/verification/verification_list.rs b/src/session/verification/verification_list.rs
index 22984e2a..4618ca32 100644
--- a/src/session/verification/verification_list.rs
+++ b/src/session/verification/verification_list.rs
@@ -22,6 +22,24 @@ impl FlowId {
     }
 }
 
+#[derive(Hash, PartialEq, Eq, Debug)]
+struct FlowIdUnowned<'a> {
+    user_id: &'a UserId,
+    flow_id: &'a str,
+}
+
+impl<'a> FlowIdUnowned<'a> {
+    pub fn new(user_id: &'a UserId, flow_id: &'a str) -> Self {
+        Self { user_id, flow_id }
+    }
+}
+
+impl indexmap::Equivalent<FlowId> for FlowIdUnowned<'_> {
+    fn equivalent(&self, key: &FlowId) -> bool {
+        self.user_id == &*key.user_id && self.flow_id == &*key.flow_id
+    }
+}
+
 mod imp {
     use glib::object::WeakRef;
     use indexmap::IndexMap;
@@ -119,14 +137,13 @@ impl VerificationList {
             debug!("Received verification event: {:?}", event);
             let request = match event {
                 AnyToDeviceEvent::KeyVerificationRequest(e) => {
-                    let flow_id = FlowId::new(e.sender.into(), e.content.transaction_id);
-                    if let Some(request) = self.get_by_id(&flow_id) {
+                    if let Some(request) = self.get_by_id(&e.sender, &e.content.transaction_id) {
                         Some(request)
                     } else {
                         let session = self.session();
                         let user = session.user().unwrap();
                         // ToDevice verifications can only be send by us
-                        if flow_id.user_id != user.user_id() {
+                        if *e.sender != *user.user_id() {
                             warn!("Received a device verification event from a different user, which isn't 
allowed");
                             continue;
                         }
@@ -159,7 +176,7 @@ impl VerificationList {
                         };
 
                         let request = IdentityVerification::for_flow_id(
-                            &flow_id.flow_id,
+                            e.content.transaction_id.as_str(),
                             &session,
                             user,
                             &start_time,
@@ -169,25 +186,25 @@ impl VerificationList {
                     }
                 }
                 AnyToDeviceEvent::KeyVerificationReady(e) => {
-                    self.get_by_id(&FlowId::new(e.sender.into(), e.content.transaction_id))
+                    self.get_by_id(&e.sender, &e.content.transaction_id)
                 }
                 AnyToDeviceEvent::KeyVerificationStart(e) => {
-                    self.get_by_id(&FlowId::new(e.sender.into(), e.content.transaction_id))
+                    self.get_by_id(&e.sender, &e.content.transaction_id)
                 }
                 AnyToDeviceEvent::KeyVerificationCancel(e) => {
-                    self.get_by_id(&FlowId::new(e.sender.into(), e.content.transaction_id))
+                    self.get_by_id(&e.sender, &e.content.transaction_id)
                 }
                 AnyToDeviceEvent::KeyVerificationAccept(e) => {
-                    self.get_by_id(&FlowId::new(e.sender.into(), e.content.transaction_id))
+                    self.get_by_id(&e.sender, &e.content.transaction_id)
                 }
                 AnyToDeviceEvent::KeyVerificationMac(e) => {
-                    self.get_by_id(&FlowId::new(e.sender.into(), e.content.transaction_id))
+                    self.get_by_id(&e.sender, &e.content.transaction_id)
                 }
                 AnyToDeviceEvent::KeyVerificationKey(e) => {
-                    self.get_by_id(&FlowId::new(e.sender.into(), e.content.transaction_id))
+                    self.get_by_id(&e.sender, &e.content.transaction_id)
                 }
                 AnyToDeviceEvent::KeyVerificationDone(e) => {
-                    self.get_by_id(&FlowId::new(e.sender.into(), e.content.transaction_id))
+                    self.get_by_id(&e.sender, &e.content.transaction_id)
                 }
                 _ => continue,
             };
@@ -232,9 +249,14 @@ impl VerificationList {
     pub fn remove(&self, request: &IdentityVerification) {
         let priv_ = imp::VerificationList::from_instance(self);
 
-        let position = if let Some((position, _, _)) = priv_.list.borrow_mut().shift_remove_full(
-            &FlowId::new(request.user().user_id(), request.flow_id().to_owned()),
-        ) {
+        let position = if let Some((position, _, _)) =
+            priv_
+                .list
+                .borrow_mut()
+                .shift_remove_full(&FlowIdUnowned::new(
+                    request.user().user_id().as_ref(),
+                    request.flow_id(),
+                )) {
             position
         } else {
             return;
@@ -243,9 +265,14 @@ impl VerificationList {
         self.items_changed(position as u32, 1, 0);
     }
 
-    pub fn get_by_id(&self, flow_id: &FlowId) -> Option<IdentityVerification> {
+    pub fn get_by_id(
+        &self,
+        user_id: &UserId,
+        flow_id: &impl AsRef<str>,
+    ) -> Option<IdentityVerification> {
         let priv_ = imp::VerificationList::from_instance(self);
 
-        priv_.list.borrow().get(flow_id).cloned()
+        let flow_id = FlowIdUnowned::new(user_id, flow_id.as_ref());
+        priv_.list.borrow().get(&flow_id).cloned()
     }
 }


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]