@@ -2,7 +2,7 @@ use std::fmt::Write;
22
33use axum:: extract:: State ;
44use axum_client_ip:: InsecureClientIp ;
5- use conduit:: { debug_info, error, info, utils, warn, Error , Result } ;
5+ use conduit:: { debug_info, error, info, utils, warn, Error , PduBuilder , Result } ;
66use register:: RegistrationKind ;
77use ruma:: {
88 api:: client:: {
@@ -15,9 +15,16 @@ use ruma::{
1515 error:: ErrorKind ,
1616 uiaa:: { AuthFlow , AuthType , UiaaInfo } ,
1717 } ,
18- events:: { room:: message:: RoomMessageEventContent , GlobalAccountDataEventType } ,
18+ events:: {
19+ room:: {
20+ message:: RoomMessageEventContent ,
21+ power_levels:: { RoomPowerLevels , RoomPowerLevelsEventContent } ,
22+ } ,
23+ GlobalAccountDataEventType , StateEventType , TimelineEventType ,
24+ } ,
1925 push, OwnedRoomId , UserId ,
2026} ;
27+ use serde_json:: value:: to_raw_value;
2128use service:: Services ;
2229
2330use super :: { join_room_by_id_helper, DEVICE_ID_LENGTH , SESSION_ID_LENGTH , TOKEN_LENGTH } ;
@@ -647,26 +654,79 @@ pub(crate) async fn check_registration_token_validity(
647654/// - Removing display name
648655/// - Removing avatar URL and blurhash
649656/// - Removing all profile data
650- /// - Leaving all rooms
657+ /// - Leaving all rooms (and forgets all of them)
651658pub async fn full_user_deactivate (
652659 services : & Services , user_id : & UserId , all_joined_rooms : Vec < OwnedRoomId > ,
653660) -> Result < ( ) > {
654661 services. users . deactivate_account ( user_id) ?;
655662
656663 super :: update_displayname ( services, user_id, None , all_joined_rooms. clone ( ) ) . await ?;
657- super :: update_avatar_url ( services, user_id, None , None , all_joined_rooms) . await ?;
658- super :: leave_all_rooms ( services, user_id) . await ;
664+ super :: update_avatar_url ( services, user_id, None , None , all_joined_rooms. clone ( ) ) . await ?;
659665
660666 let all_profile_keys = services
661667 . users
662668 . all_profile_keys ( user_id)
663669 . filter_map ( Result :: ok) ;
664670
665671 for ( profile_key, _profile_value) in all_profile_keys {
666- services
667- . users
668- . set_profile_key ( user_id, & profile_key, None ) ?;
672+ if let Err ( e) = services. users . set_profile_key ( user_id, & profile_key, None ) {
673+ warn ! ( "Failed removing {user_id} profile key {profile_key}: {e}" ) ;
674+ }
675+ }
676+
677+ for room_id in all_joined_rooms {
678+ let state_lock = services. rooms . state . mutex . lock ( & room_id) . await ;
679+
680+ let room_power_levels = services
681+ . rooms
682+ . state_accessor
683+ . room_state_get ( & room_id, & StateEventType :: RoomPowerLevels , "" ) ?
684+ . as_ref ( )
685+ . and_then ( |event| serde_json:: from_str ( event. content . get ( ) ) . ok ( ) ?)
686+ . and_then ( |content : RoomPowerLevelsEventContent | content. into ( ) ) ;
687+
688+ let user_can_demote_self = room_power_levels
689+ . as_ref ( )
690+ . is_some_and ( |power_levels_content| {
691+ RoomPowerLevels :: from ( power_levels_content. clone ( ) ) . user_can_change_user_power_level ( user_id, user_id)
692+ } ) || services
693+ . rooms
694+ . state_accessor
695+ . room_state_get ( & room_id, & StateEventType :: RoomCreate , "" ) ?
696+ . as_ref ( )
697+ . is_some_and ( |event| event. sender == user_id) ;
698+
699+ if user_can_demote_self {
700+ let mut power_levels_content = room_power_levels. unwrap_or_default ( ) ;
701+ power_levels_content. users . remove ( user_id) ;
702+
703+ // ignore errors so deactivation doesn't fail
704+ if let Err ( e) = services
705+ . rooms
706+ . timeline
707+ . build_and_append_pdu (
708+ PduBuilder {
709+ event_type : TimelineEventType :: RoomPowerLevels ,
710+ content : to_raw_value ( & power_levels_content) . expect ( "event is valid, we just created it" ) ,
711+ unsigned : None ,
712+ state_key : Some ( String :: new ( ) ) ,
713+ redacts : None ,
714+ timestamp : None ,
715+ } ,
716+ user_id,
717+ & room_id,
718+ & state_lock,
719+ )
720+ . await
721+ {
722+ warn ! ( %room_id, %user_id, "Failed to demote user's own power level: {e}" ) ;
723+ } else {
724+ info ! ( "Demoted {user_id} in {room_id} as part of account deactivation" ) ;
725+ }
726+ }
669727 }
670728
729+ super :: leave_all_rooms ( services, user_id) . await ;
730+
671731 Ok ( ( ) )
672732}
0 commit comments