@@ -57,11 +57,20 @@ 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| {
|
||||
appservice.registration.id == "irc"
|
||||
|| appservice.registration.id.contains("matrix-appservice-irc")
|
||||
|| appservice.registration.id.contains("matrix_appservice_irc")
|
||||
});
|
||||
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")
|
||||
});
|
||||
|
||||
if services
|
||||
.globals
|
||||
@@ -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| {
|
||||
appservice.registration.id == "irc"
|
||||
|| appservice.registration.id.contains("matrix-appservice-irc")
|
||||
|| appservice.registration.id.contains("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")
|
||||
});
|
||||
|
||||
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,11 +73,15 @@ pub(crate) async fn get_media_preview_legacy_route(
|
||||
)));
|
||||
}
|
||||
|
||||
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}")
|
||||
)))
|
||||
})?;
|
||||
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}")
|
||||
)))
|
||||
})?;
|
||||
|
||||
serde_json::value::to_raw_value(&preview)
|
||||
.map(get_media_preview::v3::Response::from_raw_value)
|
||||
|
||||
@@ -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,9 +179,11 @@ pub(crate) async fn create_room_route(
|
||||
}
|
||||
content.insert(
|
||||
"room_version".into(),
|
||||
json!(room_version.as_str()).try_into().map_err(|_| {
|
||||
Error::BadRequest(ErrorKind::BadJson, "Invalid creation content")
|
||||
})?,
|
||||
json!(room_version.as_str())
|
||||
.try_into()
|
||||
.map_err(|_| {
|
||||
Error::BadRequest(ErrorKind::BadJson, "Invalid creation content")
|
||||
})?,
|
||||
);
|
||||
content
|
||||
},
|
||||
@@ -231,18 +252,29 @@ 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 {
|
||||
| room::Visibility::Public => RoomPreset::PublicChat,
|
||||
| _ => RoomPreset::PrivateChat, // Room visibility should not be custom
|
||||
});
|
||||
let preset = body
|
||||
.preset
|
||||
.clone()
|
||||
.unwrap_or(match &body.visibility {
|
||||
| room::Visibility::Public => RoomPreset::PublicChat,
|
||||
| _ => RoomPreset::PrivateChat, // Room visibility should not be custom
|
||||
});
|
||||
|
||||
let mut users = BTreeMap::from_iter([(sender_user.clone(), int!(100))]);
|
||||
|
||||
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,10 +385,12 @@ 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| {
|
||||
warn!("Invalid initial state event: {:?}", e);
|
||||
Error::BadRequest(ErrorKind::InvalidParam, "Invalid initial state event.")
|
||||
})?;
|
||||
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.")
|
||||
})?;
|
||||
|
||||
debug_info!("Room creation initial state event: {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,15 +976,23 @@ 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| {
|
||||
sender_user != user_id
|
||||
&& witness.is_some_and(|witness| !witness.contains(user_id))
|
||||
});
|
||||
&& 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))
|
||||
});
|
||||
|
||||
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()) {
|
||||
|
||||
Reference in New Issue
Block a user