From 0bc40eadc3d8b1cd6a4128d49849b4a8236ac0b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20Mart=C3=ADn?= Date: Mon, 24 Jun 2024 16:00:07 +0200 Subject: [PATCH 1/5] sdk-base: when a `m.room.encryption` event is received, mark the room encryption as set. `RoomInfo::handle_state_event` will check this condition so we don't have to later ask the HS whether the room is encrypted or not through `room::is_encrypted()`. --- crates/matrix-sdk-base/src/rooms/normal.rs | 49 ++++++++++++++++++++-- 1 file changed, 46 insertions(+), 3 deletions(-) diff --git a/crates/matrix-sdk-base/src/rooms/normal.rs b/crates/matrix-sdk-base/src/rooms/normal.rs index 3fc100bbccc..2196c0b1c0d 100644 --- a/crates/matrix-sdk-base/src/rooms/normal.rs +++ b/crates/matrix-sdk-base/src/rooms/normal.rs @@ -1072,7 +1072,18 @@ impl RoomInfo { /// /// Returns true if the event modified the info, false otherwise. pub fn handle_state_event(&mut self, event: &AnySyncStateEvent) -> bool { - self.base_info.handle_state_event(event) + let ret = self.base_info.handle_state_event(event); + + // If we received an `m.room.encryption` event here, and encryption got enabled, + // then we can be certain that we have synced the encryption state event, so + // mark it here as synced. + if let AnySyncStateEvent::RoomEncryption(_) = event { + if self.is_encrypted() { + self.mark_encryption_state_synced(); + } + } + + ret } /// Handle the given stripped state event. @@ -1524,17 +1535,22 @@ mod tests { }, room::{ canonical_alias::RoomCanonicalAliasEventContent, + encryption::{ + OriginalRoomEncryptionEvent, OriginalSyncRoomEncryptionEvent, + RoomEncryptionEventContent, + }, member::{ MembershipState, RoomMemberEventContent, StrippedRoomMemberEvent, SyncRoomMemberEvent, }, name::RoomNameEventContent, }, - AnySyncStateEvent, StateEventType, StateUnsigned, SyncStateEvent, + AnySyncStateEvent, EmptyStateKey, StateEventType, StateUnsigned, SyncStateEvent, }, room_alias_id, room_id, serde::Raw, - user_id, MilliSecondsSinceUnixEpoch, OwnedEventId, OwnedUserId, UserId, + user_id, EventEncryptionAlgorithm, MilliSecondsSinceUnixEpoch, OwnedEventId, OwnedUserId, + UserId, }; use serde_json::json; use stream_assert::{assert_pending, assert_ready}; @@ -2532,4 +2548,31 @@ mod tests { actual = compute_display_name_from_heroes(1, 0, vec!["a", "b", "c"]); assert_eq!(DisplayName::EmptyWas("a, b, c".to_owned()), actual); } + + #[test] + fn test_encryption_is_set_when_encryption_event_is_received() { + let (_store, room) = make_room_test_helper(RoomState::Joined); + + assert_eq!(room.is_encryption_state_synced(), false); + assert_eq!(room.is_encrypted(), false); + + let encryption_content = + RoomEncryptionEventContent::new(EventEncryptionAlgorithm::MegolmV1AesSha2); + let encryption_event = AnySyncStateEvent::RoomEncryption(SyncStateEvent::Original( + OriginalSyncRoomEncryptionEvent { + content: encryption_content, + event_id: OwnedEventId::from_str("$1234_1").unwrap(), + sender: ALICE.to_owned(), + // we can simply use now here since this will be dropped when using a + // MinimalStateEvent in the roomInfo + origin_server_ts: timestamp(0), + state_key: EmptyStateKey, + unsigned: StateUnsigned::new(), + }, + )); + receive_state_events(&room, vec![&encryption_event]); + + assert_eq!(room.is_encryption_state_synced(), true); + assert_eq!(room.is_encrypted(), true); + } } From 004941b6b41ec4d8e4206035ec8c236e56d28ceb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20Mart=C3=ADn?= Date: Mon, 24 Jun 2024 16:00:29 +0200 Subject: [PATCH 2/5] ffi: add encryption info to `RoomInfo` --- bindings/matrix-sdk-ffi/src/room_info.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/bindings/matrix-sdk-ffi/src/room_info.rs b/bindings/matrix-sdk-ffi/src/room_info.rs index 8e89584a001..9fa63f36500 100644 --- a/bindings/matrix-sdk-ffi/src/room_info.rs +++ b/bindings/matrix-sdk-ffi/src/room_info.rs @@ -23,6 +23,7 @@ pub struct RoomInfo { is_space: bool, is_tombstoned: bool, is_favourite: bool, + is_encrypted: bool, canonical_alias: Option, alternative_aliases: Vec, membership: Membership, @@ -76,6 +77,7 @@ impl RoomInfo { is_space: room.is_space(), is_tombstoned: room.is_tombstoned(), is_favourite: room.is_favourite(), + is_encrypted: room.is_encrypted().await.unwrap_or(false), canonical_alias: room.canonical_alias().map(Into::into), alternative_aliases: room.alt_aliases().into_iter().map(Into::into).collect(), membership: room.state().into(), From 912e75c1f8ceb84700a6774a8a744909e5820717 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20Mart=C3=ADn?= Date: Mon, 24 Jun 2024 16:01:19 +0200 Subject: [PATCH 3/5] ffi: add `RoomListItem::is_encrypted()` function. --- bindings/matrix-sdk-ffi/src/room_list.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/bindings/matrix-sdk-ffi/src/room_list.rs b/bindings/matrix-sdk-ffi/src/room_list.rs index 8b875173b84..96f2deaf8e2 100644 --- a/bindings/matrix-sdk-ffi/src/room_list.rs +++ b/bindings/matrix-sdk-ffi/src/room_list.rs @@ -566,6 +566,10 @@ impl RoomListItem { self.inner.init_timeline_with_builder(timeline_builder).map_err(RoomListError::from).await } + async fn is_encrypted(&self) -> bool { + self.inner.is_encrypted().await.unwrap_or(false) + } + fn subscribe(&self, settings: Option) { self.inner.subscribe(settings.map(Into::into)); } From d8900bd6d73c72910ab19507fbfb40a0f718793f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20Mart=C3=ADn?= Date: Mon, 24 Jun 2024 16:18:18 +0200 Subject: [PATCH 4/5] Fix clippy --- crates/matrix-sdk-base/src/rooms/normal.rs | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/crates/matrix-sdk-base/src/rooms/normal.rs b/crates/matrix-sdk-base/src/rooms/normal.rs index 2196c0b1c0d..799e970cb8c 100644 --- a/crates/matrix-sdk-base/src/rooms/normal.rs +++ b/crates/matrix-sdk-base/src/rooms/normal.rs @@ -1535,10 +1535,7 @@ mod tests { }, room::{ canonical_alias::RoomCanonicalAliasEventContent, - encryption::{ - OriginalRoomEncryptionEvent, OriginalSyncRoomEncryptionEvent, - RoomEncryptionEventContent, - }, + encryption::{OriginalSyncRoomEncryptionEvent, RoomEncryptionEventContent}, member::{ MembershipState, RoomMemberEventContent, StrippedRoomMemberEvent, SyncRoomMemberEvent, @@ -2553,8 +2550,8 @@ mod tests { fn test_encryption_is_set_when_encryption_event_is_received() { let (_store, room) = make_room_test_helper(RoomState::Joined); - assert_eq!(room.is_encryption_state_synced(), false); - assert_eq!(room.is_encrypted(), false); + assert!(room.is_encryption_state_synced().not()); + assert!(room.is_encrypted().not()); let encryption_content = RoomEncryptionEventContent::new(EventEncryptionAlgorithm::MegolmV1AesSha2); @@ -2572,7 +2569,7 @@ mod tests { )); receive_state_events(&room, vec![&encryption_event]); - assert_eq!(room.is_encryption_state_synced(), true); - assert_eq!(room.is_encrypted(), true); + assert!(room.is_encryption_state_synced()); + assert!(room.is_encrypted()); } } From 0162f6ba49e92264416d45dc6a99f77d7d62f0d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20Mart=C3=ADn?= Date: Tue, 25 Jun 2024 12:42:59 +0200 Subject: [PATCH 5/5] Add doc clarification for `ffi::room_list_item.is_encrypted()` --- bindings/matrix-sdk-ffi/src/room_list.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/bindings/matrix-sdk-ffi/src/room_list.rs b/bindings/matrix-sdk-ffi/src/room_list.rs index 96f2deaf8e2..285605d2093 100644 --- a/bindings/matrix-sdk-ffi/src/room_list.rs +++ b/bindings/matrix-sdk-ffi/src/room_list.rs @@ -566,6 +566,10 @@ impl RoomListItem { self.inner.init_timeline_with_builder(timeline_builder).map_err(RoomListError::from).await } + /// Checks whether the room is encrypted or not. + /// + /// **Note**: this info may not be reliable if you don't set up + /// `m.room.encryption` as required state. async fn is_encrypted(&self) -> bool { self.inner.is_encrypted().await.unwrap_or(false) }