mirror of
https://gitlab.com/famedly/conduit.git
synced 2025-06-27 16:35:59 +00:00
chore: Make the process_admin_message
more flixable
Make it return `Option<RoomMessageEventContent>` instade of `RoomMessageEventContent` Helped-by: Matthias Ahouansou <matthias@ahouansou.cz> Signed-off-by: Awiteb <a@4rs.nl>
This commit is contained in:
parent
8a307dabd2
commit
6355116063
1 changed files with 143 additions and 117 deletions
|
@ -221,10 +221,10 @@ impl Service {
|
|||
tokio::select! {
|
||||
Some(event) = receiver.recv() => {
|
||||
let message_content = match event {
|
||||
AdminRoomEvent::SendMessage(content) => content,
|
||||
AdminRoomEvent::SendMessage(content) => Some(content),
|
||||
AdminRoomEvent::ProcessMessage(room_message, event_id) => self.process_admin_message(room_message, &event_id).await
|
||||
};
|
||||
|
||||
if let Some(message_content) = message_content {
|
||||
let mutex_state = Arc::clone(
|
||||
services().globals
|
||||
.roomid_mutex_state
|
||||
|
@ -258,6 +258,7 @@ impl Service {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn process_message(&self, room_message: String, event_id: &EventId) {
|
||||
self.sender
|
||||
|
@ -319,12 +320,14 @@ impl Service {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
// Parse and process a message from the admin room
|
||||
/// Parse and process a message from the admin room
|
||||
///
|
||||
/// May return `Option::None` if there is no process case for the message
|
||||
async fn process_admin_message(
|
||||
&self,
|
||||
room_message: String,
|
||||
event_id: &EventId,
|
||||
) -> RoomMessageEventContent {
|
||||
) -> Option<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();
|
||||
|
@ -336,7 +339,7 @@ impl Service {
|
|||
let message = error.replace("server.name", server_name.as_str());
|
||||
let html_message = self.usage_to_html(&message, server_name);
|
||||
|
||||
return RoomMessageEventContent::text_html(message, html_message);
|
||||
return Some(RoomMessageEventContent::text_html(message, html_message));
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -344,7 +347,8 @@ impl Service {
|
|||
.process_admin_command(admin_command, body, event_id)
|
||||
.await
|
||||
{
|
||||
Ok(reply_message) => reply_message,
|
||||
Ok(Some(reply_message)) => Some(reply_message),
|
||||
Ok(None) => None,
|
||||
Err(error) => {
|
||||
let markdown_message = format!(
|
||||
"Encountered an error while handling the command:\n\
|
||||
|
@ -355,7 +359,10 @@ impl Service {
|
|||
<pre>\n{error}\n</pre>",
|
||||
);
|
||||
|
||||
RoomMessageEventContent::text_html(markdown_message, html_message)
|
||||
Some(RoomMessageEventContent::text_html(
|
||||
markdown_message,
|
||||
html_message,
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -382,19 +389,22 @@ impl Service {
|
|||
AdminCommand::try_parse_from(argv).map_err(|error| error.to_string())
|
||||
}
|
||||
|
||||
/// Process the entered admin command
|
||||
///
|
||||
/// May return `Ok(Option::None)` if there is no process case for the message
|
||||
async fn process_admin_command(
|
||||
&self,
|
||||
command: AdminCommand,
|
||||
body: Vec<&str>,
|
||||
event_id: &EventId,
|
||||
) -> Result<RoomMessageEventContent> {
|
||||
) -> Result<Option<RoomMessageEventContent>> {
|
||||
let reply_message_content = match command {
|
||||
AdminCommand::RegisterAppservice => {
|
||||
if body.len() > 2 && body[0].trim() == "```" && body.last().unwrap().trim() == "```"
|
||||
{
|
||||
let appservice_config = body[1..body.len() - 1].join("\n");
|
||||
let parsed_config = serde_yaml::from_str::<Registration>(&appservice_config);
|
||||
match parsed_config {
|
||||
Some(match parsed_config {
|
||||
Ok(yaml) => match services().appservice.register_appservice(yaml).await {
|
||||
Ok(id) => RoomMessageEventContent::text_plain(format!(
|
||||
"Appservice registered with ID: {id}."
|
||||
|
@ -406,16 +416,17 @@ impl Service {
|
|||
Err(e) => RoomMessageEventContent::text_plain(format!(
|
||||
"Could not parse appservice config: {e}"
|
||||
)),
|
||||
}
|
||||
})
|
||||
} else {
|
||||
RoomMessageEventContent::text_plain(
|
||||
Some(RoomMessageEventContent::text_plain(
|
||||
"Expected code block in command body. Add --help for details.",
|
||||
)
|
||||
))
|
||||
}
|
||||
}
|
||||
AdminCommand::UnregisterAppservice {
|
||||
appservice_identifier,
|
||||
} => match services()
|
||||
} => Some(
|
||||
match services()
|
||||
.appservice
|
||||
.unregister_appservice(&appservice_identifier)
|
||||
.await
|
||||
|
@ -425,6 +436,7 @@ impl Service {
|
|||
"Failed to unregister appservice: {e}"
|
||||
)),
|
||||
},
|
||||
),
|
||||
AdminCommand::ListAppservices => {
|
||||
let appservices = services().appservice.iter_ids().await;
|
||||
let output = format!(
|
||||
|
@ -432,7 +444,7 @@ impl Service {
|
|||
appservices.len(),
|
||||
appservices.join(", ")
|
||||
);
|
||||
RoomMessageEventContent::text_plain(output)
|
||||
Some(RoomMessageEventContent::text_plain(output))
|
||||
}
|
||||
AdminCommand::ListRooms => {
|
||||
let room_ids = services().rooms.metadata.iter_ids();
|
||||
|
@ -453,16 +465,16 @@ impl Service {
|
|||
.collect::<Vec<_>>()
|
||||
.join("\n")
|
||||
);
|
||||
RoomMessageEventContent::text_plain(output)
|
||||
Some(RoomMessageEventContent::text_plain(output))
|
||||
}
|
||||
AdminCommand::ListLocalUsers => match services().users.list_local_users() {
|
||||
AdminCommand::ListLocalUsers => Some(match services().users.list_local_users() {
|
||||
Ok(users) => {
|
||||
let mut msg: String = format!("Found {} local user account(s):\n", users.len());
|
||||
msg += &users.join("\n");
|
||||
RoomMessageEventContent::text_plain(&msg)
|
||||
}
|
||||
Err(e) => RoomMessageEventContent::text_plain(e.to_string()),
|
||||
},
|
||||
}),
|
||||
AdminCommand::IncomingFederation => {
|
||||
let map = services().globals.roomid_federationhandletime.read().await;
|
||||
let mut msg: String = format!("Handling {} incoming pdus:\n", map.len());
|
||||
|
@ -477,7 +489,7 @@ impl Service {
|
|||
elapsed.as_secs() % 60
|
||||
);
|
||||
}
|
||||
RoomMessageEventContent::text_plain(&msg)
|
||||
Some(RoomMessageEventContent::text_plain(&msg))
|
||||
}
|
||||
AdminCommand::GetAuthChain { event_id } => {
|
||||
let event_id = Arc::<EventId>::from(event_id);
|
||||
|
@ -498,18 +510,18 @@ impl Service {
|
|||
.await?
|
||||
.count();
|
||||
let elapsed = start.elapsed();
|
||||
RoomMessageEventContent::text_plain(format!(
|
||||
Some(RoomMessageEventContent::text_plain(format!(
|
||||
"Loaded auth chain with length {count} in {elapsed:?}"
|
||||
))
|
||||
)))
|
||||
} else {
|
||||
RoomMessageEventContent::text_plain("Event not found.")
|
||||
Some(RoomMessageEventContent::text_plain("Event not found."))
|
||||
}
|
||||
}
|
||||
AdminCommand::ParsePdu => {
|
||||
if body.len() > 2 && body[0].trim() == "```" && body.last().unwrap().trim() == "```"
|
||||
{
|
||||
let string = body[1..body.len() - 1].join("\n");
|
||||
match serde_json::from_str(&string) {
|
||||
Some(match serde_json::from_str(&string) {
|
||||
Ok(value) => {
|
||||
match ruma::signatures::reference_hash(&value, &RoomVersionId::V6) {
|
||||
Ok(hash) => {
|
||||
|
@ -534,9 +546,11 @@ impl Service {
|
|||
Err(e) => RoomMessageEventContent::text_plain(format!(
|
||||
"Invalid json in command body: {e}"
|
||||
)),
|
||||
}
|
||||
})
|
||||
} else {
|
||||
RoomMessageEventContent::text_plain("Expected code block in command body.")
|
||||
Some(RoomMessageEventContent::text_plain(
|
||||
"Expected code block in command body.",
|
||||
))
|
||||
}
|
||||
}
|
||||
AdminCommand::GetPdu { event_id } => {
|
||||
|
@ -553,7 +567,7 @@ impl Service {
|
|||
Some(json) => {
|
||||
let json_text = serde_json::to_string_pretty(&json)
|
||||
.expect("canonical json is valid json");
|
||||
RoomMessageEventContent::text_html(
|
||||
Some(RoomMessageEventContent::text_html(
|
||||
format!(
|
||||
"{}\n```json\n{}\n```",
|
||||
if outlier {
|
||||
|
@ -572,32 +586,35 @@ impl Service {
|
|||
},
|
||||
HtmlEscape(&json_text)
|
||||
),
|
||||
)
|
||||
))
|
||||
}
|
||||
None => RoomMessageEventContent::text_plain("PDU not found."),
|
||||
None => Some(RoomMessageEventContent::text_plain("PDU not found.")),
|
||||
}
|
||||
}
|
||||
AdminCommand::MemoryUsage => {
|
||||
let response1 = services().memory_usage().await;
|
||||
let response2 = services().globals.db.memory_usage();
|
||||
|
||||
RoomMessageEventContent::text_plain(format!(
|
||||
Some(RoomMessageEventContent::text_plain(format!(
|
||||
"Services:\n{response1}\n\nDatabase:\n{response2}"
|
||||
))
|
||||
)))
|
||||
}
|
||||
AdminCommand::ClearDatabaseCaches { amount } => {
|
||||
services().globals.db.clear_caches(amount);
|
||||
|
||||
RoomMessageEventContent::text_plain("Done.")
|
||||
Some(RoomMessageEventContent::text_plain("Done."))
|
||||
}
|
||||
AdminCommand::ClearServiceCaches { amount } => {
|
||||
services().clear_caches(amount).await;
|
||||
|
||||
RoomMessageEventContent::text_plain("Done.")
|
||||
Some(RoomMessageEventContent::text_plain("Done."))
|
||||
}
|
||||
AdminCommand::ShowConfig => {
|
||||
// Construct and send the response
|
||||
RoomMessageEventContent::text_plain(format!("{}", services().globals.config))
|
||||
Some(RoomMessageEventContent::text_plain(format!(
|
||||
"{}",
|
||||
services().globals.config
|
||||
)))
|
||||
}
|
||||
AdminCommand::ResetPassword { username } => {
|
||||
let user_id = match UserId::parse_with_server_name(
|
||||
|
@ -606,17 +623,17 @@ impl Service {
|
|||
) {
|
||||
Ok(id) => id,
|
||||
Err(e) => {
|
||||
return Ok(RoomMessageEventContent::text_plain(format!(
|
||||
return Ok(Some(RoomMessageEventContent::text_plain(format!(
|
||||
"The supplied username is not a valid username: {e}"
|
||||
)))
|
||||
))))
|
||||
}
|
||||
};
|
||||
|
||||
// Checks if user is local
|
||||
if user_id.server_name() != services().globals.server_name() {
|
||||
return Ok(RoomMessageEventContent::text_plain(
|
||||
return Ok(Some(RoomMessageEventContent::text_plain(
|
||||
"The specified user is not from this server!",
|
||||
));
|
||||
)));
|
||||
};
|
||||
|
||||
// Check if the specified user is valid
|
||||
|
@ -628,13 +645,14 @@ impl Service {
|
|||
)
|
||||
.expect("conduit user exists")
|
||||
{
|
||||
return Ok(RoomMessageEventContent::text_plain(
|
||||
return Ok(Some(RoomMessageEventContent::text_plain(
|
||||
"The specified user does not exist!",
|
||||
));
|
||||
)));
|
||||
}
|
||||
|
||||
let new_password = utils::random_string(AUTO_GEN_PASSWORD_LENGTH);
|
||||
|
||||
Some(
|
||||
match services()
|
||||
.users
|
||||
.set_password(&user_id, Some(new_password.as_str()))
|
||||
|
@ -645,7 +663,8 @@ impl Service {
|
|||
Err(e) => RoomMessageEventContent::text_plain(format!(
|
||||
"Couldn't reset the password for user {user_id}: {e}"
|
||||
)),
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
AdminCommand::CreateUser { username, password } => {
|
||||
let is_auto_generated_password = password.is_none();
|
||||
|
@ -658,20 +677,20 @@ impl Service {
|
|||
) {
|
||||
Ok(id) => id,
|
||||
Err(e) => {
|
||||
return Ok(RoomMessageEventContent::text_plain(format!(
|
||||
return Ok(Some(RoomMessageEventContent::text_plain(format!(
|
||||
"The supplied username is not a valid username: {e}"
|
||||
)))
|
||||
))))
|
||||
}
|
||||
};
|
||||
if user_id.is_historical() {
|
||||
return Ok(RoomMessageEventContent::text_plain(format!(
|
||||
return Ok(Some(RoomMessageEventContent::text_plain(format!(
|
||||
"Userid {user_id} is not allowed due to historical"
|
||||
)));
|
||||
))));
|
||||
}
|
||||
if services().users.exists(&user_id)? {
|
||||
return Ok(RoomMessageEventContent::text_plain(format!(
|
||||
return Ok(Some(RoomMessageEventContent::text_plain(format!(
|
||||
"Userid {user_id} already exists"
|
||||
)));
|
||||
))));
|
||||
}
|
||||
// Create user
|
||||
services().users.create(&user_id, Some(password.as_str()))?;
|
||||
|
@ -718,17 +737,17 @@ impl Service {
|
|||
// we dont add a device since we're not the user, just the creator
|
||||
|
||||
// Inhibit login does not work for guests
|
||||
RoomMessageEventContent::text_plain(format!(
|
||||
Some(RoomMessageEventContent::text_plain(format!(
|
||||
"Created user with user_id: {user_id} and password: {password}"
|
||||
))
|
||||
)))
|
||||
}
|
||||
AdminCommand::DisableRoom { room_id } => {
|
||||
services().rooms.metadata.disable_room(&room_id, true)?;
|
||||
RoomMessageEventContent::text_plain("Room disabled.")
|
||||
Some(RoomMessageEventContent::text_plain("Room disabled."))
|
||||
}
|
||||
AdminCommand::EnableRoom { room_id } => {
|
||||
services().rooms.metadata.disable_room(&room_id, false)?;
|
||||
RoomMessageEventContent::text_plain("Room enabled.")
|
||||
Some(RoomMessageEventContent::text_plain("Room enabled."))
|
||||
}
|
||||
AdminCommand::DeactivateUser {
|
||||
leave_rooms,
|
||||
|
@ -736,14 +755,15 @@ impl Service {
|
|||
} => {
|
||||
let user_id = Arc::<UserId>::from(user_id);
|
||||
if !services().users.exists(&user_id)? {
|
||||
RoomMessageEventContent::text_plain(format!(
|
||||
Some(RoomMessageEventContent::text_plain(format!(
|
||||
"User {user_id} doesn't exist on this server"
|
||||
))
|
||||
)))
|
||||
} else if user_id.server_name() != services().globals.server_name() {
|
||||
RoomMessageEventContent::text_plain(format!(
|
||||
Some(RoomMessageEventContent::text_plain(format!(
|
||||
"User {user_id} is not from this server"
|
||||
))
|
||||
)))
|
||||
} else {
|
||||
// FIXME: Why this is here!
|
||||
RoomMessageEventContent::text_plain(format!(
|
||||
"Making {user_id} leave all rooms before deactivation..."
|
||||
));
|
||||
|
@ -754,9 +774,9 @@ impl Service {
|
|||
leave_all_rooms(&user_id).await?;
|
||||
}
|
||||
|
||||
RoomMessageEventContent::text_plain(format!(
|
||||
Some(RoomMessageEventContent::text_plain(format!(
|
||||
"User {user_id} has been deactivated"
|
||||
))
|
||||
)))
|
||||
}
|
||||
}
|
||||
AdminCommand::DeactivateAll { leave_rooms, force } => {
|
||||
|
@ -821,10 +841,10 @@ impl Service {
|
|||
html_message.push_str("</pre>\n\n");
|
||||
}
|
||||
if !markdown_message.is_empty() {
|
||||
return Ok(RoomMessageEventContent::text_html(
|
||||
return Ok(Some(RoomMessageEventContent::text_html(
|
||||
markdown_message,
|
||||
html_message,
|
||||
));
|
||||
)));
|
||||
}
|
||||
|
||||
let mut deactivation_count = 0;
|
||||
|
@ -856,16 +876,16 @@ impl Service {
|
|||
}
|
||||
|
||||
if admins.is_empty() {
|
||||
RoomMessageEventContent::text_plain(format!(
|
||||
Some(RoomMessageEventContent::text_plain(format!(
|
||||
"Deactivated {deactivation_count} accounts."
|
||||
))
|
||||
)))
|
||||
} else {
|
||||
RoomMessageEventContent::text_plain(format!("Deactivated {} accounts.\nSkipped admin accounts: {:?}. Use --force to deactivate admin accounts", deactivation_count, admins.join(", ")))
|
||||
Some(RoomMessageEventContent::text_plain(format!("Deactivated {} accounts.\nSkipped admin accounts: {:?}. Use --force to deactivate admin accounts", deactivation_count, admins.join(", "))))
|
||||
}
|
||||
} else {
|
||||
RoomMessageEventContent::text_plain(
|
||||
Some(RoomMessageEventContent::text_plain(
|
||||
"Expected code block in command body. Add --help for details.",
|
||||
)
|
||||
))
|
||||
}
|
||||
}
|
||||
AdminCommand::SignJson => {
|
||||
|
@ -882,14 +902,16 @@ impl Service {
|
|||
.expect("our request json is what ruma expects");
|
||||
let json_text = serde_json::to_string_pretty(&value)
|
||||
.expect("canonical json is valid json");
|
||||
RoomMessageEventContent::text_plain(json_text)
|
||||
Some(RoomMessageEventContent::text_plain(json_text))
|
||||
}
|
||||
Err(e) => RoomMessageEventContent::text_plain(format!("Invalid json: {e}")),
|
||||
Err(e) => Some(RoomMessageEventContent::text_plain(format!(
|
||||
"Invalid json: {e}"
|
||||
))),
|
||||
}
|
||||
} else {
|
||||
RoomMessageEventContent::text_plain(
|
||||
Some(RoomMessageEventContent::text_plain(
|
||||
"Expected code block in command body. Add --help for details.",
|
||||
)
|
||||
))
|
||||
}
|
||||
}
|
||||
AdminCommand::VerifyJson => {
|
||||
|
@ -908,18 +930,22 @@ impl Service {
|
|||
|
||||
let pub_key_map = pub_key_map.read().await;
|
||||
match ruma::signatures::verify_json(&pub_key_map, &value) {
|
||||
Ok(_) => RoomMessageEventContent::text_plain("Signature correct"),
|
||||
Err(e) => RoomMessageEventContent::text_plain(format!(
|
||||
Ok(_) => {
|
||||
Some(RoomMessageEventContent::text_plain("Signature correct"))
|
||||
}
|
||||
Err(e) => Some(RoomMessageEventContent::text_plain(format!(
|
||||
"Signature verification failed: {e}"
|
||||
)),
|
||||
))),
|
||||
}
|
||||
}
|
||||
Err(e) => RoomMessageEventContent::text_plain(format!("Invalid json: {e}")),
|
||||
Err(e) => Some(RoomMessageEventContent::text_plain(format!(
|
||||
"Invalid json: {e}"
|
||||
))),
|
||||
}
|
||||
} else {
|
||||
RoomMessageEventContent::text_plain(
|
||||
Some(RoomMessageEventContent::text_plain(
|
||||
"Expected code block in command body. Add --help for details.",
|
||||
)
|
||||
))
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue