mirror of
https://gitlab.com/famedly/conduit.git
synced 2025-06-27 16:35:59 +00:00
feat(admin-room): Delete create-user
command message
- Add the `event_id` of the user message to `AdminRoomEvent::ProcessMessage` variant to work with it in `process_admin_message` - Delete the user `create-user` command message if it's contain a plain password because the admin room are unencrypted so the password will be saved in the database if we didn't deleted it - Create new function that delete the messages from admin room called `delete_user_message` Reported-by: Matthias Ahouansou <matthias@ahouansou.cz> Helped-by: Matthias Ahouansou <matthias@ahouansou.cz> Related-to: https://gitlab.com/famedly/conduit/-/issues/432 Signed-off-by: Awiteb <a@4rs.nl>
This commit is contained in:
parent
53d3f9ae89
commit
8a307dabd2
2 changed files with 77 additions and 7 deletions
|
@ -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<impl Into<String>>,
|
||||
) -> 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<RoomMessageEventContent> {
|
||||
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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue