[fractal/fractal-next] user: Don't allow verification for verified users



commit 1332ba8823cef50a5d34eb45260fe9cdc6d4aa30
Author: Julian Sparber <julian sparber net>
Date:   Wed Jan 19 12:40:01 2022 +0100

    user: Don't allow verification for verified users

 .../room_details/member_page/member_menu.rs        | 41 ++++++++++++++++--
 .../content/room_details/member_page/mod.rs        | 22 +++++++++-
 src/session/mod.rs                                 |  2 +-
 src/session/user.rs                                | 50 +++++++++++++++++++++-
 4 files changed, 108 insertions(+), 7 deletions(-)
---
diff --git a/src/session/content/room_details/member_page/member_menu.rs 
b/src/session/content/room_details/member_page/member_menu.rs
index 6e9e05ce..8a629b12 100644
--- a/src/session/content/room_details/member_page/member_menu.rs
+++ b/src/session/content/room_details/member_page/member_menu.rs
@@ -1,6 +1,6 @@
 use gtk::{gio, glib, glib::clone, prelude::*, subclass::prelude::*};
 
-use crate::session::room::Member;
+use crate::session::{room::Member, UserActions, UserExt};
 
 mod imp {
     use super::*;
@@ -13,6 +13,7 @@ mod imp {
         pub member: RefCell<Option<Member>>,
         pub popover: OnceCell<gtk::PopoverMenu>,
         pub destroy_handler: RefCell<Option<glib::signal::SignalHandlerId>>,
+        pub actions_handler: RefCell<Option<glib::signal::SignalHandlerId>>,
     }
 
     #[glib::object_subclass]
@@ -31,7 +32,16 @@ mod imp {
                     "The member this row is showing",
                     Member::static_type(),
                     glib::ParamFlags::READWRITE | glib::ParamFlags::EXPLICIT_NOTIFY,
-                )]
+                ),
+                glib::ParamSpec::new_flags(
+                        "allowed-actions",
+                        "Allowed Actions",
+                        "The actions the currently logged-in user is allowed to perform on the selected 
member.",
+                        UserActions::static_type(),
+                        UserActions::default().bits(),
+                        glib::ParamFlags::READABLE,
+                    )
+                ]
             });
 
             PROPERTIES.as_ref()
@@ -53,6 +63,7 @@ mod imp {
         fn property(&self, obj: &Self::Type, _id: usize, pspec: &glib::ParamSpec) -> glib::Value {
             match pspec.name() {
                 "member" => obj.member().to_value(),
+                "allowed-actions" => obj.allowed_actions().to_value(),
                 _ => unimplemented!(),
             }
         }
@@ -84,13 +95,37 @@ impl MemberMenu {
 
     pub fn set_member(&self, member: Option<Member>) {
         let priv_ = imp::MemberMenu::from_instance(self);
+        let prev_member = self.member();
 
-        if self.member() == member {
+        if prev_member == member {
             return;
         }
 
+        if let Some(member) = prev_member {
+            if let Some(handler) = priv_.actions_handler.take() {
+                member.disconnect(handler);
+            }
+        }
+
+        if let Some(ref member) = member {
+            let handler = member.connect_notify_local(
+                Some("allowed-actions"),
+                clone!(@weak self as obj => move |_, _| {
+                    obj.notify("allowed-actions");
+                }),
+            );
+
+            priv_.actions_handler.replace(Some(handler));
+        }
+
         priv_.member.replace(member);
         self.notify("member");
+        self.notify("allowed-actions");
+    }
+
+    pub fn allowed_actions(&self) -> UserActions {
+        self.member()
+            .map_or(UserActions::NONE, |member| member.allowed_actions())
     }
 
     fn popover_menu(&self) -> &gtk::PopoverMenu {
diff --git a/src/session/content/room_details/member_page/mod.rs 
b/src/session/content/room_details/member_page/mod.rs
index 6288475a..bbbe11b1 100644
--- a/src/session/content/room_details/member_page/mod.rs
+++ b/src/session/content/room_details/member_page/mod.rs
@@ -14,7 +14,7 @@ use crate::prelude::*;
 use crate::session::content::RoomDetails;
 use crate::session::room::{Member, RoomAction};
 use crate::session::Room;
-use crate::session::User;
+use crate::session::{User, UserActions};
 use crate::spawn;
 use log::warn;
 
@@ -237,7 +237,25 @@ impl MemberPage {
 
     pub fn member_menu(&self) -> &MemberMenu {
         let priv_ = imp::MemberPage::from_instance(self);
-        priv_.member_menu.get_or_init(|| MemberMenu::new())
+        priv_.member_menu.get_or_init(|| {
+            let menu = MemberMenu::new();
+
+            menu.connect_notify_local(
+                Some("allowed-actions"),
+                clone!(@weak self as obj => move |menu, _| {
+                    obj.update_actions(menu.allowed_actions());
+                }),
+            );
+            self.update_actions(menu.allowed_actions());
+            menu
+        })
+    }
+
+    fn update_actions(&self, allowed_actions: UserActions) {
+        self.action_set_enabled(
+            "member.verify",
+            allowed_actions.contains(UserActions::VERIFY),
+        );
     }
 
     fn verify_member(&self, member: Member) {
diff --git a/src/session/mod.rs b/src/session/mod.rs
index 684a82fe..56eba475 100644
--- a/src/session/mod.rs
+++ b/src/session/mod.rs
@@ -19,7 +19,7 @@ pub use self::room::{Event, Item, Room};
 pub use self::room_creation::RoomCreation;
 use self::room_list::RoomList;
 use self::sidebar::Sidebar;
-pub use self::user::{User, UserExt};
+pub use self::user::{User, UserActions, UserExt};
 use self::verification::VerificationList;
 use crate::session::sidebar::ItemList;
 
diff --git a/src/session/user.rs b/src/session/user.rs
index 35177feb..beb205e4 100644
--- a/src/session/user.rs
+++ b/src/session/user.rs
@@ -1,13 +1,28 @@
 use gtk::{glib, glib::clone, prelude::*, subclass::prelude::*};
 use matrix_sdk::ruma::identifiers::{MxcUri, UserId};
 
-use crate::session::{verification::IdentityVerification, Avatar, Session};
+use crate::session::{
+    verification::{IdentityVerification, VerificationState},
+    Avatar, Session,
+};
 use crate::{spawn, spawn_tokio};
 use matrix_sdk::encryption::identities::UserIdentity;
 use std::sync::Arc;
 
 use log::error;
 
+#[glib::gflags("UserActions")]
+pub enum UserActions {
+    NONE = 0b00000000,
+    VERIFY = 0b00000001,
+}
+
+impl Default for UserActions {
+    fn default() -> Self {
+        Self::NONE
+    }
+}
+
 mod imp {
     use super::*;
     use glib::object::WeakRef;
@@ -69,6 +84,14 @@ mod imp {
                         false,
                         glib::ParamFlags::READABLE,
                     ),
+                    glib::ParamSpec::new_flags(
+                        "allowed-actions",
+                        "Allowed Actions",
+                        "The actions the currently logged-in user is allowed to perform on this user.",
+                        UserActions::static_type(),
+                        UserActions::default().bits(),
+                        glib::ParamFlags::READABLE,
+                    )
                 ]
             });
 
@@ -106,6 +129,7 @@ mod imp {
                 "session" => obj.session().to_value(),
                 "avatar" => obj.avatar().to_value(),
                 "verified" => obj.is_verified().to_value(),
+                "allowed-actions" => obj.allowed_actions().to_value(),
                 _ => unimplemented!(),
             }
         }
@@ -154,6 +178,15 @@ 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());
+        // FIXME: actually listen to room events to get updates for verification state
+        request.connect_notify_local(
+            Some("state"),
+            clone!(@weak self as obj => move |request,_| {
+                if request.state() == VerificationState::Completed {
+                    obj.init_is_verified();
+                }
+            }),
+        );
         request
     }
 
@@ -174,6 +207,7 @@ impl User {
 
             priv_.is_verified.set(is_verified);
             obj.notify("verified");
+            obj.notify("allowed-actions");
         }));
     }
 }
@@ -216,6 +250,20 @@ pub trait UserExt: IsA<User> {
     fn set_avatar_url(&self, url: Option<Box<MxcUri>>) {
         self.avatar().set_url(url);
     }
+
+    fn allowed_actions(&self) -> UserActions {
+        let user = self.upcast_ref();
+
+        let is_us = self.session().user().map_or(false, |session_user| {
+            session_user.user_id() != self.user_id()
+        });
+
+        if !user.is_verified() && is_us {
+            UserActions::VERIFY
+        } else {
+            UserActions::NONE
+        }
+    }
 }
 
 impl<T: IsA<User>> UserExt for T {}


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