diff --git a/bindings/matrix-sdk-ffi/src/room_preview.rs b/bindings/matrix-sdk-ffi/src/room_preview.rs index 8bfe94551..49d040c52 100644 --- a/bindings/matrix-sdk-ffi/src/room_preview.rs +++ b/bindings/matrix-sdk-ffi/src/room_preview.rs @@ -92,7 +92,7 @@ pub struct RoomPreviewInfo { /// The room type (space, custom) or nothing, if it's a regular room. pub room_type: RoomType, /// Is the history world-readable for this room? - pub is_history_world_readable: bool, + pub is_history_world_readable: Option, /// The membership state for the current user, if known. pub membership: Option, /// The join rule for this room (private, public, knock, etc.). diff --git a/crates/matrix-sdk-base/src/client.rs b/crates/matrix-sdk-base/src/client.rs index 1fcaee38b..34ef26936 100644 --- a/crates/matrix-sdk-base/src/client.rs +++ b/crates/matrix-sdk-base/src/client.rs @@ -1459,10 +1459,14 @@ impl BaseClient { pub async fn share_room_key(&self, room_id: &RoomId) -> Result>> { match self.olm_machine().await.as_ref() { Some(o) => { - let (history_visibility, settings) = self - .get_room(room_id) - .map(|r| (r.history_visibility(), r.encryption_settings())) - .unwrap_or((HistoryVisibility::Joined, None)); + let Some(room) = self.get_room(room_id) else { + return Err(Error::InsufficientData); + }; + + let history_visibility = room.history_visibility_or_default(); + let Some(room_encryption_event) = room.encryption_settings() else { + return Err(Error::EncryptionNotEnabled); + }; // Don't share the group session with members that are invited // if the history visibility is set to `Joined` @@ -1474,9 +1478,8 @@ impl BaseClient { let members = self.store.get_user_ids(room_id, filter).await?; - let settings = settings.ok_or(Error::EncryptionNotEnabled)?; let settings = EncryptionSettings::new( - settings, + room_encryption_event, history_visibility, self.room_key_recipient_strategy.clone(), ); diff --git a/crates/matrix-sdk-base/src/rooms/normal.rs b/crates/matrix-sdk-base/src/rooms/normal.rs index d80da1926..d05ce29d1 100644 --- a/crates/matrix-sdk-base/src/rooms/normal.rs +++ b/crates/matrix-sdk-base/src/rooms/normal.rs @@ -487,8 +487,14 @@ impl Room { } /// Get the history visibility policy of this room. - pub fn history_visibility(&self) -> HistoryVisibility { - self.inner.read().history_visibility().clone() + pub fn history_visibility(&self) -> Option { + self.inner.read().history_visibility().cloned() + } + + /// Get the history visibility policy of this room, or a sensible default if + /// the event is missing. + pub fn history_visibility_or_default(&self) -> HistoryVisibility { + self.inner.read().history_visibility_or_default().clone() } /// Is the room considered to be public. @@ -1522,11 +1528,24 @@ impl RoomInfo { /// Returns the history visibility for this room. /// - /// Defaults to `WorldReadable`, if missing. - pub fn history_visibility(&self) -> &HistoryVisibility { + /// Returns None if the event was never seen during sync. + pub fn history_visibility(&self) -> Option<&HistoryVisibility> { + match &self.base_info.history_visibility { + Some(MinimalStateEvent::Original(ev)) => Some(&ev.content.history_visibility), + _ => None, + } + } + + /// Returns the history visibility for this room, or a sensible default. + /// + /// Returns `Shared`, the default specified by the [spec], when the event is + /// missing. + /// + /// [spec]: https://spec.matrix.org/latest/client-server-api/#server-behaviour-7 + pub fn history_visibility_or_default(&self) -> &HistoryVisibility { match &self.base_info.history_visibility { Some(MinimalStateEvent::Original(ev)) => &ev.content.history_visibility, - _ => &HistoryVisibility::WorldReadable, + _ => &HistoryVisibility::Shared, } } diff --git a/crates/matrix-sdk/src/room/mod.rs b/crates/matrix-sdk/src/room/mod.rs index 011197736..285411de6 100644 --- a/crates/matrix-sdk/src/room/mod.rs +++ b/crates/matrix-sdk/src/room/mod.rs @@ -613,7 +613,7 @@ impl Room { fn are_events_visible(&self) -> bool { if let RoomState::Invited = self.inner.state() { return matches!( - self.inner.history_visibility(), + self.inner.history_visibility_or_default(), HistoryVisibility::WorldReadable | HistoryVisibility::Invited ); } diff --git a/crates/matrix-sdk/src/room_preview.rs b/crates/matrix-sdk/src/room_preview.rs index 198d335ef..58c9c68a5 100644 --- a/crates/matrix-sdk/src/room_preview.rs +++ b/crates/matrix-sdk/src/room_preview.rs @@ -68,7 +68,7 @@ pub struct RoomPreview { /// Is the room world-readable (i.e. is its history_visibility set to /// world_readable)? - pub is_world_readable: bool, + pub is_world_readable: Option, /// Has the current user been invited/joined/left this room? /// @@ -115,7 +115,9 @@ impl RoomPreview { SpaceRoomJoinRule::Private } }, - is_world_readable: *room_info.history_visibility() == HistoryVisibility::WorldReadable, + is_world_readable: room_info + .history_visibility() + .map(|vis| *vis == HistoryVisibility::WorldReadable), num_joined_members, num_active_members, state, @@ -266,7 +268,7 @@ impl RoomPreview { num_active_members, room_type: response.room_type, join_rule: response.join_rule, - is_world_readable: response.world_readable, + is_world_readable: Some(response.world_readable), state, is_direct, heroes: cached_room.map(|r| r.heroes()), @@ -361,7 +363,7 @@ async fn search_for_room_preview_in_room_directory( panic!("Unexpected PublicRoomJoinRule {:?}", room_description.join_rule) } }, - is_world_readable: room_description.is_world_readable, + is_world_readable: Some(room_description.is_world_readable), state: None, is_direct: None, heroes: None, diff --git a/testing/matrix-sdk-integration-testing/src/tests/sliding_sync/room.rs b/testing/matrix-sdk-integration-testing/src/tests/sliding_sync/room.rs index aa85dcb03..04d4a9774 100644 --- a/testing/matrix-sdk-integration-testing/src/tests/sliding_sync/room.rs +++ b/testing/matrix-sdk-integration-testing/src/tests/sliding_sync/room.rs @@ -1204,7 +1204,7 @@ fn assert_room_preview(preview: &RoomPreview, room_alias: &str) { assert_eq!(preview.num_joined_members, 1); assert!(preview.room_type.is_none()); assert_eq!(preview.join_rule, SpaceRoomJoinRule::Invite); - assert!(preview.is_world_readable); + assert!(preview.is_world_readable.unwrap()); } async fn get_room_preview_with_room_state(