Skip to content

Commit

Permalink
feat(ui): Add more properties to UnableToDecryptInfo
Browse files Browse the repository at this point in the history
  • Loading branch information
richvdh committed Dec 10, 2024
1 parent 1e72131 commit 1d72d27
Show file tree
Hide file tree
Showing 2 changed files with 98 additions and 20 deletions.
3 changes: 2 additions & 1 deletion crates/matrix-sdk-ui/src/timeline/event_handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -443,7 +443,8 @@ impl<'a, 'o> TimelineEventHandler<'a, 'o> {
// timeline.
if let Some(hook) = self.meta.unable_to_decrypt_hook.as_ref() {
if let Some(event_id) = &self.ctx.flow.event_id() {
hook.on_utd(event_id, utd_cause, self.ctx.timestamp).await;
hook.on_utd(event_id, utd_cause, self.ctx.timestamp, &self.ctx.sender)
.await;
}
}
}
Expand Down
115 changes: 96 additions & 19 deletions crates/matrix-sdk-ui/src/unable_to_decrypt_hook.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ use std::{
use growable_bloom_filter::{GrowableBloom, GrowableBloomBuilder};
use matrix_sdk::{crypto::types::events::UtdCause, Client};
use matrix_sdk_base::{StateStoreDataKey, StateStoreDataValue, StoreError};
use ruma::{EventId, MilliSecondsSinceUnixEpoch, OwnedEventId};
use ruma::{EventId, MilliSecondsSinceUnixEpoch, OwnedEventId, OwnedServerName, UserId};
use tokio::{
spawn,
sync::{Mutex as AsyncMutex, MutexGuard},
Expand Down Expand Up @@ -69,8 +69,16 @@ pub struct UnableToDecryptInfo {
/// *before* our device was created.
pub event_local_age_millis: i64,

/// Whether the user had verified their own identity at the point they received the UTD event.
/// Whether the user had verified their own identity at the point they
/// received the UTD event.
pub user_trusts_own_identity: bool,

/// The homeserver of the user that sent the undecryptable event.
pub sender_homeserver: OwnedServerName,

/// Our local user's own homeserver, or `None` if the client is not logged
/// in.
pub own_homeserver: Option<OwnedServerName>,
}

/// Data about a UTD event which we are waiting to report to the parent hook.
Expand Down Expand Up @@ -215,11 +223,14 @@ impl UtdHookManager {
/// decrypted.
/// * `event_timestamp` - The event's `origin_server_ts` field (or creation
/// time for local echo).
/// * `sender_user_id` - The Matrix user ID of the user that sent the
/// undecryptable message.
pub(crate) async fn on_utd(
&self,
event_id: &EventId,
cause: UtdCause,
event_timestamp: MilliSecondsSinceUnixEpoch,
sender_user_id: &UserId,
) {
// Hold the lock on `reported_utds` throughout, to avoid races with other
// threads.
Expand All @@ -239,7 +250,9 @@ impl UtdHookManager {
let event_local_age_millis = i64::from(event_timestamp.get()).saturating_sub_unsigned(
self.client.encryption().device_creation_timestamp().await.get().into(),
);
let user_trusts_own_identity = if let Some(own_user_id) = self.client.user_id() {

let own_user_id = self.client.user_id();
let user_trusts_own_identity = if let Some(own_user_id) = own_user_id {
if let Ok(Some(own_id)) = self.client.encryption().get_user_identity(own_user_id).await
{
own_id.is_verified()
Expand All @@ -250,12 +263,17 @@ impl UtdHookManager {
false
};

let own_homeserver = own_user_id.map(|id| id.server_name().to_owned());
let sender_homeserver = sender_user_id.server_name().to_owned();

let info = UnableToDecryptInfo {
event_id: event_id.to_owned(),
time_to_decrypt: None,
cause,
event_local_age_millis,
user_trusts_own_identity,
own_homeserver,
sender_homeserver,
};

let Some(max_delay) = self.max_delay else {
Expand Down Expand Up @@ -382,7 +400,7 @@ impl Drop for UtdHookManager {
mod tests {
use matrix_sdk::test_utils::{logged_in_client, no_retry_test_client};
use matrix_sdk_test::async_test;
use ruma::event_id;
use ruma::{event_id, server_name, user_id};

use super::*;

Expand All @@ -407,12 +425,14 @@ mod tests {

// And I call the `on_utd` method multiple times, sometimes on the same event,
let event_timestamp = MilliSecondsSinceUnixEpoch::now();
wrapper.on_utd(event_id!("$1"), UtdCause::Unknown, event_timestamp).await;
wrapper.on_utd(event_id!("$1"), UtdCause::Unknown, event_timestamp).await;
wrapper.on_utd(event_id!("$2"), UtdCause::Unknown, event_timestamp).await;
wrapper.on_utd(event_id!("$1"), UtdCause::Unknown, event_timestamp).await;
wrapper.on_utd(event_id!("$2"), UtdCause::Unknown, event_timestamp).await;
wrapper.on_utd(event_id!("$3"), UtdCause::Unknown, event_timestamp).await;
let sender_user = user_id!("@example2:localhost");
let federated_user = user_id!("@example2:example.com");
wrapper.on_utd(event_id!("$1"), UtdCause::Unknown, event_timestamp, sender_user).await;
wrapper.on_utd(event_id!("$1"), UtdCause::Unknown, event_timestamp, sender_user).await;
wrapper.on_utd(event_id!("$2"), UtdCause::Unknown, event_timestamp, federated_user).await;
wrapper.on_utd(event_id!("$1"), UtdCause::Unknown, event_timestamp, sender_user).await;
wrapper.on_utd(event_id!("$2"), UtdCause::Unknown, event_timestamp, federated_user).await;
wrapper.on_utd(event_id!("$3"), UtdCause::Unknown, event_timestamp, sender_user).await;

// Then the event ids have been deduplicated,
{
Expand All @@ -432,6 +452,12 @@ mod tests {
let utd_local_age = utds[0].event_local_age_millis;
assert!(utd_local_age >= 0);
assert!(utd_local_age <= 1000);

assert_eq!(utds[0].sender_homeserver, server_name!("localhost"));
assert_eq!(utds[0].own_homeserver, Some(server_name!("localhost").to_owned()));

assert_eq!(utds[1].sender_homeserver, server_name!("example.com"));
assert_eq!(utds[1].own_homeserver, Some(server_name!("localhost").to_owned()));
}
}

Expand All @@ -448,10 +474,20 @@ mod tests {

// I call it a couple of times with different events
wrapper
.on_utd(event_id!("$1"), UtdCause::Unknown, MilliSecondsSinceUnixEpoch::now())
.on_utd(
event_id!("$1"),
UtdCause::Unknown,
MilliSecondsSinceUnixEpoch::now(),
user_id!("@a:b"),
)
.await;
wrapper
.on_utd(event_id!("$2"), UtdCause::Unknown, MilliSecondsSinceUnixEpoch::now())
.on_utd(
event_id!("$2"),
UtdCause::Unknown,
MilliSecondsSinceUnixEpoch::now(),
user_id!("@a:b"),
)
.await;

// Sanity-check the reported event IDs
Expand All @@ -473,10 +509,20 @@ mod tests {

// Call it with more events, some of which match the previous instance
wrapper
.on_utd(event_id!("$1"), UtdCause::Unknown, MilliSecondsSinceUnixEpoch::now())
.on_utd(
event_id!("$1"),
UtdCause::Unknown,
MilliSecondsSinceUnixEpoch::now(),
user_id!("@a:b"),
)
.await;
wrapper
.on_utd(event_id!("$3"), UtdCause::Unknown, MilliSecondsSinceUnixEpoch::now())
.on_utd(
event_id!("$3"),
UtdCause::Unknown,
MilliSecondsSinceUnixEpoch::now(),
user_id!("@a:b"),
)
.await;

// Only the *new* ones should be reported
Expand All @@ -502,7 +548,12 @@ mod tests {

// a UTD event
wrapper
.on_utd(event_id!("$1"), UtdCause::Unknown, MilliSecondsSinceUnixEpoch::now())
.on_utd(
event_id!("$1"),
UtdCause::Unknown,
MilliSecondsSinceUnixEpoch::now(),
user_id!("@a:b"),
)
.await;

// The event ID should not yet have been reported.
Expand All @@ -520,7 +571,12 @@ mod tests {

// Call the new hook with the same event
wrapper
.on_utd(event_id!("$1"), UtdCause::Unknown, MilliSecondsSinceUnixEpoch::now())
.on_utd(
event_id!("$1"),
UtdCause::Unknown,
MilliSecondsSinceUnixEpoch::now(),
user_id!("@a:b"),
)
.await;

// And it should be reported.
Expand Down Expand Up @@ -557,7 +613,14 @@ mod tests {
let wrapper = UtdHookManager::new(hook.clone(), no_retry_test_client(None).await);

// And I call the `on_utd` method for an event,
wrapper.on_utd(event_id!("$1"), UtdCause::Unknown, MilliSecondsSinceUnixEpoch::now()).await;
wrapper
.on_utd(
event_id!("$1"),
UtdCause::Unknown,
MilliSecondsSinceUnixEpoch::now(),
user_id!("@a:b"),
)
.await;

// Then the UTD has been notified, but not as late-decrypted event.
{
Expand Down Expand Up @@ -593,7 +656,14 @@ mod tests {
.with_max_delay(Duration::from_secs(2));

// And I call the `on_utd` method for an event,
wrapper.on_utd(event_id!("$1"), UtdCause::Unknown, MilliSecondsSinceUnixEpoch::now()).await;
wrapper
.on_utd(
event_id!("$1"),
UtdCause::Unknown,
MilliSecondsSinceUnixEpoch::now(),
user_id!("@a:b"),
)
.await;

// Then the UTD is not being reported immediately.
assert!(hook.utds.lock().unwrap().is_empty());
Expand Down Expand Up @@ -630,7 +700,14 @@ mod tests {
.with_max_delay(Duration::from_secs(2));

// And I call the `on_utd` method for an event,
wrapper.on_utd(event_id!("$1"), UtdCause::Unknown, MilliSecondsSinceUnixEpoch::now()).await;
wrapper
.on_utd(
event_id!("$1"),
UtdCause::Unknown,
MilliSecondsSinceUnixEpoch::now(),
user_id!("@a:b"),
)
.await;

// Then the UTD has not been notified quite yet.
assert!(hook.utds.lock().unwrap().is_empty());
Expand Down

0 comments on commit 1d72d27

Please sign in to comment.