@@ -10,7 +10,12 @@ use crate::Context;
|
||||
#[implement(Context, params = "<'_>")]
|
||||
pub(super) async fn check_all_users(&self) -> Result {
|
||||
let timer = tokio::time::Instant::now();
|
||||
let users = self.services.users.iter().collect::<Vec<_>>().await;
|
||||
let users = self
|
||||
.services
|
||||
.users
|
||||
.iter()
|
||||
.collect::<Vec<_>>()
|
||||
.await;
|
||||
let query_time = timer.elapsed();
|
||||
|
||||
let total = users.len();
|
||||
|
||||
@@ -24,7 +24,10 @@ impl Context<'_> {
|
||||
) -> impl Future<Output = Result> + Send + '_ + use<'_> {
|
||||
let buf = format!("{arguments}");
|
||||
self.output.lock().then(async move |mut output| {
|
||||
output.write_all(buf.as_bytes()).map_err(Into::into).await
|
||||
output
|
||||
.write_all(buf.as_bytes())
|
||||
.map_err(Into::into)
|
||||
.await
|
||||
})
|
||||
}
|
||||
|
||||
@@ -33,7 +36,10 @@ impl Context<'_> {
|
||||
s: &'a str,
|
||||
) -> impl Future<Output = Result> + Send + 'a {
|
||||
self.output.lock().then(async move |mut output| {
|
||||
output.write_all(s.as_bytes()).map_err(Into::into).await
|
||||
output
|
||||
.write_all(s.as_bytes())
|
||||
.map_err(Into::into)
|
||||
.await
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,7 +37,13 @@ pub(super) async fn echo(&self, message: Vec<String>) -> Result {
|
||||
|
||||
#[admin_command]
|
||||
pub(super) async fn get_auth_chain(&self, event_id: OwnedEventId) -> Result {
|
||||
let Ok(event) = self.services.rooms.timeline.get_pdu_json(&event_id).await else {
|
||||
let Ok(event) = self
|
||||
.services
|
||||
.rooms
|
||||
.timeline
|
||||
.get_pdu_json(&event_id)
|
||||
.await
|
||||
else {
|
||||
return Err!("Event not found.");
|
||||
};
|
||||
|
||||
@@ -103,7 +109,12 @@ pub(super) async fn get_pdu(&self, event_id: OwnedEventId) -> Result {
|
||||
|
||||
if pdu_json.is_err() {
|
||||
outlier = true;
|
||||
pdu_json = self.services.rooms.timeline.get_pdu_json(&event_id).await;
|
||||
pdu_json = self
|
||||
.services
|
||||
.rooms
|
||||
.timeline
|
||||
.get_pdu_json(&event_id)
|
||||
.await;
|
||||
}
|
||||
|
||||
match pdu_json {
|
||||
@@ -361,7 +372,11 @@ pub(super) async fn force_device_list_updates(&self) -> Result {
|
||||
self.services
|
||||
.users
|
||||
.stream()
|
||||
.for_each(|user_id| self.services.users.mark_device_key_update(user_id))
|
||||
.for_each(|user_id| {
|
||||
self.services
|
||||
.users
|
||||
.mark_device_key_update(user_id)
|
||||
})
|
||||
.await;
|
||||
|
||||
write!(self, "Marked all devices for all users as having new keys to update").await
|
||||
@@ -407,7 +422,10 @@ pub(super) async fn change_log_level(&self, filter: Option<String>, reset: bool)
|
||||
.reload
|
||||
.reload(&new_filter_layer, Some(handles))
|
||||
{
|
||||
| Ok(()) => return self.write_str("Successfully changed log level").await,
|
||||
| Ok(()) =>
|
||||
return self
|
||||
.write_str("Successfully changed log level")
|
||||
.await,
|
||||
| Err(e) =>
|
||||
return Err!("Failed to modify and reload the global tracing log level: {e}"),
|
||||
}
|
||||
@@ -449,7 +467,12 @@ pub(super) async fn verify_json(&self) -> Result {
|
||||
let string = self.body[1..self.body.len().checked_sub(1).unwrap()].join("\n");
|
||||
match serde_json::from_str::<CanonicalJsonObject>(&string) {
|
||||
| Err(e) => return Err!("Invalid json: {e}"),
|
||||
| Ok(value) => match self.services.server_keys.verify_json(&value, None).await {
|
||||
| Ok(value) => match self
|
||||
.services
|
||||
.server_keys
|
||||
.verify_json(&value, None)
|
||||
.await
|
||||
{
|
||||
| Err(e) => return Err!("Signature verification failed: {e}"),
|
||||
| Ok(()) => write!(self, "Signature correct"),
|
||||
},
|
||||
@@ -461,10 +484,20 @@ pub(super) async fn verify_json(&self) -> Result {
|
||||
pub(super) async fn verify_pdu(&self, event_id: OwnedEventId) -> Result {
|
||||
use ruma::signatures::Verified;
|
||||
|
||||
let mut event = self.services.rooms.timeline.get_pdu_json(&event_id).await?;
|
||||
let mut event = self
|
||||
.services
|
||||
.rooms
|
||||
.timeline
|
||||
.get_pdu_json(&event_id)
|
||||
.await?;
|
||||
|
||||
event.remove("event_id");
|
||||
let msg = match self.services.server_keys.verify_event(&event, None).await {
|
||||
let msg = match self
|
||||
.services
|
||||
.server_keys
|
||||
.verify_event(&event, None)
|
||||
.await
|
||||
{
|
||||
| Err(e) => return Err(e),
|
||||
| Ok(Verified::Signatures) => "signatures OK, but content hash failed (redaction).",
|
||||
| Ok(Verified::All) => "signatures and hashes OK.",
|
||||
@@ -548,7 +581,12 @@ pub(super) async fn force_set_room_state_from_server(
|
||||
.await
|
||||
.map_err(|_| err!(Database("Failed to find the latest PDU in database")))?;
|
||||
|
||||
let room_version = self.services.rooms.state.get_room_version(&room_id).await?;
|
||||
let room_version = self
|
||||
.services
|
||||
.rooms
|
||||
.state
|
||||
.get_room_version(&room_id)
|
||||
.await?;
|
||||
|
||||
let mut state: HashMap<u64, OwnedEventId> = HashMap::new();
|
||||
|
||||
@@ -610,11 +648,14 @@ pub(super) async fn force_set_room_state_from_server(
|
||||
}
|
||||
|
||||
info!("Going through auth_chain response");
|
||||
for result in remote_state_response.auth_chain.iter().map(|pdu| {
|
||||
self.services
|
||||
.server_keys
|
||||
.validate_and_add_event_id(pdu, &room_version)
|
||||
}) {
|
||||
for result in remote_state_response
|
||||
.auth_chain
|
||||
.iter()
|
||||
.map(|pdu| {
|
||||
self.services
|
||||
.server_keys
|
||||
.validate_and_add_event_id(pdu, &room_version)
|
||||
}) {
|
||||
let Ok((event_id, value)) = result.await else {
|
||||
continue;
|
||||
};
|
||||
@@ -644,7 +685,13 @@ pub(super) async fn force_set_room_state_from_server(
|
||||
.save_state(room_id.clone().as_ref(), new_room_state)
|
||||
.await?;
|
||||
|
||||
let state_lock = self.services.rooms.state.mutex.lock(&*room_id).await;
|
||||
let state_lock = self
|
||||
.services
|
||||
.rooms
|
||||
.state
|
||||
.mutex
|
||||
.lock(&*room_id)
|
||||
.await;
|
||||
|
||||
self.services
|
||||
.rooms
|
||||
@@ -775,17 +822,22 @@ pub(super) async fn memory_stats(&self, opts: Option<String>) -> Result {
|
||||
#[cfg(tokio_unstable)]
|
||||
#[admin_command]
|
||||
pub(super) async fn runtime_metrics(&self) -> Result {
|
||||
let out = self.services.server.metrics.runtime_metrics().map_or_else(
|
||||
|| "Runtime metrics are not available.".to_owned(),
|
||||
|metrics| {
|
||||
format!(
|
||||
"```rs\nnum_workers: {}\nnum_alive_tasks: {}\nglobal_queue_depth: {}\n```",
|
||||
metrics.num_workers(),
|
||||
metrics.num_alive_tasks(),
|
||||
metrics.global_queue_depth()
|
||||
)
|
||||
},
|
||||
);
|
||||
let out = self
|
||||
.services
|
||||
.server
|
||||
.metrics
|
||||
.runtime_metrics()
|
||||
.map_or_else(
|
||||
|| "Runtime metrics are not available.".to_owned(),
|
||||
|metrics| {
|
||||
format!(
|
||||
"```rs\nnum_workers: {}\nnum_alive_tasks: {}\nglobal_queue_depth: {}\n```",
|
||||
metrics.num_workers(),
|
||||
metrics.num_alive_tasks(),
|
||||
metrics.global_queue_depth()
|
||||
)
|
||||
},
|
||||
);
|
||||
|
||||
self.write_str(&out).await
|
||||
}
|
||||
@@ -800,10 +852,15 @@ pub(super) async fn runtime_metrics(&self) -> Result {
|
||||
#[cfg(tokio_unstable)]
|
||||
#[admin_command]
|
||||
pub(super) async fn runtime_interval(&self) -> Result {
|
||||
let out = self.services.server.metrics.runtime_interval().map_or_else(
|
||||
|| "Runtime metrics are not available.".to_owned(),
|
||||
|metrics| format!("```rs\n{metrics:#?}\n```"),
|
||||
);
|
||||
let out = self
|
||||
.services
|
||||
.server
|
||||
.metrics
|
||||
.runtime_interval()
|
||||
.map_or_else(
|
||||
|| "Runtime metrics are not available.".to_owned(),
|
||||
|metrics| format!("```rs\n{metrics:#?}\n```"),
|
||||
);
|
||||
|
||||
self.write_str(&out).await
|
||||
}
|
||||
@@ -871,7 +928,12 @@ pub(super) async fn database_stats(
|
||||
|
||||
#[admin_command]
|
||||
pub(super) async fn database_files(&self, map: Option<String>, level: Option<i32>) -> Result {
|
||||
let mut files: Vec<_> = self.services.db.db.file_list().collect::<Result<_>>()?;
|
||||
let mut files: Vec<_> = self
|
||||
.services
|
||||
.db
|
||||
.db
|
||||
.file_list()
|
||||
.collect::<Result<_>>()?;
|
||||
|
||||
files.sort_by_key(|f| f.name.clone());
|
||||
|
||||
@@ -883,7 +945,11 @@ pub(super) async fn database_files(&self, map: Option<String>, level: Option<i32
|
||||
map.as_deref()
|
||||
.is_none_or(|map| map == file.column_family_name)
|
||||
})
|
||||
.filter(|file| level.as_ref().is_none_or(|&level| level == file.level))
|
||||
.filter(|file| {
|
||||
level
|
||||
.as_ref()
|
||||
.is_none_or(|&level| level == file.level)
|
||||
})
|
||||
.try_stream()
|
||||
.try_for_each(|file| {
|
||||
writeln!(
|
||||
|
||||
@@ -8,13 +8,19 @@ use crate::{admin_command, get_room_info};
|
||||
|
||||
#[admin_command]
|
||||
pub(super) async fn disable_room(&self, room_id: OwnedRoomId) -> Result {
|
||||
self.services.rooms.metadata.disable_room(&room_id, true);
|
||||
self.services
|
||||
.rooms
|
||||
.metadata
|
||||
.disable_room(&room_id, true);
|
||||
self.write_str("Room disabled.").await
|
||||
}
|
||||
|
||||
#[admin_command]
|
||||
pub(super) async fn enable_room(&self, room_id: OwnedRoomId) -> Result {
|
||||
self.services.rooms.metadata.disable_room(&room_id, false);
|
||||
self.services
|
||||
.rooms
|
||||
.metadata
|
||||
.disable_room(&room_id, false);
|
||||
self.write_str("Room enabled.").await
|
||||
}
|
||||
|
||||
|
||||
@@ -35,7 +35,13 @@ pub(super) async fn delete(
|
||||
let mut mxc_urls = Vec::with_capacity(4);
|
||||
|
||||
// parsing the PDU for any MXC URLs begins here
|
||||
match self.services.rooms.timeline.get_pdu_json(&event_id).await {
|
||||
match self
|
||||
.services
|
||||
.rooms
|
||||
.timeline
|
||||
.get_pdu_json(&event_id)
|
||||
.await
|
||||
{
|
||||
| Ok(event_json) => {
|
||||
if let Some(content_key) = event_json.get("content") {
|
||||
debug!("Event ID has \"content\".");
|
||||
@@ -255,7 +261,11 @@ pub(super) async fn delete_past_remote_media(
|
||||
pub(super) async fn delete_all_from_user(&self, username: String) -> Result {
|
||||
let user_id = parse_local_user_id(self.services, &username)?;
|
||||
|
||||
let deleted_count = self.services.media.delete_from_user(&user_id).await?;
|
||||
let deleted_count = self
|
||||
.services
|
||||
.media
|
||||
.delete_from_user(&user_id)
|
||||
.await?;
|
||||
|
||||
self.write_str(&format!("Deleted {deleted_count} total files.",))
|
||||
.await
|
||||
@@ -294,7 +304,10 @@ pub(super) async fn delete_all_from_server(
|
||||
};
|
||||
|
||||
if mxc_server_name != server_name
|
||||
|| (self.services.globals.server_is_ours(mxc_server_name)
|
||||
|| (self
|
||||
.services
|
||||
.globals
|
||||
.server_is_ours(mxc_server_name)
|
||||
&& !yes_i_want_to_delete_local_media)
|
||||
{
|
||||
trace!("skipping MXC URI {mxc}");
|
||||
@@ -323,7 +336,8 @@ pub(super) async fn get_file_info(&self, mxc: OwnedMxcUri) -> Result {
|
||||
let mxc: Mxc<'_> = mxc.as_str().try_into()?;
|
||||
let metadata = self.services.media.get_metadata(&mxc).await;
|
||||
|
||||
self.write_str(&format!("```\n{metadata:#?}\n```")).await
|
||||
self.write_str(&format!("```\n{metadata:#?}\n```"))
|
||||
.await
|
||||
}
|
||||
|
||||
#[admin_command]
|
||||
|
||||
@@ -69,7 +69,10 @@ async fn process_command(services: Arc<Services>, input: &CommandInput) -> Proce
|
||||
let (result, mut logs) = process(&context, command, &args).await;
|
||||
|
||||
let output = &mut context.output.lock().await;
|
||||
output.flush().await.expect("final flush of output stream");
|
||||
output
|
||||
.flush()
|
||||
.await
|
||||
.expect("final flush of output stream");
|
||||
|
||||
let output =
|
||||
String::from_utf8(take(output.get_mut())).expect("invalid utf8 in command output stream");
|
||||
@@ -79,7 +82,8 @@ async fn process_command(services: Arc<Services>, input: &CommandInput) -> Proce
|
||||
Ok(Some(reply(RoomMessageEventContent::notice_markdown(output), context.reply_id))),
|
||||
|
||||
| Ok(()) => {
|
||||
logs.write_str(output.as_str()).expect("output buffer");
|
||||
logs.write_str(output.as_str())
|
||||
.expect("output buffer");
|
||||
Ok(Some(reply(RoomMessageEventContent::notice_markdown(logs), context.reply_id)))
|
||||
},
|
||||
| Err(error) => {
|
||||
@@ -172,8 +176,14 @@ fn parse<'a>(
|
||||
services: &Arc<Services>,
|
||||
input: &'a CommandInput,
|
||||
) -> Result<(AdminCommand, Vec<String>, Vec<&'a str>), CommandOutput> {
|
||||
let lines = input.command.lines().filter(|line| !line.trim().is_empty());
|
||||
let command_line = lines.clone().next().expect("command missing first line");
|
||||
let lines = input
|
||||
.command
|
||||
.lines()
|
||||
.filter(|line| !line.trim().is_empty());
|
||||
let command_line = lines
|
||||
.clone()
|
||||
.next()
|
||||
.expect("command missing first line");
|
||||
let body = lines.skip(1).collect();
|
||||
match parse_command(command_line) {
|
||||
| Ok((command, args)) => Ok((command, args, body)),
|
||||
|
||||
@@ -24,7 +24,10 @@ pub(super) async fn process(subcommand: AppserviceCommand, context: &Context<'_>
|
||||
match subcommand {
|
||||
| AppserviceCommand::GetRegistration { appservice_id } => {
|
||||
let timer = tokio::time::Instant::now();
|
||||
let results = services.appservice.get_registration(&appservice_id).await;
|
||||
let results = services
|
||||
.appservice
|
||||
.get_registration(&appservice_id)
|
||||
.await;
|
||||
|
||||
let query_time = timer.elapsed();
|
||||
|
||||
@@ -32,7 +35,11 @@ pub(super) async fn process(subcommand: AppserviceCommand, context: &Context<'_>
|
||||
},
|
||||
| AppserviceCommand::All => {
|
||||
let timer = tokio::time::Instant::now();
|
||||
let results: Vec<_> = services.appservice.iter_db_ids().try_collect().await?;
|
||||
let results: Vec<_> = services
|
||||
.appservice
|
||||
.iter_db_ids()
|
||||
.try_collect()
|
||||
.await?;
|
||||
let query_time = timer.elapsed();
|
||||
|
||||
write!(context, "Query completed in {query_time:?}:\n\n```rs\n{results:#?}\n```")
|
||||
|
||||
@@ -39,7 +39,10 @@ pub(super) async fn process(subcommand: GlobalsCommand, context: &Context<'_>) -
|
||||
},
|
||||
| GlobalsCommand::SigningKeysFor { origin } => {
|
||||
let timer = tokio::time::Instant::now();
|
||||
let results = services.server_keys.verify_keys_for(&origin).await;
|
||||
let results = services
|
||||
.server_keys
|
||||
.verify_keys_for(&origin)
|
||||
.await;
|
||||
let query_time = timer.elapsed();
|
||||
|
||||
write!(context, "Query completed in {query_time:?}:\n\n```rs\n{results:#?}\n```")
|
||||
|
||||
@@ -194,8 +194,13 @@ pub(super) async fn compact(
|
||||
}
|
||||
|
||||
let range = (
|
||||
start.as_ref().map(String::as_bytes).map(Into::into),
|
||||
stop.as_ref().map(String::as_bytes).map(Into::into),
|
||||
start
|
||||
.as_ref()
|
||||
.map(String::as_bytes)
|
||||
.map(Into::into),
|
||||
stop.as_ref()
|
||||
.map(String::as_bytes)
|
||||
.map(Into::into),
|
||||
);
|
||||
|
||||
let options = Options {
|
||||
@@ -429,7 +434,13 @@ pub(super) async fn raw_get(&self, map: String, key: String) -> Result {
|
||||
|
||||
#[admin_command]
|
||||
pub(super) async fn raw_maps(&self) -> Result {
|
||||
let list: Vec<_> = self.services.db.iter().map(at!(0)).copied().collect();
|
||||
let list: Vec<_> = self
|
||||
.services
|
||||
.db
|
||||
.iter()
|
||||
.map(at!(0))
|
||||
.copied()
|
||||
.collect();
|
||||
|
||||
self.write_str(&format!("{list:#?}")).await
|
||||
}
|
||||
|
||||
@@ -27,7 +27,12 @@ async fn destinations_cache(&self, server_name: Option<OwnedServerName>) -> Resu
|
||||
writeln!(self, "| Server Name | Destination | Hostname | Expires |").await?;
|
||||
writeln!(self, "| ----------- | ----------- | -------- | ------- |").await?;
|
||||
|
||||
let mut destinations = self.services.resolver.cache.destinations().boxed();
|
||||
let mut destinations = self
|
||||
.services
|
||||
.resolver
|
||||
.cache
|
||||
.destinations()
|
||||
.boxed();
|
||||
|
||||
while let Some((name, CachedDest { dest, host, expire })) = destinations.next().await {
|
||||
if let Some(server_name) = server_name.as_ref() {
|
||||
|
||||
@@ -30,7 +30,11 @@ pub(super) async fn process(subcommand: RoomAliasCommand, context: &Context<'_>)
|
||||
match subcommand {
|
||||
| RoomAliasCommand::ResolveLocalAlias { alias } => {
|
||||
let timer = tokio::time::Instant::now();
|
||||
let results = services.rooms.alias.resolve_local_alias(&alias).await;
|
||||
let results = services
|
||||
.rooms
|
||||
.alias
|
||||
.resolve_local_alias(&alias)
|
||||
.await;
|
||||
let query_time = timer.elapsed();
|
||||
|
||||
write!(context, "Query completed in {query_time:?}:\n\n```rs\n{results:#?}\n```")
|
||||
|
||||
@@ -182,7 +182,11 @@ pub(super) async fn process(subcommand: RoomStateCacheCommand, context: &Context
|
||||
},
|
||||
| RoomStateCacheCommand::RoomJoinedCount { room_id } => {
|
||||
let timer = tokio::time::Instant::now();
|
||||
let results = services.rooms.state_cache.room_joined_count(&room_id).await;
|
||||
let results = services
|
||||
.rooms
|
||||
.state_cache
|
||||
.room_joined_count(&room_id)
|
||||
.await;
|
||||
let query_time = timer.elapsed();
|
||||
|
||||
context
|
||||
|
||||
@@ -25,7 +25,12 @@ pub(crate) enum RoomTimelineCommand {
|
||||
|
||||
#[admin_command]
|
||||
pub(super) async fn last(&self, room_id: OwnedRoomOrAliasId) -> Result {
|
||||
let room_id = self.services.rooms.alias.resolve(&room_id).await?;
|
||||
let room_id = self
|
||||
.services
|
||||
.rooms
|
||||
.alias
|
||||
.resolve(&room_id)
|
||||
.await?;
|
||||
|
||||
let result = self
|
||||
.services
|
||||
@@ -44,7 +49,12 @@ pub(super) async fn pdus(
|
||||
from: Option<String>,
|
||||
limit: Option<usize>,
|
||||
) -> Result {
|
||||
let room_id = self.services.rooms.alias.resolve(&room_id).await?;
|
||||
let room_id = self
|
||||
.services
|
||||
.rooms
|
||||
.alias
|
||||
.resolve(&room_id)
|
||||
.await?;
|
||||
|
||||
let from: Option<PduCount> = from.as_deref().map(str::parse).transpose()?;
|
||||
|
||||
|
||||
@@ -223,7 +223,11 @@ pub(super) async fn process(subcommand: SendingCommand, context: &Context<'_>) -
|
||||
},
|
||||
| SendingCommand::GetLatestEduCount { server_name } => {
|
||||
let timer = tokio::time::Instant::now();
|
||||
let results = services.sending.db.get_latest_educount(&server_name).await;
|
||||
let results = services
|
||||
.sending
|
||||
.db
|
||||
.get_latest_educount(&server_name)
|
||||
.await;
|
||||
let query_time = timer.elapsed();
|
||||
|
||||
context
|
||||
|
||||
@@ -31,9 +31,19 @@ pub(super) async fn short_event_id(&self, event_id: OwnedEventId) -> Result {
|
||||
|
||||
#[admin_command]
|
||||
pub(super) async fn short_room_id(&self, room_id: OwnedRoomOrAliasId) -> Result {
|
||||
let room_id = self.services.rooms.alias.resolve(&room_id).await?;
|
||||
let room_id = self
|
||||
.services
|
||||
.rooms
|
||||
.alias
|
||||
.resolve(&room_id)
|
||||
.await?;
|
||||
|
||||
let shortid = self.services.rooms.short.get_shortroomid(&room_id).await?;
|
||||
let shortid = self
|
||||
.services
|
||||
.rooms
|
||||
.short
|
||||
.get_shortroomid(&room_id)
|
||||
.await?;
|
||||
|
||||
self.write_str(&format!("{shortid:#?}")).await
|
||||
}
|
||||
|
||||
@@ -155,7 +155,11 @@ async fn get_room_backups(
|
||||
#[admin_command]
|
||||
async fn get_all_backups(&self, user_id: OwnedUserId, version: String) -> Result {
|
||||
let timer = tokio::time::Instant::now();
|
||||
let result = self.services.key_backups.get_all(&user_id, &version).await;
|
||||
let result = self
|
||||
.services
|
||||
.key_backups
|
||||
.get_all(&user_id, &version)
|
||||
.await;
|
||||
let query_time = timer.elapsed();
|
||||
|
||||
self.write_str(&format!("Query completed in {query_time:?}:\n\n```rs\n{result:#?}\n```"))
|
||||
@@ -193,7 +197,11 @@ async fn get_latest_backup_version(&self, user_id: OwnedUserId) -> Result {
|
||||
#[admin_command]
|
||||
async fn get_latest_backup(&self, user_id: OwnedUserId) -> Result {
|
||||
let timer = tokio::time::Instant::now();
|
||||
let result = self.services.key_backups.get_latest_backup(&user_id).await;
|
||||
let result = self
|
||||
.services
|
||||
.key_backups
|
||||
.get_latest_backup(&user_id)
|
||||
.await;
|
||||
let query_time = timer.elapsed();
|
||||
|
||||
self.write_str(&format!("Query completed in {query_time:?}:\n\n```rs\n{result:#?}\n```"))
|
||||
@@ -203,7 +211,13 @@ async fn get_latest_backup(&self, user_id: OwnedUserId) -> Result {
|
||||
#[admin_command]
|
||||
async fn iter_users(&self) -> Result {
|
||||
let timer = tokio::time::Instant::now();
|
||||
let result: Vec<OwnedUserId> = self.services.users.stream().map(Into::into).collect().await;
|
||||
let result: Vec<OwnedUserId> = self
|
||||
.services
|
||||
.users
|
||||
.stream()
|
||||
.map(Into::into)
|
||||
.collect()
|
||||
.await;
|
||||
|
||||
let query_time = timer.elapsed();
|
||||
|
||||
@@ -296,7 +310,11 @@ async fn get_device_metadata(&self, user_id: OwnedUserId, device_id: OwnedDevice
|
||||
#[admin_command]
|
||||
async fn get_devices_version(&self, user_id: OwnedUserId) -> Result {
|
||||
let timer = tokio::time::Instant::now();
|
||||
let device = self.services.users.get_devicelist_version(&user_id).await;
|
||||
let device = self
|
||||
.services
|
||||
.users
|
||||
.get_devicelist_version(&user_id)
|
||||
.await;
|
||||
let query_time = timer.elapsed();
|
||||
|
||||
self.write_str(&format!("Query completed in {query_time:?}:\n\n```rs\n{device:#?}\n```"))
|
||||
@@ -334,7 +352,11 @@ async fn get_device_keys(&self, user_id: OwnedUserId, device_id: OwnedDeviceId)
|
||||
#[admin_command]
|
||||
async fn get_user_signing_key(&self, user_id: OwnedUserId) -> Result {
|
||||
let timer = tokio::time::Instant::now();
|
||||
let result = self.services.users.get_user_signing_key(&user_id).await;
|
||||
let result = self
|
||||
.services
|
||||
.users
|
||||
.get_user_signing_key(&user_id)
|
||||
.await;
|
||||
let query_time = timer.elapsed();
|
||||
|
||||
self.write_str(&format!("Query completed in {query_time:?}:\n\n```rs\n{result:#?}\n```"))
|
||||
|
||||
@@ -60,7 +60,14 @@ pub(super) async fn process(command: RoomAliasCommand, context: &Context<'_>) ->
|
||||
};
|
||||
match command {
|
||||
| RoomAliasCommand::Set { force, room_id, .. } => {
|
||||
match (force, services.rooms.alias.resolve_local_alias(&room_alias).await) {
|
||||
match (
|
||||
force,
|
||||
services
|
||||
.rooms
|
||||
.alias
|
||||
.resolve_local_alias(&room_alias)
|
||||
.await,
|
||||
) {
|
||||
| (true, Ok(id)) => {
|
||||
match services.rooms.alias.set_alias(
|
||||
&room_alias,
|
||||
@@ -93,7 +100,12 @@ pub(super) async fn process(command: RoomAliasCommand, context: &Context<'_>) ->
|
||||
}
|
||||
},
|
||||
| RoomAliasCommand::Remove { .. } => {
|
||||
match services.rooms.alias.resolve_local_alias(&room_alias).await {
|
||||
match services
|
||||
.rooms
|
||||
.alias
|
||||
.resolve_local_alias(&room_alias)
|
||||
.await
|
||||
{
|
||||
| Err(_) => Err!("Alias isn't in use."),
|
||||
| Ok(id) => match services
|
||||
.rooms
|
||||
@@ -103,14 +115,24 @@ pub(super) async fn process(command: RoomAliasCommand, context: &Context<'_>) ->
|
||||
{
|
||||
| Err(err) => Err!("Failed to remove alias: {err}"),
|
||||
| Ok(()) =>
|
||||
context.write_str(&format!("Removed alias from {id}")).await,
|
||||
context
|
||||
.write_str(&format!("Removed alias from {id}"))
|
||||
.await,
|
||||
},
|
||||
}
|
||||
},
|
||||
| RoomAliasCommand::Which { .. } => {
|
||||
match services.rooms.alias.resolve_local_alias(&room_alias).await {
|
||||
match services
|
||||
.rooms
|
||||
.alias
|
||||
.resolve_local_alias(&room_alias)
|
||||
.await
|
||||
{
|
||||
| Err(_) => Err!("Alias isn't in use."),
|
||||
| Ok(id) => context.write_str(&format!("Alias resolves to {id}")).await,
|
||||
| Ok(id) =>
|
||||
context
|
||||
.write_str(&format!("Alias resolves to {id}"))
|
||||
.await,
|
||||
}
|
||||
},
|
||||
| RoomAliasCommand::List { .. } => unreachable!(),
|
||||
@@ -126,11 +148,13 @@ pub(super) async fn process(command: RoomAliasCommand, context: &Context<'_>) ->
|
||||
.collect()
|
||||
.await;
|
||||
|
||||
let plain_list = aliases.iter().fold(String::new(), |mut output, alias| {
|
||||
writeln!(output, "- {alias}")
|
||||
.expect("should be able to write to string buffer");
|
||||
output
|
||||
});
|
||||
let plain_list = aliases
|
||||
.iter()
|
||||
.fold(String::new(), |mut output, alias| {
|
||||
writeln!(output, "- {alias}")
|
||||
.expect("should be able to write to string buffer");
|
||||
output
|
||||
});
|
||||
|
||||
let plain = format!("Aliases for {room_id}:\n{plain_list}");
|
||||
context.write_str(&plain).await
|
||||
|
||||
@@ -20,11 +20,23 @@ pub(super) async fn list_rooms(
|
||||
.metadata
|
||||
.iter_ids()
|
||||
.filter_map(|room_id| async move {
|
||||
(!exclude_disabled || !self.services.rooms.metadata.is_disabled(room_id).await)
|
||||
(!exclude_disabled
|
||||
|| !self
|
||||
.services
|
||||
.rooms
|
||||
.metadata
|
||||
.is_disabled(room_id)
|
||||
.await)
|
||||
.then_some(room_id)
|
||||
})
|
||||
.filter_map(|room_id| async move {
|
||||
(!exclude_banned || !self.services.rooms.metadata.is_banned(room_id).await)
|
||||
(!exclude_banned
|
||||
|| !self
|
||||
.services
|
||||
.rooms
|
||||
.metadata
|
||||
.is_banned(room_id)
|
||||
.await)
|
||||
.then_some(room_id)
|
||||
})
|
||||
.then(|room_id| get_room_info(self.services, room_id))
|
||||
@@ -62,7 +74,12 @@ pub(super) async fn list_rooms(
|
||||
|
||||
#[admin_command]
|
||||
pub(super) async fn exists(&self, room_id: OwnedRoomId) -> Result {
|
||||
let result = self.services.rooms.metadata.exists(&room_id).await;
|
||||
let result = self
|
||||
.services
|
||||
.rooms
|
||||
.metadata
|
||||
.exists(&room_id)
|
||||
.await;
|
||||
|
||||
self.write_str(&format!("{result}")).await
|
||||
}
|
||||
|
||||
@@ -70,7 +70,10 @@ async fn ban_room(&self, room: OwnedRoomOrAliasId) -> Result {
|
||||
};
|
||||
|
||||
debug!("Room specified is a room ID, banning room ID");
|
||||
self.services.rooms.metadata.ban_room(room_id, true);
|
||||
self.services
|
||||
.rooms
|
||||
.metadata
|
||||
.ban_room(room_id, true);
|
||||
|
||||
room_id.to_owned()
|
||||
} else if room.is_room_alias_id() {
|
||||
@@ -128,7 +131,10 @@ async fn ban_room(&self, room: OwnedRoomOrAliasId) -> Result {
|
||||
},
|
||||
};
|
||||
|
||||
self.services.rooms.metadata.ban_room(&room_id, true);
|
||||
self.services
|
||||
.rooms
|
||||
.metadata
|
||||
.ban_room(&room_id, true);
|
||||
|
||||
room_id
|
||||
} else {
|
||||
@@ -159,7 +165,10 @@ async fn ban_room(&self, room: OwnedRoomOrAliasId) -> Result {
|
||||
warn!("Failed to leave room: {e}");
|
||||
}
|
||||
|
||||
self.services.rooms.state_cache.forget(&room_id, user_id);
|
||||
self.services
|
||||
.rooms
|
||||
.state_cache
|
||||
.forget(&room_id, user_id);
|
||||
}
|
||||
|
||||
self.services
|
||||
@@ -178,9 +187,15 @@ async fn ban_room(&self, room: OwnedRoomOrAliasId) -> Result {
|
||||
.await;
|
||||
|
||||
// unpublish from room directory
|
||||
self.services.rooms.directory.set_not_public(&room_id);
|
||||
self.services
|
||||
.rooms
|
||||
.directory
|
||||
.set_not_public(&room_id);
|
||||
|
||||
self.services.rooms.metadata.disable_room(&room_id, true);
|
||||
self.services
|
||||
.rooms
|
||||
.metadata
|
||||
.disable_room(&room_id, true);
|
||||
|
||||
self.write_str(
|
||||
"Room banned, removed all our local users, and disabled incoming federation with room.",
|
||||
@@ -302,7 +317,10 @@ async fn ban_list_of_rooms(&self) -> Result {
|
||||
}
|
||||
|
||||
for room_id in room_ids {
|
||||
self.services.rooms.metadata.ban_room(&room_id, true);
|
||||
self.services
|
||||
.rooms
|
||||
.metadata
|
||||
.ban_room(&room_id, true);
|
||||
|
||||
debug!("Banned {room_id} successfully");
|
||||
room_ban_count = room_ban_count.saturating_add(1);
|
||||
@@ -327,7 +345,10 @@ async fn ban_list_of_rooms(&self) -> Result {
|
||||
warn!("Failed to leave room: {e}");
|
||||
}
|
||||
|
||||
self.services.rooms.state_cache.forget(&room_id, user_id);
|
||||
self.services
|
||||
.rooms
|
||||
.state_cache
|
||||
.forget(&room_id, user_id);
|
||||
}
|
||||
|
||||
// remove any local aliases, ignore errors
|
||||
@@ -347,9 +368,15 @@ async fn ban_list_of_rooms(&self) -> Result {
|
||||
.await;
|
||||
|
||||
// unpublish from room directory, ignore errors
|
||||
self.services.rooms.directory.set_not_public(&room_id);
|
||||
self.services
|
||||
.rooms
|
||||
.directory
|
||||
.set_not_public(&room_id);
|
||||
|
||||
self.services.rooms.metadata.disable_room(&room_id, true);
|
||||
self.services
|
||||
.rooms
|
||||
.metadata
|
||||
.disable_room(&room_id, true);
|
||||
}
|
||||
|
||||
self.write_str(&format!(
|
||||
@@ -374,7 +401,10 @@ async fn unban_room(&self, room: OwnedRoomOrAliasId) -> Result {
|
||||
};
|
||||
|
||||
debug!("Room specified is a room ID, unbanning room ID");
|
||||
self.services.rooms.metadata.ban_room(room_id, false);
|
||||
self.services
|
||||
.rooms
|
||||
.metadata
|
||||
.ban_room(room_id, false);
|
||||
|
||||
room_id.to_owned()
|
||||
} else if room.is_room_alias_id() {
|
||||
@@ -430,7 +460,10 @@ async fn unban_room(&self, room: OwnedRoomOrAliasId) -> Result {
|
||||
},
|
||||
};
|
||||
|
||||
self.services.rooms.metadata.ban_room(&room_id, false);
|
||||
self.services
|
||||
.rooms
|
||||
.metadata
|
||||
.ban_room(&room_id, false);
|
||||
|
||||
room_id
|
||||
} else {
|
||||
@@ -441,7 +474,10 @@ async fn unban_room(&self, room: OwnedRoomOrAliasId) -> Result {
|
||||
);
|
||||
};
|
||||
|
||||
self.services.rooms.metadata.disable_room(&room_id, false);
|
||||
self.services
|
||||
.rooms
|
||||
.metadata
|
||||
.disable_room(&room_id, false);
|
||||
self.write_str("Room unbanned and federation re-enabled.")
|
||||
.await
|
||||
}
|
||||
|
||||
@@ -82,7 +82,14 @@ pub(super) async fn create_user(&self, username: String, password: Option<String
|
||||
.new_user_displayname_suffix
|
||||
.is_empty()
|
||||
{
|
||||
write!(displayname, " {}", self.services.server.config.new_user_displayname_suffix)?;
|
||||
write!(
|
||||
displayname,
|
||||
" {}",
|
||||
self.services
|
||||
.server
|
||||
.config
|
||||
.new_user_displayname_suffix
|
||||
)?;
|
||||
}
|
||||
|
||||
self.services
|
||||
@@ -106,7 +113,13 @@ pub(super) async fn create_user(&self, username: String, password: Option<String
|
||||
)
|
||||
.await?;
|
||||
|
||||
if !self.services.server.config.auto_join_rooms.is_empty() {
|
||||
if !self
|
||||
.services
|
||||
.server
|
||||
.config
|
||||
.auto_join_rooms
|
||||
.is_empty()
|
||||
{
|
||||
for room in &self.services.server.config.auto_join_rooms {
|
||||
let Ok(room_id) = self.services.rooms.alias.resolve(room).await else {
|
||||
error!(
|
||||
@@ -178,7 +191,10 @@ pub(super) async fn create_user(&self, username: String, password: Option<String
|
||||
.await
|
||||
.is_ok_and(is_equal_to!(1))
|
||||
{
|
||||
self.services.admin.make_user_admin(&user_id).await?;
|
||||
self.services
|
||||
.admin
|
||||
.make_user_admin(&user_id)
|
||||
.await?;
|
||||
warn!("Granting {user_id} admin privileges as the first user");
|
||||
}
|
||||
} else {
|
||||
@@ -199,7 +215,10 @@ pub(super) async fn deactivate(&self, no_leave_rooms: bool, user_id: String) ->
|
||||
return Err!("Not allowed to deactivate the server service account.",);
|
||||
}
|
||||
|
||||
self.services.users.deactivate_account(&user_id).await?;
|
||||
self.services
|
||||
.users
|
||||
.deactivate_account(&user_id)
|
||||
.await?;
|
||||
|
||||
if !no_leave_rooms {
|
||||
self.services
|
||||
@@ -312,7 +331,12 @@ pub(super) async fn deactivate_all(&self, no_leave_rooms: bool, force: bool) ->
|
||||
let mut deactivation_count: usize = 0;
|
||||
|
||||
for user_id in user_ids {
|
||||
match self.services.users.deactivate_account(&user_id).await {
|
||||
match self
|
||||
.services
|
||||
.users
|
||||
.deactivate_account(&user_id)
|
||||
.await
|
||||
{
|
||||
| Err(e) => {
|
||||
self.services
|
||||
.admin
|
||||
@@ -640,7 +664,12 @@ pub(super) async fn force_leave_room(
|
||||
room_id: OwnedRoomOrAliasId,
|
||||
) -> Result {
|
||||
let user_id = parse_local_user_id(self.services, &user_id)?;
|
||||
let room_id = self.services.rooms.alias.resolve(&room_id).await?;
|
||||
let room_id = self
|
||||
.services
|
||||
.rooms
|
||||
.alias
|
||||
.resolve(&room_id)
|
||||
.await?;
|
||||
|
||||
assert!(
|
||||
self.services.globals.user_is_local(&user_id),
|
||||
@@ -666,14 +695,25 @@ pub(super) async fn force_leave_room(
|
||||
#[admin_command]
|
||||
pub(super) async fn force_demote(&self, user_id: String, room_id: OwnedRoomOrAliasId) -> Result {
|
||||
let user_id = parse_local_user_id(self.services, &user_id)?;
|
||||
let room_id = self.services.rooms.alias.resolve(&room_id).await?;
|
||||
let room_id = self
|
||||
.services
|
||||
.rooms
|
||||
.alias
|
||||
.resolve(&room_id)
|
||||
.await?;
|
||||
|
||||
assert!(
|
||||
self.services.globals.user_is_local(&user_id),
|
||||
"Parsed user_id must be a local user"
|
||||
);
|
||||
|
||||
let state_lock = self.services.rooms.state.mutex.lock(&room_id).await;
|
||||
let state_lock = self
|
||||
.services
|
||||
.rooms
|
||||
.state
|
||||
.mutex
|
||||
.lock(&room_id)
|
||||
.await;
|
||||
|
||||
let room_power_levels: Option<RoomPowerLevelsEventContent> = self
|
||||
.services
|
||||
@@ -730,7 +770,10 @@ pub(super) async fn make_user_admin(&self, user_id: String) -> Result {
|
||||
"Parsed user_id must be a local user"
|
||||
);
|
||||
|
||||
self.services.admin.make_user_admin(&user_id).await?;
|
||||
self.services
|
||||
.admin
|
||||
.make_user_admin(&user_id)
|
||||
.await?;
|
||||
|
||||
self.write_str(&format!("{user_id} has been granted admin privileges.",))
|
||||
.await
|
||||
@@ -793,7 +836,10 @@ pub(super) async fn delete_room_tag(
|
||||
content: TagEventContent { tags: BTreeMap::new() },
|
||||
});
|
||||
|
||||
tags_event.content.tags.remove(&tag.clone().into());
|
||||
tags_event
|
||||
.content
|
||||
.tags
|
||||
.remove(&tag.clone().into());
|
||||
|
||||
self.services
|
||||
.account_data
|
||||
@@ -858,7 +904,13 @@ pub(super) async fn redact_event(&self, event_id: OwnedEventId) -> Result {
|
||||
);
|
||||
|
||||
let redaction_event_id = {
|
||||
let state_lock = self.services.rooms.state.mutex.lock(&room_id).await;
|
||||
let state_lock = self
|
||||
.services
|
||||
.rooms
|
||||
.state
|
||||
.mutex
|
||||
.lock(&room_id)
|
||||
.await;
|
||||
|
||||
self.services
|
||||
.rooms
|
||||
|
||||
Reference in New Issue
Block a user