diff --git a/src/service/admin/mod.rs b/src/service/admin/mod.rs index 484fc134..4b5b39cf 100644 --- a/src/service/admin/mod.rs +++ b/src/service/admin/mod.rs @@ -20,6 +20,7 @@ use ruma::{ message::RoomMessageEventContent, name::RoomNameEventContent, power_levels::RoomPowerLevelsEventContent, + redaction::RoomRedactionEventContent, topic::RoomTopicEventContent, }, TimelineEventType, @@ -182,7 +183,7 @@ enum AdminCommand { #[derive(Debug)] pub enum AdminRoomEvent { - ProcessMessage(String), + ProcessMessage(String, ruma::OwnedEventId), SendMessage(RoomMessageEventContent), } @@ -221,7 +222,7 @@ impl Service { Some(event) = receiver.recv() => { let message_content = match event { AdminRoomEvent::SendMessage(content) => content, - AdminRoomEvent::ProcessMessage(room_message) => self.process_admin_message(room_message).await + AdminRoomEvent::ProcessMessage(room_message, event_id) => self.process_admin_message(room_message, &event_id).await }; let mutex_state = Arc::clone( @@ -258,9 +259,12 @@ impl Service { } } - pub fn process_message(&self, room_message: String) { + pub fn process_message(&self, room_message: String, event_id: &EventId) { self.sender - .send(AdminRoomEvent::ProcessMessage(room_message)) + .send(AdminRoomEvent::ProcessMessage( + room_message, + event_id.into(), + )) .unwrap(); } @@ -270,8 +274,57 @@ impl Service { .unwrap(); } + /// Delete user message in the conduit admin room. + pub async fn delete_user_message( + &self, + event_id: &EventId, + reason: Option>, + ) -> Result<()> { + let conduit_user = + UserId::parse_with_server_name("conduit", services().globals.server_name()) + .expect("@conduit:server_name is valid"); + if let Some(room_id) = services().admin.get_admin_room()? { + let mutex_state = Arc::clone( + services() + .globals + .roomid_mutex_state + .write() + .await + .entry(room_id.clone()) + .or_default(), + ); + let state_lock = mutex_state.lock().await; + + services() + .rooms + .timeline + .build_and_append_pdu( + PduBuilder { + event_type: TimelineEventType::RoomRedaction, + content: to_raw_value(&RoomRedactionEventContent { + redacts: Some(event_id.into()), + reason: reason.map(Into::into), + }) + .expect("event is valid, we just created it"), + unsigned: None, + state_key: None, + redacts: Some(event_id.into()), + }, + &conduit_user, + &room_id, + &state_lock, + ) + .await?; + } + Ok(()) + } + // Parse and process a message from the admin room - async fn process_admin_message(&self, room_message: String) -> RoomMessageEventContent { + async fn process_admin_message( + &self, + room_message: String, + event_id: &EventId, + ) -> RoomMessageEventContent { let mut lines = room_message.lines().filter(|l| !l.trim().is_empty()); let command_line = lines.next().expect("each string has at least one line"); let body: Vec<_> = lines.collect(); @@ -287,7 +340,10 @@ impl Service { } }; - match self.process_admin_command(admin_command, body).await { + match self + .process_admin_command(admin_command, body, event_id) + .await + { Ok(reply_message) => reply_message, Err(error) => { let markdown_message = format!( @@ -330,6 +386,7 @@ impl Service { &self, command: AdminCommand, body: Vec<&str>, + event_id: &EventId, ) -> Result { let reply_message_content = match command { AdminCommand::RegisterAppservice => { @@ -591,6 +648,7 @@ impl Service { } } AdminCommand::CreateUser { username, password } => { + let is_auto_generated_password = password.is_none(); let password = password.unwrap_or_else(|| utils::random_string(AUTO_GEN_PASSWORD_LENGTH)); // Validate user id @@ -645,6 +703,18 @@ impl Service { .expect("to json value always works"), )?; + // We'll delete the user message because it's contain a plain password + // and the admin room are not encrypted + if !is_auto_generated_password { + services() + .admin + .delete_user_message( + event_id, + Some("Message contained a plaintext password"), + ) + .await?; + } + // we dont add a device since we're not the user, just the creator // Inhibit login does not work for guests diff --git a/src/service/rooms/timeline/mod.rs b/src/service/rooms/timeline/mod.rs index acb00d01..5b309a0a 100644 --- a/src/service/rooms/timeline/mod.rs +++ b/src/service/rooms/timeline/mod.rs @@ -499,7 +499,7 @@ impl Service { if let Some(admin_room) = services().admin.get_admin_room()? { if to_conduit && !from_conduit && admin_room == pdu.room_id { - services().admin.process_message(body); + services().admin.process_message(body, &pdu.event_id); } } }