diff --git a/src/admin/user/commands.rs b/src/admin/user/commands.rs index b51f32ef..20691f1a 100644 --- a/src/admin/user/commands.rs +++ b/src/admin/user/commands.rs @@ -1,6 +1,6 @@ use std::{collections::BTreeMap, fmt::Write as _}; -use api::client::{join_room_by_id_helper, leave_all_rooms, leave_room, update_avatar_url, update_displayname}; +use api::client::{full_user_deactivate, join_room_by_id_helper, leave_room}; use conduit::{error, info, utils, warn, PduBuilder, Result}; use ruma::{ events::{ @@ -184,10 +184,8 @@ pub(super) async fn deactivate(&self, no_leave_rooms: bool, user_id: String) -> .rooms_joined(&user_id) .filter_map(Result::ok) .collect(); - update_displayname(self.services, &user_id, None, all_joined_rooms.clone()).await?; - update_avatar_url(self.services, &user_id, None, None, all_joined_rooms).await?; - self.services.users.set_timezone(&user_id, None).await?; - leave_all_rooms(self.services, &user_id).await; + + full_user_deactivate(self.services, &user_id, all_joined_rooms).await?; } Ok(RoomMessageEventContent::text_plain(format!( @@ -293,10 +291,7 @@ pub(super) async fn deactivate_all(&self, no_leave_rooms: bool, force: bool) -> .rooms_joined(&user_id) .filter_map(Result::ok) .collect(); - update_displayname(self.services, &user_id, None, all_joined_rooms.clone()).await?; - update_avatar_url(self.services, &user_id, None, None, all_joined_rooms).await?; - self.services.users.set_timezone(&user_id, None).await?; - leave_all_rooms(self.services, &user_id).await; + full_user_deactivate(self.services, &user_id, all_joined_rooms).await?; } }, Err(e) => { diff --git a/src/api/client/account.rs b/src/api/client/account.rs index 605ab20b..27e6523b 100644 --- a/src/api/client/account.rs +++ b/src/api/client/account.rs @@ -18,6 +18,7 @@ use ruma::{ events::{room::message::RoomMessageEventContent, GlobalAccountDataEventType}, push, OwnedRoomId, UserId, }; +use service::Services; use super::{join_room_by_id_helper, DEVICE_ID_LENGTH, SESSION_ID_LENGTH, TOKEN_LENGTH}; use crate::Ruma; @@ -553,12 +554,6 @@ pub(crate) async fn deactivate_route( return Err(Error::BadRequest(ErrorKind::NotJson, "Not json.")); } - // Remove devices and mark account as deactivated - services.users.deactivate_account(sender_user)?; - - // Remove timezone profile field - services.users.set_timezone(sender_user, None).await?; - // Remove profile pictures and display name let all_joined_rooms: Vec = services .rooms @@ -566,12 +561,8 @@ pub(crate) async fn deactivate_route( .rooms_joined(sender_user) .filter_map(Result::ok) .collect(); - super::update_displayname(&services, sender_user, None, all_joined_rooms.clone()).await?; - super::update_avatar_url(&services, sender_user, None, None, all_joined_rooms).await?; - services.users.set_timezone(sender_user, None).await?; - // Make the user leave all rooms before deactivation - super::leave_all_rooms(&services, sender_user).await; + full_user_deactivate(&services, sender_user, all_joined_rooms).await?; info!("User {sender_user} deactivated their account."); services @@ -649,3 +640,33 @@ pub(crate) async fn check_registration_token_validity( valid: reg_token == body.token, }) } + +/// Runs through all the deactivation steps: +/// +/// - Mark as deactivated +/// - Removing display name +/// - Removing avatar URL and blurhash +/// - Removing all profile data +/// - Leaving all rooms +pub async fn full_user_deactivate( + services: &Services, user_id: &UserId, all_joined_rooms: Vec, +) -> Result<()> { + services.users.deactivate_account(user_id)?; + + super::update_displayname(services, user_id, None, all_joined_rooms.clone()).await?; + super::update_avatar_url(services, user_id, None, None, all_joined_rooms).await?; + super::leave_all_rooms(services, user_id).await; + + let all_profile_keys = services + .users + .all_profile_keys(user_id) + .filter_map(Result::ok); + + for (profile_key, _profile_value) in all_profile_keys { + services + .users + .set_profile_key(user_id, &profile_key, None)?; + } + + Ok(()) +} diff --git a/src/api/client/membership.rs b/src/api/client/membership.rs index 514403e7..b3b3c80e 100644 --- a/src/api/client/membership.rs +++ b/src/api/client/membership.rs @@ -43,10 +43,7 @@ use serde_json::value::{to_raw_value, RawValue as RawJsonValue}; use service::{appservice::RegistrationInfo, rooms::state::RoomMutexGuard, Services}; use tokio::sync::RwLock; -use crate::{ - client::{update_avatar_url, update_displayname}, - Ruma, -}; +use crate::{client::full_user_deactivate, Ruma}; /// Checks if the room is banned in any way possible and the sender user is not /// an admin. @@ -82,10 +79,6 @@ async fn banned_room_check( ))) .await; - if let Err(e) = services.users.deactivate_account(user_id) { - warn!(%user_id, %e, "Failed to deactivate account"); - } - let all_joined_rooms: Vec = services .rooms .state_cache @@ -93,10 +86,7 @@ async fn banned_room_check( .filter_map(Result::ok) .collect(); - update_displayname(services, user_id, None, all_joined_rooms.clone()).await?; - update_avatar_url(services, user_id, None, None, all_joined_rooms).await?; - services.users.set_timezone(user_id, None).await?; - leave_all_rooms(services, user_id).await; + full_user_deactivate(services, user_id, all_joined_rooms).await?; } return Err(Error::BadRequest( @@ -126,10 +116,6 @@ async fn banned_room_check( ))) .await; - if let Err(e) = services.users.deactivate_account(user_id) { - warn!(%user_id, %e, "Failed to deactivate account"); - } - let all_joined_rooms: Vec = services .rooms .state_cache @@ -137,10 +123,7 @@ async fn banned_room_check( .filter_map(Result::ok) .collect(); - update_displayname(services, user_id, None, all_joined_rooms.clone()).await?; - update_avatar_url(services, user_id, None, None, all_joined_rooms).await?; - services.users.set_timezone(user_id, None).await?; - leave_all_rooms(services, user_id).await; + full_user_deactivate(services, user_id, all_joined_rooms).await?; } return Err(Error::BadRequest( diff --git a/src/api/client/mod.rs b/src/api/client/mod.rs index 5dcdc51a..4b7b64b9 100644 --- a/src/api/client/mod.rs +++ b/src/api/client/mod.rs @@ -37,6 +37,7 @@ pub(super) mod unversioned; pub(super) mod user_directory; pub(super) mod voip; +pub use account::full_user_deactivate; pub(super) use account::*; pub(super) use alias::*; pub(super) use appservice::*;