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,
|
message::RoomMessageEventContent,
|
||||||
name::RoomNameEventContent,
|
name::RoomNameEventContent,
|
||||||
power_levels::RoomPowerLevelsEventContent,
|
power_levels::RoomPowerLevelsEventContent,
|
||||||
|
redaction::RoomRedactionEventContent,
|
||||||
topic::RoomTopicEventContent,
|
topic::RoomTopicEventContent,
|
||||||
},
|
},
|
||||||
TimelineEventType,
|
TimelineEventType,
|
||||||
|
@ -182,7 +183,7 @@ enum AdminCommand {
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum AdminRoomEvent {
|
pub enum AdminRoomEvent {
|
||||||
ProcessMessage(String),
|
ProcessMessage(String, ruma::OwnedEventId),
|
||||||
SendMessage(RoomMessageEventContent),
|
SendMessage(RoomMessageEventContent),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -221,7 +222,7 @@ impl Service {
|
||||||
Some(event) = receiver.recv() => {
|
Some(event) = receiver.recv() => {
|
||||||
let message_content = match event {
|
let message_content = match event {
|
||||||
AdminRoomEvent::SendMessage(content) => content,
|
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(
|
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
|
self.sender
|
||||||
.send(AdminRoomEvent::ProcessMessage(room_message))
|
.send(AdminRoomEvent::ProcessMessage(
|
||||||
|
room_message,
|
||||||
|
event_id.into(),
|
||||||
|
))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -270,8 +274,57 @@ impl Service {
|
||||||
.unwrap();
|
.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
|
// 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 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 command_line = lines.next().expect("each string has at least one line");
|
||||||
let body: Vec<_> = lines.collect();
|
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,
|
Ok(reply_message) => reply_message,
|
||||||
Err(error) => {
|
Err(error) => {
|
||||||
let markdown_message = format!(
|
let markdown_message = format!(
|
||||||
|
@ -330,6 +386,7 @@ impl Service {
|
||||||
&self,
|
&self,
|
||||||
command: AdminCommand,
|
command: AdminCommand,
|
||||||
body: Vec<&str>,
|
body: Vec<&str>,
|
||||||
|
event_id: &EventId,
|
||||||
) -> Result<RoomMessageEventContent> {
|
) -> Result<RoomMessageEventContent> {
|
||||||
let reply_message_content = match command {
|
let reply_message_content = match command {
|
||||||
AdminCommand::RegisterAppservice => {
|
AdminCommand::RegisterAppservice => {
|
||||||
|
@ -591,6 +648,7 @@ impl Service {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
AdminCommand::CreateUser { username, password } => {
|
AdminCommand::CreateUser { username, password } => {
|
||||||
|
let is_auto_generated_password = password.is_none();
|
||||||
let password =
|
let password =
|
||||||
password.unwrap_or_else(|| utils::random_string(AUTO_GEN_PASSWORD_LENGTH));
|
password.unwrap_or_else(|| utils::random_string(AUTO_GEN_PASSWORD_LENGTH));
|
||||||
// Validate user id
|
// Validate user id
|
||||||
|
@ -645,6 +703,18 @@ impl Service {
|
||||||
.expect("to json value always works"),
|
.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
|
// we dont add a device since we're not the user, just the creator
|
||||||
|
|
||||||
// Inhibit login does not work for guests
|
// Inhibit login does not work for guests
|
||||||
|
|
|
@ -499,7 +499,7 @@ impl Service {
|
||||||
|
|
||||||
if let Some(admin_room) = services().admin.get_admin_room()? {
|
if let Some(admin_room) = services().admin.get_admin_room()? {
|
||||||
if to_conduit && !from_conduit && admin_room == pdu.room_id {
|
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