[fractal/fractal-next] verification: Use incomming requests on cross-signing setup



commit fb547d0f3bdd125f2b1ae301f0b6cce7f7496e55
Author: Julian Sparber <julian sparber net>
Date:   Tue Mar 22 12:37:06 2022 +0100

    verification: Use incomming requests on cross-signing setup

 .../content/verification/session_verification.rs   | 16 ++++--
 src/session/mod.rs                                 |  7 +--
 src/session/verification/identity_verification.rs  | 61 +++++++++++++++-------
 src/session/verification/verification_list.rs      | 16 ++++++
 4 files changed, 74 insertions(+), 26 deletions(-)
---
diff --git a/src/session/content/verification/session_verification.rs 
b/src/session/content/verification/session_verification.rs
index 7e5dbb26b..27a4640b0 100644
--- a/src/session/content/verification/session_verification.rs
+++ b/src/session/content/verification/session_verification.rs
@@ -1,7 +1,7 @@
 use adw::subclass::prelude::*;
 use gettextrs::gettext;
 use gtk::{glib, glib::clone, prelude::*, subclass::prelude::*, CompositeTemplate};
-use log::error;
+use log::{debug, error};
 
 use super::IdentityVerificationWidget;
 use crate::{
@@ -247,8 +247,18 @@ impl SessionVerification {
             .set_visible_child_name("wait-for-device");
 
         spawn!(clone!(@weak self as obj => async move {
-            let request = IdentityVerification::create(&obj.session(), None).await;
-            obj.session().verification_list().add(request.clone());
+            let session = obj.session();
+            let verification_list = session.verification_list();
+            let request = if let Some(request) = verification_list.get_session() {
+                debug!("Use session verification started by another session");
+                request.set_force_current_session(true);
+                request
+            } else {
+                let request = IdentityVerification::create(&session, None).await;
+                debug!("Start a new session verification");
+                verification_list.add(request.clone());
+                request
+            };
             obj.set_request(Some(request));
         }));
     }
diff --git a/src/session/mod.rs b/src/session/mod.rs
index 093adaa5e..c5ab3922f 100644
--- a/src/session/mod.rs
+++ b/src/session/mod.rs
@@ -633,12 +633,13 @@ impl Session {
         debug!("Received sync response");
         match response {
             Ok(response) => {
-                if !self.is_ready() {
-                    self.mark_ready();
-                }
                 self.room_list().handle_response_rooms(response.rooms);
                 self.verification_list()
                     .handle_response_to_device(response.to_device);
+
+                if !self.is_ready() {
+                    self.mark_ready();
+                }
             }
             Err(error) => {
                 if let matrix_sdk::Error::Http(HttpError::ClientApi(FromHttpResponseError::Http(
diff --git a/src/session/verification/identity_verification.rs 
b/src/session/verification/identity_verification.rs
index 8d63e4029..071804dc8 100644
--- a/src/session/verification/identity_verification.rs
+++ b/src/session/verification/identity_verification.rs
@@ -181,6 +181,7 @@ mod imp {
         pub start_time: OnceCell<glib::DateTime>,
         pub receive_time: OnceCell<glib::DateTime>,
         pub hide_error: Cell<bool>,
+        pub force_current_session: Cell<bool>,
     }
 
     #[glib::object_subclass]
@@ -222,7 +223,7 @@ mod imp {
                         "The mode of this verification",
                         Mode::static_type(),
                         Mode::default() as i32,
-                        glib::ParamFlags::READWRITE | glib::ParamFlags::CONSTRUCT_ONLY,
+                        glib::ParamFlags::READABLE,
                     ),
                     glib::ParamSpecFlags::new(
                         "supported-methods",
@@ -260,6 +261,13 @@ mod imp {
                         glib::DateTime::static_type(),
                         glib::ParamFlags::READABLE,
                     ),
+                    glib::ParamSpecBoolean::new(
+                        "force-current-session",
+                        "Force Current Session",
+                        "Whether this should be automatically accepted and treated as a 
Mode::CurrentSession",
+                        false,
+                        glib::ParamFlags::READWRITE| glib::ParamFlags::EXPLICIT_NOTIFY,
+                    ),
                 ]
             });
 
@@ -277,7 +285,6 @@ mod imp {
                 "user" => obj.set_user(value.get().unwrap()),
                 "session" => obj.set_session(value.get().unwrap()),
                 "state" => obj.set_state(value.get().unwrap()),
-                "mode" => obj.set_mode(value.get().unwrap()),
                 "flow-id" => obj.set_flow_id(value.get().unwrap()),
                 "start-time" => obj.set_start_time(value.get().unwrap()),
                 "supported-methods" => obj.set_supported_methods(value.get().unwrap()),
@@ -296,6 +303,7 @@ mod imp {
                 "supported-methods" => obj.supported_methods().to_value(),
                 "start-time" => obj.start_time().to_value(),
                 "receive-time" => obj.receive_time().to_value(),
+                "force-current-session" => obj.force_current_session().to_value(),
                 _ => unimplemented!(),
             }
         }
@@ -353,10 +361,9 @@ glib::wrapper! {
 }
 
 impl IdentityVerification {
-    fn for_error(mode: Mode, session: &Session, user: &User, start_time: &glib::DateTime) -> Self {
+    fn for_error(session: &Session, user: &User, start_time: &glib::DateTime) -> Self {
         glib::Object::new(&[
             ("state", &State::Error),
-            ("mode", &mode),
             ("session", session),
             ("user", user),
             ("start-time", start_time),
@@ -386,10 +393,10 @@ impl IdentityVerification {
     /// If `User` is `None` a new session verification is started for our own
     /// user and send to other devices
     pub async fn create(session: &Session, user: Option<&User>) -> Self {
-        let (mode, user) = if let Some(user) = user {
-            (Mode::User, user)
+        let user = if let Some(user) = user {
+            user
         } else {
-            (Mode::CurrentSession, session.user().unwrap())
+            session.user().unwrap()
         };
 
         let supported_methods =
@@ -406,7 +413,6 @@ impl IdentityVerification {
                 Ok(request) => {
                     let obj = glib::Object::new(&[
                         ("state", &State::RequestSend),
-                        ("mode", &mode),
                         ("supported-methods", &supported_methods),
                         ("flow-id", &request.flow_id()),
                         ("session", session),
@@ -425,7 +431,7 @@ impl IdentityVerification {
             error!("Starting a verification failed: Crypto identity wasn't found");
         }
 
-        Self::for_error(mode, session, user, &glib::DateTime::now_local().unwrap())
+        Self::for_error(session, user, &glib::DateTime::now_local().unwrap())
     }
 
     fn start_handler(&self) {
@@ -491,6 +497,23 @@ impl IdentityVerification {
         self.imp().user.set(user).unwrap()
     }
 
+    pub fn force_current_session(&self) -> bool {
+        self.imp().force_current_session.get()
+    }
+
+    /// Force that this `IdentityVerification` is considered a
+    /// `Mode::CurrentSession`. This is usfull that incoming requests during
+    /// setup are accepted directly.
+    pub fn set_force_current_session(&self, force: bool) {
+        if self.force_current_session() == force {
+            return;
+        }
+
+        self.imp().force_current_session.set(force);
+        self.accept();
+        self.notify("force-current-session");
+    }
+
     /// The current `Session`.
     pub fn session(&self) -> Session {
         self.imp().session.get().unwrap().upgrade().unwrap()
@@ -614,19 +637,17 @@ impl IdentityVerification {
     }
 
     pub fn mode(&self) -> Mode {
-        *self.imp().mode.get_or_init(|| {
-            let session = self.session();
-            let our_user = session.user().unwrap();
-            if our_user.user_id() == self.user().user_id() {
-                Mode::OtherSession
+        let session = self.session();
+        let our_user = session.user().unwrap();
+        if our_user.user_id() == self.user().user_id() {
+            if self.force_current_session() {
+                Mode::CurrentSession
             } else {
-                Mode::User
+                Mode::OtherSession
             }
-        })
-    }
-
-    fn set_mode(&self, mode: Mode) {
-        self.imp().mode.set(mode).unwrap();
+        } else {
+            Mode::User
+        }
     }
 
     /// Whether this request is finished
diff --git a/src/session/verification/verification_list.rs b/src/session/verification/verification_list.rs
index 987db11ac..cdd234c33 100644
--- a/src/session/verification/verification_list.rs
+++ b/src/session/verification/verification_list.rs
@@ -243,6 +243,7 @@ impl VerificationList {
             );
             length as u32
         };
+
         self.items_changed(length, 0, 1)
     }
 
@@ -271,4 +272,19 @@ impl VerificationList {
         let flow_id = FlowIdUnowned::new(user_id, flow_id.as_ref());
         self.imp().list.borrow().get(&flow_id).cloned()
     }
+
+    // Returns the first valid session verification if any
+    pub fn get_session(&self) -> Option<IdentityVerification> {
+        let list = self.imp().list.borrow();
+        let session = self.session();
+        let user_id = session.user().unwrap().user_id();
+
+        for (_, item) in list.iter() {
+            if !item.is_finished() && item.user().user_id() == user_id {
+                return Some(item.to_owned());
+            }
+        }
+
+        None
+    }
 }


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