From cbef772eaa7caab536180a37f20b9e41747f955e Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Mon, 7 Apr 2025 14:54:10 +0200 Subject: [PATCH] refactor(base): Move `handle_room_member_event_for_profiles` as a processor. This patch moves the `handle_room_member_event_for_profiles` function inside the collection of response processors under the name `profiles::upsert_or_delete`. --- crates/matrix-sdk-base/src/client.rs | 52 +++-------------- .../src/response_processors/mod.rs | 1 + .../src/response_processors/profiles.rs | 58 +++++++++++++++++++ 3 files changed, 67 insertions(+), 44 deletions(-) create mode 100644 crates/matrix-sdk-base/src/response_processors/profiles.rs diff --git a/crates/matrix-sdk-base/src/client.rs b/crates/matrix-sdk-base/src/client.rs index cf2891c97..6e5344ffa 100644 --- a/crates/matrix-sdk-base/src/client.rs +++ b/crates/matrix-sdk-base/src/client.rs @@ -43,14 +43,14 @@ use ruma::{ marked_unread::MarkedUnreadEventContent, push_rules::{PushRulesEvent, PushRulesEventContent}, room::{ - member::{MembershipState, RoomMemberEventContent, SyncRoomMemberEvent}, + member::{MembershipState, SyncRoomMemberEvent}, power_levels::{ RoomPowerLevelsEvent, RoomPowerLevelsEventContent, StrippedRoomPowerLevelsEvent, }, }, AnyRoomAccountDataEvent, AnyStrippedStateEvent, AnySyncEphemeralRoomEvent, AnySyncMessageLikeEvent, AnySyncStateEvent, AnySyncTimelineEvent, - GlobalAccountDataEventType, StateEvent, StateEventType, SyncStateEvent, + GlobalAccountDataEventType, StateEvent, StateEventType, }, push::{Action, PushConditionRoomCtx, Ruleset}, serde::Raw, @@ -62,11 +62,13 @@ use tokio::sync::{broadcast, Mutex}; use tokio::sync::{RwLock, RwLockReadGuard}; use tracing::{debug, error, info, instrument, trace, warn}; +#[cfg(feature = "e2e-encryption")] +use crate::RoomMemberships; use crate::{ deserialized_responses::{DisplayName, RawAnySyncOrStrippedTimelineEvent, TimelineEvent}, error::{Error, Result}, event_cache::store::EventCacheStoreLock, - response_processors::{account_data::AccountDataProcessor, Context}, + response_processors::{self as processors, account_data::AccountDataProcessor, Context}, rooms::{ normal::{RoomInfoNotableUpdate, RoomInfoNotableUpdateReasons, RoomMembersUpdate}, Room, RoomInfo, RoomState, @@ -79,11 +81,6 @@ use crate::{ sync::{JoinedRoomUpdate, LeftRoomUpdate, Notification, RoomUpdates, SyncResponse, Timeline}, RoomStateFilter, SessionMeta, }; -#[cfg(feature = "e2e-encryption")] -use crate::{ - response_processors::{self as processors}, - RoomMemberships, -}; /// A no (network) IO client implementation. /// @@ -498,7 +495,7 @@ impl BaseClient { } } - handle_room_member_event_for_profiles( + processors::profiles::upsert_or_delete( context, room.room_id(), member, @@ -716,7 +713,7 @@ impl BaseClient { _ => (), } - handle_room_member_event_for_profiles(context, &room_info.room_id, member); + processors::profiles::upsert_or_delete(context, &room_info.room_id, member); } state_events @@ -1424,7 +1421,7 @@ impl BaseClient { } let sync_member: SyncRoomMemberEvent = member.clone().into(); - handle_room_member_event_for_profiles(&mut context, room_id, &sync_member); + processors::profiles::upsert_or_delete(&mut context, room_id, &sync_member); context .state_changes @@ -1760,39 +1757,6 @@ impl BaseClient { } } -fn handle_room_member_event_for_profiles( - context: &mut Context, - room_id: &RoomId, - event: &SyncStateEvent, -) { - // Senders can fake the profile easily so we keep track of profiles that the - // member set themselves to avoid having confusing profile changes when a - // member gets kicked/banned. - if event.state_key() == event.sender() { - context - .state_changes - .profiles - .entry(room_id.to_owned()) - .or_default() - .insert(event.sender().to_owned(), event.into()); - } - - if *event.membership() == MembershipState::Invite { - // Remove any profile previously stored for the invited user. - // - // A room member could have joined the room and left it later; in that case, the - // server may return a dummy, empty profile along the `leave` event. We - // don't want to reuse that empty profile when the member has been - // re-invited, so we remove it from the database. - context - .state_changes - .profiles_to_delete - .entry(room_id.to_owned()) - .or_default() - .push(event.state_key().clone()); - } -} - /// Represent the `required_state` values sent by a sync request. /// /// This is useful to track what state events have been requested when handling diff --git a/crates/matrix-sdk-base/src/response_processors/mod.rs b/crates/matrix-sdk-base/src/response_processors/mod.rs index 38c65a2db..524e36402 100644 --- a/crates/matrix-sdk-base/src/response_processors/mod.rs +++ b/crates/matrix-sdk-base/src/response_processors/mod.rs @@ -17,6 +17,7 @@ pub mod account_data; pub mod e2ee; #[cfg(feature = "e2e-encryption")] pub mod latest_event; +pub mod profiles; #[cfg(feature = "e2e-encryption")] pub mod verification; diff --git a/crates/matrix-sdk-base/src/response_processors/profiles.rs b/crates/matrix-sdk-base/src/response_processors/profiles.rs new file mode 100644 index 000000000..f717d81ed --- /dev/null +++ b/crates/matrix-sdk-base/src/response_processors/profiles.rs @@ -0,0 +1,58 @@ +// Copyright 2025 The Matrix.org Foundation C.I.C. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use ruma::{ + events::{ + room::member::{MembershipState, RoomMemberEventContent}, + SyncStateEvent, + }, + RoomId, +}; + +use super::Context; + +/// Decide whether the profile must be created, updated or deleted based on the +/// [`RoomMemberEventContent`]. +pub fn upsert_or_delete( + context: &mut Context, + room_id: &RoomId, + event: &SyncStateEvent, +) { + // Senders can fake the profile easily so we keep track of profiles that the + // member set themselves to avoid having confusing profile changes when a + // member gets kicked/banned. + if event.state_key() == event.sender() { + context + .state_changes + .profiles + .entry(room_id.to_owned()) + .or_default() + .insert(event.sender().to_owned(), event.into()); + } + + if *event.membership() == MembershipState::Invite { + // Remove any profile previously stored for the invited user. + // + // A room member could have joined the room and left it later; in that case, the + // server may return a dummy, empty profile along the `leave` event. We + // don't want to reuse that empty profile when the member has been + // re-invited, so we remove it from the database. + context + .state_changes + .profiles_to_delete + .entry(room_id.to_owned()) + .or_default() + .push(event.state_key().clone()); + } +}