From d5d1678bf9a9b9c4c786b01dad16b20f3f14a0cf Mon Sep 17 00:00:00 2001 From: Doug Date: Wed, 16 Oct 2024 17:04:02 +0100 Subject: [PATCH 1/3] chore(ffi): Expose is_verified UserIdentity method. --- bindings/matrix-sdk-ffi/src/encryption.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/bindings/matrix-sdk-ffi/src/encryption.rs b/bindings/matrix-sdk-ffi/src/encryption.rs index 25849e60e42..8d712d257a6 100644 --- a/bindings/matrix-sdk-ffi/src/encryption.rs +++ b/bindings/matrix-sdk-ffi/src/encryption.rs @@ -461,6 +461,14 @@ impl UserIdentity { pub(crate) fn master_key(&self) -> Option { self.inner.master_key().get_first_key().map(|k| k.to_base64()) } + + /// Is the user identity considered to be verified. + /// + /// If the identity belongs to another user, our own user identity needs to + /// be verified as well for the identity to be considered to be verified. + pub fn is_verified(&self) -> bool { + self.inner.is_verified() + } } #[derive(uniffi::Object)] From afc2594bf778ad17a900d45b7e382bae226e5539 Mon Sep 17 00:00:00 2001 From: Doug Date: Fri, 18 Oct 2024 11:12:06 +0100 Subject: [PATCH 2/3] chore(ffi): Expose the request_user_identity Encryption method. --- bindings/matrix-sdk-ffi/src/encryption.rs | 44 ++++++++++++++++++++--- 1 file changed, 40 insertions(+), 4 deletions(-) diff --git a/bindings/matrix-sdk-ffi/src/encryption.rs b/bindings/matrix-sdk-ffi/src/encryption.rs index 8d712d257a6..bed3430327a 100644 --- a/bindings/matrix-sdk-ffi/src/encryption.rs +++ b/bindings/matrix-sdk-ffi/src/encryption.rs @@ -411,12 +411,22 @@ impl Encryption { self.inner.wait_for_e2ee_initialization_tasks().await; } - /// Get the E2EE identity of a user. + /// Get the E2EE identity of a user from the crypto store. /// - /// Returns Ok(None) if this user does not exist. + /// Usually, we only have the E2EE identity of a user locally if the user + /// is tracked, meaning that we are both members of the same encrypted room. /// - /// Returns an error if there was a problem contacting the crypto store, or - /// if our client is not logged in. + /// To get the E2EE identity of a user even if it is not available locally + /// use `request_user_identity()`. + /// + /// # Arguments + /// + /// * `user_id` - The unique id of the user that the identity belongs to. + /// + /// Returns a `UserIdentity` if one is found and the crypto store + /// didn't throw an error. + /// + /// This will always return None if the client hasn't been logged in. pub async fn get_user_identity( &self, user_id: String, @@ -424,6 +434,32 @@ impl Encryption { let identity = self.inner.get_user_identity(user_id.as_str().try_into()?).await?; Ok(identity.map(|i| Arc::new(UserIdentity { inner: i }))) } + + /// Get the E2EE identity of a user from the homeserver. + /// + /// The E2EE identity returned is always guaranteed to be up-to-date. If the + /// E2EE identity is not found, it should mean that the user did not set + /// up cross-signing. + /// + /// If you want the E2EE identity of a user without making a request to the + /// homeserver, use `get_user_identity()` instead. + /// + /// # Arguments + /// + /// * `user_id` - The ID of the user that the identity belongs to. + /// + /// Returns a `UserIdentity` if one is found. Returns an error if there + /// was an issue with the crypto store or with the request to the + /// homeserver. + /// + /// This will always return `None` if the client hasn't been logged in. + pub async fn request_user_identity( + &self, + user_id: String, + ) -> Result>, ClientError> { + let identity = self.inner.request_user_identity(user_id.as_str().try_into()?).await?; + Ok(identity.map(|i| Arc::new(UserIdentity { inner: i }))) + } } /// The E2EE identity of a user. From 195fed7f5c1f60dc8ccc50ef92e7ccca6189f446 Mon Sep 17 00:00:00 2001 From: Doug Date: Mon, 21 Oct 2024 11:38:53 +0100 Subject: [PATCH 3/3] chore(ffi): Combine get/request_user_identity functions. --- bindings/matrix-sdk-ffi/src/encryption.rs | 55 +++++++++-------------- 1 file changed, 22 insertions(+), 33 deletions(-) diff --git a/bindings/matrix-sdk-ffi/src/encryption.rs b/bindings/matrix-sdk-ffi/src/encryption.rs index bed3430327a..e6ab1253b41 100644 --- a/bindings/matrix-sdk-ffi/src/encryption.rs +++ b/bindings/matrix-sdk-ffi/src/encryption.rs @@ -6,6 +6,7 @@ use matrix_sdk::{ encryption::{backups, recovery}, }; use thiserror::Error; +use tracing::{error, info}; use zeroize::Zeroize; use super::RUNTIME; @@ -411,38 +412,12 @@ impl Encryption { self.inner.wait_for_e2ee_initialization_tasks().await; } - /// Get the E2EE identity of a user from the crypto store. + /// Get the E2EE identity of a user. /// - /// Usually, we only have the E2EE identity of a user locally if the user - /// is tracked, meaning that we are both members of the same encrypted room. - /// - /// To get the E2EE identity of a user even if it is not available locally - /// use `request_user_identity()`. - /// - /// # Arguments - /// - /// * `user_id` - The unique id of the user that the identity belongs to. - /// - /// Returns a `UserIdentity` if one is found and the crypto store - /// didn't throw an error. - /// - /// This will always return None if the client hasn't been logged in. - pub async fn get_user_identity( - &self, - user_id: String, - ) -> Result>, ClientError> { - let identity = self.inner.get_user_identity(user_id.as_str().try_into()?).await?; - Ok(identity.map(|i| Arc::new(UserIdentity { inner: i }))) - } - - /// Get the E2EE identity of a user from the homeserver. - /// - /// The E2EE identity returned is always guaranteed to be up-to-date. If the - /// E2EE identity is not found, it should mean that the user did not set - /// up cross-signing. - /// - /// If you want the E2EE identity of a user without making a request to the - /// homeserver, use `get_user_identity()` instead. + /// This method always tries to fetch the identity from the store, which we + /// only have if the user is tracked, meaning that we are both members + /// of the same encrypted room. If no user is found locally, a request will + /// be made to the homeserver. /// /// # Arguments /// @@ -453,12 +428,26 @@ impl Encryption { /// homeserver. /// /// This will always return `None` if the client hasn't been logged in. - pub async fn request_user_identity( + pub async fn user_identity( &self, user_id: String, ) -> Result>, ClientError> { + match self.inner.get_user_identity(user_id.as_str().try_into()?).await { + Ok(Some(identity)) => { + return Ok(Some(Arc::new(UserIdentity { inner: identity }))); + } + Ok(None) => { + info!("No identity found in the store."); + } + Err(error) => { + error!("Failed fetching identity from the store: {}", error); + } + }; + + info!("Requesting identity from the server."); + let identity = self.inner.request_user_identity(user_id.as_str().try_into()?).await?; - Ok(identity.map(|i| Arc::new(UserIdentity { inner: i }))) + Ok(identity.map(|identity| Arc::new(UserIdentity { inner: identity }))) } }