@@ -1,5 +1,5 @@
|
||||
array_width = 80
|
||||
chain_width = 60
|
||||
chain_width = 50
|
||||
comment_width = 80
|
||||
condense_wildcard_suffixes = true
|
||||
style_edition = "2024"
|
||||
|
||||
@@ -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,7 +648,10 @@ 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| {
|
||||
for result in remote_state_response
|
||||
.auth_chain
|
||||
.iter()
|
||||
.map(|pdu| {
|
||||
self.services
|
||||
.server_keys
|
||||
.validate_and_add_event_id(pdu, &room_version)
|
||||
@@ -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,7 +822,12 @@ 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(
|
||||
let out = self
|
||||
.services
|
||||
.server
|
||||
.metrics
|
||||
.runtime_metrics()
|
||||
.map_or_else(
|
||||
|| "Runtime metrics are not available.".to_owned(),
|
||||
|metrics| {
|
||||
format!(
|
||||
@@ -800,7 +852,12 @@ 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(
|
||||
let out = self
|
||||
.services
|
||||
.server
|
||||
.metrics
|
||||
.runtime_interval()
|
||||
.map_or_else(
|
||||
|| "Runtime metrics are not available.".to_owned(),
|
||||
|metrics| format!("```rs\n{metrics:#?}\n```"),
|
||||
);
|
||||
@@ -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,7 +148,9 @@ pub(super) async fn process(command: RoomAliasCommand, context: &Context<'_>) ->
|
||||
.collect()
|
||||
.await;
|
||||
|
||||
let plain_list = aliases.iter().fold(String::new(), |mut output, alias| {
|
||||
let plain_list = aliases
|
||||
.iter()
|
||||
.fold(String::new(), |mut output, alias| {
|
||||
writeln!(output, "- {alias}")
|
||||
.expect("should be able to write to string buffer");
|
||||
output
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -57,10 +57,19 @@ pub(crate) async fn get_register_available_route(
|
||||
body: Ruma<get_username_availability::v3::Request>,
|
||||
) -> Result<get_username_availability::v3::Response> {
|
||||
// workaround for https://github.com/matrix-org/matrix-appservice-irc/issues/1780 due to inactivity of fixing the issue
|
||||
let is_matrix_appservice_irc = body.appservice_info.as_ref().is_some_and(|appservice| {
|
||||
let is_matrix_appservice_irc = body
|
||||
.appservice_info
|
||||
.as_ref()
|
||||
.is_some_and(|appservice| {
|
||||
appservice.registration.id == "irc"
|
||||
|| appservice.registration.id.contains("matrix-appservice-irc")
|
||||
|| appservice.registration.id.contains("matrix_appservice_irc")
|
||||
|| appservice
|
||||
.registration
|
||||
.id
|
||||
.contains("matrix-appservice-irc")
|
||||
|| appservice
|
||||
.registration
|
||||
.id
|
||||
.contains("matrix_appservice_irc")
|
||||
});
|
||||
|
||||
if services
|
||||
@@ -114,7 +123,11 @@ pub(crate) async fn get_register_available_route(
|
||||
}
|
||||
}
|
||||
|
||||
if services.appservice.is_exclusive_user_id(&user_id).await {
|
||||
if services
|
||||
.appservice
|
||||
.is_exclusive_user_id(&user_id)
|
||||
.await
|
||||
{
|
||||
return Err!(Request(Exclusive("Username is reserved by an appservice.")));
|
||||
}
|
||||
|
||||
@@ -175,7 +188,9 @@ pub(crate) async fn register_route(
|
||||
info!(
|
||||
"Guest registration disabled / registration enabled with token configured, \
|
||||
rejecting guest registration attempt, initial device name: \"{}\"",
|
||||
body.initial_device_display_name.as_deref().unwrap_or("")
|
||||
body.initial_device_display_name
|
||||
.as_deref()
|
||||
.unwrap_or("")
|
||||
);
|
||||
return Err!(Request(GuestAccessForbidden("Guest registration is disabled.")));
|
||||
}
|
||||
@@ -186,7 +201,9 @@ pub(crate) async fn register_route(
|
||||
warn!(
|
||||
"Guest account attempted to register before a real admin user has been registered, \
|
||||
rejecting registration. Guest's initial device name: \"{}\"",
|
||||
body.initial_device_display_name.as_deref().unwrap_or("")
|
||||
body.initial_device_display_name
|
||||
.as_deref()
|
||||
.unwrap_or("")
|
||||
);
|
||||
return Err!(Request(Forbidden("Registration is temporarily disabled.")));
|
||||
}
|
||||
@@ -195,13 +212,24 @@ pub(crate) async fn register_route(
|
||||
| (Some(username), false) => {
|
||||
// workaround for https://github.com/matrix-org/matrix-appservice-irc/issues/1780 due to inactivity of fixing the issue
|
||||
let is_matrix_appservice_irc =
|
||||
body.appservice_info.as_ref().is_some_and(|appservice| {
|
||||
body.appservice_info
|
||||
.as_ref()
|
||||
.is_some_and(|appservice| {
|
||||
appservice.registration.id == "irc"
|
||||
|| appservice.registration.id.contains("matrix-appservice-irc")
|
||||
|| appservice.registration.id.contains("matrix_appservice_irc")
|
||||
|| appservice
|
||||
.registration
|
||||
.id
|
||||
.contains("matrix-appservice-irc")
|
||||
|| appservice
|
||||
.registration
|
||||
.id
|
||||
.contains("matrix_appservice_irc")
|
||||
});
|
||||
|
||||
if services.globals.forbidden_usernames().is_match(username)
|
||||
if services
|
||||
.globals
|
||||
.forbidden_usernames()
|
||||
.is_match(username)
|
||||
&& !emergency_mode_enabled
|
||||
{
|
||||
return Err!(Request(Forbidden("Username is forbidden")));
|
||||
@@ -270,7 +298,10 @@ pub(crate) async fn register_route(
|
||||
return Err!(Request(MissingToken("Missing appservice token.")));
|
||||
},
|
||||
}
|
||||
} else if services.appservice.is_exclusive_user_id(&user_id).await && !emergency_mode_enabled
|
||||
} else if services
|
||||
.appservice
|
||||
.is_exclusive_user_id(&user_id)
|
||||
.await && !emergency_mode_enabled
|
||||
{
|
||||
return Err!(Request(Exclusive("Username is reserved by an appservice.")));
|
||||
}
|
||||
@@ -348,7 +379,10 @@ pub(crate) async fn register_route(
|
||||
|
||||
// If `new_user_displayname_suffix` is set, registration will push whatever
|
||||
// content is set to the user's display name with a space before it
|
||||
if !services.globals.new_user_displayname_suffix().is_empty()
|
||||
if !services
|
||||
.globals
|
||||
.new_user_displayname_suffix()
|
||||
.is_empty()
|
||||
&& body.appservice_info.is_none()
|
||||
{
|
||||
write!(displayname, " {}", services.server.config.new_user_displayname_suffix)
|
||||
@@ -365,7 +399,9 @@ pub(crate) async fn register_route(
|
||||
.update(
|
||||
None,
|
||||
&user_id,
|
||||
GlobalAccountDataEventType::PushRules.to_string().into(),
|
||||
GlobalAccountDataEventType::PushRules
|
||||
.to_string()
|
||||
.into(),
|
||||
&serde_json::to_value(ruma::events::push_rules::PushRulesEvent {
|
||||
content: ruma::events::push_rules::PushRulesEventContent {
|
||||
global: push::Ruleset::server_default(&user_id),
|
||||
@@ -411,7 +447,10 @@ pub(crate) async fn register_route(
|
||||
|
||||
debug_info!(%user_id, %device_id, "User account was created");
|
||||
|
||||
let device_display_name = body.initial_device_display_name.as_deref().unwrap_or("");
|
||||
let device_display_name = body
|
||||
.initial_device_display_name
|
||||
.as_deref()
|
||||
.unwrap_or("");
|
||||
|
||||
// log in conduit admin channel if a non-guest user registered
|
||||
if body.appservice_info.is_none() && !is_guest {
|
||||
@@ -651,7 +690,10 @@ pub(crate) async fn change_password_route(
|
||||
.then_some(pushkey)
|
||||
})
|
||||
.for_each(|pushkey| async move {
|
||||
services.pusher.delete_pusher(sender_user, &pushkey).await;
|
||||
services
|
||||
.pusher
|
||||
.delete_pusher(sender_user, &pushkey)
|
||||
.await;
|
||||
})
|
||||
.await;
|
||||
}
|
||||
@@ -680,7 +722,10 @@ pub(crate) async fn whoami_route(
|
||||
State(services): State<crate::State>,
|
||||
body: Ruma<whoami::v3::Request>,
|
||||
) -> Result<whoami::v3::Response> {
|
||||
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
|
||||
let sender_user = body
|
||||
.sender_user
|
||||
.as_ref()
|
||||
.expect("user is authenticated");
|
||||
let device_id = body.sender_device.clone();
|
||||
|
||||
Ok(whoami::v3::Response {
|
||||
@@ -790,7 +835,10 @@ pub(crate) async fn deactivate_route(
|
||||
pub(crate) async fn third_party_route(
|
||||
body: Ruma<get_3pids::v3::Request>,
|
||||
) -> Result<get_3pids::v3::Response> {
|
||||
let _sender_user = body.sender_user.as_ref().expect("user is authenticated");
|
||||
let _sender_user = body
|
||||
.sender_user
|
||||
.as_ref()
|
||||
.expect("user is authenticated");
|
||||
|
||||
Ok(get_3pids::v3::Response::new(Vec::new()))
|
||||
}
|
||||
@@ -850,7 +898,11 @@ pub async fn full_user_deactivate(
|
||||
user_id: &UserId,
|
||||
all_joined_rooms: &[OwnedRoomId],
|
||||
) -> Result<()> {
|
||||
services.users.deactivate_account(user_id).await.ok();
|
||||
services
|
||||
.users
|
||||
.deactivate_account(user_id)
|
||||
.await
|
||||
.ok();
|
||||
super::update_displayname(services, user_id, None, all_joined_rooms).await;
|
||||
super::update_avatar_url(services, user_id, None, None, all_joined_rooms).await;
|
||||
|
||||
@@ -858,7 +910,9 @@ pub async fn full_user_deactivate(
|
||||
.users
|
||||
.all_profile_keys(user_id)
|
||||
.ready_for_each(|(profile_key, _)| {
|
||||
services.users.set_profile_key(user_id, &profile_key, None);
|
||||
services
|
||||
.users
|
||||
.set_profile_key(user_id, &profile_key, None);
|
||||
})
|
||||
.await;
|
||||
|
||||
|
||||
@@ -17,7 +17,10 @@ pub(crate) async fn create_alias_route(
|
||||
State(services): State<crate::State>,
|
||||
body: Ruma<create_alias::v3::Request>,
|
||||
) -> Result<create_alias::v3::Response> {
|
||||
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
|
||||
let sender_user = body
|
||||
.sender_user
|
||||
.as_ref()
|
||||
.expect("user is authenticated");
|
||||
|
||||
services
|
||||
.rooms
|
||||
@@ -62,7 +65,10 @@ pub(crate) async fn delete_alias_route(
|
||||
State(services): State<crate::State>,
|
||||
body: Ruma<delete_alias::v3::Request>,
|
||||
) -> Result<delete_alias::v3::Response> {
|
||||
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
|
||||
let sender_user = body
|
||||
.sender_user
|
||||
.as_ref()
|
||||
.expect("user is authenticated");
|
||||
|
||||
services
|
||||
.rooms
|
||||
@@ -90,7 +96,11 @@ pub(crate) async fn get_alias_route(
|
||||
) -> Result<get_alias::v3::Response> {
|
||||
let room_alias = body.body.room_alias;
|
||||
|
||||
let Ok((room_id, servers)) = services.rooms.alias.resolve_alias(&room_alias, None).await
|
||||
let Ok((room_id, servers)) = services
|
||||
.rooms
|
||||
.alias
|
||||
.resolve_alias(&room_alias, None)
|
||||
.await
|
||||
else {
|
||||
return Err!(Request(NotFound("Room with alias not found.")));
|
||||
};
|
||||
|
||||
@@ -26,7 +26,11 @@ pub(crate) async fn get_capabilities_route(
|
||||
|
||||
let mut capabilities = Capabilities::default();
|
||||
capabilities.room_versions = RoomVersionsCapability {
|
||||
default: services.server.config.default_room_version.clone(),
|
||||
default: services
|
||||
.server
|
||||
.config
|
||||
.default_room_version
|
||||
.clone(),
|
||||
available,
|
||||
};
|
||||
|
||||
|
||||
@@ -107,7 +107,9 @@ pub(crate) async fn get_context_route(
|
||||
.collect();
|
||||
|
||||
let (base_event, events_before, events_after): (_, Vec<_>, Vec<_>) =
|
||||
join3(base_event, events_before, events_after).boxed().await;
|
||||
join3(base_event, events_before, events_after)
|
||||
.boxed()
|
||||
.await;
|
||||
|
||||
let lazy_loading_context = lazy_loading::Context {
|
||||
user_id: sender_user,
|
||||
@@ -138,7 +140,12 @@ pub(crate) async fn get_context_route(
|
||||
.rooms
|
||||
.state_accessor
|
||||
.pdu_shortstatehash(state_at)
|
||||
.or_else(|_| services.rooms.state.get_room_shortstatehash(room_id))
|
||||
.or_else(|_| {
|
||||
services
|
||||
.rooms
|
||||
.state
|
||||
.get_room_shortstatehash(room_id)
|
||||
})
|
||||
.map_ok(|shortstatehash| {
|
||||
services
|
||||
.rooms
|
||||
@@ -177,14 +184,20 @@ pub(crate) async fn get_context_route(
|
||||
Some(event_id)
|
||||
})
|
||||
.broad_filter_map(|event_id: &OwnedEventId| {
|
||||
services.rooms.timeline.get_pdu(event_id.as_ref()).ok()
|
||||
services
|
||||
.rooms
|
||||
.timeline
|
||||
.get_pdu(event_id.as_ref())
|
||||
.ok()
|
||||
})
|
||||
.map(PduEvent::into_state_event)
|
||||
.collect()
|
||||
.await;
|
||||
|
||||
Ok(get_context::v3::Response {
|
||||
event: base_event.map(at!(1)).map(PduEvent::into_room_event),
|
||||
event: base_event
|
||||
.map(at!(1))
|
||||
.map(PduEvent::into_room_event),
|
||||
|
||||
start: events_before
|
||||
.last()
|
||||
|
||||
@@ -21,7 +21,10 @@ pub(crate) async fn get_devices_route(
|
||||
State(services): State<crate::State>,
|
||||
body: Ruma<get_devices::v3::Request>,
|
||||
) -> Result<get_devices::v3::Response> {
|
||||
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
|
||||
let sender_user = body
|
||||
.sender_user
|
||||
.as_ref()
|
||||
.expect("user is authenticated");
|
||||
|
||||
let devices: Vec<device::Device> = services
|
||||
.users
|
||||
@@ -39,7 +42,10 @@ pub(crate) async fn get_device_route(
|
||||
State(services): State<crate::State>,
|
||||
body: Ruma<get_device::v3::Request>,
|
||||
) -> Result<get_device::v3::Response> {
|
||||
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
|
||||
let sender_user = body
|
||||
.sender_user
|
||||
.as_ref()
|
||||
.expect("user is authenticated");
|
||||
|
||||
let device = services
|
||||
.users
|
||||
@@ -69,7 +75,9 @@ pub(crate) async fn update_device_route(
|
||||
{
|
||||
| Ok(mut device) => {
|
||||
device.display_name.clone_from(&body.display_name);
|
||||
device.last_seen_ip.clone_from(&Some(client.to_string()));
|
||||
device
|
||||
.last_seen_ip
|
||||
.clone_from(&Some(client.to_string()));
|
||||
device
|
||||
.last_seen_ts
|
||||
.clone_from(&Some(MilliSecondsSinceUnixEpoch::now()));
|
||||
@@ -213,7 +221,10 @@ pub(crate) async fn delete_devices_route(
|
||||
enabled"
|
||||
);
|
||||
for device_id in &body.devices {
|
||||
services.users.remove_device(sender_user, device_id).await;
|
||||
services
|
||||
.users
|
||||
.remove_device(sender_user, device_id)
|
||||
.await;
|
||||
}
|
||||
|
||||
return Ok(delete_devices::v3::Response {});
|
||||
@@ -256,7 +267,10 @@ pub(crate) async fn delete_devices_route(
|
||||
}
|
||||
|
||||
for device_id in &body.devices {
|
||||
services.users.remove_device(sender_user, device_id).await;
|
||||
services
|
||||
.users
|
||||
.remove_device(sender_user, device_id)
|
||||
.await;
|
||||
}
|
||||
|
||||
Ok(delete_devices::v3::Response {})
|
||||
|
||||
@@ -137,7 +137,12 @@ pub(crate) async fn set_room_visibility_route(
|
||||
) -> Result<set_room_visibility::v3::Response> {
|
||||
let sender_user = body.sender_user();
|
||||
|
||||
if !services.rooms.metadata.exists(&body.room_id).await {
|
||||
if !services
|
||||
.rooms
|
||||
.metadata
|
||||
.exists(&body.room_id)
|
||||
.await
|
||||
{
|
||||
// Return 404 if the room doesn't exist
|
||||
return Err!(Request(NotFound("Room not found")));
|
||||
}
|
||||
@@ -158,7 +163,10 @@ pub(crate) async fn set_room_visibility_route(
|
||||
|
||||
match &body.visibility {
|
||||
| room::Visibility::Public => {
|
||||
if services.server.config.lockdown_public_room_directory
|
||||
if services
|
||||
.server
|
||||
.config
|
||||
.lockdown_public_room_directory
|
||||
&& !services.users.is_admin(sender_user).await
|
||||
&& body.appservice_info.is_none()
|
||||
{
|
||||
@@ -197,7 +205,10 @@ pub(crate) async fn set_room_visibility_route(
|
||||
}
|
||||
info!("{sender_user} made {0} public to the room directory", body.room_id);
|
||||
},
|
||||
| room::Visibility::Private => services.rooms.directory.set_not_public(&body.room_id),
|
||||
| room::Visibility::Private => services
|
||||
.rooms
|
||||
.directory
|
||||
.set_not_public(&body.room_id),
|
||||
| _ => {
|
||||
return Err!(Request(InvalidParam("Room visibility type is not supported.",)));
|
||||
},
|
||||
@@ -213,13 +224,23 @@ pub(crate) async fn get_room_visibility_route(
|
||||
State(services): State<crate::State>,
|
||||
body: Ruma<get_room_visibility::v3::Request>,
|
||||
) -> Result<get_room_visibility::v3::Response> {
|
||||
if !services.rooms.metadata.exists(&body.room_id).await {
|
||||
if !services
|
||||
.rooms
|
||||
.metadata
|
||||
.exists(&body.room_id)
|
||||
.await
|
||||
{
|
||||
// Return 404 if the room doesn't exist
|
||||
return Err!(Request(NotFound("Room not found")));
|
||||
}
|
||||
|
||||
Ok(get_room_visibility::v3::Response {
|
||||
visibility: if services.rooms.directory.is_public_room(&body.room_id).await {
|
||||
visibility: if services
|
||||
.rooms
|
||||
.directory
|
||||
.is_public_room(&body.room_id)
|
||||
.await
|
||||
{
|
||||
room::Visibility::Public
|
||||
} else {
|
||||
room::Visibility::Private
|
||||
@@ -332,9 +353,15 @@ pub(crate) async fn get_public_rooms_filtered_helper(
|
||||
.unwrap_or_else(|_| uint!(0))
|
||||
.into();
|
||||
|
||||
let chunk: Vec<_> = all_rooms.into_iter().skip(num_since).take(limit).collect();
|
||||
let chunk: Vec<_> = all_rooms
|
||||
.into_iter()
|
||||
.skip(num_since)
|
||||
.take(limit)
|
||||
.collect();
|
||||
|
||||
let prev_batch = num_since.ne(&0).then_some(format!("p{num_since}"));
|
||||
let prev_batch = num_since
|
||||
.ne(&0)
|
||||
.then_some(format!("p{num_since}"));
|
||||
|
||||
let next_batch = chunk
|
||||
.len()
|
||||
@@ -383,9 +410,17 @@ async fn user_can_publish_room(
|
||||
}
|
||||
|
||||
async fn public_rooms_chunk(services: &Services, room_id: OwnedRoomId) -> PublicRoomsChunk {
|
||||
let name = services.rooms.state_accessor.get_name(&room_id).ok();
|
||||
let name = services
|
||||
.rooms
|
||||
.state_accessor
|
||||
.get_name(&room_id)
|
||||
.ok();
|
||||
|
||||
let room_type = services.rooms.state_accessor.get_room_type(&room_id).ok();
|
||||
let room_type = services
|
||||
.rooms
|
||||
.state_accessor
|
||||
.get_room_type(&room_id)
|
||||
.ok();
|
||||
|
||||
let canonical_alias = services
|
||||
.rooms
|
||||
@@ -395,9 +430,16 @@ async fn public_rooms_chunk(services: &Services, room_id: OwnedRoomId) -> Public
|
||||
|
||||
let avatar_url = services.rooms.state_accessor.get_avatar(&room_id);
|
||||
|
||||
let topic = services.rooms.state_accessor.get_room_topic(&room_id).ok();
|
||||
let topic = services
|
||||
.rooms
|
||||
.state_accessor
|
||||
.get_room_topic(&room_id)
|
||||
.ok();
|
||||
|
||||
let world_readable = services.rooms.state_accessor.is_world_readable(&room_id);
|
||||
let world_readable = services
|
||||
.rooms
|
||||
.state_accessor
|
||||
.is_world_readable(&room_id);
|
||||
|
||||
let join_rule = services
|
||||
.rooms
|
||||
@@ -410,9 +452,15 @@ async fn public_rooms_chunk(services: &Services, room_id: OwnedRoomId) -> Public
|
||||
| _ => "invite".into(),
|
||||
});
|
||||
|
||||
let guest_can_join = services.rooms.state_accessor.guest_can_join(&room_id);
|
||||
let guest_can_join = services
|
||||
.rooms
|
||||
.state_accessor
|
||||
.guest_can_join(&room_id);
|
||||
|
||||
let num_joined_members = services.rooms.state_cache.room_joined_count(&room_id);
|
||||
let num_joined_members = services
|
||||
.rooms
|
||||
.state_cache
|
||||
.room_joined_count(&room_id);
|
||||
|
||||
let (
|
||||
(avatar_url, canonical_alias, guest_can_join, join_rule, name),
|
||||
|
||||
@@ -13,7 +13,10 @@ pub(crate) async fn get_filter_route(
|
||||
State(services): State<crate::State>,
|
||||
body: Ruma<get_filter::v3::Request>,
|
||||
) -> Result<get_filter::v3::Response> {
|
||||
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
|
||||
let sender_user = body
|
||||
.sender_user
|
||||
.as_ref()
|
||||
.expect("user is authenticated");
|
||||
|
||||
services
|
||||
.users
|
||||
@@ -30,9 +33,14 @@ pub(crate) async fn create_filter_route(
|
||||
State(services): State<crate::State>,
|
||||
body: Ruma<create_filter::v3::Request>,
|
||||
) -> Result<create_filter::v3::Response> {
|
||||
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
|
||||
let sender_user = body
|
||||
.sender_user
|
||||
.as_ref()
|
||||
.expect("user is authenticated");
|
||||
|
||||
let filter_id = services.users.create_filter(sender_user, &body.filter);
|
||||
let filter_id = services
|
||||
.users
|
||||
.create_filter(sender_user, &body.filter);
|
||||
|
||||
Ok(create_filter::v3::Response::new(filter_id))
|
||||
}
|
||||
|
||||
@@ -126,7 +126,10 @@ pub(crate) async fn get_keys_route(
|
||||
State(services): State<crate::State>,
|
||||
body: Ruma<get_keys::v3::Request>,
|
||||
) -> Result<get_keys::v3::Response> {
|
||||
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
|
||||
let sender_user = body
|
||||
.sender_user
|
||||
.as_ref()
|
||||
.expect("user is authenticated");
|
||||
|
||||
get_keys_helper(
|
||||
&services,
|
||||
@@ -157,8 +160,14 @@ pub(crate) async fn upload_signing_keys_route(
|
||||
State(services): State<crate::State>,
|
||||
body: Ruma<upload_signing_keys::v3::Request>,
|
||||
) -> Result<upload_signing_keys::v3::Response> {
|
||||
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
|
||||
let sender_device = body.sender_device.as_ref().expect("user is authenticated");
|
||||
let sender_user = body
|
||||
.sender_user
|
||||
.as_ref()
|
||||
.expect("user is authenticated");
|
||||
let sender_device = body
|
||||
.sender_device
|
||||
.as_ref()
|
||||
.expect("user is authenticated");
|
||||
|
||||
// UIAA
|
||||
let mut uiaainfo = UiaaInfo {
|
||||
@@ -373,7 +382,10 @@ pub(crate) async fn get_key_changes_route(
|
||||
State(services): State<crate::State>,
|
||||
body: Ruma<get_key_changes::v3::Request>,
|
||||
) -> Result<get_key_changes::v3::Response> {
|
||||
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
|
||||
let sender_user = body
|
||||
.sender_user
|
||||
.as_ref()
|
||||
.expect("user is authenticated");
|
||||
|
||||
let mut device_list_updates = HashSet::new();
|
||||
|
||||
@@ -396,7 +408,11 @@ pub(crate) async fn get_key_changes_route(
|
||||
.await,
|
||||
);
|
||||
|
||||
let mut rooms_joined = services.rooms.state_cache.rooms_joined(sender_user).boxed();
|
||||
let mut rooms_joined = services
|
||||
.rooms
|
||||
.state_cache
|
||||
.rooms_joined(sender_user)
|
||||
.boxed();
|
||||
|
||||
while let Some(room_id) = rooms_joined.next().await {
|
||||
device_list_updates.extend(
|
||||
@@ -449,7 +465,11 @@ where
|
||||
let mut devices = services.users.all_device_ids(user_id).boxed();
|
||||
|
||||
while let Some(device_id) = devices.next().await {
|
||||
if let Ok(mut keys) = services.users.get_device_keys(user_id, device_id).await {
|
||||
if let Ok(mut keys) = services
|
||||
.users
|
||||
.get_device_keys(user_id, device_id)
|
||||
.await
|
||||
{
|
||||
let metadata = services
|
||||
.users
|
||||
.get_device_metadata(user_id, device_id)
|
||||
@@ -469,7 +489,11 @@ where
|
||||
} else {
|
||||
for device_id in device_ids {
|
||||
let mut container = BTreeMap::new();
|
||||
if let Ok(mut keys) = services.users.get_device_keys(user_id, device_id).await {
|
||||
if let Ok(mut keys) = services
|
||||
.users
|
||||
.get_device_keys(user_id, device_id)
|
||||
.await
|
||||
{
|
||||
let metadata = services
|
||||
.users
|
||||
.get_device_metadata(user_id, device_id)
|
||||
@@ -545,7 +569,9 @@ where
|
||||
.await
|
||||
{
|
||||
let (_, mut our_master_key) = parse_master_key(&user, &our_master_key)?;
|
||||
master_key.signatures.append(&mut our_master_key.signatures);
|
||||
master_key
|
||||
.signatures
|
||||
.append(&mut our_master_key.signatures);
|
||||
}
|
||||
let json = serde_json::to_value(master_key).expect("to_value always works");
|
||||
let raw = serde_json::from_value(json).expect("Raw::from_value always works");
|
||||
@@ -588,7 +614,9 @@ fn add_unsigned_device_display_name(
|
||||
if let Some(display_name) = metadata.display_name {
|
||||
let mut object = keys.deserialize_as::<serde_json::Map<String, serde_json::Value>>()?;
|
||||
|
||||
let unsigned = object.entry("unsigned").or_insert_with(|| json!({}));
|
||||
let unsigned = object
|
||||
.entry("unsigned")
|
||||
.or_insert_with(|| json!({}));
|
||||
if let serde_json::Value::Object(unsigned_object) = unsigned {
|
||||
if include_display_names {
|
||||
unsigned_object.insert("device_display_name".to_owned(), display_name.into());
|
||||
|
||||
@@ -51,7 +51,10 @@ pub(crate) async fn create_content_route(
|
||||
InsecureClientIp(client): InsecureClientIp,
|
||||
body: Ruma<create_content::v3::Request>,
|
||||
) -> Result<create_content::v3::Response> {
|
||||
let user = body.sender_user.as_ref().expect("user is authenticated");
|
||||
let user = body
|
||||
.sender_user
|
||||
.as_ref()
|
||||
.expect("user is authenticated");
|
||||
|
||||
let filename = body.filename.as_deref();
|
||||
let content_type = body.content_type.as_deref();
|
||||
@@ -94,7 +97,10 @@ pub(crate) async fn get_content_thumbnail_route(
|
||||
InsecureClientIp(client): InsecureClientIp,
|
||||
body: Ruma<get_content_thumbnail::v1::Request>,
|
||||
) -> Result<get_content_thumbnail::v1::Response> {
|
||||
let user = body.sender_user.as_ref().expect("user is authenticated");
|
||||
let user = body
|
||||
.sender_user
|
||||
.as_ref()
|
||||
.expect("user is authenticated");
|
||||
|
||||
let dim = Dim::from_ruma(body.width, body.height, body.method.clone())?;
|
||||
let mxc = Mxc {
|
||||
@@ -131,7 +137,10 @@ pub(crate) async fn get_content_route(
|
||||
InsecureClientIp(client): InsecureClientIp,
|
||||
body: Ruma<get_content::v1::Request>,
|
||||
) -> Result<get_content::v1::Response> {
|
||||
let user = body.sender_user.as_ref().expect("user is authenticated");
|
||||
let user = body
|
||||
.sender_user
|
||||
.as_ref()
|
||||
.expect("user is authenticated");
|
||||
|
||||
let mxc = Mxc {
|
||||
server_name: &body.server_name,
|
||||
@@ -167,7 +176,10 @@ pub(crate) async fn get_content_as_filename_route(
|
||||
InsecureClientIp(client): InsecureClientIp,
|
||||
body: Ruma<get_content_as_filename::v1::Request>,
|
||||
) -> Result<get_content_as_filename::v1::Response> {
|
||||
let user = body.sender_user.as_ref().expect("user is authenticated");
|
||||
let user = body
|
||||
.sender_user
|
||||
.as_ref()
|
||||
.expect("user is authenticated");
|
||||
|
||||
let mxc = Mxc {
|
||||
server_name: &body.server_name,
|
||||
@@ -203,7 +215,10 @@ pub(crate) async fn get_media_preview_route(
|
||||
InsecureClientIp(client): InsecureClientIp,
|
||||
body: Ruma<get_media_preview::v1::Request>,
|
||||
) -> Result<get_media_preview::v1::Response> {
|
||||
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
|
||||
let sender_user = body
|
||||
.sender_user
|
||||
.as_ref()
|
||||
.expect("user is authenticated");
|
||||
|
||||
let url = &body.url;
|
||||
let url = Url::parse(&body.url).map_err(|e| {
|
||||
|
||||
@@ -55,7 +55,10 @@ pub(crate) async fn get_media_preview_legacy_route(
|
||||
InsecureClientIp(client): InsecureClientIp,
|
||||
body: Ruma<get_media_preview::v3::Request>,
|
||||
) -> Result<get_media_preview::v3::Response> {
|
||||
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
|
||||
let sender_user = body
|
||||
.sender_user
|
||||
.as_ref()
|
||||
.expect("user is authenticated");
|
||||
|
||||
let url = &body.url;
|
||||
let url = Url::parse(&body.url).map_err(|e| {
|
||||
@@ -70,7 +73,11 @@ pub(crate) async fn get_media_preview_legacy_route(
|
||||
)));
|
||||
}
|
||||
|
||||
let preview = services.media.get_url_preview(&url).await.map_err(|e| {
|
||||
let preview = services
|
||||
.media
|
||||
.get_url_preview(&url)
|
||||
.await
|
||||
.map_err(|e| {
|
||||
err!(Request(Unknown(
|
||||
debug_error!(%sender_user, %url, "Failed to fetch a URL preview: {e}")
|
||||
)))
|
||||
|
||||
@@ -85,14 +85,22 @@ async fn banned_room_check(
|
||||
|| services
|
||||
.config
|
||||
.forbidden_remote_server_names
|
||||
.is_match(room_id.server_name().expect("legacy room mxid").host())
|
||||
{
|
||||
.is_match(
|
||||
room_id
|
||||
.server_name()
|
||||
.expect("legacy room mxid")
|
||||
.host(),
|
||||
) {
|
||||
warn!(
|
||||
"User {user_id} who is not an admin attempted to send an invite for or \
|
||||
attempted to join a banned room or banned room server name: {room_id}"
|
||||
);
|
||||
|
||||
if services.server.config.auto_deactivate_banned_room_attempts {
|
||||
if services
|
||||
.server
|
||||
.config
|
||||
.auto_deactivate_banned_room_attempts
|
||||
{
|
||||
warn!(
|
||||
"Automatically deactivating user {user_id} due to attempted banned room join"
|
||||
);
|
||||
@@ -131,7 +139,11 @@ async fn banned_room_check(
|
||||
name {server_name} that is globally forbidden. Rejecting.",
|
||||
);
|
||||
|
||||
if services.server.config.auto_deactivate_banned_room_attempts {
|
||||
if services
|
||||
.server
|
||||
.config
|
||||
.auto_deactivate_banned_room_attempts
|
||||
{
|
||||
warn!(
|
||||
"Automatically deactivating user {user_id} due to attempted banned room join"
|
||||
);
|
||||
@@ -247,7 +259,10 @@ pub(crate) async fn join_room_by_id_or_alias_route(
|
||||
InsecureClientIp(client): InsecureClientIp,
|
||||
body: Ruma<join_room_by_id_or_alias::v3::Request>,
|
||||
) -> Result<join_room_by_id_or_alias::v3::Response> {
|
||||
let sender_user = body.sender_user.as_deref().expect("user is authenticated");
|
||||
let sender_user = body
|
||||
.sender_user
|
||||
.as_deref()
|
||||
.expect("user is authenticated");
|
||||
let appservice_info = &body.appservice_info;
|
||||
let body = body.body;
|
||||
|
||||
@@ -513,9 +528,12 @@ pub(crate) async fn invite_user_route(
|
||||
|
||||
match &body.recipient {
|
||||
| invite_user::v3::InvitationRecipient::UserId { user_id } => {
|
||||
let sender_ignored_recipient = services.users.user_is_ignored(sender_user, user_id);
|
||||
let recipient_ignored_by_sender =
|
||||
services.users.user_is_ignored(user_id, sender_user);
|
||||
let sender_ignored_recipient = services
|
||||
.users
|
||||
.user_is_ignored(sender_user, user_id);
|
||||
let recipient_ignored_by_sender = services
|
||||
.users
|
||||
.user_is_ignored(user_id, sender_user);
|
||||
|
||||
let (sender_ignored_recipient, recipient_ignored_by_sender) =
|
||||
join!(sender_ignored_recipient, recipient_ignored_by_sender);
|
||||
@@ -567,7 +585,12 @@ pub(crate) async fn kick_user_route(
|
||||
State(services): State<crate::State>,
|
||||
body: Ruma<kick_user::v3::Request>,
|
||||
) -> Result<kick_user::v3::Response> {
|
||||
let state_lock = services.rooms.state.mutex.lock(&body.room_id).await;
|
||||
let state_lock = services
|
||||
.rooms
|
||||
.state
|
||||
.mutex
|
||||
.lock(&body.room_id)
|
||||
.await;
|
||||
|
||||
let Ok(event) = services
|
||||
.rooms
|
||||
@@ -626,7 +649,12 @@ pub(crate) async fn ban_user_route(
|
||||
return Err!(Request(Forbidden("You cannot ban yourself.")));
|
||||
}
|
||||
|
||||
let state_lock = services.rooms.state.mutex.lock(&body.room_id).await;
|
||||
let state_lock = services
|
||||
.rooms
|
||||
.state
|
||||
.mutex
|
||||
.lock(&body.room_id)
|
||||
.await;
|
||||
|
||||
let current_member_content = services
|
||||
.rooms
|
||||
@@ -667,7 +695,12 @@ pub(crate) async fn unban_user_route(
|
||||
State(services): State<crate::State>,
|
||||
body: Ruma<unban_user::v3::Request>,
|
||||
) -> Result<unban_user::v3::Response> {
|
||||
let state_lock = services.rooms.state.mutex.lock(&body.room_id).await;
|
||||
let state_lock = services
|
||||
.rooms
|
||||
.state
|
||||
.mutex
|
||||
.lock(&body.room_id)
|
||||
.await;
|
||||
|
||||
let current_member_content = services
|
||||
.rooms
|
||||
@@ -722,9 +755,18 @@ pub(crate) async fn forget_room_route(
|
||||
let user_id = body.sender_user();
|
||||
let room_id = &body.room_id;
|
||||
|
||||
let joined = services.rooms.state_cache.is_joined(user_id, room_id);
|
||||
let knocked = services.rooms.state_cache.is_knocked(user_id, room_id);
|
||||
let invited = services.rooms.state_cache.is_invited(user_id, room_id);
|
||||
let joined = services
|
||||
.rooms
|
||||
.state_cache
|
||||
.is_joined(user_id, room_id);
|
||||
let knocked = services
|
||||
.rooms
|
||||
.state_cache
|
||||
.is_knocked(user_id, room_id);
|
||||
let invited = services
|
||||
.rooms
|
||||
.state_cache
|
||||
.is_invited(user_id, room_id);
|
||||
|
||||
pin_mut!(joined, knocked, invited);
|
||||
if joined.or(knocked).or(invited).await {
|
||||
@@ -745,8 +787,17 @@ pub(crate) async fn forget_room_route(
|
||||
.map(|member| member.membership)
|
||||
.is_ok_and(is_matching!(MembershipState::Leave | MembershipState::Ban));
|
||||
|
||||
if non_membership || services.rooms.state_cache.is_left(user_id, room_id).await {
|
||||
services.rooms.state_cache.forget(room_id, user_id);
|
||||
if non_membership
|
||||
|| services
|
||||
.rooms
|
||||
.state_cache
|
||||
.is_left(user_id, room_id)
|
||||
.await
|
||||
{
|
||||
services
|
||||
.rooms
|
||||
.state_cache
|
||||
.forget(room_id, user_id);
|
||||
}
|
||||
|
||||
Ok(forget_room::v3::Response::new())
|
||||
@@ -791,7 +842,10 @@ fn membership_filter(
|
||||
| Some(_) | None => MembershipState::Leave,
|
||||
};
|
||||
|
||||
let evt_membership = pdu.get_content::<RoomMemberEventContent>().ok()?.membership;
|
||||
let evt_membership = pdu
|
||||
.get_content::<RoomMemberEventContent>()
|
||||
.ok()?
|
||||
.membership;
|
||||
|
||||
if for_membership.is_some() && not_membership.is_some() {
|
||||
if membership_state_filter != evt_membership
|
||||
@@ -912,7 +966,13 @@ pub async fn join_room_by_id_helper(
|
||||
.unwrap_or(false)
|
||||
&& appservice_info.is_none();
|
||||
|
||||
if user_is_guest && !services.rooms.state_accessor.guest_can_join(room_id).await {
|
||||
if user_is_guest
|
||||
&& !services
|
||||
.rooms
|
||||
.state_accessor
|
||||
.guest_can_join(room_id)
|
||||
.await
|
||||
{
|
||||
return Err!(Request(Forbidden("Guests are not allowed to join this room")));
|
||||
}
|
||||
|
||||
@@ -999,7 +1059,10 @@ async fn join_room_by_id_helper_remote(
|
||||
return Err!(BadServerResponse("Remote room version is not supported by conduwuit"));
|
||||
};
|
||||
|
||||
if !services.server.supported_room_version(&room_version_id) {
|
||||
if !services
|
||||
.server
|
||||
.supported_room_version(&room_version_id)
|
||||
{
|
||||
return Err!(BadServerResponse(
|
||||
"Remote room version {room_version_id} is not supported by conduwuit"
|
||||
));
|
||||
@@ -1198,7 +1261,10 @@ async fn join_room_by_id_helper_remote(
|
||||
},
|
||||
};
|
||||
|
||||
services.rooms.outlier.add_pdu_outlier(&event_id, &value);
|
||||
services
|
||||
.rooms
|
||||
.outlier
|
||||
.add_pdu_outlier(&event_id, &value);
|
||||
if let Some(state_key) = &pdu.state_key {
|
||||
let shortstatekey = services
|
||||
.rooms
|
||||
@@ -1229,7 +1295,10 @@ async fn join_room_by_id_helper_remote(
|
||||
})
|
||||
.ready_filter_map(Result::ok)
|
||||
.ready_for_each(|(event_id, value)| {
|
||||
services.rooms.outlier.add_pdu_outlier(&event_id, &value);
|
||||
services
|
||||
.rooms
|
||||
.outlier
|
||||
.add_pdu_outlier(&event_id, &value);
|
||||
})
|
||||
.await;
|
||||
|
||||
@@ -1238,10 +1307,20 @@ async fn join_room_by_id_helper_remote(
|
||||
debug!("Running send_join auth check");
|
||||
let fetch_state = &state;
|
||||
let state_fetch = |k: StateEventType, s: StateKey| async move {
|
||||
let shortstatekey = services.rooms.short.get_shortstatekey(&k, &s).await.ok()?;
|
||||
let shortstatekey = services
|
||||
.rooms
|
||||
.short
|
||||
.get_shortstatekey(&k, &s)
|
||||
.await
|
||||
.ok()?;
|
||||
|
||||
let event_id = fetch_state.get(&shortstatekey)?;
|
||||
services.rooms.timeline.get_pdu(event_id).await.ok()
|
||||
services
|
||||
.rooms
|
||||
.timeline
|
||||
.get_pdu(event_id)
|
||||
.await
|
||||
.ok()
|
||||
};
|
||||
|
||||
let auth_check = state_res::event_auth::auth_check(
|
||||
@@ -1436,7 +1515,10 @@ async fn join_room_by_id_helper_local(
|
||||
return Err!(BadServerResponse("Remote room version is not supported by conduwuit"));
|
||||
};
|
||||
|
||||
if !services.server.supported_room_version(&room_version_id) {
|
||||
if !services
|
||||
.server
|
||||
.supported_room_version(&room_version_id)
|
||||
{
|
||||
return Err!(BadServerResponse(
|
||||
"Remote room version {room_version_id} is not supported by conduwuit"
|
||||
));
|
||||
@@ -1572,7 +1654,10 @@ async fn make_join_request(
|
||||
federation::membership::prepare_join_event::v1::Request {
|
||||
room_id: room_id.to_owned(),
|
||||
user_id: sender_user.to_owned(),
|
||||
ver: services.server.supported_room_versions().collect(),
|
||||
ver: services
|
||||
.server
|
||||
.supported_room_versions()
|
||||
.collect(),
|
||||
},
|
||||
)
|
||||
.await;
|
||||
@@ -1667,7 +1752,11 @@ pub(crate) async fn invite_helper(
|
||||
(pdu, pdu_json, invite_room_state)
|
||||
};
|
||||
|
||||
let room_version_id = services.rooms.state.get_room_version(room_id).await?;
|
||||
let room_version_id = services
|
||||
.rooms
|
||||
.state
|
||||
.get_room_version(room_id)
|
||||
.await?;
|
||||
|
||||
let response = services
|
||||
.sending
|
||||
@@ -1723,7 +1812,10 @@ pub(crate) async fn invite_helper(
|
||||
err!(Request(InvalidParam("Could not accept incoming PDU as timeline event.")))
|
||||
})?;
|
||||
|
||||
return services.sending.send_pdu_room(room_id, &pdu_id).await;
|
||||
return services
|
||||
.sending
|
||||
.send_pdu_room(room_id, &pdu_id)
|
||||
.await;
|
||||
}
|
||||
|
||||
if !services
|
||||
@@ -1797,7 +1889,10 @@ pub async fn leave_all_rooms(services: &Services, user_id: &UserId) {
|
||||
warn!(%user_id, "Failed to leave {room_id} remotely: {e}");
|
||||
}
|
||||
|
||||
services.rooms.state_cache.forget(&room_id, user_id);
|
||||
services
|
||||
.rooms
|
||||
.state_cache
|
||||
.forget(&room_id, user_id);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1856,7 +1951,10 @@ pub async fn leave_room(
|
||||
|
||||
// Ask a remote server if we don't have this room and are not knocking on it
|
||||
if dont_have_room.and(not_knocked).await {
|
||||
if let Err(e) = remote_leave_room(services, user_id, room_id).boxed().await {
|
||||
if let Err(e) = remote_leave_room(services, user_id, room_id)
|
||||
.boxed()
|
||||
.await
|
||||
{
|
||||
warn!(%user_id, "Failed to leave room {room_id} remotely: {e}");
|
||||
// Don't tell the client about this error
|
||||
}
|
||||
@@ -1865,8 +1963,18 @@ pub async fn leave_room(
|
||||
.rooms
|
||||
.state_cache
|
||||
.invite_state(user_id, room_id)
|
||||
.or_else(|_| services.rooms.state_cache.knock_state(user_id, room_id))
|
||||
.or_else(|_| services.rooms.state_cache.left_state(user_id, room_id))
|
||||
.or_else(|_| {
|
||||
services
|
||||
.rooms
|
||||
.state_cache
|
||||
.knock_state(user_id, room_id)
|
||||
})
|
||||
.or_else(|_| {
|
||||
services
|
||||
.rooms
|
||||
.state_cache
|
||||
.left_state(user_id, room_id)
|
||||
})
|
||||
.await
|
||||
.ok();
|
||||
|
||||
@@ -2029,7 +2137,10 @@ async fn remote_leave_room(
|
||||
)));
|
||||
};
|
||||
|
||||
if !services.server.supported_room_version(&room_version_id) {
|
||||
if !services
|
||||
.server
|
||||
.supported_room_version(&room_version_id)
|
||||
{
|
||||
return Err!(BadServerResponse(warn!(
|
||||
"Remote room version {room_version_id} for {room_id} is not supported by conduwuit",
|
||||
)));
|
||||
@@ -2186,7 +2297,11 @@ async fn knock_room_helper_local(
|
||||
) -> Result {
|
||||
debug_info!("We can knock locally");
|
||||
|
||||
let room_version_id = services.rooms.state.get_room_version(room_id).await?;
|
||||
let room_version_id = services
|
||||
.rooms
|
||||
.state
|
||||
.get_room_version(room_id)
|
||||
.await?;
|
||||
|
||||
if matches!(
|
||||
room_version_id,
|
||||
@@ -2237,7 +2352,10 @@ async fn knock_room_helper_local(
|
||||
|
||||
let room_version_id = make_knock_response.room_version;
|
||||
|
||||
if !services.server.supported_room_version(&room_version_id) {
|
||||
if !services
|
||||
.server
|
||||
.supported_room_version(&room_version_id)
|
||||
{
|
||||
return Err!(BadServerResponse(
|
||||
"Remote room version {room_version_id} is not supported by conduwuit"
|
||||
));
|
||||
@@ -2367,7 +2485,10 @@ async fn knock_room_helper_remote(
|
||||
|
||||
let room_version_id = make_knock_response.room_version;
|
||||
|
||||
if !services.server.supported_room_version(&room_version_id) {
|
||||
if !services
|
||||
.server
|
||||
.supported_room_version(&room_version_id)
|
||||
{
|
||||
return Err!(BadServerResponse(
|
||||
"Remote room version {room_version_id} is not supported by conduwuit"
|
||||
));
|
||||
@@ -2481,7 +2602,10 @@ async fn knock_room_helper_remote(
|
||||
.get_or_create_shortstatekey(&event_type, &state_key)
|
||||
.await;
|
||||
|
||||
services.rooms.outlier.add_pdu_outlier(&event_id, &event);
|
||||
services
|
||||
.rooms
|
||||
.outlier
|
||||
.add_pdu_outlier(&event_id, &event);
|
||||
state_map.insert(shortstatekey, event_id.clone());
|
||||
}
|
||||
|
||||
@@ -2489,7 +2613,11 @@ async fn knock_room_helper_remote(
|
||||
let compressed: CompressedState = services
|
||||
.rooms
|
||||
.state_compressor
|
||||
.compress_state_events(state_map.iter().map(|(ssk, eid)| (ssk, eid.borrow())))
|
||||
.compress_state_events(
|
||||
state_map
|
||||
.iter()
|
||||
.map(|(ssk, eid)| (ssk, eid.borrow())),
|
||||
)
|
||||
.collect()
|
||||
.await;
|
||||
|
||||
@@ -2582,7 +2710,10 @@ async fn make_knock_request(
|
||||
federation::knock::create_knock_event_template::v1::Request {
|
||||
room_id: room_id.to_owned(),
|
||||
user_id: sender_user.to_owned(),
|
||||
ver: services.server.supported_room_versions().collect(),
|
||||
ver: services
|
||||
.server
|
||||
.supported_room_versions()
|
||||
.collect(),
|
||||
},
|
||||
)
|
||||
.await;
|
||||
|
||||
@@ -258,7 +258,9 @@ pub(crate) async fn is_ignored_pdu(
|
||||
return true;
|
||||
}
|
||||
|
||||
let ignored_type = IGNORED_MESSAGE_TYPES.binary_search(&pdu.kind).is_ok();
|
||||
let ignored_type = IGNORED_MESSAGE_TYPES
|
||||
.binary_search(&pdu.kind)
|
||||
.is_ok();
|
||||
|
||||
let ignored_server = services
|
||||
.config
|
||||
@@ -266,7 +268,11 @@ pub(crate) async fn is_ignored_pdu(
|
||||
.is_match(pdu.sender().server_name().host());
|
||||
|
||||
if ignored_type
|
||||
&& (ignored_server || services.users.user_is_ignored(&pdu.sender, user_id).await)
|
||||
&& (ignored_server
|
||||
|| services
|
||||
.users
|
||||
.user_is_ignored(&pdu.sender, user_id)
|
||||
.await)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -19,7 +19,10 @@ pub(crate) async fn create_openid_token_route(
|
||||
State(services): State<crate::State>,
|
||||
body: Ruma<account::request_openid_token::v3::Request>,
|
||||
) -> Result<account::request_openid_token::v3::Response> {
|
||||
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
|
||||
let sender_user = body
|
||||
.sender_user
|
||||
.as_ref()
|
||||
.expect("user is authenticated");
|
||||
|
||||
if sender_user != &body.user_id {
|
||||
return Err(Error::BadRequest(
|
||||
|
||||
@@ -50,7 +50,11 @@ pub(crate) async fn get_presence_route(
|
||||
.await;
|
||||
|
||||
if has_shared_rooms {
|
||||
if let Ok(presence) = services.presence.get_presence(&body.user_id).await {
|
||||
if let Ok(presence) = services
|
||||
.presence
|
||||
.get_presence(&body.user_id)
|
||||
.await
|
||||
{
|
||||
presence_event = Some(presence);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,7 +35,10 @@ pub(crate) async fn set_displayname_route(
|
||||
State(services): State<crate::State>,
|
||||
body: Ruma<set_display_name::v3::Request>,
|
||||
) -> Result<set_display_name::v3::Response> {
|
||||
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
|
||||
let sender_user = body
|
||||
.sender_user
|
||||
.as_ref()
|
||||
.expect("user is authenticated");
|
||||
|
||||
if *sender_user != body.user_id && body.appservice_info.is_none() {
|
||||
return Err!(Request(Forbidden("You cannot update the profile of another user")));
|
||||
@@ -111,7 +114,11 @@ pub(crate) async fn get_displayname_route(
|
||||
}
|
||||
|
||||
Ok(get_display_name::v3::Response {
|
||||
displayname: services.users.displayname(&body.user_id).await.ok(),
|
||||
displayname: services
|
||||
.users
|
||||
.displayname(&body.user_id)
|
||||
.await
|
||||
.ok(),
|
||||
})
|
||||
}
|
||||
|
||||
@@ -124,7 +131,10 @@ pub(crate) async fn set_avatar_url_route(
|
||||
State(services): State<crate::State>,
|
||||
body: Ruma<set_avatar_url::v3::Request>,
|
||||
) -> Result<set_avatar_url::v3::Response> {
|
||||
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
|
||||
let sender_user = body
|
||||
.sender_user
|
||||
.as_ref()
|
||||
.expect("user is authenticated");
|
||||
|
||||
if *sender_user != body.user_id && body.appservice_info.is_none() {
|
||||
return Err!(Request(Forbidden("You cannot update the profile of another user")));
|
||||
@@ -212,7 +222,11 @@ pub(crate) async fn get_avatar_url_route(
|
||||
}
|
||||
|
||||
Ok(get_avatar_url::v3::Response {
|
||||
avatar_url: services.users.avatar_url(&body.user_id).await.ok(),
|
||||
avatar_url: services
|
||||
.users
|
||||
.avatar_url(&body.user_id)
|
||||
.await
|
||||
.ok(),
|
||||
blurhash: services.users.blurhash(&body.user_id).await.ok(),
|
||||
})
|
||||
}
|
||||
@@ -295,9 +309,17 @@ pub(crate) async fn get_profile_route(
|
||||
custom_profile_fields.remove("m.tz");
|
||||
|
||||
Ok(get_profile::v3::Response {
|
||||
avatar_url: services.users.avatar_url(&body.user_id).await.ok(),
|
||||
avatar_url: services
|
||||
.users
|
||||
.avatar_url(&body.user_id)
|
||||
.await
|
||||
.ok(),
|
||||
blurhash: services.users.blurhash(&body.user_id).await.ok(),
|
||||
displayname: services.users.displayname(&body.user_id).await.ok(),
|
||||
displayname: services
|
||||
.users
|
||||
.displayname(&body.user_id)
|
||||
.await
|
||||
.ok(),
|
||||
tz: services.users.timezone(&body.user_id).await.ok(),
|
||||
custom_profile_fields,
|
||||
})
|
||||
@@ -324,7 +346,9 @@ pub async fn update_displayname(
|
||||
return;
|
||||
}
|
||||
|
||||
services.users.set_displayname(user_id, displayname.clone());
|
||||
services
|
||||
.users
|
||||
.set_displayname(user_id, displayname.clone());
|
||||
|
||||
// Send a new join membership event into all joined rooms
|
||||
let avatar_url = ¤t_avatar_url;
|
||||
@@ -376,8 +400,12 @@ pub async fn update_avatar_url(
|
||||
return;
|
||||
}
|
||||
|
||||
services.users.set_avatar_url(user_id, avatar_url.clone());
|
||||
services.users.set_blurhash(user_id, blurhash.clone());
|
||||
services
|
||||
.users
|
||||
.set_avatar_url(user_id, avatar_url.clone());
|
||||
services
|
||||
.users
|
||||
.set_blurhash(user_id, blurhash.clone());
|
||||
|
||||
// Send a new join membership event into all joined rooms
|
||||
let avatar_url = &avatar_url;
|
||||
|
||||
@@ -84,7 +84,9 @@ pub(crate) async fn get_pushrules_all_route(
|
||||
.update(
|
||||
None,
|
||||
sender_user,
|
||||
GlobalAccountDataEventType::PushRules.to_string().into(),
|
||||
GlobalAccountDataEventType::PushRules
|
||||
.to_string()
|
||||
.into(),
|
||||
&serde_json::to_value(PushRulesEvent {
|
||||
content: PushRulesEventContent { global: global_ruleset.clone() },
|
||||
})
|
||||
@@ -106,7 +108,10 @@ pub(crate) async fn get_pushrules_global_route(
|
||||
State(services): State<crate::State>,
|
||||
body: Ruma<get_pushrules_global_scope::v3::Request>,
|
||||
) -> Result<get_pushrules_global_scope::v3::Response> {
|
||||
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
|
||||
let sender_user = body
|
||||
.sender_user
|
||||
.as_ref()
|
||||
.expect("user is authenticated");
|
||||
|
||||
let Some(content_value) = services
|
||||
.account_data
|
||||
@@ -123,7 +128,9 @@ pub(crate) async fn get_pushrules_global_route(
|
||||
.update(
|
||||
None,
|
||||
sender_user,
|
||||
GlobalAccountDataEventType::PushRules.to_string().into(),
|
||||
GlobalAccountDataEventType::PushRules
|
||||
.to_string()
|
||||
.into(),
|
||||
&serde_json::to_value(PushRulesEvent {
|
||||
content: PushRulesEventContent {
|
||||
global: Ruleset::server_default(sender_user),
|
||||
@@ -177,7 +184,9 @@ pub(crate) async fn get_pushrules_global_route(
|
||||
.update(
|
||||
None,
|
||||
sender_user,
|
||||
GlobalAccountDataEventType::PushRules.to_string().into(),
|
||||
GlobalAccountDataEventType::PushRules
|
||||
.to_string()
|
||||
.into(),
|
||||
&serde_json::to_value(PushRulesEvent {
|
||||
content: PushRulesEventContent { global: global_ruleset.clone() },
|
||||
})
|
||||
@@ -197,7 +206,10 @@ pub(crate) async fn get_pushrule_route(
|
||||
State(services): State<crate::State>,
|
||||
body: Ruma<get_pushrule::v3::Request>,
|
||||
) -> Result<get_pushrule::v3::Response> {
|
||||
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
|
||||
let sender_user = body
|
||||
.sender_user
|
||||
.as_ref()
|
||||
.expect("user is authenticated");
|
||||
|
||||
// remove old deprecated mentions push rules as per MSC4210
|
||||
#[allow(deprecated)]
|
||||
@@ -234,7 +246,10 @@ pub(crate) async fn set_pushrule_route(
|
||||
State(services): State<crate::State>,
|
||||
body: Ruma<set_pushrule::v3::Request>,
|
||||
) -> Result<set_pushrule::v3::Response> {
|
||||
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
|
||||
let sender_user = body
|
||||
.sender_user
|
||||
.as_ref()
|
||||
.expect("user is authenticated");
|
||||
let body = body.body;
|
||||
|
||||
let mut account_data: PushRulesEvent = services
|
||||
@@ -280,7 +295,9 @@ pub(crate) async fn set_pushrule_route(
|
||||
.update(
|
||||
None,
|
||||
sender_user,
|
||||
GlobalAccountDataEventType::PushRules.to_string().into(),
|
||||
GlobalAccountDataEventType::PushRules
|
||||
.to_string()
|
||||
.into(),
|
||||
&serde_json::to_value(account_data).expect("to json value always works"),
|
||||
)
|
||||
.await?;
|
||||
@@ -295,7 +312,10 @@ pub(crate) async fn get_pushrule_actions_route(
|
||||
State(services): State<crate::State>,
|
||||
body: Ruma<get_pushrule_actions::v3::Request>,
|
||||
) -> Result<get_pushrule_actions::v3::Response> {
|
||||
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
|
||||
let sender_user = body
|
||||
.sender_user
|
||||
.as_ref()
|
||||
.expect("user is authenticated");
|
||||
|
||||
// remove old deprecated mentions push rules as per MSC4210
|
||||
#[allow(deprecated)]
|
||||
@@ -329,7 +349,10 @@ pub(crate) async fn set_pushrule_actions_route(
|
||||
State(services): State<crate::State>,
|
||||
body: Ruma<set_pushrule_actions::v3::Request>,
|
||||
) -> Result<set_pushrule_actions::v3::Response> {
|
||||
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
|
||||
let sender_user = body
|
||||
.sender_user
|
||||
.as_ref()
|
||||
.expect("user is authenticated");
|
||||
|
||||
let mut account_data: PushRulesEvent = services
|
||||
.account_data
|
||||
@@ -351,7 +374,9 @@ pub(crate) async fn set_pushrule_actions_route(
|
||||
.update(
|
||||
None,
|
||||
sender_user,
|
||||
GlobalAccountDataEventType::PushRules.to_string().into(),
|
||||
GlobalAccountDataEventType::PushRules
|
||||
.to_string()
|
||||
.into(),
|
||||
&serde_json::to_value(account_data).expect("to json value always works"),
|
||||
)
|
||||
.await?;
|
||||
@@ -366,7 +391,10 @@ pub(crate) async fn get_pushrule_enabled_route(
|
||||
State(services): State<crate::State>,
|
||||
body: Ruma<get_pushrule_enabled::v3::Request>,
|
||||
) -> Result<get_pushrule_enabled::v3::Response> {
|
||||
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
|
||||
let sender_user = body
|
||||
.sender_user
|
||||
.as_ref()
|
||||
.expect("user is authenticated");
|
||||
|
||||
// remove old deprecated mentions push rules as per MSC4210
|
||||
#[allow(deprecated)]
|
||||
@@ -400,7 +428,10 @@ pub(crate) async fn set_pushrule_enabled_route(
|
||||
State(services): State<crate::State>,
|
||||
body: Ruma<set_pushrule_enabled::v3::Request>,
|
||||
) -> Result<set_pushrule_enabled::v3::Response> {
|
||||
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
|
||||
let sender_user = body
|
||||
.sender_user
|
||||
.as_ref()
|
||||
.expect("user is authenticated");
|
||||
|
||||
let mut account_data: PushRulesEvent = services
|
||||
.account_data
|
||||
@@ -422,7 +453,9 @@ pub(crate) async fn set_pushrule_enabled_route(
|
||||
.update(
|
||||
None,
|
||||
sender_user,
|
||||
GlobalAccountDataEventType::PushRules.to_string().into(),
|
||||
GlobalAccountDataEventType::PushRules
|
||||
.to_string()
|
||||
.into(),
|
||||
&serde_json::to_value(account_data).expect("to json value always works"),
|
||||
)
|
||||
.await?;
|
||||
@@ -437,7 +470,10 @@ pub(crate) async fn delete_pushrule_route(
|
||||
State(services): State<crate::State>,
|
||||
body: Ruma<delete_pushrule::v3::Request>,
|
||||
) -> Result<delete_pushrule::v3::Response> {
|
||||
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
|
||||
let sender_user = body
|
||||
.sender_user
|
||||
.as_ref()
|
||||
.expect("user is authenticated");
|
||||
|
||||
let mut account_data: PushRulesEvent = services
|
||||
.account_data
|
||||
@@ -468,7 +504,9 @@ pub(crate) async fn delete_pushrule_route(
|
||||
.update(
|
||||
None,
|
||||
sender_user,
|
||||
GlobalAccountDataEventType::PushRules.to_string().into(),
|
||||
GlobalAccountDataEventType::PushRules
|
||||
.to_string()
|
||||
.into(),
|
||||
&serde_json::to_value(account_data).expect("to json value always works"),
|
||||
)
|
||||
.await?;
|
||||
@@ -483,7 +521,10 @@ pub(crate) async fn get_pushers_route(
|
||||
State(services): State<crate::State>,
|
||||
body: Ruma<get_pushers::v3::Request>,
|
||||
) -> Result<get_pushers::v3::Response> {
|
||||
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
|
||||
let sender_user = body
|
||||
.sender_user
|
||||
.as_ref()
|
||||
.expect("user is authenticated");
|
||||
|
||||
Ok(get_pushers::v3::Response {
|
||||
pushers: services.pusher.get_pushers(sender_user).await,
|
||||
@@ -499,7 +540,10 @@ pub(crate) async fn set_pushers_route(
|
||||
State(services): State<crate::State>,
|
||||
body: Ruma<set_pusher::v3::Request>,
|
||||
) -> Result<set_pusher::v3::Response> {
|
||||
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
|
||||
let sender_user = body
|
||||
.sender_user
|
||||
.as_ref()
|
||||
.expect("user is authenticated");
|
||||
|
||||
services
|
||||
.pusher
|
||||
@@ -520,7 +564,9 @@ async fn recreate_push_rules_and_return(
|
||||
.update(
|
||||
None,
|
||||
sender_user,
|
||||
GlobalAccountDataEventType::PushRules.to_string().into(),
|
||||
GlobalAccountDataEventType::PushRules
|
||||
.to_string()
|
||||
.into(),
|
||||
&serde_json::to_value(PushRulesEvent {
|
||||
content: PushRulesEventContent {
|
||||
global: Ruleset::server_default(sender_user),
|
||||
|
||||
@@ -15,10 +15,18 @@ pub(crate) async fn redact_event_route(
|
||||
State(services): State<crate::State>,
|
||||
body: Ruma<redact_event::v3::Request>,
|
||||
) -> Result<redact_event::v3::Response> {
|
||||
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
|
||||
let sender_user = body
|
||||
.sender_user
|
||||
.as_ref()
|
||||
.expect("user is authenticated");
|
||||
let body = body.body;
|
||||
|
||||
let state_lock = services.rooms.state.mutex.lock(&body.room_id).await;
|
||||
let state_lock = services
|
||||
.rooms
|
||||
.state
|
||||
.mutex
|
||||
.lock(&body.room_id)
|
||||
.await;
|
||||
|
||||
let event_id = services
|
||||
.rooms
|
||||
|
||||
@@ -30,7 +30,10 @@ pub(crate) async fn report_room_route(
|
||||
body: Ruma<report_room::v3::Request>,
|
||||
) -> Result<report_room::v3::Response> {
|
||||
// user authentication
|
||||
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
|
||||
let sender_user = body
|
||||
.sender_user
|
||||
.as_ref()
|
||||
.expect("user is authenticated");
|
||||
|
||||
info!(
|
||||
"Received room report by user {sender_user} for room {} with reason: \"{}\"",
|
||||
@@ -38,7 +41,11 @@ pub(crate) async fn report_room_route(
|
||||
body.reason.as_deref().unwrap_or("")
|
||||
);
|
||||
|
||||
if body.reason.as_ref().is_some_and(|s| s.len() > 750) {
|
||||
if body
|
||||
.reason
|
||||
.as_ref()
|
||||
.is_some_and(|s| s.len() > 750)
|
||||
{
|
||||
return Err(Error::BadRequest(
|
||||
ErrorKind::InvalidParam,
|
||||
"Reason too long, should be 750 characters or fewer",
|
||||
@@ -84,7 +91,10 @@ pub(crate) async fn report_event_route(
|
||||
body: Ruma<report_content::v3::Request>,
|
||||
) -> Result<report_content::v3::Response> {
|
||||
// user authentication
|
||||
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
|
||||
let sender_user = body
|
||||
.sender_user
|
||||
.as_ref()
|
||||
.expect("user is authenticated");
|
||||
|
||||
info!(
|
||||
"Received event report by user {sender_user} for room {} and event ID {}, with reason: \
|
||||
@@ -97,7 +107,12 @@ pub(crate) async fn report_event_route(
|
||||
delay_response().await;
|
||||
|
||||
// check if we know about the reported event ID or if it's invalid
|
||||
let Ok(pdu) = services.rooms.timeline.get_pdu(&body.event_id).await else {
|
||||
let Ok(pdu) = services
|
||||
.rooms
|
||||
.timeline
|
||||
.get_pdu(&body.event_id)
|
||||
.await
|
||||
else {
|
||||
return Err!(Request(NotFound("Event ID is not known to us or Event ID is invalid")));
|
||||
};
|
||||
|
||||
|
||||
@@ -15,7 +15,10 @@ pub(crate) async fn get_room_aliases_route(
|
||||
State(services): State<crate::State>,
|
||||
body: Ruma<aliases::v3::Request>,
|
||||
) -> Result<aliases::v3::Response> {
|
||||
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
|
||||
let sender_user = body
|
||||
.sender_user
|
||||
.as_ref()
|
||||
.expect("user is authenticated");
|
||||
|
||||
if !services
|
||||
.rooms
|
||||
|
||||
@@ -58,7 +58,10 @@ pub(crate) async fn create_room_route(
|
||||
) -> Result<create_room::v3::Response> {
|
||||
use create_room::v3::RoomPreset;
|
||||
|
||||
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
|
||||
let sender_user = body
|
||||
.sender_user
|
||||
.as_ref()
|
||||
.expect("user is authenticated");
|
||||
|
||||
if !services.globals.allow_room_creation()
|
||||
&& body.appservice_info.is_none()
|
||||
@@ -76,7 +79,13 @@ pub(crate) async fn create_room_route(
|
||||
};
|
||||
|
||||
// check if room ID doesn't already exist instead of erroring on auth check
|
||||
if services.rooms.short.get_shortroomid(&room_id).await.is_ok() {
|
||||
if services
|
||||
.rooms
|
||||
.short
|
||||
.get_shortroomid(&room_id)
|
||||
.await
|
||||
.is_ok()
|
||||
{
|
||||
return Err(Error::BadRequest(
|
||||
ErrorKind::RoomInUse,
|
||||
"Room with that custom room ID already exists",
|
||||
@@ -84,7 +93,10 @@ pub(crate) async fn create_room_route(
|
||||
}
|
||||
|
||||
if body.visibility == room::Visibility::Public
|
||||
&& services.server.config.lockdown_public_room_directory
|
||||
&& services
|
||||
.server
|
||||
.config
|
||||
.lockdown_public_room_directory
|
||||
&& !services.users.is_admin(sender_user).await
|
||||
&& body.appservice_info.is_none()
|
||||
{
|
||||
@@ -123,7 +135,10 @@ pub(crate) async fn create_room_route(
|
||||
|
||||
let room_version = match body.room_version.clone() {
|
||||
| Some(room_version) =>
|
||||
if services.server.supported_room_version(&room_version) {
|
||||
if services
|
||||
.server
|
||||
.supported_room_version(&room_version)
|
||||
{
|
||||
room_version
|
||||
} else {
|
||||
return Err(Error::BadRequest(
|
||||
@@ -131,7 +146,11 @@ pub(crate) async fn create_room_route(
|
||||
"This server does not support that room version.",
|
||||
));
|
||||
},
|
||||
| None => services.server.config.default_room_version.clone(),
|
||||
| None => services
|
||||
.server
|
||||
.config
|
||||
.default_room_version
|
||||
.clone(),
|
||||
};
|
||||
|
||||
let create_content = match &body.creation_content {
|
||||
@@ -160,7 +179,9 @@ pub(crate) async fn create_room_route(
|
||||
}
|
||||
content.insert(
|
||||
"room_version".into(),
|
||||
json!(room_version.as_str()).try_into().map_err(|_| {
|
||||
json!(room_version.as_str())
|
||||
.try_into()
|
||||
.map_err(|_| {
|
||||
Error::BadRequest(ErrorKind::BadJson, "Invalid creation content")
|
||||
})?,
|
||||
);
|
||||
@@ -231,7 +252,10 @@ pub(crate) async fn create_room_route(
|
||||
// 3. Power levels
|
||||
|
||||
// Figure out preset. We need it for preset specific events
|
||||
let preset = body.preset.clone().unwrap_or(match &body.visibility {
|
||||
let preset = body
|
||||
.preset
|
||||
.clone()
|
||||
.unwrap_or(match &body.visibility {
|
||||
| room::Visibility::Public => RoomPreset::PublicChat,
|
||||
| _ => RoomPreset::PrivateChat, // Room visibility should not be custom
|
||||
});
|
||||
@@ -240,9 +264,17 @@ pub(crate) async fn create_room_route(
|
||||
|
||||
if preset == RoomPreset::TrustedPrivateChat {
|
||||
for invite in &body.invite {
|
||||
if services.users.user_is_ignored(sender_user, invite).await {
|
||||
if services
|
||||
.users
|
||||
.user_is_ignored(sender_user, invite)
|
||||
.await
|
||||
{
|
||||
continue;
|
||||
} else if services.users.user_is_ignored(invite, sender_user).await {
|
||||
} else if services
|
||||
.users
|
||||
.user_is_ignored(invite, sender_user)
|
||||
.await
|
||||
{
|
||||
// silently drop the invite to the recipient if they've been ignored by the
|
||||
// sender, pretend it worked
|
||||
continue;
|
||||
@@ -353,7 +385,9 @@ pub(crate) async fn create_room_route(
|
||||
|
||||
// 6. Events listed in initial_state
|
||||
for event in &body.initial_state {
|
||||
let mut pdu_builder = event.deserialize_as::<PduBuilder>().map_err(|e| {
|
||||
let mut pdu_builder = event
|
||||
.deserialize_as::<PduBuilder>()
|
||||
.map_err(|e| {
|
||||
warn!("Invalid initial state event: {:?}", e);
|
||||
Error::BadRequest(ErrorKind::InvalidParam, "Invalid initial state event.")
|
||||
})?;
|
||||
@@ -370,7 +404,9 @@ pub(crate) async fn create_room_route(
|
||||
}
|
||||
|
||||
// Implicit state key defaults to ""
|
||||
pdu_builder.state_key.get_or_insert_with(StateKey::new);
|
||||
pdu_builder
|
||||
.state_key
|
||||
.get_or_insert_with(StateKey::new);
|
||||
|
||||
// Silently skip encryption events if they are not allowed
|
||||
if pdu_builder.event_type == TimelineEventType::RoomEncryption
|
||||
@@ -419,9 +455,17 @@ pub(crate) async fn create_room_route(
|
||||
// 8. Events implied by invite (and TODO: invite_3pid)
|
||||
drop(state_lock);
|
||||
for user_id in &body.invite {
|
||||
if services.users.user_is_ignored(sender_user, user_id).await {
|
||||
if services
|
||||
.users
|
||||
.user_is_ignored(sender_user, user_id)
|
||||
.await
|
||||
{
|
||||
continue;
|
||||
} else if services.users.user_is_ignored(user_id, sender_user).await {
|
||||
} else if services
|
||||
.users
|
||||
.user_is_ignored(user_id, sender_user)
|
||||
.await
|
||||
{
|
||||
// silently drop the invite to the recipient if they've been ignored by the
|
||||
// sender, pretend it worked
|
||||
continue;
|
||||
|
||||
@@ -43,7 +43,11 @@ pub(crate) async fn room_initial_sync_route(
|
||||
.await?;
|
||||
|
||||
let messages = PaginationChunk {
|
||||
start: events.last().map(at!(0)).as_ref().map(ToString::to_string),
|
||||
start: events
|
||||
.last()
|
||||
.map(at!(0))
|
||||
.as_ref()
|
||||
.map(ToString::to_string),
|
||||
|
||||
end: events
|
||||
.first()
|
||||
@@ -64,7 +68,12 @@ pub(crate) async fn room_initial_sync_route(
|
||||
account_data: None,
|
||||
state: state.into(),
|
||||
messages: messages.chunk.is_empty().or_some(messages),
|
||||
visibility: services.rooms.directory.visibility(room_id).await.into(),
|
||||
visibility: services
|
||||
.rooms
|
||||
.directory
|
||||
.visibility(room_id)
|
||||
.await
|
||||
.into(),
|
||||
membership: services
|
||||
.rooms
|
||||
.state_cache
|
||||
|
||||
@@ -102,7 +102,9 @@ async fn room_summary_response(
|
||||
room_version: room.room_version,
|
||||
encryption: room.encryption,
|
||||
allowed_room_ids: room.allowed_room_ids,
|
||||
membership: sender_user.is_some().then_some(MembershipState::Leave),
|
||||
membership: sender_user
|
||||
.is_some()
|
||||
.then_some(MembershipState::Leave),
|
||||
})
|
||||
}
|
||||
|
||||
@@ -112,9 +114,18 @@ async fn local_room_summary_response(
|
||||
sender_user: Option<&UserId>,
|
||||
) -> Result<get_summary::msc3266::Response> {
|
||||
trace!(?sender_user, "Sending local room summary response for {room_id:?}");
|
||||
let join_rule = services.rooms.state_accessor.get_join_rules(room_id);
|
||||
let world_readable = services.rooms.state_accessor.is_world_readable(room_id);
|
||||
let guest_can_join = services.rooms.state_accessor.guest_can_join(room_id);
|
||||
let join_rule = services
|
||||
.rooms
|
||||
.state_accessor
|
||||
.get_join_rules(room_id);
|
||||
let world_readable = services
|
||||
.rooms
|
||||
.state_accessor
|
||||
.is_world_readable(room_id);
|
||||
let guest_can_join = services
|
||||
.rooms
|
||||
.state_accessor
|
||||
.guest_can_join(room_id);
|
||||
|
||||
let (join_rule, world_readable, guest_can_join) =
|
||||
join3(join_rule, world_readable, guest_can_join).await;
|
||||
@@ -137,11 +148,23 @@ async fn local_room_summary_response(
|
||||
.get_canonical_alias(room_id)
|
||||
.ok();
|
||||
|
||||
let name = services.rooms.state_accessor.get_name(room_id).ok();
|
||||
let name = services
|
||||
.rooms
|
||||
.state_accessor
|
||||
.get_name(room_id)
|
||||
.ok();
|
||||
|
||||
let topic = services.rooms.state_accessor.get_room_topic(room_id).ok();
|
||||
let topic = services
|
||||
.rooms
|
||||
.state_accessor
|
||||
.get_room_topic(room_id)
|
||||
.ok();
|
||||
|
||||
let room_type = services.rooms.state_accessor.get_room_type(room_id).ok();
|
||||
let room_type = services
|
||||
.rooms
|
||||
.state_accessor
|
||||
.get_room_type(room_id)
|
||||
.ok();
|
||||
|
||||
let avatar_url = services
|
||||
.rooms
|
||||
@@ -149,7 +172,11 @@ async fn local_room_summary_response(
|
||||
.get_avatar(room_id)
|
||||
.map(|res| res.into_option().unwrap_or_default().url);
|
||||
|
||||
let room_version = services.rooms.state.get_room_version(room_id).ok();
|
||||
let room_version = services
|
||||
.rooms
|
||||
.state
|
||||
.get_room_version(room_id)
|
||||
.ok();
|
||||
|
||||
let encryption = services
|
||||
.rooms
|
||||
@@ -208,7 +235,10 @@ async fn local_room_summary_response(
|
||||
room_version,
|
||||
encryption,
|
||||
membership,
|
||||
allowed_room_ids: join_rule.allowed_rooms().map(Into::into).collect(),
|
||||
allowed_room_ids: join_rule
|
||||
.allowed_rooms()
|
||||
.map(Into::into)
|
||||
.collect(),
|
||||
join_rule: join_rule.into(),
|
||||
})
|
||||
}
|
||||
@@ -292,10 +322,16 @@ where
|
||||
.rooms
|
||||
.state_accessor
|
||||
.user_can_see_state_events(sender_user, room_id);
|
||||
let is_guest = services.users.is_deactivated(sender_user).unwrap_or(false);
|
||||
let user_in_allowed_restricted_room = allowed_room_ids
|
||||
.stream()
|
||||
.any(|room| services.rooms.state_cache.is_joined(sender_user, room));
|
||||
let is_guest = services
|
||||
.users
|
||||
.is_deactivated(sender_user)
|
||||
.unwrap_or(false);
|
||||
let user_in_allowed_restricted_room = allowed_room_ids.stream().any(|room| {
|
||||
services
|
||||
.rooms
|
||||
.state_cache
|
||||
.is_joined(sender_user, room)
|
||||
});
|
||||
|
||||
let (user_can_see_state_events, is_guest, user_in_allowed_restricted_room) =
|
||||
join3(user_can_see_state_events, is_guest, user_in_allowed_restricted_room)
|
||||
|
||||
@@ -54,9 +54,15 @@ pub(crate) async fn upgrade_room_route(
|
||||
TRANSFERABLE_STATE_EVENTS.is_sorted(),
|
||||
"TRANSFERABLE_STATE_EVENTS is not sorted"
|
||||
);
|
||||
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
|
||||
let sender_user = body
|
||||
.sender_user
|
||||
.as_ref()
|
||||
.expect("user is authenticated");
|
||||
|
||||
if !services.server.supported_room_version(&body.new_version) {
|
||||
if !services
|
||||
.server
|
||||
.supported_room_version(&body.new_version)
|
||||
{
|
||||
return Err(Error::BadRequest(
|
||||
ErrorKind::UnsupportedRoomVersion,
|
||||
"This server does not support that room version.",
|
||||
@@ -72,7 +78,12 @@ pub(crate) async fn upgrade_room_route(
|
||||
.get_or_create_shortroomid(&replacement_room)
|
||||
.await;
|
||||
|
||||
let state_lock = services.rooms.state.mutex.lock(&body.room_id).await;
|
||||
let state_lock = services
|
||||
.rooms
|
||||
.state
|
||||
.mutex
|
||||
.lock(&body.room_id)
|
||||
.await;
|
||||
|
||||
// Send a m.room.tombstone event to the old room to indicate that it is not
|
||||
// intended to be used any further Fail if the sender does not have the required
|
||||
@@ -93,7 +104,12 @@ pub(crate) async fn upgrade_room_route(
|
||||
|
||||
// Change lock to replacement room
|
||||
drop(state_lock);
|
||||
let state_lock = services.rooms.state.mutex.lock(&replacement_room).await;
|
||||
let state_lock = services
|
||||
.rooms
|
||||
.state
|
||||
.mutex
|
||||
.lock(&replacement_room)
|
||||
.await;
|
||||
|
||||
// Get the old room creation event
|
||||
let mut create_event_content: CanonicalJsonObject = services
|
||||
|
||||
@@ -110,7 +110,12 @@ async fn category_room_events(
|
||||
limit,
|
||||
};
|
||||
|
||||
let (count, results) = services.rooms.search.search_pdus(&query).await.ok()?;
|
||||
let (count, results) = services
|
||||
.rooms
|
||||
.search
|
||||
.search_pdus(&query)
|
||||
.await
|
||||
.ok()?;
|
||||
|
||||
results
|
||||
.collect::<Vec<_>>()
|
||||
@@ -201,8 +206,12 @@ async fn check_room_visible(
|
||||
let check_visible = search.filter.rooms.is_some();
|
||||
let check_state = check_visible && search.include_state.is_some_and(is_true!());
|
||||
|
||||
let is_joined =
|
||||
!check_visible || services.rooms.state_cache.is_joined(user_id, room_id).await;
|
||||
let is_joined = !check_visible
|
||||
|| services
|
||||
.rooms
|
||||
.state_cache
|
||||
.is_joined(user_id, room_id)
|
||||
.await;
|
||||
|
||||
let state_visible = !check_state
|
||||
|| services
|
||||
|
||||
@@ -30,10 +30,19 @@ pub(crate) async fn send_message_event_route(
|
||||
return Err!(Request(Forbidden("Encryption has been disabled")));
|
||||
}
|
||||
|
||||
let state_lock = services.rooms.state.mutex.lock(&body.room_id).await;
|
||||
let state_lock = services
|
||||
.rooms
|
||||
.state
|
||||
.mutex
|
||||
.lock(&body.room_id)
|
||||
.await;
|
||||
|
||||
if body.event_type == MessageLikeEventType::CallInvite
|
||||
&& services.rooms.directory.is_public_room(&body.room_id).await
|
||||
&& services
|
||||
.rooms
|
||||
.directory
|
||||
.is_public_room(&body.room_id)
|
||||
.await
|
||||
{
|
||||
return Err!(Request(Forbidden("Room call invites are not allowed in public rooms")));
|
||||
}
|
||||
|
||||
@@ -100,7 +100,9 @@ pub(crate) async fn login_route(
|
||||
)?;
|
||||
|
||||
if !services.globals.user_is_local(&user_id)
|
||||
|| !services.globals.user_is_local(&lowercased_user_id)
|
||||
|| !services
|
||||
.globals
|
||||
.user_is_local(&lowercased_user_id)
|
||||
{
|
||||
return Err!(Request(Unknown("User ID does not belong to this homeserver")));
|
||||
}
|
||||
@@ -149,7 +151,10 @@ pub(crate) async fn login_route(
|
||||
if !services.server.config.login_via_existing_session {
|
||||
return Err!(Request(Unknown("Token login is not enabled.")));
|
||||
}
|
||||
services.users.find_from_login_token(token).await?
|
||||
services
|
||||
.users
|
||||
.find_from_login_token(token)
|
||||
.await?
|
||||
},
|
||||
#[allow(deprecated)]
|
||||
| login::v3::LoginInfo::ApplicationService(login::v3::ApplicationService {
|
||||
@@ -312,7 +317,9 @@ pub(crate) async fn login_token_route(
|
||||
}
|
||||
|
||||
let login_token = utils::random_string(TOKEN_LENGTH);
|
||||
let expires_in = services.users.create_login_token(sender_user, &login_token);
|
||||
let expires_in = services
|
||||
.users
|
||||
.create_login_token(sender_user, &login_token);
|
||||
|
||||
Ok(get_login_token::v1::Response {
|
||||
expires_in: Duration::from_millis(expires_in),
|
||||
@@ -335,8 +342,14 @@ pub(crate) async fn logout_route(
|
||||
InsecureClientIp(client): InsecureClientIp,
|
||||
body: Ruma<logout::v3::Request>,
|
||||
) -> Result<logout::v3::Response> {
|
||||
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
|
||||
let sender_device = body.sender_device.as_ref().expect("user is authenticated");
|
||||
let sender_user = body
|
||||
.sender_user
|
||||
.as_ref()
|
||||
.expect("user is authenticated");
|
||||
let sender_device = body
|
||||
.sender_device
|
||||
.as_ref()
|
||||
.expect("user is authenticated");
|
||||
|
||||
services
|
||||
.users
|
||||
@@ -365,12 +378,19 @@ pub(crate) async fn logout_all_route(
|
||||
InsecureClientIp(client): InsecureClientIp,
|
||||
body: Ruma<logout_all::v3::Request>,
|
||||
) -> Result<logout_all::v3::Response> {
|
||||
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
|
||||
let sender_user = body
|
||||
.sender_user
|
||||
.as_ref()
|
||||
.expect("user is authenticated");
|
||||
|
||||
services
|
||||
.users
|
||||
.all_device_ids(sender_user)
|
||||
.for_each(|device_id| services.users.remove_device(sender_user, device_id))
|
||||
.for_each(|device_id| {
|
||||
services
|
||||
.users
|
||||
.remove_device(sender_user, device_id)
|
||||
})
|
||||
.await;
|
||||
|
||||
Ok(logout_all::v3::Response::new())
|
||||
|
||||
@@ -73,7 +73,10 @@ pub(crate) async fn get_state_events_route(
|
||||
State(services): State<crate::State>,
|
||||
body: Ruma<get_state_events::v3::Request>,
|
||||
) -> Result<get_state_events::v3::Response> {
|
||||
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
|
||||
let sender_user = body
|
||||
.sender_user
|
||||
.as_ref()
|
||||
.expect("user is authenticated");
|
||||
|
||||
if !services
|
||||
.rooms
|
||||
|
||||
@@ -51,7 +51,11 @@ async fn load_timeline(
|
||||
|
||||
// Take the last events for the timeline
|
||||
pin_mut!(non_timeline_pdus);
|
||||
let timeline_pdus: Vec<_> = non_timeline_pdus.by_ref().take(limit).collect().await;
|
||||
let timeline_pdus: Vec<_> = non_timeline_pdus
|
||||
.by_ref()
|
||||
.take(limit)
|
||||
.collect()
|
||||
.await;
|
||||
|
||||
let timeline_pdus: Vec<_> = timeline_pdus.into_iter().rev().collect();
|
||||
|
||||
|
||||
@@ -480,7 +480,10 @@ async fn handle_left_room(
|
||||
|
||||
let mut left_state_events = Vec::new();
|
||||
|
||||
let since_shortstatehash = services.rooms.user.get_token_shortstatehash(room_id, since);
|
||||
let since_shortstatehash = services
|
||||
.rooms
|
||||
.user
|
||||
.get_token_shortstatehash(room_id, since);
|
||||
|
||||
let since_state_ids: HashMap<_, OwnedEventId> = since_shortstatehash
|
||||
.map_ok(|since_shortstatehash| {
|
||||
@@ -640,7 +643,11 @@ async fn load_joined_room(
|
||||
let (timeline_pdus, limited) = timeline;
|
||||
let initial = since_shortstatehash.is_none();
|
||||
let lazy_loading_enabled = filter.room.state.lazy_load_options.is_enabled()
|
||||
|| filter.room.timeline.lazy_load_options.is_enabled();
|
||||
|| filter
|
||||
.room
|
||||
.timeline
|
||||
.lazy_load_options
|
||||
.is_enabled();
|
||||
|
||||
let lazy_loading_context = &lazy_loading::Context {
|
||||
user_id: sender_user,
|
||||
@@ -652,7 +659,12 @@ async fn load_joined_room(
|
||||
|
||||
// Reset lazy loading because this is an initial sync
|
||||
let lazy_load_reset: OptionFuture<_> = initial
|
||||
.then(|| services.rooms.lazy_loading.reset(lazy_loading_context))
|
||||
.then(|| {
|
||||
services
|
||||
.rooms
|
||||
.lazy_loading
|
||||
.reset(lazy_loading_context)
|
||||
})
|
||||
.into();
|
||||
|
||||
lazy_load_reset.await;
|
||||
@@ -964,7 +976,10 @@ async fn calculate_state_initial(
|
||||
.ready_filter_map(|((event_type, state_key), event_id)| {
|
||||
let lazy = !full_state
|
||||
&& event_type == StateEventType::RoomMember
|
||||
&& state_key.as_str().try_into().is_ok_and(|user_id: &UserId| {
|
||||
&& state_key
|
||||
.as_str()
|
||||
.try_into()
|
||||
.is_ok_and(|user_id: &UserId| {
|
||||
sender_user != user_id
|
||||
&& witness.is_some_and(|witness| !witness.contains(user_id))
|
||||
});
|
||||
@@ -972,7 +987,12 @@ async fn calculate_state_initial(
|
||||
lazy.or_some(event_id)
|
||||
})
|
||||
.broad_filter_map(|event_id: OwnedEventId| async move {
|
||||
services.rooms.timeline.get_pdu(&event_id).await.ok()
|
||||
services
|
||||
.rooms
|
||||
.timeline
|
||||
.get_pdu(&event_id)
|
||||
.await
|
||||
.ok()
|
||||
})
|
||||
.collect()
|
||||
.map(Ok);
|
||||
@@ -1085,7 +1105,12 @@ async fn calculate_state_incremental<'a>(
|
||||
.ok()
|
||||
})
|
||||
.broad_filter_map(|event_id: OwnedEventId| async move {
|
||||
services.rooms.timeline.get_pdu(&event_id).await.ok()
|
||||
services
|
||||
.rooms
|
||||
.timeline
|
||||
.get_pdu(&event_id)
|
||||
.await
|
||||
.ok()
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
.await;
|
||||
@@ -1118,7 +1143,9 @@ async fn calculate_state_incremental<'a>(
|
||||
})
|
||||
.await;
|
||||
|
||||
let send_member_count = state_events.iter().any(|event| event.kind == RoomMember);
|
||||
let send_member_count = state_events
|
||||
.iter()
|
||||
.any(|event| event.kind == RoomMember);
|
||||
|
||||
let (joined_member_count, invited_member_count, heroes) = if send_member_count {
|
||||
calculate_counts(services, room_id, sender_user).await?
|
||||
@@ -1205,8 +1232,11 @@ async fn fold_hero(
|
||||
sender_user: &UserId,
|
||||
pdu: PduEvent,
|
||||
) -> Vec<OwnedUserId> {
|
||||
let Some(user_id): Option<&UserId> =
|
||||
pdu.state_key.as_deref().map(TryInto::try_into).flat_ok()
|
||||
let Some(user_id): Option<&UserId> = pdu
|
||||
.state_key
|
||||
.as_deref()
|
||||
.map(TryInto::try_into)
|
||||
.flat_ok()
|
||||
else {
|
||||
return heroes;
|
||||
};
|
||||
@@ -1229,8 +1259,14 @@ async fn fold_hero(
|
||||
}
|
||||
|
||||
let (is_invited, is_joined) = join(
|
||||
services.rooms.state_cache.is_invited(user_id, room_id),
|
||||
services.rooms.state_cache.is_joined(user_id, room_id),
|
||||
services
|
||||
.rooms
|
||||
.state_cache
|
||||
.is_invited(user_id, room_id),
|
||||
services
|
||||
.rooms
|
||||
.state_cache
|
||||
.is_joined(user_id, room_id),
|
||||
)
|
||||
.await;
|
||||
|
||||
|
||||
@@ -53,8 +53,14 @@ pub(crate) async fn sync_events_v4_route(
|
||||
body: Ruma<sync_events::v4::Request>,
|
||||
) -> Result<sync_events::v4::Response> {
|
||||
debug_assert!(DEFAULT_BUMP_TYPES.is_sorted(), "DEFAULT_BUMP_TYPES is not sorted");
|
||||
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
|
||||
let sender_device = body.sender_device.as_ref().expect("user is authenticated");
|
||||
let sender_user = body
|
||||
.sender_user
|
||||
.as_ref()
|
||||
.expect("user is authenticated");
|
||||
let sender_device = body
|
||||
.sender_device
|
||||
.as_ref()
|
||||
.expect("user is authenticated");
|
||||
let mut body = body.body;
|
||||
|
||||
// Setup watchers, so if there's no response, we can wait for them
|
||||
@@ -80,7 +86,9 @@ pub(crate) async fn sync_events_v4_route(
|
||||
}
|
||||
|
||||
if globalsince == 0 {
|
||||
services.sync.forget_sync_request_connection(&db_key);
|
||||
services
|
||||
.sync
|
||||
.forget_sync_request_connection(&db_key);
|
||||
}
|
||||
|
||||
// Get sticky parameters from cache
|
||||
@@ -113,8 +121,14 @@ pub(crate) async fn sync_events_v4_route(
|
||||
.collect()
|
||||
.await;
|
||||
|
||||
let all_invited_rooms: Vec<&RoomId> = all_invited_rooms.iter().map(AsRef::as_ref).collect();
|
||||
let all_knocked_rooms: Vec<&RoomId> = all_knocked_rooms.iter().map(AsRef::as_ref).collect();
|
||||
let all_invited_rooms: Vec<&RoomId> = all_invited_rooms
|
||||
.iter()
|
||||
.map(AsRef::as_ref)
|
||||
.collect();
|
||||
let all_knocked_rooms: Vec<&RoomId> = all_knocked_rooms
|
||||
.iter()
|
||||
.map(AsRef::as_ref)
|
||||
.collect();
|
||||
|
||||
let all_rooms: Vec<&RoomId> = all_joined_rooms
|
||||
.iter()
|
||||
@@ -123,8 +137,14 @@ pub(crate) async fn sync_events_v4_route(
|
||||
.chain(all_knocked_rooms.iter().map(AsRef::as_ref))
|
||||
.collect();
|
||||
|
||||
let all_joined_rooms = all_joined_rooms.iter().map(AsRef::as_ref).collect();
|
||||
let all_invited_rooms = all_invited_rooms.iter().map(AsRef::as_ref).collect();
|
||||
let all_joined_rooms = all_joined_rooms
|
||||
.iter()
|
||||
.map(AsRef::as_ref)
|
||||
.collect();
|
||||
let all_invited_rooms = all_invited_rooms
|
||||
.iter()
|
||||
.map(AsRef::as_ref)
|
||||
.collect();
|
||||
|
||||
if body.extensions.to_device.enabled.unwrap_or(false) {
|
||||
services
|
||||
@@ -143,7 +163,12 @@ pub(crate) async fn sync_events_v4_route(
|
||||
global: Vec::new(),
|
||||
rooms: BTreeMap::new(),
|
||||
};
|
||||
if body.extensions.account_data.enabled.unwrap_or(false) {
|
||||
if body
|
||||
.extensions
|
||||
.account_data
|
||||
.enabled
|
||||
.unwrap_or(false)
|
||||
{
|
||||
account_data.global = services
|
||||
.account_data
|
||||
.changes_since(None, sender_user, globalsince, Some(next_batch))
|
||||
@@ -179,8 +204,11 @@ pub(crate) async fn sync_events_v4_route(
|
||||
|
||||
for room_id in &all_joined_rooms {
|
||||
let room_id: &&RoomId = room_id;
|
||||
let Ok(current_shortstatehash) =
|
||||
services.rooms.state.get_room_shortstatehash(room_id).await
|
||||
let Ok(current_shortstatehash) = services
|
||||
.rooms
|
||||
.state
|
||||
.get_room_shortstatehash(room_id)
|
||||
.await
|
||||
else {
|
||||
error!("Room {room_id} has no state");
|
||||
continue;
|
||||
@@ -373,13 +401,16 @@ pub(crate) async fn sync_events_v4_route(
|
||||
Vec::new()
|
||||
};
|
||||
|
||||
new_known_rooms.extend(room_ids.clone().into_iter().map(ToOwned::to_owned));
|
||||
new_known_rooms.extend(
|
||||
room_ids
|
||||
.clone()
|
||||
.into_iter()
|
||||
.map(ToOwned::to_owned),
|
||||
);
|
||||
for room_id in &room_ids {
|
||||
let todo_room = todo_rooms.entry((*room_id).to_owned()).or_insert((
|
||||
BTreeSet::new(),
|
||||
0_usize,
|
||||
u64::MAX,
|
||||
));
|
||||
let todo_room = todo_rooms
|
||||
.entry((*room_id).to_owned())
|
||||
.or_insert((BTreeSet::new(), 0_usize, u64::MAX));
|
||||
|
||||
let limit: usize = list
|
||||
.room_details
|
||||
@@ -409,7 +440,10 @@ pub(crate) async fn sync_events_v4_route(
|
||||
op: SlidingOp::Sync,
|
||||
range: Some(r),
|
||||
index: None,
|
||||
room_ids: room_ids.into_iter().map(ToOwned::to_owned).collect(),
|
||||
room_ids: room_ids
|
||||
.into_iter()
|
||||
.map(ToOwned::to_owned)
|
||||
.collect(),
|
||||
room_id: None,
|
||||
}
|
||||
})
|
||||
@@ -575,7 +609,10 @@ pub(crate) async fn sync_events_v4_route(
|
||||
|
||||
if roomsince != &0
|
||||
&& timeline_pdus.is_empty()
|
||||
&& account_data.rooms.get(room_id).is_some_and(Vec::is_empty)
|
||||
&& account_data
|
||||
.rooms
|
||||
.get(room_id)
|
||||
.is_some_and(Vec::is_empty)
|
||||
&& receipt_size == 0
|
||||
{
|
||||
continue;
|
||||
@@ -610,8 +647,9 @@ pub(crate) async fn sync_events_v4_route(
|
||||
|
||||
for (_, pdu) in timeline_pdus {
|
||||
let ts = MilliSecondsSinceUnixEpoch(pdu.origin_server_ts);
|
||||
if DEFAULT_BUMP_TYPES.binary_search(&pdu.kind).is_ok()
|
||||
&& timestamp.is_none_or(|time| time <= ts)
|
||||
if DEFAULT_BUMP_TYPES
|
||||
.binary_search(&pdu.kind)
|
||||
.is_ok() && timestamp.is_none_or(|time| time <= ts)
|
||||
{
|
||||
timestamp = Some(ts);
|
||||
}
|
||||
@@ -658,7 +696,11 @@ pub(crate) async fn sync_events_v4_route(
|
||||
| Ordering::Greater => {
|
||||
let firsts = heroes[1..]
|
||||
.iter()
|
||||
.map(|h| h.name.clone().unwrap_or_else(|| h.user_id.to_string()))
|
||||
.map(|h| {
|
||||
h.name
|
||||
.clone()
|
||||
.unwrap_or_else(|| h.user_id.to_string())
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
.join(", ");
|
||||
|
||||
@@ -694,7 +736,12 @@ pub(crate) async fn sync_events_v4_route(
|
||||
.or(name),
|
||||
avatar: match heroes_avatar {
|
||||
| Some(heroes_avatar) => ruma::JsOption::Some(heroes_avatar),
|
||||
| _ => match services.rooms.state_accessor.get_avatar(room_id).await {
|
||||
| _ => match services
|
||||
.rooms
|
||||
.state_accessor
|
||||
.get_avatar(room_id)
|
||||
.await
|
||||
{
|
||||
| ruma::JsOption::Some(avatar) => ruma::JsOption::from_option(avatar.url),
|
||||
| ruma::JsOption::Null => ruma::JsOption::Null,
|
||||
| ruma::JsOption::Undefined => ruma::JsOption::Undefined,
|
||||
@@ -817,9 +864,16 @@ async fn filter_rooms<'a>(
|
||||
.iter()
|
||||
.stream()
|
||||
.filter_map(|r| async move {
|
||||
let room_type = services.rooms.state_accessor.get_room_type(r).await;
|
||||
let room_type = services
|
||||
.rooms
|
||||
.state_accessor
|
||||
.get_room_type(r)
|
||||
.await;
|
||||
|
||||
if room_type.as_ref().is_err_and(|e| !e.is_not_found()) {
|
||||
if room_type
|
||||
.as_ref()
|
||||
.is_err_and(|e| !e.is_not_found())
|
||||
{
|
||||
return None;
|
||||
}
|
||||
|
||||
|
||||
@@ -63,8 +63,14 @@ pub(crate) async fn sync_events_v5_route(
|
||||
body: Ruma<sync_events::v5::Request>,
|
||||
) -> Result<sync_events::v5::Response> {
|
||||
debug_assert!(DEFAULT_BUMP_TYPES.is_sorted(), "DEFAULT_BUMP_TYPES is not sorted");
|
||||
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
|
||||
let sender_device = body.sender_device.as_ref().expect("user is authenticated");
|
||||
let sender_user = body
|
||||
.sender_user
|
||||
.as_ref()
|
||||
.expect("user is authenticated");
|
||||
let sender_device = body
|
||||
.sender_device
|
||||
.as_ref()
|
||||
.expect("user is authenticated");
|
||||
let mut body = body.body;
|
||||
|
||||
// Setup watchers, so if there's no response, we can wait for them
|
||||
@@ -90,7 +96,9 @@ pub(crate) async fn sync_events_v5_route(
|
||||
|
||||
// Client / User requested an initial sync
|
||||
if globalsince == 0 {
|
||||
services.sync.forget_snake_sync_connection(&snake_key);
|
||||
services
|
||||
.sync
|
||||
.forget_snake_sync_connection(&snake_key);
|
||||
}
|
||||
|
||||
// Get sticky parameters from cache
|
||||
@@ -191,7 +199,11 @@ pub(crate) async fn sync_events_v5_route(
|
||||
if response.rooms.iter().all(|(id, r)| {
|
||||
r.timeline.is_empty()
|
||||
&& r.required_state.is_empty()
|
||||
&& !response.extensions.receipts.rooms.contains_key(id)
|
||||
&& !response
|
||||
.extensions
|
||||
.receipts
|
||||
.rooms
|
||||
.contains_key(id)
|
||||
}) && response
|
||||
.extensions
|
||||
.to_device
|
||||
@@ -322,8 +334,11 @@ where
|
||||
let room_ids =
|
||||
active_rooms[usize_from_ruma(range.0)..usize_from_ruma(range.1)].to_vec();
|
||||
|
||||
let new_rooms: BTreeSet<OwnedRoomId> =
|
||||
room_ids.clone().into_iter().map(From::from).collect();
|
||||
let new_rooms: BTreeSet<OwnedRoomId> = room_ids
|
||||
.clone()
|
||||
.into_iter()
|
||||
.map(From::from)
|
||||
.collect();
|
||||
|
||||
new_known_rooms.extend(new_rooms);
|
||||
//new_known_rooms.extend(room_ids..cloned());
|
||||
@@ -394,7 +409,10 @@ where
|
||||
let mut invite_state = None;
|
||||
let (timeline_pdus, limited);
|
||||
let new_room_id: &RoomId = (*room_id).as_ref();
|
||||
if all_invited_rooms.clone().any(is_equal_to!(new_room_id)) {
|
||||
if all_invited_rooms
|
||||
.clone()
|
||||
.any(is_equal_to!(new_room_id))
|
||||
{
|
||||
// TODO: figure out a timestamp we can use for remote invites
|
||||
invite_state = services
|
||||
.rooms
|
||||
@@ -521,8 +539,9 @@ where
|
||||
|
||||
for (_, pdu) in timeline_pdus {
|
||||
let ts = pdu.origin_server_ts;
|
||||
if DEFAULT_BUMP_TYPES.binary_search(&pdu.kind).is_ok()
|
||||
&& timestamp.is_none_or(|time| time <= ts)
|
||||
if DEFAULT_BUMP_TYPES
|
||||
.binary_search(&pdu.kind)
|
||||
.is_ok() && timestamp.is_none_or(|time| time <= ts)
|
||||
{
|
||||
timestamp = Some(ts);
|
||||
}
|
||||
@@ -569,7 +588,11 @@ where
|
||||
| Ordering::Greater => {
|
||||
let firsts = heroes[1..]
|
||||
.iter()
|
||||
.map(|h| h.name.clone().unwrap_or_else(|| h.user_id.to_string()))
|
||||
.map(|h| {
|
||||
h.name
|
||||
.clone()
|
||||
.unwrap_or_else(|| h.user_id.to_string())
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
.join(", ");
|
||||
|
||||
@@ -605,7 +628,12 @@ where
|
||||
.or(name),
|
||||
avatar: match heroes_avatar {
|
||||
| Some(heroes_avatar) => ruma::JsOption::Some(heroes_avatar),
|
||||
| _ => match services.rooms.state_accessor.get_avatar(room_id).await {
|
||||
| _ => match services
|
||||
.rooms
|
||||
.state_accessor
|
||||
.get_avatar(room_id)
|
||||
.await
|
||||
{
|
||||
| ruma::JsOption::Some(avatar) => ruma::JsOption::from_option(avatar.url),
|
||||
| ruma::JsOption::Null => ruma::JsOption::Null,
|
||||
| ruma::JsOption::Undefined => ruma::JsOption::Undefined,
|
||||
@@ -674,7 +702,12 @@ async fn collect_account_data(
|
||||
rooms: BTreeMap::new(),
|
||||
};
|
||||
|
||||
if !body.extensions.account_data.enabled.unwrap_or(false) {
|
||||
if !body
|
||||
.extensions
|
||||
.account_data
|
||||
.enabled
|
||||
.unwrap_or(false)
|
||||
{
|
||||
return sync_events::v5::response::AccountData::default();
|
||||
}
|
||||
|
||||
@@ -732,8 +765,11 @@ where
|
||||
);
|
||||
|
||||
for room_id in all_joined_rooms {
|
||||
let Ok(current_shortstatehash) =
|
||||
services.rooms.state.get_room_shortstatehash(room_id).await
|
||||
let Ok(current_shortstatehash) = services
|
||||
.rooms
|
||||
.state
|
||||
.get_room_shortstatehash(room_id)
|
||||
.await
|
||||
else {
|
||||
error!("Room {room_id} has no state");
|
||||
continue;
|
||||
@@ -934,9 +970,16 @@ where
|
||||
Rooms: Stream<Item = &'a RoomId> + Send + 'a,
|
||||
{
|
||||
rooms.filter_map(async |room_id| {
|
||||
let room_type = services.rooms.state_accessor.get_room_type(room_id).await;
|
||||
let room_type = services
|
||||
.rooms
|
||||
.state_accessor
|
||||
.get_room_type(room_id)
|
||||
.await;
|
||||
|
||||
if room_type.as_ref().is_err_and(|e| !e.is_not_found()) {
|
||||
if room_type
|
||||
.as_ref()
|
||||
.is_err_and(|e| !e.is_not_found())
|
||||
{
|
||||
return None;
|
||||
}
|
||||
|
||||
|
||||
@@ -21,7 +21,10 @@ pub(crate) async fn update_tag_route(
|
||||
State(services): State<crate::State>,
|
||||
body: Ruma<create_tag::v3::Request>,
|
||||
) -> Result<create_tag::v3::Response> {
|
||||
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
|
||||
let sender_user = body
|
||||
.sender_user
|
||||
.as_ref()
|
||||
.expect("user is authenticated");
|
||||
|
||||
let mut tags_event = services
|
||||
.account_data
|
||||
@@ -58,7 +61,10 @@ pub(crate) async fn delete_tag_route(
|
||||
State(services): State<crate::State>,
|
||||
body: Ruma<delete_tag::v3::Request>,
|
||||
) -> Result<delete_tag::v3::Response> {
|
||||
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
|
||||
let sender_user = body
|
||||
.sender_user
|
||||
.as_ref()
|
||||
.expect("user is authenticated");
|
||||
|
||||
let mut tags_event = services
|
||||
.account_data
|
||||
@@ -68,7 +74,10 @@ pub(crate) async fn delete_tag_route(
|
||||
content: TagEventContent { tags: BTreeMap::new() },
|
||||
});
|
||||
|
||||
tags_event.content.tags.remove(&body.tag.clone().into());
|
||||
tags_event
|
||||
.content
|
||||
.tags
|
||||
.remove(&body.tag.clone().into());
|
||||
|
||||
services
|
||||
.account_data
|
||||
@@ -92,7 +101,10 @@ pub(crate) async fn get_tags_route(
|
||||
State(services): State<crate::State>,
|
||||
body: Ruma<get_tags::v3::Request>,
|
||||
) -> Result<get_tags::v3::Response> {
|
||||
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
|
||||
let sender_user = body
|
||||
.sender_user
|
||||
.as_ref()
|
||||
.expect("user is authenticated");
|
||||
|
||||
let tags_event = services
|
||||
.account_data
|
||||
|
||||
@@ -21,7 +21,10 @@ pub(crate) async fn send_event_to_device_route(
|
||||
State(services): State<crate::State>,
|
||||
body: Ruma<send_event_to_device::v3::Request>,
|
||||
) -> Result<send_event_to_device::v3::Response> {
|
||||
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
|
||||
let sender_user = body
|
||||
.sender_user
|
||||
.as_ref()
|
||||
.expect("user is authenticated");
|
||||
let sender_device = body.sender_device.as_deref();
|
||||
|
||||
// Check if this is a new transaction id
|
||||
|
||||
@@ -30,7 +30,10 @@ pub(crate) async fn create_typing_event_route(
|
||||
match body.state {
|
||||
| Typing::Yes(duration) => {
|
||||
let duration = utils::clamp(
|
||||
duration.as_millis().try_into().unwrap_or(u64::MAX),
|
||||
duration
|
||||
.as_millis()
|
||||
.try_into()
|
||||
.unwrap_or(u64::MAX),
|
||||
services
|
||||
.server
|
||||
.config
|
||||
|
||||
@@ -69,7 +69,10 @@ pub(crate) async fn delete_timezone_key_route(
|
||||
State(services): State<crate::State>,
|
||||
body: Ruma<delete_timezone_key::unstable::Request>,
|
||||
) -> Result<delete_timezone_key::unstable::Response> {
|
||||
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
|
||||
let sender_user = body
|
||||
.sender_user
|
||||
.as_ref()
|
||||
.expect("user is authenticated");
|
||||
|
||||
if *sender_user != body.user_id && body.appservice_info.is_none() {
|
||||
return Err!(Request(Forbidden("You cannot update the profile of another user")));
|
||||
@@ -97,13 +100,18 @@ pub(crate) async fn set_timezone_key_route(
|
||||
State(services): State<crate::State>,
|
||||
body: Ruma<set_timezone_key::unstable::Request>,
|
||||
) -> Result<set_timezone_key::unstable::Response> {
|
||||
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
|
||||
let sender_user = body
|
||||
.sender_user
|
||||
.as_ref()
|
||||
.expect("user is authenticated");
|
||||
|
||||
if *sender_user != body.user_id && body.appservice_info.is_none() {
|
||||
return Err!(Request(Forbidden("You cannot update the profile of another user")));
|
||||
}
|
||||
|
||||
services.users.set_timezone(&body.user_id, body.tz.clone());
|
||||
services
|
||||
.users
|
||||
.set_timezone(&body.user_id, body.tz.clone());
|
||||
|
||||
if services.config.allow_local_presence {
|
||||
// Presence update
|
||||
@@ -125,7 +133,10 @@ pub(crate) async fn set_profile_key_route(
|
||||
State(services): State<crate::State>,
|
||||
body: Ruma<set_profile_key::unstable::Request>,
|
||||
) -> Result<set_profile_key::unstable::Response> {
|
||||
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
|
||||
let sender_user = body
|
||||
.sender_user
|
||||
.as_ref()
|
||||
.expect("user is authenticated");
|
||||
|
||||
if *sender_user != body.user_id && body.appservice_info.is_none() {
|
||||
return Err!(Request(Forbidden("You cannot update the profile of another user")));
|
||||
@@ -218,7 +229,10 @@ pub(crate) async fn delete_profile_key_route(
|
||||
State(services): State<crate::State>,
|
||||
body: Ruma<delete_profile_key::unstable::Request>,
|
||||
) -> Result<delete_profile_key::unstable::Response> {
|
||||
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
|
||||
let sender_user = body
|
||||
.sender_user
|
||||
.as_ref()
|
||||
.expect("user is authenticated");
|
||||
|
||||
if *sender_user != body.user_id && body.appservice_info.is_none() {
|
||||
return Err!(Request(Forbidden("You cannot update the profile of another user")));
|
||||
|
||||
@@ -37,7 +37,12 @@ pub(crate) async fn search_users_route(
|
||||
let mut users = services
|
||||
.users
|
||||
.stream()
|
||||
.ready_filter(|user_id| user_id.as_str().to_lowercase().contains(&search_term))
|
||||
.ready_filter(|user_id| {
|
||||
user_id
|
||||
.as_str()
|
||||
.to_lowercase()
|
||||
.contains(&search_term)
|
||||
})
|
||||
.map(ToOwned::to_owned)
|
||||
.broad_filter_map(async |user_id| {
|
||||
let display_name = services.users.displayname(&user_id).await.ok();
|
||||
|
||||
@@ -45,15 +45,30 @@ pub(crate) async fn well_known_support(
|
||||
.as_ref()
|
||||
.map(ToString::to_string);
|
||||
|
||||
let role = services.server.config.well_known.support_role.clone();
|
||||
let role = services
|
||||
.server
|
||||
.config
|
||||
.well_known
|
||||
.support_role
|
||||
.clone();
|
||||
|
||||
// support page or role must be either defined for this to be valid
|
||||
if support_page.is_none() && role.is_none() {
|
||||
return Err(Error::BadRequest(ErrorKind::NotFound, "Not found."));
|
||||
}
|
||||
|
||||
let email_address = services.server.config.well_known.support_email.clone();
|
||||
let matrix_id = services.server.config.well_known.support_mxid.clone();
|
||||
let email_address = services
|
||||
.server
|
||||
.config
|
||||
.well_known
|
||||
.support_email
|
||||
.clone();
|
||||
let matrix_id = services
|
||||
.server
|
||||
.config
|
||||
.well_known
|
||||
.support_mxid
|
||||
.clone();
|
||||
|
||||
// if a role is specified, an email address or matrix id is required
|
||||
if role.is_some() && (email_address.is_none() && matrix_id.is_none()) {
|
||||
|
||||
@@ -140,9 +140,13 @@ fn into_http_request(request: &Request, body: Bytes) -> hyper::Request<Bytes> {
|
||||
.uri(request.parts.uri.clone())
|
||||
.method(request.parts.method.clone());
|
||||
|
||||
*http_request.headers_mut().expect("mutable http headers") = request.parts.headers.clone();
|
||||
*http_request
|
||||
.headers_mut()
|
||||
.expect("mutable http headers") = request.parts.headers.clone();
|
||||
|
||||
let http_request = http_request.body(body).expect("http request body");
|
||||
let http_request = http_request
|
||||
.body(body)
|
||||
.expect("http request body");
|
||||
|
||||
let headers = http_request.headers();
|
||||
let method = http_request.method();
|
||||
|
||||
@@ -93,7 +93,11 @@ pub(super) async fn auth(
|
||||
| &get_display_name::v3::Request::METADATA
|
||||
| &get_avatar_url::v3::Request::METADATA
|
||||
| &get_timezone_key::unstable::Request::METADATA => {
|
||||
if services.server.config.require_auth_for_profile_requests {
|
||||
if services
|
||||
.server
|
||||
.config
|
||||
.require_auth_for_profile_requests
|
||||
{
|
||||
match token {
|
||||
| Token::Appservice(_) | Token::User(_) => {
|
||||
// we should have validated the token above
|
||||
|
||||
@@ -23,7 +23,11 @@ where
|
||||
.inspect_err(|e| error!("response error: {e}"))
|
||||
.map_or_else(
|
||||
|_| StatusCode::INTERNAL_SERVER_ERROR.into_response(),
|
||||
|r| r.map(BytesMut::freeze).map(Full::new).into_response(),
|
||||
|r| {
|
||||
r.map(BytesMut::freeze)
|
||||
.map(Full::new)
|
||||
.into_response()
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,8 +49,19 @@ pub(crate) async fn get_event_authorization_route(
|
||||
.auth_chain
|
||||
.event_ids_iter(room_id, once(body.event_id.borrow()))
|
||||
.ready_filter_map(Result::ok)
|
||||
.filter_map(|id| async move { services.rooms.timeline.get_pdu_json(&id).await.ok() })
|
||||
.then(|pdu| services.sending.convert_to_outgoing_federation_event(pdu))
|
||||
.filter_map(|id| async move {
|
||||
services
|
||||
.rooms
|
||||
.timeline
|
||||
.get_pdu_json(&id)
|
||||
.await
|
||||
.ok()
|
||||
})
|
||||
.then(|pdu| {
|
||||
services
|
||||
.sending
|
||||
.convert_to_outgoing_federation_event(pdu)
|
||||
})
|
||||
.collect()
|
||||
.await;
|
||||
|
||||
|
||||
@@ -38,7 +38,12 @@ pub(crate) async fn get_missing_events_route(
|
||||
|
||||
let mut i: usize = 0;
|
||||
while i < queued_events.len() && events.len() < limit {
|
||||
let Ok(pdu) = services.rooms.timeline.get_pdu(&queued_events[i]).await else {
|
||||
let Ok(pdu) = services
|
||||
.rooms
|
||||
.timeline
|
||||
.get_pdu(&queued_events[i])
|
||||
.await
|
||||
else {
|
||||
debug!(
|
||||
?body.origin,
|
||||
"Event {} does not exist locally, skipping", &queued_events[i]
|
||||
|
||||
@@ -17,7 +17,12 @@ pub(crate) async fn get_hierarchy_route(
|
||||
State(services): State<crate::State>,
|
||||
body: Ruma<get_hierarchy::v1::Request>,
|
||||
) -> Result<get_hierarchy::v1::Response> {
|
||||
if !services.rooms.metadata.exists(&body.room_id).await {
|
||||
if !services
|
||||
.rooms
|
||||
.metadata
|
||||
.exists(&body.room_id)
|
||||
.await
|
||||
{
|
||||
return Err!(Request(NotFound("Room does not exist.")));
|
||||
}
|
||||
|
||||
@@ -60,8 +65,15 @@ pub(crate) async fn get_hierarchy_route(
|
||||
.unzip()
|
||||
.map(|(children, inaccessible_children): (Vec<_>, Vec<_>)| {
|
||||
(
|
||||
children.into_iter().flatten().map(Into::into).collect(),
|
||||
inaccessible_children.into_iter().flatten().collect(),
|
||||
children
|
||||
.into_iter()
|
||||
.flatten()
|
||||
.map(Into::into)
|
||||
.collect(),
|
||||
inaccessible_children
|
||||
.into_iter()
|
||||
.flatten()
|
||||
.collect(),
|
||||
)
|
||||
})
|
||||
.await;
|
||||
|
||||
@@ -29,7 +29,10 @@ pub(crate) async fn create_invite_route(
|
||||
.acl_check(body.origin(), &body.room_id)
|
||||
.await?;
|
||||
|
||||
if !services.server.supported_room_version(&body.room_version) {
|
||||
if !services
|
||||
.server
|
||||
.supported_room_version(&body.room_version)
|
||||
{
|
||||
return Err(Error::BadRequest(
|
||||
ErrorKind::IncompatibleRoomVersion { room_version: body.room_version.clone() },
|
||||
"Server does not support this room version.",
|
||||
@@ -69,7 +72,10 @@ pub(crate) async fn create_invite_route(
|
||||
.map(UserId::to_owned)
|
||||
.map_err(|e| err!(Request(InvalidParam("Invalid state_key property: {e}"))))?;
|
||||
|
||||
if !services.globals.server_is_ours(invited_user.server_name()) {
|
||||
if !services
|
||||
.globals
|
||||
.server_is_ours(invited_user.server_name())
|
||||
{
|
||||
return Err!(Request(InvalidParam("User does not belong to this homeserver.")));
|
||||
}
|
||||
|
||||
@@ -96,8 +102,11 @@ pub(crate) async fn create_invite_route(
|
||||
.try_into()
|
||||
.map_err(|e| err!(Request(InvalidParam("Invalid sender property: {e}"))))?;
|
||||
|
||||
if services.rooms.metadata.is_banned(&body.room_id).await
|
||||
&& !services.users.is_admin(&invited_user).await
|
||||
if services
|
||||
.rooms
|
||||
.metadata
|
||||
.is_banned(&body.room_id)
|
||||
.await && !services.users.is_admin(&invited_user).await
|
||||
{
|
||||
return Err!(Request(Forbidden("This room is banned on this homeserver.")));
|
||||
}
|
||||
|
||||
@@ -27,7 +27,10 @@ pub(crate) async fn get_server_keys_route(
|
||||
) -> Result<impl IntoResponse> {
|
||||
let server_name = services.globals.server_name();
|
||||
let active_key_id = services.server_keys.active_key_id();
|
||||
let mut all_keys = services.server_keys.verify_keys_for(server_name).await;
|
||||
let mut all_keys = services
|
||||
.server_keys
|
||||
.verify_keys_for(server_name)
|
||||
.await;
|
||||
|
||||
let verify_keys = all_keys
|
||||
.remove_entry(active_key_id)
|
||||
|
||||
@@ -26,7 +26,12 @@ pub(crate) async fn create_join_event_template_route(
|
||||
State(services): State<crate::State>,
|
||||
body: Ruma<prepare_join_event::v1::Request>,
|
||||
) -> Result<prepare_join_event::v1::Response> {
|
||||
if !services.rooms.metadata.exists(&body.room_id).await {
|
||||
if !services
|
||||
.rooms
|
||||
.metadata
|
||||
.exists(&body.room_id)
|
||||
.await
|
||||
{
|
||||
return Err!(Request(NotFound("Room is unknown to this server.")));
|
||||
}
|
||||
|
||||
@@ -68,7 +73,11 @@ pub(crate) async fn create_join_event_template_route(
|
||||
}
|
||||
}
|
||||
|
||||
let room_version_id = services.rooms.state.get_room_version(&body.room_id).await?;
|
||||
let room_version_id = services
|
||||
.rooms
|
||||
.state
|
||||
.get_room_version(&body.room_id)
|
||||
.await?;
|
||||
if !body.ver.contains(&room_version_id) {
|
||||
return Err(Error::BadRequest(
|
||||
ErrorKind::IncompatibleRoomVersion { room_version: room_version_id },
|
||||
@@ -76,7 +85,12 @@ pub(crate) async fn create_join_event_template_route(
|
||||
));
|
||||
}
|
||||
|
||||
let state_lock = services.rooms.state.mutex.lock(&body.room_id).await;
|
||||
let state_lock = services
|
||||
.rooms
|
||||
.state
|
||||
.mutex
|
||||
.lock(&body.room_id)
|
||||
.await;
|
||||
|
||||
let join_authorized_via_users_server: Option<OwnedUserId> = {
|
||||
use RoomVersionId::*;
|
||||
@@ -157,7 +171,12 @@ pub(crate) async fn user_can_perform_restricted_join(
|
||||
return Ok(false);
|
||||
}
|
||||
|
||||
if services.rooms.state_cache.is_joined(user_id, room_id).await {
|
||||
if services
|
||||
.rooms
|
||||
.state_cache
|
||||
.is_joined(user_id, room_id)
|
||||
.await
|
||||
{
|
||||
// joining user is already joined, there is nothing we need to do
|
||||
return Ok(false);
|
||||
}
|
||||
@@ -196,7 +215,12 @@ pub(crate) async fn user_can_perform_restricted_join(
|
||||
}
|
||||
})
|
||||
.stream()
|
||||
.any(|m| services.rooms.state_cache.is_joined(user_id, &m.room_id))
|
||||
.any(|m| {
|
||||
services
|
||||
.rooms
|
||||
.state_cache
|
||||
.is_joined(user_id, &m.room_id)
|
||||
})
|
||||
.await
|
||||
{
|
||||
Ok(true)
|
||||
|
||||
@@ -17,7 +17,12 @@ pub(crate) async fn create_knock_event_template_route(
|
||||
State(services): State<crate::State>,
|
||||
body: Ruma<create_knock_event_template::v1::Request>,
|
||||
) -> Result<create_knock_event_template::v1::Response> {
|
||||
if !services.rooms.metadata.exists(&body.room_id).await {
|
||||
if !services
|
||||
.rooms
|
||||
.metadata
|
||||
.exists(&body.room_id)
|
||||
.await
|
||||
{
|
||||
return Err!(Request(NotFound("Room is unknown to this server.")));
|
||||
}
|
||||
|
||||
@@ -57,7 +62,11 @@ pub(crate) async fn create_knock_event_template_route(
|
||||
}
|
||||
}
|
||||
|
||||
let room_version_id = services.rooms.state.get_room_version(&body.room_id).await?;
|
||||
let room_version_id = services
|
||||
.rooms
|
||||
.state
|
||||
.get_room_version(&body.room_id)
|
||||
.await?;
|
||||
|
||||
if matches!(room_version_id, V1 | V2 | V3 | V4 | V5 | V6) {
|
||||
return Err(Error::BadRequest(
|
||||
@@ -73,7 +82,12 @@ pub(crate) async fn create_knock_event_template_route(
|
||||
));
|
||||
}
|
||||
|
||||
let state_lock = services.rooms.state.mutex.lock(&body.room_id).await;
|
||||
let state_lock = services
|
||||
.rooms
|
||||
.state
|
||||
.mutex
|
||||
.lock(&body.room_id)
|
||||
.await;
|
||||
|
||||
if let Ok(membership) = services
|
||||
.rooms
|
||||
|
||||
@@ -16,7 +16,12 @@ pub(crate) async fn create_leave_event_template_route(
|
||||
State(services): State<crate::State>,
|
||||
body: Ruma<prepare_leave_event::v1::Request>,
|
||||
) -> Result<prepare_leave_event::v1::Response> {
|
||||
if !services.rooms.metadata.exists(&body.room_id).await {
|
||||
if !services
|
||||
.rooms
|
||||
.metadata
|
||||
.exists(&body.room_id)
|
||||
.await
|
||||
{
|
||||
return Err!(Request(NotFound("Room is unknown to this server.")));
|
||||
}
|
||||
|
||||
@@ -33,8 +38,17 @@ pub(crate) async fn create_leave_event_template_route(
|
||||
.acl_check(body.origin(), &body.room_id)
|
||||
.await?;
|
||||
|
||||
let room_version_id = services.rooms.state.get_room_version(&body.room_id).await?;
|
||||
let state_lock = services.rooms.state.mutex.lock(&body.room_id).await;
|
||||
let room_version_id = services
|
||||
.rooms
|
||||
.state
|
||||
.get_room_version(&body.room_id)
|
||||
.await?;
|
||||
let state_lock = services
|
||||
.rooms
|
||||
.state
|
||||
.mutex
|
||||
.lock(&body.room_id)
|
||||
.await;
|
||||
|
||||
let (_pdu, mut pdu_json) = services
|
||||
.rooms
|
||||
|
||||
@@ -73,7 +73,10 @@ pub(crate) async fn get_profile_information_route(
|
||||
));
|
||||
}
|
||||
|
||||
if !services.globals.server_is_ours(body.user_id.server_name()) {
|
||||
if !services
|
||||
.globals
|
||||
.server_is_ours(body.user_id.server_name())
|
||||
{
|
||||
return Err(Error::BadRequest(
|
||||
ErrorKind::InvalidParam,
|
||||
"User does not belong to this server.",
|
||||
@@ -88,10 +91,18 @@ pub(crate) async fn get_profile_information_route(
|
||||
|
||||
match &body.field {
|
||||
| Some(ProfileField::DisplayName) => {
|
||||
displayname = services.users.displayname(&body.user_id).await.ok();
|
||||
displayname = services
|
||||
.users
|
||||
.displayname(&body.user_id)
|
||||
.await
|
||||
.ok();
|
||||
},
|
||||
| Some(ProfileField::AvatarUrl) => {
|
||||
avatar_url = services.users.avatar_url(&body.user_id).await.ok();
|
||||
avatar_url = services
|
||||
.users
|
||||
.avatar_url(&body.user_id)
|
||||
.await
|
||||
.ok();
|
||||
blurhash = services.users.blurhash(&body.user_id).await.ok();
|
||||
},
|
||||
| Some(custom_field) => {
|
||||
@@ -104,8 +115,16 @@ pub(crate) async fn get_profile_information_route(
|
||||
}
|
||||
},
|
||||
| None => {
|
||||
displayname = services.users.displayname(&body.user_id).await.ok();
|
||||
avatar_url = services.users.avatar_url(&body.user_id).await.ok();
|
||||
displayname = services
|
||||
.users
|
||||
.displayname(&body.user_id)
|
||||
.await
|
||||
.ok();
|
||||
avatar_url = services
|
||||
.users
|
||||
.avatar_url(&body.user_id)
|
||||
.await
|
||||
.ok();
|
||||
blurhash = services.users.blurhash(&body.user_id).await.ok();
|
||||
tz = services.users.timezone(&body.user_id).await.ok();
|
||||
custom_profile_fields = services
|
||||
|
||||
@@ -92,7 +92,12 @@ pub(crate) async fn send_transaction_message_route(
|
||||
.pdus
|
||||
.iter()
|
||||
.stream()
|
||||
.broad_then(|pdu| services.rooms.event_handler.parse_incoming_pdu(pdu))
|
||||
.broad_then(|pdu| {
|
||||
services
|
||||
.rooms
|
||||
.event_handler
|
||||
.parse_incoming_pdu(pdu)
|
||||
})
|
||||
.inspect_err(|e| debug_warn!("Could not parse PDU: {e}"))
|
||||
.ready_filter_map(Result::ok);
|
||||
|
||||
@@ -215,7 +220,11 @@ async fn handle_edu(services: &Services, client: &IpAddr, origin: &ServerName, e
|
||||
| Edu::Presence(presence) if services.server.config.allow_incoming_presence =>
|
||||
handle_edu_presence(services, client, origin, presence).await,
|
||||
|
||||
| Edu::Receipt(receipt) if services.server.config.allow_incoming_read_receipts =>
|
||||
| Edu::Receipt(receipt)
|
||||
if services
|
||||
.server
|
||||
.config
|
||||
.allow_incoming_read_receipts =>
|
||||
handle_edu_receipt(services, client, origin, receipt).await,
|
||||
|
||||
| Edu::Typing(typing) if services.server.config.allow_incoming_typing =>
|
||||
@@ -454,7 +463,10 @@ async fn handle_edu_device_list_update(
|
||||
return;
|
||||
}
|
||||
|
||||
services.users.mark_device_key_update(&user_id).await;
|
||||
services
|
||||
.users
|
||||
.mark_device_key_update(&user_id)
|
||||
.await;
|
||||
}
|
||||
|
||||
async fn handle_edu_direct_to_device(
|
||||
|
||||
@@ -53,7 +53,11 @@ async fn create_join_event(
|
||||
|
||||
// We do not add the event_id field to the pdu here because of signature and
|
||||
// hashes checks
|
||||
let room_version_id = services.rooms.state.get_room_version(room_id).await?;
|
||||
let room_version_id = services
|
||||
.rooms
|
||||
.state
|
||||
.get_room_version(room_id)
|
||||
.await?;
|
||||
|
||||
let Ok((event_id, mut value)) = gen_event_id_canonical_json(pdu, &room_version_id) else {
|
||||
// Event could not be converted to canonical json
|
||||
@@ -239,7 +243,11 @@ async fn create_join_event(
|
||||
.auth_chain
|
||||
.event_ids_iter(room_id, starting_events)
|
||||
.broad_and_then(|event_id| async move {
|
||||
services.rooms.timeline.get_pdu_json(&event_id).await
|
||||
services
|
||||
.rooms
|
||||
.timeline
|
||||
.get_pdu_json(&event_id)
|
||||
.await
|
||||
})
|
||||
.broad_and_then(|pdu| {
|
||||
services
|
||||
@@ -251,7 +259,10 @@ async fn create_join_event(
|
||||
.boxed()
|
||||
.await?;
|
||||
|
||||
services.sending.send_pdu_room(room_id, &pdu_id).await?;
|
||||
services
|
||||
.sending
|
||||
.send_pdu_room(room_id, &pdu_id)
|
||||
.await?;
|
||||
|
||||
Ok(create_join_event::v1::RoomState {
|
||||
auth_chain,
|
||||
|
||||
@@ -55,7 +55,12 @@ pub(crate) async fn create_knock_event_v1_route(
|
||||
}
|
||||
}
|
||||
|
||||
if !services.rooms.metadata.exists(&body.room_id).await {
|
||||
if !services
|
||||
.rooms
|
||||
.metadata
|
||||
.exists(&body.room_id)
|
||||
.await
|
||||
{
|
||||
return Err!(Request(NotFound("Room is unknown to this server.")));
|
||||
}
|
||||
|
||||
@@ -66,7 +71,11 @@ pub(crate) async fn create_knock_event_v1_route(
|
||||
.acl_check(body.origin(), &body.room_id)
|
||||
.await?;
|
||||
|
||||
let room_version_id = services.rooms.state.get_room_version(&body.room_id).await?;
|
||||
let room_version_id = services
|
||||
.rooms
|
||||
.state
|
||||
.get_room_version(&body.room_id)
|
||||
.await?;
|
||||
|
||||
if matches!(room_version_id, V1 | V2 | V3 | V4 | V5 | V6) {
|
||||
return Err!(Request(Forbidden("Room version does not support knocking.")));
|
||||
|
||||
@@ -59,7 +59,11 @@ async fn create_leave_event(
|
||||
|
||||
// We do not add the event_id field to the pdu here because of signature and
|
||||
// hashes checks
|
||||
let room_version_id = services.rooms.state.get_room_version(room_id).await?;
|
||||
let room_version_id = services
|
||||
.rooms
|
||||
.state
|
||||
.get_room_version(room_id)
|
||||
.await?;
|
||||
let Ok((event_id, value)) = gen_event_id_canonical_json(pdu, &room_version_id) else {
|
||||
// Event could not be converted to canonical json
|
||||
return Err!(Request(BadJson("Could not convert event to canonical json.")));
|
||||
|
||||
@@ -43,11 +43,10 @@ pub(super) async fn check(&self) -> Result {
|
||||
let server_can_see: OptionFuture<_> = self
|
||||
.event_id
|
||||
.map(|event_id| {
|
||||
self.services.rooms.state_accessor.server_can_see_event(
|
||||
self.origin,
|
||||
self.room_id,
|
||||
event_id,
|
||||
)
|
||||
self.services
|
||||
.rooms
|
||||
.state_accessor
|
||||
.server_can_see_event(self.origin, self.room_id, event_id)
|
||||
})
|
||||
.into();
|
||||
|
||||
|
||||
@@ -369,7 +369,11 @@ where
|
||||
fn key(name: &str) -> Result<Key> {
|
||||
// tikv asserts the output buffer length is tight to the number of required mibs
|
||||
// so we slice that down here.
|
||||
let segs = name.chars().filter(is_equal_to!(&'.')).count().try_add(1)?;
|
||||
let segs = name
|
||||
.chars()
|
||||
.filter(is_equal_to!(&'.'))
|
||||
.count()
|
||||
.try_add(1)?;
|
||||
|
||||
let name = self::name(name)?;
|
||||
let mut buf = [0_usize; KEY_SEGS];
|
||||
|
||||
@@ -150,7 +150,10 @@ pub fn check(config: &Config) -> Result {
|
||||
}
|
||||
|
||||
// check if we can read the token file path, and check if the file is empty
|
||||
if config.registration_token_file.as_ref().is_some_and(|path| {
|
||||
if config
|
||||
.registration_token_file
|
||||
.as_ref()
|
||||
.is_some_and(|path| {
|
||||
let Ok(token) = std::fs::read_to_string(path).inspect_err(|e| {
|
||||
error!("Failed to read the registration token file: {e}");
|
||||
}) else {
|
||||
|
||||
@@ -2218,8 +2218,12 @@ fn default_admin_room_tag() -> String { "m.server_notice".to_owned() }
|
||||
fn parallelism_scaled_f64(val: f64) -> f64 { val * (sys::available_parallelism() as f64) }
|
||||
|
||||
fn parallelism_scaled_u32(val: u32) -> u32 {
|
||||
let val = val.try_into().expect("failed to cast u32 to usize");
|
||||
parallelism_scaled(val).try_into().unwrap_or(u32::MAX)
|
||||
let val = val
|
||||
.try_into()
|
||||
.expect("failed to cast u32 to usize");
|
||||
parallelism_scaled(val)
|
||||
.try_into()
|
||||
.unwrap_or(u32::MAX)
|
||||
}
|
||||
|
||||
fn parallelism_scaled(val: usize) -> usize { val.saturating_mul(sys::available_parallelism()) }
|
||||
|
||||
@@ -46,7 +46,10 @@ impl ProxyConfig {
|
||||
| Self::Global { url } => Some(Proxy::all(url)?),
|
||||
| Self::ByDomain(proxies) => Some(Proxy::custom(move |url| {
|
||||
// first matching proxy
|
||||
proxies.iter().find_map(|proxy| proxy.for_url(url)).cloned()
|
||||
proxies
|
||||
.iter()
|
||||
.find_map(|proxy| proxy.for_url(url))
|
||||
.cloned()
|
||||
})),
|
||||
})
|
||||
}
|
||||
|
||||
@@ -100,7 +100,9 @@ pub fn trap() {
|
||||
|
||||
#[must_use]
|
||||
pub fn panic_str(p: &Box<dyn Any + Send>) -> &'static str {
|
||||
p.downcast_ref::<&str>().copied().unwrap_or_default()
|
||||
p.downcast_ref::<&str>()
|
||||
.copied()
|
||||
.unwrap_or_default()
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
|
||||
@@ -184,7 +184,9 @@ impl Error {
|
||||
| Self::Request(kind, _, code) => response::status_code(kind, *code),
|
||||
| Self::BadRequest(kind, ..) => response::bad_request_code(kind),
|
||||
| Self::FeatureDisabled(..) => response::bad_request_code(&self.kind()),
|
||||
| Self::Reqwest(error) => error.status().unwrap_or(StatusCode::INTERNAL_SERVER_ERROR),
|
||||
| Self::Reqwest(error) => error
|
||||
.status()
|
||||
.unwrap_or(StatusCode::INTERNAL_SERVER_ERROR),
|
||||
| Self::Conflict(_) => StatusCode::CONFLICT,
|
||||
| Self::Io(error) => response::io_error_code(error.kind()),
|
||||
| _ => StatusCode::INTERNAL_SERVER_ERROR,
|
||||
|
||||
@@ -20,7 +20,11 @@ impl axum::response::IntoResponse for Error {
|
||||
.inspect_err(|e| error!("error response error: {e}"))
|
||||
.map_or_else(
|
||||
|_| StatusCode::INTERNAL_SERVER_ERROR.into_response(),
|
||||
|r| r.map(BytesMut::freeze).map(Full::new).into_response(),
|
||||
|r| {
|
||||
r.map(BytesMut::freeze)
|
||||
.map(Full::new)
|
||||
.into_response()
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,7 +42,10 @@ static DEPENDENCIES: OnceLock<DepsSet> = OnceLock::new();
|
||||
|
||||
#[must_use]
|
||||
pub fn dependencies_names() -> Vec<&'static str> {
|
||||
dependencies().keys().map(String::as_str).collect()
|
||||
dependencies()
|
||||
.keys()
|
||||
.map(String::as_str)
|
||||
.collect()
|
||||
}
|
||||
|
||||
pub fn dependencies() -> &'static DepsSet {
|
||||
|
||||
@@ -25,7 +25,8 @@ type RoomVersion = (RoomVersionId, RoomVersionStability);
|
||||
impl crate::Server {
|
||||
#[inline]
|
||||
pub fn supported_room_version(&self, version: &RoomVersionId) -> bool {
|
||||
self.supported_room_versions().any(is_equal_to!(*version))
|
||||
self.supported_room_versions()
|
||||
.any(is_equal_to!(*version))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
||||
@@ -20,10 +20,19 @@ impl Data<'_> {
|
||||
pub fn level(&self) -> Level { *self.event.metadata().level() }
|
||||
|
||||
#[must_use]
|
||||
pub fn mod_name(&self) -> &str { self.event.metadata().module_path().unwrap_or_default() }
|
||||
pub fn mod_name(&self) -> &str {
|
||||
self.event
|
||||
.metadata()
|
||||
.module_path()
|
||||
.unwrap_or_default()
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn span_name(&self) -> &str { self.current.metadata().map_or(EMPTY, |s| s.name()) }
|
||||
pub fn span_name(&self) -> &str {
|
||||
self.current
|
||||
.metadata()
|
||||
.map_or(EMPTY, |s| s.name())
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn message(&self) -> &str {
|
||||
|
||||
@@ -103,8 +103,10 @@ where
|
||||
writer: Writer<'_>,
|
||||
event: &Event<'_>,
|
||||
) -> Result<(), std::fmt::Error> {
|
||||
let is_debug =
|
||||
cfg!(debug_assertions) && event.fields().any(|field| field.name() == "_debug");
|
||||
let is_debug = cfg!(debug_assertions)
|
||||
&& event
|
||||
.fields()
|
||||
.any(|field| field.name() == "_debug");
|
||||
|
||||
match *event.metadata().level() {
|
||||
| Level::ERROR if !is_debug => self.pretty.format_event(ctx, writer, event),
|
||||
|
||||
@@ -56,7 +56,9 @@ impl LogLevelReloadHandles {
|
||||
.iter()
|
||||
.filter(|(name, _)| names.is_some_and(|names| names.contains(&name.as_str())))
|
||||
.for_each(|(_, handle)| {
|
||||
_ = handle.reload(new_value.clone()).or_else(error::else_log);
|
||||
_ = handle
|
||||
.reload(new_value.clone())
|
||||
.or_else(error::else_log);
|
||||
});
|
||||
|
||||
Ok(())
|
||||
|
||||
@@ -58,7 +58,11 @@ fn matches_sender(&self, filter: &RoomEventFilter) -> bool {
|
||||
#[implement(super::Pdu)]
|
||||
fn matches_type(&self, filter: &RoomEventFilter) -> bool {
|
||||
let event_type = &self.kind.to_cow_str();
|
||||
if filter.not_types.iter().any(is_equal_to!(event_type)) {
|
||||
if filter
|
||||
.not_types
|
||||
.iter()
|
||||
.any(is_equal_to!(event_type))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -97,7 +97,11 @@ impl From<Id> for RawId {
|
||||
match id.shorteventid {
|
||||
| Count::Normal(shorteventid) => {
|
||||
vec.extend(shorteventid.to_be_bytes());
|
||||
Self::Normal(vec.as_ref().try_into().expect("RawVec into RawId::Normal"))
|
||||
Self::Normal(
|
||||
vec.as_ref()
|
||||
.try_into()
|
||||
.expect("RawVec into RawId::Normal"),
|
||||
)
|
||||
},
|
||||
| Count::Backfilled(shorteventid) => {
|
||||
vec.extend(0_u64.to_be_bytes());
|
||||
|
||||
@@ -102,7 +102,8 @@ where
|
||||
#[implement(Pdu)]
|
||||
#[must_use]
|
||||
pub fn get_unsigned_as_value(&self) -> JsonValue {
|
||||
self.get_unsigned::<JsonValue>().unwrap_or_default()
|
||||
self.get_unsigned::<JsonValue>()
|
||||
.unwrap_or_default()
|
||||
}
|
||||
|
||||
#[implement(Pdu)]
|
||||
|
||||
@@ -104,7 +104,10 @@ pub fn auth_types_for_event(
|
||||
}
|
||||
|
||||
if membership == MembershipState::Invite {
|
||||
if let Some(Ok(t_id)) = content.third_party_invite.map(|t| t.deserialize()) {
|
||||
if let Some(Ok(t_id)) = content
|
||||
.third_party_invite
|
||||
.map(|t| t.deserialize())
|
||||
{
|
||||
let key =
|
||||
(StateEventType::RoomThirdPartyInvite, t_id.signed.token.into());
|
||||
if !auth_types.contains(&key) {
|
||||
@@ -564,9 +567,12 @@ fn valid_membership_change(
|
||||
}
|
||||
|
||||
let power_levels_event_id = power_levels_event.as_ref().map(Event::event_id);
|
||||
let sender_membership_event_id = sender_membership_event.as_ref().map(Event::event_id);
|
||||
let target_user_membership_event_id =
|
||||
target_user_membership_event.as_ref().map(Event::event_id);
|
||||
let sender_membership_event_id = sender_membership_event
|
||||
.as_ref()
|
||||
.map(Event::event_id);
|
||||
let target_user_membership_event_id = target_user_membership_event
|
||||
.as_ref()
|
||||
.map(Event::event_id);
|
||||
|
||||
let user_for_join_auth_is_valid = if let Some(user_for_join_auth) = user_for_join_auth {
|
||||
// Is the authorised user allowed to invite users into this room
|
||||
@@ -725,7 +731,9 @@ fn valid_membership_change(
|
||||
allow
|
||||
} else if !sender_is_joined
|
||||
|| target_user_current_membership == MembershipState::Ban
|
||||
&& sender_power.filter(|&p| p < &power_levels.ban).is_some()
|
||||
&& sender_power
|
||||
.filter(|&p| p < &power_levels.ban)
|
||||
.is_some()
|
||||
{
|
||||
warn!(
|
||||
?target_user_membership_event_id,
|
||||
@@ -734,8 +742,9 @@ fn valid_membership_change(
|
||||
);
|
||||
false
|
||||
} else {
|
||||
let allow = sender_power.filter(|&p| p >= &power_levels.kick).is_some()
|
||||
&& target_power < sender_power;
|
||||
let allow = sender_power
|
||||
.filter(|&p| p >= &power_levels.kick)
|
||||
.is_some() && target_power < sender_power;
|
||||
if !allow {
|
||||
warn!(
|
||||
?target_user_membership_event_id,
|
||||
@@ -750,8 +759,9 @@ fn valid_membership_change(
|
||||
warn!(?sender_membership_event_id, "Can't ban user if sender is not joined");
|
||||
false
|
||||
} else {
|
||||
let allow = sender_power.filter(|&p| p >= &power_levels.ban).is_some()
|
||||
&& target_power < sender_power;
|
||||
let allow = sender_power
|
||||
.filter(|&p| p >= &power_levels.ban)
|
||||
.is_some() && target_power < sender_power;
|
||||
if !allow {
|
||||
warn!(
|
||||
?target_user_membership_event_id,
|
||||
@@ -829,7 +839,9 @@ fn can_send_event(event: impl Event, ple: Option<impl Event>, user_level: Int) -
|
||||
return false;
|
||||
}
|
||||
|
||||
if event.state_key().is_some_and(|k| k.starts_with('@'))
|
||||
if event
|
||||
.state_key()
|
||||
.is_some_and(|k| k.starts_with('@'))
|
||||
&& event.state_key() != Some(event.sender().as_str())
|
||||
{
|
||||
return false; // permission required to post in this room
|
||||
@@ -1040,7 +1052,11 @@ fn get_send_level(
|
||||
.and_then(|ple| {
|
||||
from_json_str::<RoomPowerLevelsEventContent>(ple.content().get())
|
||||
.map(|content| {
|
||||
content.events.get(e_type).copied().unwrap_or_else(|| {
|
||||
content
|
||||
.events
|
||||
.get(e_type)
|
||||
.copied()
|
||||
.unwrap_or_else(|| {
|
||||
if state_key.is_some() {
|
||||
content.state_default
|
||||
} else {
|
||||
@@ -1135,13 +1151,21 @@ mod tests {
|
||||
#[test]
|
||||
fn test_ban_pass() {
|
||||
let _ = tracing::subscriber::set_default(
|
||||
tracing_subscriber::fmt().with_test_writer().finish(),
|
||||
tracing_subscriber::fmt()
|
||||
.with_test_writer()
|
||||
.finish(),
|
||||
);
|
||||
let events = INITIAL_EVENTS();
|
||||
|
||||
let auth_events = events
|
||||
.values()
|
||||
.map(|ev| (ev.event_type().with_state_key(ev.state_key().unwrap()), ev.clone()))
|
||||
.map(|ev| {
|
||||
(
|
||||
ev.event_type()
|
||||
.with_state_key(ev.state_key().unwrap()),
|
||||
ev.clone(),
|
||||
)
|
||||
})
|
||||
.collect::<StateMap<_>>();
|
||||
|
||||
let requester = to_pdu_event(
|
||||
@@ -1180,13 +1204,21 @@ mod tests {
|
||||
#[test]
|
||||
fn test_join_non_creator() {
|
||||
let _ = tracing::subscriber::set_default(
|
||||
tracing_subscriber::fmt().with_test_writer().finish(),
|
||||
tracing_subscriber::fmt()
|
||||
.with_test_writer()
|
||||
.finish(),
|
||||
);
|
||||
let events = INITIAL_EVENTS_CREATE_ROOM();
|
||||
|
||||
let auth_events = events
|
||||
.values()
|
||||
.map(|ev| (ev.event_type().with_state_key(ev.state_key().unwrap()), ev.clone()))
|
||||
.map(|ev| {
|
||||
(
|
||||
ev.event_type()
|
||||
.with_state_key(ev.state_key().unwrap()),
|
||||
ev.clone(),
|
||||
)
|
||||
})
|
||||
.collect::<StateMap<_>>();
|
||||
|
||||
let requester = to_pdu_event(
|
||||
@@ -1225,13 +1257,21 @@ mod tests {
|
||||
#[test]
|
||||
fn test_join_creator() {
|
||||
let _ = tracing::subscriber::set_default(
|
||||
tracing_subscriber::fmt().with_test_writer().finish(),
|
||||
tracing_subscriber::fmt()
|
||||
.with_test_writer()
|
||||
.finish(),
|
||||
);
|
||||
let events = INITIAL_EVENTS_CREATE_ROOM();
|
||||
|
||||
let auth_events = events
|
||||
.values()
|
||||
.map(|ev| (ev.event_type().with_state_key(ev.state_key().unwrap()), ev.clone()))
|
||||
.map(|ev| {
|
||||
(
|
||||
ev.event_type()
|
||||
.with_state_key(ev.state_key().unwrap()),
|
||||
ev.clone(),
|
||||
)
|
||||
})
|
||||
.collect::<StateMap<_>>();
|
||||
|
||||
let requester = to_pdu_event(
|
||||
@@ -1270,13 +1310,21 @@ mod tests {
|
||||
#[test]
|
||||
fn test_ban_fail() {
|
||||
let _ = tracing::subscriber::set_default(
|
||||
tracing_subscriber::fmt().with_test_writer().finish(),
|
||||
tracing_subscriber::fmt()
|
||||
.with_test_writer()
|
||||
.finish(),
|
||||
);
|
||||
let events = INITIAL_EVENTS();
|
||||
|
||||
let auth_events = events
|
||||
.values()
|
||||
.map(|ev| (ev.event_type().with_state_key(ev.state_key().unwrap()), ev.clone()))
|
||||
.map(|ev| {
|
||||
(
|
||||
ev.event_type()
|
||||
.with_state_key(ev.state_key().unwrap()),
|
||||
ev.clone(),
|
||||
)
|
||||
})
|
||||
.collect::<StateMap<_>>();
|
||||
|
||||
let requester = to_pdu_event(
|
||||
@@ -1315,7 +1363,9 @@ mod tests {
|
||||
#[test]
|
||||
fn test_restricted_join_rule() {
|
||||
let _ = tracing::subscriber::set_default(
|
||||
tracing_subscriber::fmt().with_test_writer().finish(),
|
||||
tracing_subscriber::fmt()
|
||||
.with_test_writer()
|
||||
.finish(),
|
||||
);
|
||||
let mut events = INITIAL_EVENTS();
|
||||
*events.get_mut(&event_id("IJR")).unwrap() = to_pdu_event(
|
||||
@@ -1338,7 +1388,13 @@ mod tests {
|
||||
|
||||
let auth_events = events
|
||||
.values()
|
||||
.map(|ev| (ev.event_type().with_state_key(ev.state_key().unwrap()), ev.clone()))
|
||||
.map(|ev| {
|
||||
(
|
||||
ev.event_type()
|
||||
.with_state_key(ev.state_key().unwrap()),
|
||||
ev.clone(),
|
||||
)
|
||||
})
|
||||
.collect::<StateMap<_>>();
|
||||
|
||||
let requester = to_pdu_event(
|
||||
@@ -1395,7 +1451,9 @@ mod tests {
|
||||
#[test]
|
||||
fn test_knock() {
|
||||
let _ = tracing::subscriber::set_default(
|
||||
tracing_subscriber::fmt().with_test_writer().finish(),
|
||||
tracing_subscriber::fmt()
|
||||
.with_test_writer()
|
||||
.finish(),
|
||||
);
|
||||
let mut events = INITIAL_EVENTS();
|
||||
*events.get_mut(&event_id("IJR")).unwrap() = to_pdu_event(
|
||||
@@ -1410,7 +1468,13 @@ mod tests {
|
||||
|
||||
let auth_events = events
|
||||
.values()
|
||||
.map(|ev| (ev.event_type().with_state_key(ev.state_key().unwrap()), ev.clone()))
|
||||
.map(|ev| {
|
||||
(
|
||||
ev.event_type()
|
||||
.with_state_key(ev.state_key().unwrap()),
|
||||
ev.clone(),
|
||||
)
|
||||
})
|
||||
.collect::<StateMap<_>>();
|
||||
|
||||
let requester = to_pdu_event(
|
||||
|
||||
@@ -429,7 +429,10 @@ where
|
||||
|
||||
reverse_graph.entry(node).or_default();
|
||||
for edge in edges {
|
||||
reverse_graph.entry(edge).or_default().insert(node);
|
||||
reverse_graph
|
||||
.entry(edge)
|
||||
.or_default()
|
||||
.insert(node);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -710,7 +713,9 @@ where
|
||||
.iter()
|
||||
.stream()
|
||||
.broad_filter_map(async |ev_id| {
|
||||
fetch_event(ev_id.clone()).await.map(|event| (event, ev_id))
|
||||
fetch_event(ev_id.clone())
|
||||
.await
|
||||
.map(|event| (event, ev_id))
|
||||
})
|
||||
.broad_filter_map(|(event, ev_id)| {
|
||||
get_mainline_depth(Some(event.clone()), &mainline_map, fetch_event)
|
||||
@@ -782,7 +787,11 @@ async fn add_event_and_auth_chain_to_graph<E, F, Fut>(
|
||||
while let Some(eid) = state.pop() {
|
||||
graph.entry(eid.clone()).or_default();
|
||||
let event = fetch_event(eid.clone()).await;
|
||||
let auth_events = event.as_ref().map(Event::auth_events).into_iter().flatten();
|
||||
let auth_events = event
|
||||
.as_ref()
|
||||
.map(Event::auth_events)
|
||||
.into_iter()
|
||||
.flatten();
|
||||
|
||||
// Prefer the store to event as the store filters dedups the events
|
||||
for aid in auth_events {
|
||||
@@ -792,7 +801,10 @@ async fn add_event_and_auth_chain_to_graph<E, F, Fut>(
|
||||
}
|
||||
|
||||
// We just inserted this at the start of the while loop
|
||||
graph.get_mut(eid.borrow()).unwrap().insert(aid.to_owned());
|
||||
graph
|
||||
.get_mut(eid.borrow())
|
||||
.unwrap()
|
||||
.insert(aid.to_owned());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -890,13 +902,21 @@ mod tests {
|
||||
use futures::future::ready;
|
||||
|
||||
let _ = tracing::subscriber::set_default(
|
||||
tracing_subscriber::fmt().with_test_writer().finish(),
|
||||
tracing_subscriber::fmt()
|
||||
.with_test_writer()
|
||||
.finish(),
|
||||
);
|
||||
let events = INITIAL_EVENTS();
|
||||
|
||||
let event_map = events
|
||||
.values()
|
||||
.map(|ev| (ev.event_type().with_state_key(ev.state_key().unwrap()), ev.clone()))
|
||||
.map(|ev| {
|
||||
(
|
||||
ev.event_type()
|
||||
.with_state_key(ev.state_key().unwrap()),
|
||||
ev.clone(),
|
||||
)
|
||||
})
|
||||
.collect::<StateMap<_>>();
|
||||
|
||||
let auth_chain: HashSet<OwnedEventId> = HashSet::new();
|
||||
@@ -965,7 +985,9 @@ mod tests {
|
||||
#[tokio::test]
|
||||
async fn ban_vs_power_level() {
|
||||
let _ = tracing::subscriber::set_default(
|
||||
tracing_subscriber::fmt().with_test_writer().finish(),
|
||||
tracing_subscriber::fmt()
|
||||
.with_test_writer()
|
||||
.finish(),
|
||||
);
|
||||
|
||||
let events = &[
|
||||
@@ -1015,7 +1037,9 @@ mod tests {
|
||||
#[tokio::test]
|
||||
async fn topic_basic() {
|
||||
let _ = tracing::subscriber::set_default(
|
||||
tracing_subscriber::fmt().with_test_writer().finish(),
|
||||
tracing_subscriber::fmt()
|
||||
.with_test_writer()
|
||||
.finish(),
|
||||
);
|
||||
|
||||
let events = &[
|
||||
@@ -1080,7 +1104,9 @@ mod tests {
|
||||
#[tokio::test]
|
||||
async fn topic_reset() {
|
||||
let _ = tracing::subscriber::set_default(
|
||||
tracing_subscriber::fmt().with_test_writer().finish(),
|
||||
tracing_subscriber::fmt()
|
||||
.with_test_writer()
|
||||
.finish(),
|
||||
);
|
||||
|
||||
let events = &[
|
||||
@@ -1130,7 +1156,9 @@ mod tests {
|
||||
#[tokio::test]
|
||||
async fn join_rule_evasion() {
|
||||
let _ = tracing::subscriber::set_default(
|
||||
tracing_subscriber::fmt().with_test_writer().finish(),
|
||||
tracing_subscriber::fmt()
|
||||
.with_test_writer()
|
||||
.finish(),
|
||||
);
|
||||
|
||||
let events = &[
|
||||
@@ -1163,7 +1191,9 @@ mod tests {
|
||||
#[tokio::test]
|
||||
async fn offtopic_power_level() {
|
||||
let _ = tracing::subscriber::set_default(
|
||||
tracing_subscriber::fmt().with_test_writer().finish(),
|
||||
tracing_subscriber::fmt()
|
||||
.with_test_writer()
|
||||
.finish(),
|
||||
);
|
||||
|
||||
let events = &[
|
||||
@@ -1199,7 +1229,10 @@ mod tests {
|
||||
.map(|list| list.into_iter().map(event_id).collect::<Vec<_>>())
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let expected_state_ids = vec!["PC"].into_iter().map(event_id).collect::<Vec<_>>();
|
||||
let expected_state_ids = vec!["PC"]
|
||||
.into_iter()
|
||||
.map(event_id)
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
do_check(events, edges, expected_state_ids).await;
|
||||
}
|
||||
@@ -1207,7 +1240,9 @@ mod tests {
|
||||
#[tokio::test]
|
||||
async fn topic_setting() {
|
||||
let _ = tracing::subscriber::set_default(
|
||||
tracing_subscriber::fmt().with_test_writer().finish(),
|
||||
tracing_subscriber::fmt()
|
||||
.with_test_writer()
|
||||
.finish(),
|
||||
);
|
||||
|
||||
let events = &[
|
||||
@@ -1289,7 +1324,9 @@ mod tests {
|
||||
use futures::future::ready;
|
||||
|
||||
let _ = tracing::subscriber::set_default(
|
||||
tracing_subscriber::fmt().with_test_writer().finish(),
|
||||
tracing_subscriber::fmt()
|
||||
.with_test_writer()
|
||||
.finish(),
|
||||
);
|
||||
|
||||
let mut store = TestStore::<PduEvent>(hashmap! {});
|
||||
@@ -1332,7 +1369,9 @@ mod tests {
|
||||
#[tokio::test]
|
||||
async fn test_lexicographical_sort() {
|
||||
let _ = tracing::subscriber::set_default(
|
||||
tracing_subscriber::fmt().with_test_writer().finish(),
|
||||
tracing_subscriber::fmt()
|
||||
.with_test_writer()
|
||||
.finish(),
|
||||
);
|
||||
|
||||
let graph = hashmap! {
|
||||
@@ -1361,7 +1400,9 @@ mod tests {
|
||||
#[tokio::test]
|
||||
async fn ban_with_auth_chains() {
|
||||
let _ = tracing::subscriber::set_default(
|
||||
tracing_subscriber::fmt().with_test_writer().finish(),
|
||||
tracing_subscriber::fmt()
|
||||
.with_test_writer()
|
||||
.finish(),
|
||||
);
|
||||
let ban = BAN_STATE_SET();
|
||||
|
||||
@@ -1383,7 +1424,9 @@ mod tests {
|
||||
use futures::future::ready;
|
||||
|
||||
let _ = tracing::subscriber::set_default(
|
||||
tracing_subscriber::fmt().with_test_writer().finish(),
|
||||
tracing_subscriber::fmt()
|
||||
.with_test_writer()
|
||||
.finish(),
|
||||
);
|
||||
let init = INITIAL_EVENTS();
|
||||
let ban = BAN_STATE_SET();
|
||||
@@ -1402,7 +1445,13 @@ mod tests {
|
||||
inner.get(&event_id("PA")).unwrap(),
|
||||
]
|
||||
.iter()
|
||||
.map(|ev| (ev.event_type().with_state_key(ev.state_key().unwrap()), ev.event_id.clone()))
|
||||
.map(|ev| {
|
||||
(
|
||||
ev.event_type()
|
||||
.with_state_key(ev.state_key().unwrap()),
|
||||
ev.event_id.clone(),
|
||||
)
|
||||
})
|
||||
.collect::<StateMap<_>>();
|
||||
|
||||
let state_set_b = [
|
||||
@@ -1415,7 +1464,13 @@ mod tests {
|
||||
inner.get(&event_id("PA")).unwrap(),
|
||||
]
|
||||
.iter()
|
||||
.map(|ev| (ev.event_type().with_state_key(ev.state_key().unwrap()), ev.event_id.clone()))
|
||||
.map(|ev| {
|
||||
(
|
||||
ev.event_type()
|
||||
.with_state_key(ev.state_key().unwrap()),
|
||||
ev.event_id.clone(),
|
||||
)
|
||||
})
|
||||
.collect::<StateMap<_>>();
|
||||
|
||||
let ev_map = &store.0;
|
||||
@@ -1479,7 +1534,10 @@ mod tests {
|
||||
.map(|list| list.into_iter().map(event_id).collect::<Vec<_>>())
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let expected_state_ids = vec!["JR"].into_iter().map(event_id).collect::<Vec<_>>();
|
||||
let expected_state_ids = vec!["JR"]
|
||||
.into_iter()
|
||||
.map(event_id)
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
do_check(&join_rule.values().cloned().collect::<Vec<_>>(), edges, expected_state_ids)
|
||||
.await;
|
||||
|
||||
@@ -206,12 +206,16 @@ pub(crate) async fn do_check(
|
||||
)
|
||||
});
|
||||
|
||||
let key = ev.event_type().with_state_key(ev.state_key().unwrap());
|
||||
let key = ev
|
||||
.event_type()
|
||||
.with_state_key(ev.state_key().unwrap());
|
||||
|
||||
expected_state.insert(key, node);
|
||||
}
|
||||
|
||||
let start_state = state_at_event.get(event_id!("$START:foo")).unwrap();
|
||||
let start_state = state_at_event
|
||||
.get(event_id!("$START:foo"))
|
||||
.unwrap();
|
||||
|
||||
let end_state = state_at_event
|
||||
.get(event_id!("$END:foo"))
|
||||
@@ -340,21 +344,33 @@ impl TestStore<PduEvent> {
|
||||
let state_at_bob = [&create_event, &alice_mem, &join_rules, &bob_mem]
|
||||
.iter()
|
||||
.map(|e| {
|
||||
(e.event_type().with_state_key(e.state_key().unwrap()), e.event_id().to_owned())
|
||||
(
|
||||
e.event_type()
|
||||
.with_state_key(e.state_key().unwrap()),
|
||||
e.event_id().to_owned(),
|
||||
)
|
||||
})
|
||||
.collect::<StateMap<_>>();
|
||||
|
||||
let state_at_charlie = [&create_event, &alice_mem, &join_rules, &charlie_mem]
|
||||
.iter()
|
||||
.map(|e| {
|
||||
(e.event_type().with_state_key(e.state_key().unwrap()), e.event_id().to_owned())
|
||||
(
|
||||
e.event_type()
|
||||
.with_state_key(e.state_key().unwrap()),
|
||||
e.event_id().to_owned(),
|
||||
)
|
||||
})
|
||||
.collect::<StateMap<_>>();
|
||||
|
||||
let expected = [&create_event, &alice_mem, &join_rules, &bob_mem, &charlie_mem]
|
||||
.iter()
|
||||
.map(|e| {
|
||||
(e.event_type().with_state_key(e.state_key().unwrap()), e.event_id().to_owned())
|
||||
(
|
||||
e.event_type()
|
||||
.with_state_key(e.state_key().unwrap()),
|
||||
e.event_id().to_owned(),
|
||||
)
|
||||
})
|
||||
.collect::<StateMap<_>>();
|
||||
|
||||
|
||||
@@ -31,7 +31,9 @@ impl Metrics {
|
||||
let runtime_monitor = runtime.as_ref().map(RuntimeMonitor::new);
|
||||
|
||||
#[cfg(tokio_unstable)]
|
||||
let runtime_intervals = runtime_monitor.as_ref().map(RuntimeMonitor::intervals);
|
||||
let runtime_intervals = runtime_monitor
|
||||
.as_ref()
|
||||
.map(RuntimeMonitor::intervals);
|
||||
|
||||
Self {
|
||||
_runtime: runtime.clone(),
|
||||
|
||||
@@ -27,7 +27,10 @@ pub fn to_name(path: &OsStr) -> Result<String> {
|
||||
.expect("path file stem")
|
||||
.to_str()
|
||||
.expect("name string");
|
||||
let name = name.strip_prefix("lib").unwrap_or(name).to_owned();
|
||||
let name = name
|
||||
.strip_prefix("lib")
|
||||
.unwrap_or(name)
|
||||
.to_owned();
|
||||
|
||||
Ok(name)
|
||||
}
|
||||
|
||||
@@ -21,7 +21,9 @@ pub fn from_str(str: &str) -> Result<usize> {
|
||||
#[inline]
|
||||
#[must_use]
|
||||
pub fn pretty(bytes: usize) -> String {
|
||||
let bytes: u64 = bytes.try_into().expect("failed to convert usize to u64");
|
||||
let bytes: u64 = bytes
|
||||
.try_into()
|
||||
.expect("failed to convert usize to u64");
|
||||
|
||||
ByteSize::b(bytes).display().iec().to_string()
|
||||
}
|
||||
|
||||
@@ -73,7 +73,9 @@ where
|
||||
|
||||
Ok(Guard::<Key, Val> {
|
||||
map: Arc::clone(&self.map),
|
||||
val: val.try_lock_owned().map_err(|_| err!("would yield"))?,
|
||||
val: val
|
||||
.try_lock_owned()
|
||||
.map_err(|_| err!("would yield"))?,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -97,7 +99,9 @@ where
|
||||
|
||||
Ok(Guard::<Key, Val> {
|
||||
map: Arc::clone(&self.map),
|
||||
val: val.try_lock_owned().map_err(|_| err!("would yield"))?,
|
||||
val: val
|
||||
.try_lock_owned()
|
||||
.map_err(|_| err!("would yield"))?,
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -12,6 +12,9 @@ impl<T> UnwrapInfallible<T> for Result<T, Infallible> {
|
||||
fn unwrap_infallible(self) -> T {
|
||||
// SAFETY: Branchless unwrap for errors that can never happen. In debug
|
||||
// mode this is asserted.
|
||||
unsafe { self.debug_inspect_err(error::infallible).unwrap_unchecked() }
|
||||
unsafe {
|
||||
self.debug_inspect_err(error::infallible)
|
||||
.unwrap_unchecked()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -68,7 +68,11 @@ where
|
||||
a.map(move |ai| (ai, b.clone()))
|
||||
.filter_map(|(ai, b)| async move {
|
||||
let mut lock = b.lock().await;
|
||||
while let Some(bi) = Pin::new(&mut *lock).next_if(|bi| *bi <= ai).await.as_ref() {
|
||||
while let Some(bi) = Pin::new(&mut *lock)
|
||||
.next_if(|bi| *bi <= ai)
|
||||
.await
|
||||
.as_ref()
|
||||
{
|
||||
if ai == *bi {
|
||||
return Some(ai);
|
||||
}
|
||||
|
||||
@@ -65,7 +65,11 @@ where
|
||||
let h = h.into().unwrap_or_else(runtime::Handle::current);
|
||||
self.broadn_and_then(n, move |val| {
|
||||
let (h, f) = (h.clone(), f.clone());
|
||||
async move { h.spawn_blocking(move || f(val)).map_err(E::from).await? }
|
||||
async move {
|
||||
h.spawn_blocking(move || f(val))
|
||||
.map_err(E::from)
|
||||
.await?
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user