[fractal/fractal-next] verification: Allow starting user verifications



commit 82301e36e7c03e7ac10ebefa55d74d0adafa2663
Author: Julian Sparber <julian sparber net>
Date:   Tue Jan 18 16:13:36 2022 +0100

    verification: Allow starting user verifications

 .../content/room_details/member_page/mod.rs        |  9 ++++-
 src/session/room/timeline.rs                       | 32 +++++++++------
 src/session/user.rs                                | 45 ++++++++++++++++++++--
 3 files changed, 69 insertions(+), 17 deletions(-)
---
diff --git a/src/session/content/room_details/member_page/mod.rs 
b/src/session/content/room_details/member_page/mod.rs
index 70c27883..6288475a 100644
--- a/src/session/content/room_details/member_page/mod.rs
+++ b/src/session/content/room_details/member_page/mod.rs
@@ -14,6 +14,8 @@ use crate::prelude::*;
 use crate::session::content::RoomDetails;
 use crate::session::room::{Member, RoomAction};
 use crate::session::Room;
+use crate::session::User;
+use crate::spawn;
 use log::warn;
 
 mod imp {
@@ -238,7 +240,10 @@ impl MemberPage {
         priv_.member_menu.get_or_init(|| MemberMenu::new())
     }
 
-    fn verify_member(&self, _member: Member) {
-        todo!("Show member verification");
+    fn verify_member(&self, member: Member) {
+        // TODO: show the verification immediately when started
+        spawn!(clone!(@weak self as obj => async move {
+            member.upcast::<User>().verify_identity().await;
+        }));
     }
 }
diff --git a/src/session/room/timeline.rs b/src/session/room/timeline.rs
index f88527d4..b38543a1 100644
--- a/src/session/room/timeline.rs
+++ b/src/session/room/timeline.rs
@@ -726,21 +726,31 @@ impl Timeline {
                         return;
                     };
 
-                    let request = IdentityVerification::for_flow_id(
-                        event.matrix_event_id().as_str(),
-                        &session,
-                        &user_to_verify.upcast(),
-                        &event.timestamp(),
-                    );
-
                     // Ignore the request when we have a newer one
                     let previous_verification = self.verification();
-                    if previous_verification.is_none()
-                        || request.start_time() > previous_verification.unwrap().start_time()
+                    if !(previous_verification.is_none()
+                        || &event.timestamp() > previous_verification.unwrap().start_time())
                     {
-                        session.verification_list().add(request.clone());
-                        self.set_verification(request);
+                        return;
                     }
+
+                    let request = if let Some(request) = verification_list
+                        .get_by_id(&user_to_verify.user_id(), &event.matrix_event_id())
+                    {
+                        request
+                    } else {
+                        let request = IdentityVerification::for_flow_id(
+                            event.matrix_event_id().as_str(),
+                            &session,
+                            &user_to_verify.upcast(),
+                            &event.timestamp(),
+                        );
+
+                        verification_list.add(request.clone());
+                        request
+                    };
+
+                    self.set_verification(request);
                 }
 
                 return;
diff --git a/src/session/user.rs b/src/session/user.rs
index 1a53bb3e..35177feb 100644
--- a/src/session/user.rs
+++ b/src/session/user.rs
@@ -1,8 +1,8 @@
-use gtk::{glib, prelude::*, subclass::prelude::*};
+use gtk::{glib, glib::clone, prelude::*, subclass::prelude::*};
 use matrix_sdk::ruma::identifiers::{MxcUri, UserId};
 
-use crate::session::{Avatar, Session};
-use crate::spawn_tokio;
+use crate::session::{verification::IdentityVerification, Avatar, Session};
+use crate::{spawn, spawn_tokio};
 use matrix_sdk::encryption::identities::UserIdentity;
 use std::sync::Arc;
 
@@ -12,7 +12,7 @@ mod imp {
     use super::*;
     use glib::object::WeakRef;
     use once_cell::{sync::Lazy, unsync::OnceCell};
-    use std::cell::RefCell;
+    use std::cell::{Cell, RefCell};
 
     #[derive(Debug, Default)]
     pub struct User {
@@ -20,6 +20,7 @@ mod imp {
         pub display_name: RefCell<Option<String>>,
         pub session: OnceCell<WeakRef<Session>>,
         pub avatar: OnceCell<Avatar>,
+        pub is_verified: Cell<bool>,
     }
 
     #[glib::object_subclass]
@@ -61,6 +62,13 @@ mod imp {
                         Session::static_type(),
                         glib::ParamFlags::READWRITE | glib::ParamFlags::CONSTRUCT_ONLY,
                     ),
+                    glib::ParamSpec::new_boolean(
+                        "verified",
+                        "Verified",
+                        "Whether this user has been verified",
+                        false,
+                        glib::ParamFlags::READABLE,
+                    ),
                 ]
             });
 
@@ -97,6 +105,7 @@ mod imp {
                 "user-id" => obj.user_id().as_str().to_value(),
                 "session" => obj.session().to_value(),
                 "avatar" => obj.avatar().to_value(),
+                "verified" => obj.is_verified().to_value(),
                 _ => unimplemented!(),
             }
         }
@@ -111,6 +120,8 @@ mod imp {
                 .flags(glib::BindingFlags::SYNC_CREATE)
                 .build()
                 .unwrap();
+
+            obj.init_is_verified();
         }
     }
 }
@@ -139,6 +150,32 @@ impl User {
             }
         }
     }
+
+    pub async fn verify_identity(&self) -> IdentityVerification {
+        let request = IdentityVerification::create(&self.session(), Some(self)).await;
+        self.session().verification_list().add(request.clone());
+        request
+    }
+
+    pub fn is_verified(&self) -> bool {
+        let priv_ = imp::User::from_instance(self);
+
+        priv_.is_verified.get()
+    }
+
+    fn init_is_verified(&self) {
+        spawn!(clone!(@weak self as obj => async move {
+            let priv_ = imp::User::from_instance(&obj);
+            let is_verified = obj.crypto_identity().await.map_or(false, |i| i.verified());
+
+            if is_verified == obj.is_verified() {
+                return;
+            }
+
+            priv_.is_verified.set(is_verified);
+            obj.notify("verified");
+        }));
+    }
 }
 
 pub trait UserExt: IsA<User> {


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