run cargo fix for rust 2024 changes and rustfmt

Signed-off-by: June Clementine Strawberry <strawberry@puppygock.gay>
This commit is contained in:
June Clementine Strawberry 2025-02-23 01:17:45 -05:00
parent e97952b7f6
commit a1e1f40ded
No known key found for this signature in database
320 changed files with 2212 additions and 2039 deletions

View file

@ -3,34 +3,35 @@ use std::fmt::Write;
use axum::extract::State;
use axum_client_ip::InsecureClientIp;
use conduwuit::{
debug_info, error, info, is_equal_to, utils, utils::ReadyExt, warn, Error, PduBuilder, Result,
Error, PduBuilder, Result, debug_info, error, info, is_equal_to, utils, utils::ReadyExt, warn,
};
use futures::{FutureExt, StreamExt};
use register::RegistrationKind;
use ruma::{
OwnedRoomId, UserId,
api::client::{
account::{
change_password, check_registration_token_validity, deactivate, get_3pids,
get_username_availability,
ThirdPartyIdRemovalStatus, change_password, check_registration_token_validity,
deactivate, get_3pids, get_username_availability,
register::{self, LoginType},
request_3pid_management_token_via_email, request_3pid_management_token_via_msisdn,
whoami, ThirdPartyIdRemovalStatus,
whoami,
},
error::ErrorKind,
uiaa::{AuthFlow, AuthType, UiaaInfo},
},
events::{
GlobalAccountDataEventType, StateEventType,
room::{
message::RoomMessageEventContent,
power_levels::{RoomPowerLevels, RoomPowerLevelsEventContent},
},
GlobalAccountDataEventType, StateEventType,
},
push, OwnedRoomId, UserId,
push,
};
use service::Services;
use super::{join_room_by_id_helper, DEVICE_ID_LENGTH, SESSION_ID_LENGTH, TOKEN_LENGTH};
use super::{DEVICE_ID_LENGTH, SESSION_ID_LENGTH, TOKEN_LENGTH, join_room_by_id_helper};
use crate::Ruma;
const RANDOM_USER_ID_LENGTH: usize = 10;
@ -218,12 +219,20 @@ pub(crate) async fn register_route(
};
if body.body.login_type == Some(LoginType::ApplicationService) {
if let Some(ref info) = body.appservice_info {
if !info.is_user_match(&user_id) {
return Err(Error::BadRequest(ErrorKind::Exclusive, "User is not in namespace."));
}
} else {
return Err(Error::BadRequest(ErrorKind::MissingToken, "Missing appservice token."));
match body.appservice_info {
| Some(ref info) =>
if !info.is_user_match(&user_id) {
return Err(Error::BadRequest(
ErrorKind::Exclusive,
"User is not in namespace.",
));
},
| _ => {
return Err(Error::BadRequest(
ErrorKind::MissingToken,
"Missing appservice token.",
));
},
}
} else if services.appservice.is_exclusive_user_id(&user_id).await {
return Err(Error::BadRequest(ErrorKind::Exclusive, "User ID reserved by appservice."));
@ -256,33 +265,39 @@ pub(crate) async fn register_route(
};
if !skip_auth {
if let Some(auth) = &body.auth {
let (worked, uiaainfo) = services
.uiaa
.try_auth(
&UserId::parse_with_server_name("", services.globals.server_name())
.expect("we know this is valid"),
"".into(),
auth,
&uiaainfo,
)
.await?;
if !worked {
return Err(Error::Uiaa(uiaainfo));
}
// Success!
} else if let Some(json) = body.json_body {
uiaainfo.session = Some(utils::random_string(SESSION_ID_LENGTH));
services.uiaa.create(
&UserId::parse_with_server_name("", services.globals.server_name())
.expect("we know this is valid"),
"".into(),
&uiaainfo,
&json,
);
return Err(Error::Uiaa(uiaainfo));
} else {
return Err(Error::BadRequest(ErrorKind::NotJson, "Not json."));
match &body.auth {
| Some(auth) => {
let (worked, uiaainfo) = services
.uiaa
.try_auth(
&UserId::parse_with_server_name("", services.globals.server_name())
.expect("we know this is valid"),
"".into(),
auth,
&uiaainfo,
)
.await?;
if !worked {
return Err(Error::Uiaa(uiaainfo));
}
// Success!
},
| _ => match body.json_body {
| Some(json) => {
uiaainfo.session = Some(utils::random_string(SESSION_ID_LENGTH));
services.uiaa.create(
&UserId::parse_with_server_name("", services.globals.server_name())
.expect("we know this is valid"),
"".into(),
&uiaainfo,
&json,
);
return Err(Error::Uiaa(uiaainfo));
},
| _ => {
return Err(Error::BadRequest(ErrorKind::NotJson, "Not json."));
},
},
}
}
@ -463,7 +478,7 @@ pub(crate) async fn register_route(
}
if let Some(room_server_name) = room.server_name() {
if let Err(e) = join_room_by_id_helper(
match join_room_by_id_helper(
&services,
&user_id,
&room_id,
@ -475,10 +490,15 @@ pub(crate) async fn register_route(
.boxed()
.await
{
// don't return this error so we don't fail registrations
error!("Failed to automatically join room {room} for user {user_id}: {e}");
} else {
info!("Automatically joined room {room} for user {user_id}");
| Err(e) => {
// don't return this error so we don't fail registrations
error!(
"Failed to automatically join room {room} for user {user_id}: {e}"
);
},
| _ => {
info!("Automatically joined room {room} for user {user_id}");
},
};
}
}
@ -532,26 +552,32 @@ pub(crate) async fn change_password_route(
auth_error: None,
};
if let Some(auth) = &body.auth {
let (worked, uiaainfo) = services
.uiaa
.try_auth(sender_user, sender_device, auth, &uiaainfo)
.await?;
match &body.auth {
| Some(auth) => {
let (worked, uiaainfo) = services
.uiaa
.try_auth(sender_user, sender_device, auth, &uiaainfo)
.await?;
if !worked {
return Err(Error::Uiaa(uiaainfo));
}
if !worked {
return Err(Error::Uiaa(uiaainfo));
}
// Success!
} else if let Some(json) = body.json_body {
uiaainfo.session = Some(utils::random_string(SESSION_ID_LENGTH));
services
.uiaa
.create(sender_user, sender_device, &uiaainfo, &json);
// Success!
},
| _ => match body.json_body {
| Some(json) => {
uiaainfo.session = Some(utils::random_string(SESSION_ID_LENGTH));
services
.uiaa
.create(sender_user, sender_device, &uiaainfo, &json);
return Err(Error::Uiaa(uiaainfo));
} else {
return Err(Error::BadRequest(ErrorKind::NotJson, "Not json."));
return Err(Error::Uiaa(uiaainfo));
},
| _ => {
return Err(Error::BadRequest(ErrorKind::NotJson, "Not json."));
},
},
}
services
@ -636,25 +662,31 @@ pub(crate) async fn deactivate_route(
auth_error: None,
};
if let Some(auth) = &body.auth {
let (worked, uiaainfo) = services
.uiaa
.try_auth(sender_user, sender_device, auth, &uiaainfo)
.await?;
match &body.auth {
| Some(auth) => {
let (worked, uiaainfo) = services
.uiaa
.try_auth(sender_user, sender_device, auth, &uiaainfo)
.await?;
if !worked {
return Err(Error::Uiaa(uiaainfo));
}
// Success!
} else if let Some(json) = body.json_body {
uiaainfo.session = Some(utils::random_string(SESSION_ID_LENGTH));
services
.uiaa
.create(sender_user, sender_device, &uiaainfo, &json);
if !worked {
return Err(Error::Uiaa(uiaainfo));
}
// Success!
},
| _ => match body.json_body {
| Some(json) => {
uiaainfo.session = Some(utils::random_string(SESSION_ID_LENGTH));
services
.uiaa
.create(sender_user, sender_device, &uiaainfo, &json);
return Err(Error::Uiaa(uiaainfo));
} else {
return Err(Error::BadRequest(ErrorKind::NotJson, "Not json."));
return Err(Error::Uiaa(uiaainfo));
},
| _ => {
return Err(Error::BadRequest(ErrorKind::NotJson, "Not json."));
},
},
}
// Remove profile pictures and display name
@ -809,7 +841,7 @@ pub async fn full_user_deactivate(
power_levels_content.users.remove(user_id);
// ignore errors so deactivation doesn't fail
if let Err(e) = services
match services
.rooms
.timeline
.build_and_append_pdu(
@ -820,9 +852,12 @@ pub async fn full_user_deactivate(
)
.await
{
warn!(%room_id, %user_id, "Failed to demote user's own power level: {e}");
} else {
info!("Demoted {user_id} in {room_id} as part of account deactivation");
| Err(e) => {
warn!(%room_id, %user_id, "Failed to demote user's own power level: {e}");
},
| _ => {
info!("Demoted {user_id} in {room_id} as part of account deactivation");
},
}
}
}

View file

@ -1,6 +1,7 @@
use axum::extract::State;
use conduwuit::{err, Err};
use conduwuit::{Err, err};
use ruma::{
RoomId, UserId,
api::client::config::{
get_global_account_data, get_room_account_data, set_global_account_data,
set_room_account_data,
@ -10,12 +11,11 @@ use ruma::{
GlobalAccountDataEventType, RoomAccountDataEventType,
},
serde::Raw,
RoomId, UserId,
};
use serde::Deserialize;
use serde_json::{json, value::RawValue as RawJsonValue};
use crate::{service::Services, Result, Ruma};
use crate::{Result, Ruma, service::Services};
/// # `PUT /_matrix/client/r0/user/{userId}/account_data/{type}`
///

View file

@ -1,10 +1,10 @@
use axum::extract::State;
use conduwuit::{debug, Err, Result};
use conduwuit::{Err, Result, debug};
use futures::StreamExt;
use rand::seq::SliceRandom;
use ruma::{
api::client::alias::{create_alias, delete_alias, get_alias},
OwnedServerName, RoomAliasId, RoomId,
api::client::alias::{create_alias, delete_alias, get_alias},
};
use service::Services;
@ -128,18 +128,26 @@ async fn room_available_servers(
// insert our server as the very first choice if in list, else check if we can
// prefer the room alias server first
if let Some(server_index) = servers
match servers
.iter()
.position(|server_name| services.globals.server_is_ours(server_name))
{
servers.swap_remove(server_index);
servers.insert(0, services.globals.server_name().to_owned());
} else if let Some(alias_server_index) = servers
.iter()
.position(|server| server == room_alias.server_name())
{
servers.swap_remove(alias_server_index);
servers.insert(0, room_alias.server_name().into());
| Some(server_index) => {
servers.swap_remove(server_index);
servers.insert(0, services.globals.server_name().to_owned());
},
| _ => {
match servers
.iter()
.position(|server| server == room_alias.server_name())
{
| Some(alias_server_index) => {
servers.swap_remove(alias_server_index);
servers.insert(0, room_alias.server_name().into());
},
| _ => {},
}
},
}
servers

View file

@ -1,5 +1,5 @@
use axum::extract::State;
use conduwuit::{err, Err, Result};
use conduwuit::{Err, Result, err};
use ruma::api::{appservice::ping, client::appservice::request_ping};
use crate::Ruma;

View file

@ -1,6 +1,7 @@
use axum::extract::State;
use conduwuit::{err, Err};
use conduwuit::{Err, err};
use ruma::{
UInt,
api::client::backup::{
add_backup_keys, add_backup_keys_for_room, add_backup_keys_for_session,
create_backup_version, delete_backup_keys, delete_backup_keys_for_room,
@ -8,7 +9,6 @@ use ruma::{
get_backup_keys_for_room, get_backup_keys_for_session, get_latest_backup_info,
update_backup_version,
},
UInt,
};
use crate::{Result, Ruma};

View file

@ -3,11 +3,11 @@ use std::collections::BTreeMap;
use axum::extract::State;
use conduwuit::{Result, Server};
use ruma::{
RoomVersionId,
api::client::discovery::get_capabilities::{
self, Capabilities, GetLoginTokenCapability, RoomVersionStability,
RoomVersionsCapability, ThirdPartyIdChangesCapability,
},
RoomVersionId,
};
use serde_json::json;

View file

@ -1,23 +1,22 @@
use axum::extract::State;
use conduwuit::{
at, err, ref_at,
Err, PduEvent, Result, at, err, ref_at,
utils::{
IterStream,
future::TryExtExt,
stream::{BroadbandExt, ReadyExt, TryIgnore, WidebandExt},
IterStream,
},
Err, PduEvent, Result,
};
use futures::{
future::{join, join3, try_join3, OptionFuture},
FutureExt, StreamExt, TryFutureExt, TryStreamExt,
future::{OptionFuture, join, join3, try_join3},
};
use ruma::{api::client::context::get_context, events::StateEventType, OwnedEventId, UserId};
use ruma::{OwnedEventId, UserId, api::client::context::get_context, events::StateEventType};
use service::rooms::{lazy_loading, lazy_loading::Options, short::ShortStateKey};
use crate::{
client::message::{event_filter, ignored_filter, lazy_loading_witness, visibility_filter},
Ruma,
client::message::{event_filter, ignored_filter, lazy_loading_witness, visibility_filter},
};
const LIMIT_MAX: usize = 100;

View file

@ -1,18 +1,18 @@
use axum::extract::State;
use axum_client_ip::InsecureClientIp;
use conduwuit::{err, Err};
use conduwuit::{Err, err};
use futures::StreamExt;
use ruma::{
MilliSecondsSinceUnixEpoch,
api::client::{
device::{self, delete_device, delete_devices, get_device, get_devices, update_device},
error::ErrorKind,
uiaa::{AuthFlow, AuthType, UiaaInfo},
},
MilliSecondsSinceUnixEpoch,
};
use super::SESSION_ID_LENGTH;
use crate::{utils, Error, Result, Ruma};
use crate::{Error, Result, Ruma, utils};
/// # `GET /_matrix/client/r0/devices`
///
@ -107,25 +107,31 @@ pub(crate) async fn delete_device_route(
auth_error: None,
};
if let Some(auth) = &body.auth {
let (worked, uiaainfo) = services
.uiaa
.try_auth(sender_user, sender_device, auth, &uiaainfo)
.await?;
match &body.auth {
| Some(auth) => {
let (worked, uiaainfo) = services
.uiaa
.try_auth(sender_user, sender_device, auth, &uiaainfo)
.await?;
if !worked {
return Err!(Uiaa(uiaainfo));
}
// Success!
} else if let Some(json) = body.json_body {
uiaainfo.session = Some(utils::random_string(SESSION_ID_LENGTH));
services
.uiaa
.create(sender_user, sender_device, &uiaainfo, &json);
if !worked {
return Err!(Uiaa(uiaainfo));
}
// Success!
},
| _ => match body.json_body {
| Some(json) => {
uiaainfo.session = Some(utils::random_string(SESSION_ID_LENGTH));
services
.uiaa
.create(sender_user, sender_device, &uiaainfo, &json);
return Err!(Uiaa(uiaainfo));
} else {
return Err!(Request(NotJson("Not json.")));
return Err!(Uiaa(uiaainfo));
},
| _ => {
return Err!(Request(NotJson("Not json.")));
},
},
}
services
@ -164,25 +170,31 @@ pub(crate) async fn delete_devices_route(
auth_error: None,
};
if let Some(auth) = &body.auth {
let (worked, uiaainfo) = services
.uiaa
.try_auth(sender_user, sender_device, auth, &uiaainfo)
.await?;
match &body.auth {
| Some(auth) => {
let (worked, uiaainfo) = services
.uiaa
.try_auth(sender_user, sender_device, auth, &uiaainfo)
.await?;
if !worked {
return Err(Error::Uiaa(uiaainfo));
}
// Success!
} else if let Some(json) = body.json_body {
uiaainfo.session = Some(utils::random_string(SESSION_ID_LENGTH));
services
.uiaa
.create(sender_user, sender_device, &uiaainfo, &json);
if !worked {
return Err(Error::Uiaa(uiaainfo));
}
// Success!
},
| _ => match body.json_body {
| Some(json) => {
uiaainfo.session = Some(utils::random_string(SESSION_ID_LENGTH));
services
.uiaa
.create(sender_user, sender_device, &uiaainfo, &json);
return Err(Error::Uiaa(uiaainfo));
} else {
return Err(Error::BadRequest(ErrorKind::NotJson, "Not json."));
return Err(Error::Uiaa(uiaainfo));
},
| _ => {
return Err(Error::BadRequest(ErrorKind::NotJson, "Not json."));
},
},
}
for device_id in &body.devices {

View file

@ -1,8 +1,9 @@
use axum::extract::State;
use axum_client_ip::InsecureClientIp;
use conduwuit::{info, warn, Err, Error, Result};
use conduwuit::{Err, Error, Result, info, warn};
use futures::{StreamExt, TryFutureExt};
use ruma::{
OwnedRoomId, RoomId, ServerName, UInt, UserId,
api::{
client::{
directory::{
@ -16,13 +17,13 @@ use ruma::{
},
directory::{Filter, PublicRoomJoinRule, PublicRoomsChunk, RoomNetwork},
events::{
StateEventType,
room::{
join_rules::{JoinRule, RoomJoinRulesEventContent},
power_levels::{RoomPowerLevels, RoomPowerLevelsEventContent},
},
StateEventType,
},
uint, OwnedRoomId, RoomId, ServerName, UInt, UserId,
uint,
};
use service::Services;
@ -365,30 +366,34 @@ async fn user_can_publish_room(
user_id: &UserId,
room_id: &RoomId,
) -> Result<bool> {
if let Ok(event) = services
match services
.rooms
.state_accessor
.room_state_get(room_id, &StateEventType::RoomPowerLevels, "")
.await
{
serde_json::from_str(event.content.get())
| Ok(event) => serde_json::from_str(event.content.get())
.map_err(|_| Error::bad_database("Invalid event content for m.room.power_levels"))
.map(|content: RoomPowerLevelsEventContent| {
RoomPowerLevels::from(content)
.user_can_send_state(user_id, StateEventType::RoomHistoryVisibility)
})
} else if let Ok(event) = services
.rooms
.state_accessor
.room_state_get(room_id, &StateEventType::RoomCreate, "")
.await
{
Ok(event.sender == user_id)
} else {
return Err(Error::BadRequest(
ErrorKind::forbidden(),
"User is not allowed to publish this room",
));
}),
| _ => {
match services
.rooms
.state_accessor
.room_state_get(room_id, &StateEventType::RoomCreate, "")
.await
{
| Ok(event) => Ok(event.sender == user_id),
| _ => {
return Err(Error::BadRequest(
ErrorKind::forbidden(),
"User is not allowed to publish this room",
));
},
}
},
}
}

View file

@ -1,9 +1,10 @@
use std::collections::{BTreeMap, HashMap, HashSet};
use axum::extract::State;
use conduwuit::{debug, err, info, result::NotFound, utils, Err, Error, Result};
use futures::{stream::FuturesUnordered, StreamExt};
use conduwuit::{Err, Error, Result, debug, err, info, result::NotFound, utils};
use futures::{StreamExt, stream::FuturesUnordered};
use ruma::{
OneTimeKeyAlgorithm, OwnedDeviceId, OwnedUserId, UserId,
api::{
client::{
error::ErrorKind,
@ -17,14 +18,13 @@ use ruma::{
},
encryption::CrossSigningKey,
serde::Raw,
OneTimeKeyAlgorithm, OwnedDeviceId, OwnedUserId, UserId,
};
use serde_json::json;
use super::SESSION_ID_LENGTH;
use crate::{
service::{users::parse_master_key, Services},
Ruma,
service::{Services, users::parse_master_key},
};
/// # `POST /_matrix/client/r0/keys/upload`
@ -126,7 +126,7 @@ pub(crate) async fn upload_signing_keys_route(
auth_error: None,
};
if let Ok(exists) = check_for_new_keys(
match check_for_new_keys(
services,
sender_user,
body.self_signing_key.as_ref(),
@ -136,32 +136,45 @@ pub(crate) async fn upload_signing_keys_route(
.await
.inspect_err(|e| info!(?e))
{
if let Some(result) = exists {
// No-op, they tried to reupload the same set of keys
// (lost connection for example)
return Ok(result);
}
debug!("Skipping UIA in accordance with MSC3967, the user didn't have any existing keys");
// Some of the keys weren't found, so we let them upload
} else if let Some(auth) = &body.auth {
let (worked, uiaainfo) = services
.uiaa
.try_auth(sender_user, sender_device, auth, &uiaainfo)
.await?;
| Ok(exists) => {
if let Some(result) = exists {
// No-op, they tried to reupload the same set of keys
// (lost connection for example)
return Ok(result);
}
debug!(
"Skipping UIA in accordance with MSC3967, the user didn't have any existing keys"
);
// Some of the keys weren't found, so we let them upload
},
| _ => {
match &body.auth {
| Some(auth) => {
let (worked, uiaainfo) = services
.uiaa
.try_auth(sender_user, sender_device, auth, &uiaainfo)
.await?;
if !worked {
return Err(Error::Uiaa(uiaainfo));
}
// Success!
} else if let Some(json) = body.json_body {
uiaainfo.session = Some(utils::random_string(SESSION_ID_LENGTH));
services
.uiaa
.create(sender_user, sender_device, &uiaainfo, &json);
if !worked {
return Err(Error::Uiaa(uiaainfo));
}
// Success!
},
| _ => match body.json_body {
| Some(json) => {
uiaainfo.session = Some(utils::random_string(SESSION_ID_LENGTH));
services
.uiaa
.create(sender_user, sender_device, &uiaainfo, &json);
return Err(Error::Uiaa(uiaainfo));
} else {
return Err(Error::BadRequest(ErrorKind::NotJson, "Not json."));
return Err(Error::Uiaa(uiaainfo));
},
| _ => {
return Err(Error::BadRequest(ErrorKind::NotJson, "Not json."));
},
},
}
},
}
services
@ -471,37 +484,40 @@ where
.collect();
while let Some((server, response)) = futures.next().await {
if let Ok(response) = response {
for (user, master_key) in response.master_keys {
let (master_key_id, mut master_key) = parse_master_key(&user, &master_key)?;
match response {
| Ok(response) => {
for (user, master_key) in response.master_keys {
let (master_key_id, mut master_key) = parse_master_key(&user, &master_key)?;
if let Ok(our_master_key) = services
.users
.get_key(&master_key_id, sender_user, &user, &allowed_signatures)
.await
{
let (_, mut our_master_key) = parse_master_key(&user, &our_master_key)?;
master_key.signatures.append(&mut our_master_key.signatures);
if let Ok(our_master_key) = services
.users
.get_key(&master_key_id, sender_user, &user, &allowed_signatures)
.await
{
let (_, mut our_master_key) = parse_master_key(&user, &our_master_key)?;
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");
services
.users
.add_cross_signing_keys(
&user, &raw, &None, &None,
false, /* Dont notify. A notification would trigger another key
* request resulting in an endless loop */
)
.await?;
if let Some(raw) = raw {
master_keys.insert(user.clone(), raw);
}
}
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");
services
.users
.add_cross_signing_keys(
&user, &raw, &None, &None,
false, /* Dont notify. A notification would trigger another key request
* resulting in an endless loop */
)
.await?;
if let Some(raw) = raw {
master_keys.insert(user.clone(), raw);
}
}
self_signing_keys.extend(response.self_signing_keys);
device_keys.extend(response.device_keys);
} else {
failures.insert(server.to_string(), json!({}));
self_signing_keys.extend(response.self_signing_keys);
device_keys.extend(response.device_keys);
},
| _ => {
failures.insert(server.to_string(), json!({}));
},
}
}

View file

@ -3,16 +3,16 @@ use std::time::Duration;
use axum::extract::State;
use axum_client_ip::InsecureClientIp;
use conduwuit::{
err,
Err, Result, err,
utils::{self, content_disposition::make_content_disposition, math::ruma_from_usize},
Err, Result,
};
use conduwuit_service::{
media::{Dim, FileMeta, CACHE_CONTROL_IMMUTABLE, CORP_CROSS_ORIGIN, MXC_LENGTH},
Services,
media::{CACHE_CONTROL_IMMUTABLE, CORP_CROSS_ORIGIN, Dim, FileMeta, MXC_LENGTH},
};
use reqwest::Url;
use ruma::{
Mxc, UserId,
api::client::{
authenticated_media::{
get_content, get_content_as_filename, get_content_thumbnail, get_media_config,
@ -20,7 +20,6 @@ use ruma::{
},
media::create_content,
},
Mxc, UserId,
};
use crate::Ruma;

View file

@ -3,21 +3,20 @@
use axum::extract::State;
use axum_client_ip::InsecureClientIp;
use conduwuit::{
err,
Err, Result, err,
utils::{content_disposition::make_content_disposition, math::ruma_from_usize},
Err, Result,
};
use conduwuit_service::media::{Dim, FileMeta, CACHE_CONTROL_IMMUTABLE, CORP_CROSS_ORIGIN};
use conduwuit_service::media::{CACHE_CONTROL_IMMUTABLE, CORP_CROSS_ORIGIN, Dim, FileMeta};
use reqwest::Url;
use ruma::{
Mxc,
api::client::media::{
create_content, get_content, get_content_as_filename, get_content_thumbnail,
get_media_config, get_media_preview,
},
Mxc,
};
use crate::{client::create_content_route, Ruma, RumaResponse};
use crate::{Ruma, RumaResponse, client::create_content_route};
/// # `GET /_matrix/media/v3/config`
///
@ -142,46 +141,52 @@ pub(crate) async fn get_content_legacy_route(
media_id: &body.media_id,
};
if let Some(FileMeta {
content,
content_type,
content_disposition,
}) = services.media.get(&mxc).await?
{
let content_disposition =
make_content_disposition(content_disposition.as_ref(), content_type.as_deref(), None);
match services.media.get(&mxc).await? {
| Some(FileMeta {
content,
content_type,
content_disposition,
}) => {
let content_disposition = make_content_disposition(
content_disposition.as_ref(),
content_type.as_deref(),
None,
);
Ok(get_content::v3::Response {
file: content.expect("entire file contents"),
content_type: content_type.map(Into::into),
content_disposition: Some(content_disposition),
cross_origin_resource_policy: Some(CORP_CROSS_ORIGIN.into()),
cache_control: Some(CACHE_CONTROL_IMMUTABLE.into()),
})
} else if !services.globals.server_is_ours(&body.server_name) && body.allow_remote {
let response = services
.media
.fetch_remote_content_legacy(&mxc, body.allow_redirect, body.timeout_ms)
.await
.map_err(|e| {
err!(Request(NotFound(debug_warn!(%mxc, "Fetching media failed: {e:?}"))))
})?;
Ok(get_content::v3::Response {
file: content.expect("entire file contents"),
content_type: content_type.map(Into::into),
content_disposition: Some(content_disposition),
cross_origin_resource_policy: Some(CORP_CROSS_ORIGIN.into()),
cache_control: Some(CACHE_CONTROL_IMMUTABLE.into()),
})
},
| _ =>
if !services.globals.server_is_ours(&body.server_name) && body.allow_remote {
let response = services
.media
.fetch_remote_content_legacy(&mxc, body.allow_redirect, body.timeout_ms)
.await
.map_err(|e| {
err!(Request(NotFound(debug_warn!(%mxc, "Fetching media failed: {e:?}"))))
})?;
let content_disposition = make_content_disposition(
response.content_disposition.as_ref(),
response.content_type.as_deref(),
None,
);
let content_disposition = make_content_disposition(
response.content_disposition.as_ref(),
response.content_type.as_deref(),
None,
);
Ok(get_content::v3::Response {
file: response.file,
content_type: response.content_type,
content_disposition: Some(content_disposition),
cross_origin_resource_policy: Some(CORP_CROSS_ORIGIN.into()),
cache_control: Some(CACHE_CONTROL_IMMUTABLE.into()),
})
} else {
Err!(Request(NotFound("Media not found.")))
Ok(get_content::v3::Response {
file: response.file,
content_type: response.content_type,
content_disposition: Some(content_disposition),
cross_origin_resource_policy: Some(CORP_CROSS_ORIGIN.into()),
cache_control: Some(CACHE_CONTROL_IMMUTABLE.into()),
})
} else {
Err!(Request(NotFound("Media not found.")))
},
}
}
@ -227,49 +232,52 @@ pub(crate) async fn get_content_as_filename_legacy_route(
media_id: &body.media_id,
};
if let Some(FileMeta {
content,
content_type,
content_disposition,
}) = services.media.get(&mxc).await?
{
let content_disposition = make_content_disposition(
content_disposition.as_ref(),
content_type.as_deref(),
Some(&body.filename),
);
match services.media.get(&mxc).await? {
| Some(FileMeta {
content,
content_type,
content_disposition,
}) => {
let content_disposition = make_content_disposition(
content_disposition.as_ref(),
content_type.as_deref(),
Some(&body.filename),
);
Ok(get_content_as_filename::v3::Response {
file: content.expect("entire file contents"),
content_type: content_type.map(Into::into),
content_disposition: Some(content_disposition),
cross_origin_resource_policy: Some(CORP_CROSS_ORIGIN.into()),
cache_control: Some(CACHE_CONTROL_IMMUTABLE.into()),
})
} else if !services.globals.server_is_ours(&body.server_name) && body.allow_remote {
let response = services
.media
.fetch_remote_content_legacy(&mxc, body.allow_redirect, body.timeout_ms)
.await
.map_err(|e| {
err!(Request(NotFound(debug_warn!(%mxc, "Fetching media failed: {e:?}"))))
})?;
Ok(get_content_as_filename::v3::Response {
file: content.expect("entire file contents"),
content_type: content_type.map(Into::into),
content_disposition: Some(content_disposition),
cross_origin_resource_policy: Some(CORP_CROSS_ORIGIN.into()),
cache_control: Some(CACHE_CONTROL_IMMUTABLE.into()),
})
},
| _ =>
if !services.globals.server_is_ours(&body.server_name) && body.allow_remote {
let response = services
.media
.fetch_remote_content_legacy(&mxc, body.allow_redirect, body.timeout_ms)
.await
.map_err(|e| {
err!(Request(NotFound(debug_warn!(%mxc, "Fetching media failed: {e:?}"))))
})?;
let content_disposition = make_content_disposition(
response.content_disposition.as_ref(),
response.content_type.as_deref(),
None,
);
let content_disposition = make_content_disposition(
response.content_disposition.as_ref(),
response.content_type.as_deref(),
None,
);
Ok(get_content_as_filename::v3::Response {
content_disposition: Some(content_disposition),
content_type: response.content_type,
file: response.file,
cross_origin_resource_policy: Some(CORP_CROSS_ORIGIN.into()),
cache_control: Some(CACHE_CONTROL_IMMUTABLE.into()),
})
} else {
Err!(Request(NotFound("Media not found.")))
Ok(get_content_as_filename::v3::Response {
content_disposition: Some(content_disposition),
content_type: response.content_type,
file: response.file,
cross_origin_resource_policy: Some(CORP_CROSS_ORIGIN.into()),
cache_control: Some(CACHE_CONTROL_IMMUTABLE.into()),
})
} else {
Err!(Request(NotFound("Media not found.")))
},
}
}
@ -315,46 +323,52 @@ pub(crate) async fn get_content_thumbnail_legacy_route(
};
let dim = Dim::from_ruma(body.width, body.height, body.method.clone())?;
if let Some(FileMeta {
content,
content_type,
content_disposition,
}) = services.media.get_thumbnail(&mxc, &dim).await?
{
let content_disposition =
make_content_disposition(content_disposition.as_ref(), content_type.as_deref(), None);
match services.media.get_thumbnail(&mxc, &dim).await? {
| Some(FileMeta {
content,
content_type,
content_disposition,
}) => {
let content_disposition = make_content_disposition(
content_disposition.as_ref(),
content_type.as_deref(),
None,
);
Ok(get_content_thumbnail::v3::Response {
file: content.expect("entire file contents"),
content_type: content_type.map(Into::into),
cross_origin_resource_policy: Some(CORP_CROSS_ORIGIN.into()),
cache_control: Some(CACHE_CONTROL_IMMUTABLE.into()),
content_disposition: Some(content_disposition),
})
} else if !services.globals.server_is_ours(&body.server_name) && body.allow_remote {
let response = services
.media
.fetch_remote_thumbnail_legacy(&body)
.await
.map_err(|e| {
err!(Request(NotFound(debug_warn!(%mxc, "Fetching media failed: {e:?}"))))
})?;
Ok(get_content_thumbnail::v3::Response {
file: content.expect("entire file contents"),
content_type: content_type.map(Into::into),
cross_origin_resource_policy: Some(CORP_CROSS_ORIGIN.into()),
cache_control: Some(CACHE_CONTROL_IMMUTABLE.into()),
content_disposition: Some(content_disposition),
})
},
| _ =>
if !services.globals.server_is_ours(&body.server_name) && body.allow_remote {
let response = services
.media
.fetch_remote_thumbnail_legacy(&body)
.await
.map_err(|e| {
err!(Request(NotFound(debug_warn!(%mxc, "Fetching media failed: {e:?}"))))
})?;
let content_disposition = make_content_disposition(
response.content_disposition.as_ref(),
response.content_type.as_deref(),
None,
);
let content_disposition = make_content_disposition(
response.content_disposition.as_ref(),
response.content_type.as_deref(),
None,
);
Ok(get_content_thumbnail::v3::Response {
file: response.file,
content_type: response.content_type,
cross_origin_resource_policy: Some(CORP_CROSS_ORIGIN.into()),
cache_control: Some(CACHE_CONTROL_IMMUTABLE.into()),
content_disposition: Some(content_disposition),
})
} else {
Err!(Request(NotFound("Media not found.")))
Ok(get_content_thumbnail::v3::Response {
file: response.file,
content_type: response.content_type,
cross_origin_resource_policy: Some(CORP_CROSS_ORIGIN.into()),
cache_control: Some(CACHE_CONTROL_IMMUTABLE.into()),
content_disposition: Some(content_disposition),
})
} else {
Err!(Request(NotFound("Media not found.")))
},
}
}

View file

@ -9,51 +9,51 @@ use std::{
use axum::extract::State;
use axum_client_ip::InsecureClientIp;
use conduwuit::{
at, debug, debug_info, debug_warn, err, error, info,
pdu::{gen_event_id_canonical_json, PduBuilder},
Err, PduEvent, Result, StateKey, at, debug, debug_info, debug_warn, err, error, info,
pdu::{PduBuilder, gen_event_id_canonical_json},
result::FlatOk,
state_res, trace,
utils::{self, shuffle, IterStream, ReadyExt},
warn, Err, PduEvent, Result, StateKey,
utils::{self, IterStream, ReadyExt, shuffle},
warn,
};
use futures::{join, FutureExt, StreamExt, TryFutureExt};
use futures::{FutureExt, StreamExt, TryFutureExt, join};
use ruma::{
CanonicalJsonObject, CanonicalJsonValue, OwnedEventId, OwnedRoomId, OwnedServerName,
OwnedUserId, RoomId, RoomVersionId, ServerName, UserId,
api::{
client::{
error::ErrorKind,
knock::knock_room,
membership::{
ban_user, forget_room, get_member_events, invite_user, join_room_by_id,
join_room_by_id_or_alias,
ThirdPartySigned, ban_user, forget_room, get_member_events, invite_user,
join_room_by_id, join_room_by_id_or_alias,
joined_members::{self, v3::RoomMember},
joined_rooms, kick_user, leave_room, unban_user, ThirdPartySigned,
joined_rooms, kick_user, leave_room, unban_user,
},
},
federation::{self, membership::create_invite},
},
canonical_json::to_canonical_value,
events::{
StateEventType,
room::{
join_rules::{AllowRule, JoinRule, RoomJoinRulesEventContent},
member::{MembershipState, RoomMemberEventContent},
message::RoomMessageEventContent,
},
StateEventType,
},
CanonicalJsonObject, CanonicalJsonValue, OwnedEventId, OwnedRoomId, OwnedServerName,
OwnedUserId, RoomId, RoomVersionId, ServerName, UserId,
};
use service::{
Services,
appservice::RegistrationInfo,
pdu::gen_event_id,
rooms::{
state::RoomMutexGuard,
state_compressor::{CompressedState, HashSetCompressStateEvent},
},
Services,
};
use crate::{client::full_user_deactivate, Ruma};
use crate::{Ruma, client::full_user_deactivate};
/// Checks if the room is banned in any way possible and the sender user is not
/// an admin.
@ -507,43 +507,54 @@ pub(crate) async fn invite_user_route(
)
.await?;
if let invite_user::v3::InvitationRecipient::UserId { user_id } = &body.recipient {
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);
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, recipient_ignored_by_sender) =
join!(sender_ignored_recipient, recipient_ignored_by_sender);
let (sender_ignored_recipient, recipient_ignored_by_sender) =
join!(sender_ignored_recipient, recipient_ignored_by_sender);
if sender_ignored_recipient {
return Err!(Request(Forbidden(
"You cannot invite users you have ignored to rooms."
)));
}
if let Ok(target_user_membership) = services
.rooms
.state_accessor
.get_member(&body.room_id, user_id)
.await
{
if target_user_membership.membership == MembershipState::Ban {
return Err!(Request(Forbidden("User is banned from this room.")));
if sender_ignored_recipient {
return Err!(Request(Forbidden(
"You cannot invite users you have ignored to rooms."
)));
}
}
if recipient_ignored_by_sender {
// silently drop the invite to the recipient if they've been ignored by the
// sender, pretend it worked
return Ok(invite_user::v3::Response {});
}
if let Ok(target_user_membership) = services
.rooms
.state_accessor
.get_member(&body.room_id, user_id)
.await
{
if target_user_membership.membership == MembershipState::Ban {
return Err!(Request(Forbidden("User is banned from this room.")));
}
}
invite_helper(&services, sender_user, user_id, &body.room_id, body.reason.clone(), false)
if recipient_ignored_by_sender {
// silently drop the invite to the recipient if they've been ignored by the
// sender, pretend it worked
return Ok(invite_user::v3::Response {});
}
invite_helper(
&services,
sender_user,
user_id,
&body.room_id,
body.reason.clone(),
false,
)
.boxed()
.await?;
Ok(invite_user::v3::Response {})
} else {
Err!(Request(NotFound("User not found.")))
Ok(invite_user::v3::Response {})
},
| _ => {
Err!(Request(NotFound("User not found.")))
},
}
}
@ -1830,38 +1841,46 @@ async fn remote_leave_room(
.collect()
.await;
if let Ok(invite_state) = services
match services
.rooms
.state_cache
.invite_state(user_id, room_id)
.await
{
servers.extend(
invite_state
.iter()
.filter_map(|event| event.get_field("sender").ok().flatten())
.filter_map(|sender: &str| UserId::parse(sender).ok())
.map(|user| user.server_name().to_owned()),
);
} else if let Ok(knock_state) = services
.rooms
.state_cache
.knock_state(user_id, room_id)
.await
{
servers.extend(
knock_state
.iter()
.filter_map(|event| event.get_field("sender").ok().flatten())
.filter_map(|sender: &str| UserId::parse(sender).ok())
.filter_map(|sender| {
if !services.globals.user_is_local(sender) {
Some(sender.server_name().to_owned())
} else {
None
}
}),
);
| Ok(invite_state) => {
servers.extend(
invite_state
.iter()
.filter_map(|event| event.get_field("sender").ok().flatten())
.filter_map(|sender: &str| UserId::parse(sender).ok())
.map(|user| user.server_name().to_owned()),
);
},
| _ => {
match services
.rooms
.state_cache
.knock_state(user_id, room_id)
.await
{
| Ok(knock_state) => {
servers.extend(
knock_state
.iter()
.filter_map(|event| event.get_field("sender").ok().flatten())
.filter_map(|sender: &str| UserId::parse(sender).ok())
.filter_map(|sender| {
if !services.globals.user_is_local(sender) {
Some(sender.server_name().to_owned())
} else {
None
}
}),
);
},
| _ => {},
}
},
}
if let Some(room_id_server_name) = room_id.server_name() {

View file

@ -1,30 +1,29 @@
use axum::extract::State;
use conduwuit::{
at,
Event, PduCount, PduEvent, Result, at,
utils::{
IterStream, ReadyExt,
result::{FlatOk, LogErr},
stream::{BroadbandExt, TryIgnore, WidebandExt},
IterStream, ReadyExt,
},
Event, PduCount, PduEvent, Result,
};
use futures::{future::OptionFuture, pin_mut, FutureExt, StreamExt, TryFutureExt};
use futures::{FutureExt, StreamExt, TryFutureExt, future::OptionFuture, pin_mut};
use ruma::{
RoomId, UserId,
api::{
client::{filter::RoomEventFilter, message::get_message_events},
Direction,
client::{filter::RoomEventFilter, message::get_message_events},
},
events::{AnyStateEvent, StateEventType, TimelineEventType, TimelineEventType::*},
serde::Raw,
RoomId, UserId,
};
use service::{
Services,
rooms::{
lazy_loading,
lazy_loading::{Options, Witness},
timeline::PdusIterItem,
},
Services,
};
use crate::Ruma;

View file

@ -70,37 +70,38 @@ pub(crate) async fn get_presence_route(
}
}
if let Some(presence) = presence_event {
let status_msg = if presence
.content
.status_msg
.as_ref()
.is_some_and(String::is_empty)
{
None
} else {
presence.content.status_msg
};
let last_active_ago = match presence.content.currently_active {
| Some(true) => None,
| _ => presence
match presence_event {
| Some(presence) => {
let status_msg = if presence
.content
.last_active_ago
.map(|millis| Duration::from_millis(millis.into())),
};
.status_msg
.as_ref()
.is_some_and(String::is_empty)
{
None
} else {
presence.content.status_msg
};
Ok(get_presence::v3::Response {
// TODO: Should ruma just use the presenceeventcontent type here?
status_msg,
currently_active: presence.content.currently_active,
last_active_ago,
presence: presence.content.presence,
})
} else {
Err(Error::BadRequest(
let last_active_ago = match presence.content.currently_active {
| Some(true) => None,
| _ => presence
.content
.last_active_ago
.map(|millis| Duration::from_millis(millis.into())),
};
Ok(get_presence::v3::Response {
// TODO: Should ruma just use the presenceeventcontent type here?
status_msg,
currently_active: presence.content.currently_active,
last_active_ago,
presence: presence.content.presence,
})
},
| _ => Err(Error::BadRequest(
ErrorKind::NotFound,
"Presence state for this user was not found",
))
)),
}
}

View file

@ -2,12 +2,14 @@ use std::collections::BTreeMap;
use axum::extract::State;
use conduwuit::{
Err, Error, Result,
pdu::PduBuilder,
utils::{stream::TryIgnore, IterStream},
warn, Err, Error, Result,
utils::{IterStream, stream::TryIgnore},
warn,
};
use futures::{future::join3, StreamExt, TryStreamExt};
use futures::{StreamExt, TryStreamExt, future::join3};
use ruma::{
OwnedMxcUri, OwnedRoomId, UserId,
api::{
client::{
error::ErrorKind,
@ -19,7 +21,6 @@ use ruma::{
},
events::room::member::{MembershipState, RoomMemberEventContent},
presence::PresenceState,
OwnedMxcUri, OwnedRoomId, UserId,
};
use service::Services;

View file

@ -1,6 +1,7 @@
use axum::extract::State;
use conduwuit::{err, Err};
use conduwuit::{Err, err};
use ruma::{
CanonicalJsonObject, CanonicalJsonValue,
api::client::{
error::ErrorKind,
push::{
@ -10,14 +11,13 @@ use ruma::{
},
},
events::{
push_rules::{PushRulesEvent, PushRulesEventContent},
GlobalAccountDataEventType,
push_rules::{PushRulesEvent, PushRulesEventContent},
},
push::{
InsertPushRuleError, PredefinedContentRuleId, PredefinedOverrideRuleId,
RemovePushRuleError, Ruleset,
},
CanonicalJsonObject, CanonicalJsonValue,
};
use service::Services;

View file

@ -1,14 +1,14 @@
use std::collections::BTreeMap;
use axum::extract::State;
use conduwuit::{err, Err, PduCount};
use conduwuit::{Err, PduCount, err};
use ruma::{
MilliSecondsSinceUnixEpoch,
api::client::{read_marker::set_read_marker, receipt::create_receipt},
events::{
receipt::{ReceiptThread, ReceiptType},
RoomAccountDataEventType,
receipt::{ReceiptThread, ReceiptType},
},
MilliSecondsSinceUnixEpoch,
};
use crate::{Result, Ruma};

View file

@ -3,7 +3,7 @@ use ruma::{
api::client::redact::redact_event, events::room::redaction::RoomRedactionEventContent,
};
use crate::{service::pdu::PduBuilder, Result, Ruma};
use crate::{Result, Ruma, service::pdu::PduBuilder};
/// # `PUT /_matrix/client/r0/rooms/{roomId}/redact/{eventId}/{txnId}`
///

View file

@ -1,22 +1,21 @@
use axum::extract::State;
use conduwuit::{
at,
utils::{result::FlatOk, stream::WidebandExt, IterStream, ReadyExt},
PduCount, Result,
PduCount, Result, at,
utils::{IterStream, ReadyExt, result::FlatOk, stream::WidebandExt},
};
use futures::StreamExt;
use ruma::{
EventId, RoomId, UInt, UserId,
api::{
Direction,
client::relations::{
get_relating_events, get_relating_events_with_rel_type,
get_relating_events_with_rel_type_and_event_type,
},
Direction,
},
events::{relation::RelationType, TimelineEventType},
EventId, RoomId, UInt, UserId,
events::{TimelineEventType, relation::RelationType},
};
use service::{rooms::timeline::PdusIterItem, Services};
use service::{Services, rooms::timeline::PdusIterItem};
use crate::Ruma;

View file

@ -2,22 +2,22 @@ use std::time::Duration;
use axum::extract::State;
use axum_client_ip::InsecureClientIp;
use conduwuit::{info, utils::ReadyExt, Err};
use conduwuit::{Err, info, utils::ReadyExt};
use rand::Rng;
use ruma::{
EventId, RoomId, UserId,
api::client::{
error::ErrorKind,
room::{report_content, report_room},
},
events::room::message,
int, EventId, RoomId, UserId,
int,
};
use tokio::time::sleep;
use crate::{
debug_info,
service::{pdu::PduEvent, Services},
Error, Result, Ruma,
Error, Result, Ruma, debug_info,
service::{Services, pdu::PduEvent},
};
/// # `POST /_matrix/client/v3/rooms/{roomId}/report`

View file

@ -2,15 +2,17 @@ use std::collections::BTreeMap;
use axum::extract::State;
use conduwuit::{
debug_info, debug_warn, err, error, info, pdu::PduBuilder, warn, Err, Error, Result, StateKey,
Err, Error, Result, StateKey, debug_info, debug_warn, err, error, info, pdu::PduBuilder, warn,
};
use futures::FutureExt;
use ruma::{
CanonicalJsonObject, Int, OwnedRoomAliasId, OwnedRoomId, OwnedUserId, RoomId, RoomVersionId,
api::client::{
error::ErrorKind,
room::{self, create_room},
},
events::{
TimelineEventType,
room::{
canonical_alias::RoomCanonicalAliasEventContent,
create::RoomCreateEventContent,
@ -22,16 +24,14 @@ use ruma::{
power_levels::RoomPowerLevelsEventContent,
topic::RoomTopicEventContent,
},
TimelineEventType,
},
int,
serde::{JsonObject, Raw},
CanonicalJsonObject, Int, OwnedRoomAliasId, OwnedRoomId, OwnedUserId, RoomId, RoomVersionId,
};
use serde_json::{json, value::to_raw_value};
use service::{appservice::RegistrationInfo, Services};
use service::{Services, appservice::RegistrationInfo};
use crate::{client::invite_helper, Ruma};
use crate::{Ruma, client::invite_helper};
/// # `POST /_matrix/client/v3/createRoom`
///
@ -68,10 +68,9 @@ pub(crate) async fn create_room_route(
));
}
let room_id: OwnedRoomId = if let Some(custom_room_id) = &body.room_id {
custom_room_id_check(&services, custom_room_id)?
} else {
RoomId::new(&services.server.name)
let room_id: OwnedRoomId = match &body.room_id {
| Some(custom_room_id) => custom_room_id_check(&services, custom_room_id)?,
| _ => RoomId::new(&services.server.name),
};
// check if room ID doesn't already exist instead of erroring on auth check
@ -114,10 +113,10 @@ pub(crate) async fn create_room_route(
.await;
let state_lock = services.rooms.state.mutex.lock(&room_id).await;
let alias: Option<OwnedRoomAliasId> = if let Some(alias) = body.room_alias_name.as_ref() {
Some(room_alias_check(&services, alias, body.appservice_info.as_ref()).await?)
} else {
None
let alias: Option<OwnedRoomAliasId> = match body.room_alias_name.as_ref() {
| Some(alias) =>
Some(room_alias_check(&services, alias, body.appservice_info.as_ref()).await?),
| _ => None,
};
let room_version = match body.room_version.clone() {

View file

@ -1,9 +1,9 @@
use axum::extract::State;
use conduwuit::{err, Err, Event, Result};
use futures::{future::try_join, FutureExt, TryFutureExt};
use conduwuit::{Err, Event, Result, err};
use futures::{FutureExt, TryFutureExt, future::try_join};
use ruma::api::client::room::get_room_event;
use crate::{client::is_ignored_pdu, Ruma};
use crate::{Ruma, client::is_ignored_pdu};
/// # `GET /_matrix/client/r0/rooms/{roomId}/event/{eventId}`
///

View file

@ -1,8 +1,7 @@
use axum::extract::State;
use conduwuit::{
at,
utils::{stream::TryTools, BoolExt},
Err, PduEvent, Result,
Err, PduEvent, Result, at,
utils::{BoolExt, stream::TryTools},
};
use futures::TryStreamExt;
use ruma::api::client::room::initial_sync::v3::{PaginationChunk, Request, Response};

View file

@ -1,19 +1,20 @@
use std::cmp::max;
use axum::extract::State;
use conduwuit::{err, info, pdu::PduBuilder, Error, Result, StateKey};
use conduwuit::{Error, Result, StateKey, err, info, pdu::PduBuilder};
use futures::StreamExt;
use ruma::{
CanonicalJsonObject, RoomId, RoomVersionId,
api::client::{error::ErrorKind, room::upgrade_room},
events::{
StateEventType, TimelineEventType,
room::{
member::{MembershipState, RoomMemberEventContent},
power_levels::RoomPowerLevelsEventContent,
tombstone::RoomTombstoneEventContent,
},
StateEventType, TimelineEventType,
},
int, CanonicalJsonObject, RoomId, RoomVersionId,
int,
};
use serde_json::{json, value::to_raw_value};

View file

@ -2,23 +2,22 @@ use std::collections::BTreeMap;
use axum::extract::State;
use conduwuit::{
at, is_true,
Err, PduEvent, Result, at, is_true,
result::FlatOk,
utils::{stream::ReadyExt, IterStream},
Err, PduEvent, Result,
utils::{IterStream, stream::ReadyExt},
};
use futures::{future::OptionFuture, FutureExt, StreamExt, TryFutureExt, TryStreamExt};
use futures::{FutureExt, StreamExt, TryFutureExt, TryStreamExt, future::OptionFuture};
use ruma::{
OwnedRoomId, RoomId, UInt, UserId,
api::client::search::search_events::{
self,
v3::{Criteria, EventContextResult, ResultCategories, ResultRoomEvents, SearchResult},
},
events::AnyStateEvent,
serde::Raw,
OwnedRoomId, RoomId, UInt, UserId,
};
use search_events::v3::{Request, Response};
use service::{rooms::search::RoomQuery, Services};
use service::{Services, rooms::search::RoomQuery};
use crate::Ruma;

View file

@ -1,11 +1,11 @@
use std::collections::BTreeMap;
use axum::extract::State;
use conduwuit::{err, Err};
use conduwuit::{Err, err};
use ruma::{api::client::message::send_message_event, events::MessageLikeEventType};
use serde_json::from_str;
use crate::{service::pdu::PduBuilder, utils, Result, Ruma};
use crate::{Result, Ruma, service::pdu::PduBuilder, utils};
/// # `PUT /_matrix/client/v3/rooms/{roomId}/send/{eventType}/{txnId}`
///

View file

@ -2,9 +2,10 @@ use std::time::Duration;
use axum::extract::State;
use axum_client_ip::InsecureClientIp;
use conduwuit::{debug, err, info, utils::ReadyExt, warn, Err};
use conduwuit::{Err, debug, err, info, utils::ReadyExt, warn};
use futures::StreamExt;
use ruma::{
OwnedUserId, UserId,
api::client::{
error::ErrorKind,
session::{
@ -21,12 +22,11 @@ use ruma::{
},
uiaa,
},
OwnedUserId, UserId,
};
use service::uiaa::SESSION_ID_LENGTH;
use super::{DEVICE_ID_LENGTH, TOKEN_LENGTH};
use crate::{utils, utils::hash, Error, Result, Ruma};
use crate::{Error, Result, Ruma, utils, utils::hash};
/// # `GET /_matrix/client/v3/login`
///
@ -139,18 +139,20 @@ pub(crate) async fn login_route(
Error::BadRequest(ErrorKind::InvalidUsername, "Username is invalid.")
})?;
if let Some(ref info) = body.appservice_info {
if !info.is_user_match(&user_id) {
match body.appservice_info {
| Some(ref info) =>
if !info.is_user_match(&user_id) {
return Err(Error::BadRequest(
ErrorKind::Exclusive,
"User is not in namespace.",
));
},
| _ => {
return Err(Error::BadRequest(
ErrorKind::Exclusive,
"User is not in namespace.",
ErrorKind::MissingToken,
"Missing appservice token.",
));
}
} else {
return Err(Error::BadRequest(
ErrorKind::MissingToken,
"Missing appservice token.",
));
},
}
user_id
@ -259,26 +261,32 @@ pub(crate) async fn login_token_route(
auth_error: None,
};
if let Some(auth) = &body.auth {
let (worked, uiaainfo) = services
.uiaa
.try_auth(sender_user, sender_device, auth, &uiaainfo)
.await?;
match &body.auth {
| Some(auth) => {
let (worked, uiaainfo) = services
.uiaa
.try_auth(sender_user, sender_device, auth, &uiaainfo)
.await?;
if !worked {
return Err(Error::Uiaa(uiaainfo));
}
if !worked {
return Err(Error::Uiaa(uiaainfo));
}
// Success!
} else if let Some(json) = body.json_body.as_ref() {
uiaainfo.session = Some(utils::random_string(SESSION_ID_LENGTH));
services
.uiaa
.create(sender_user, sender_device, &uiaainfo, json);
// Success!
},
| _ => match body.json_body.as_ref() {
| Some(json) => {
uiaainfo.session = Some(utils::random_string(SESSION_ID_LENGTH));
services
.uiaa
.create(sender_user, sender_device, &uiaainfo, json);
return Err(Error::Uiaa(uiaainfo));
} else {
return Err!(Request(NotJson("No JSON body was sent when required.")));
return Err(Error::Uiaa(uiaainfo));
},
| _ => {
return Err!(Request(NotJson("No JSON body was sent when required.")));
},
},
}
let login_token = utils::random_string(TOKEN_LENGTH);

View file

@ -5,18 +5,18 @@ use std::{
use axum::extract::State;
use conduwuit::{
utils::{future::TryExtExt, stream::IterStream},
Err, Result,
utils::{future::TryExtExt, stream::IterStream},
};
use futures::{future::OptionFuture, StreamExt, TryFutureExt};
use futures::{StreamExt, TryFutureExt, future::OptionFuture};
use ruma::{
api::client::space::get_hierarchy, OwnedRoomId, OwnedServerName, RoomId, UInt, UserId,
OwnedRoomId, OwnedServerName, RoomId, UInt, UserId, api::client::space::get_hierarchy,
};
use service::{
rooms::spaces::{
get_parent_children_via, summary_to_chunk, PaginationToken, SummaryAccessibility,
},
Services,
rooms::spaces::{
PaginationToken, SummaryAccessibility, get_parent_children_via, summary_to_chunk,
},
};
use crate::Ruma;

View file

@ -1,19 +1,19 @@
use axum::extract::State;
use conduwuit::{err, pdu::PduBuilder, utils::BoolExt, Err, PduEvent, Result};
use conduwuit::{Err, PduEvent, Result, err, pdu::PduBuilder, utils::BoolExt};
use futures::TryStreamExt;
use ruma::{
OwnedEventId, RoomId, UserId,
api::client::state::{get_state_events, get_state_events_for_key, send_state_event},
events::{
AnyStateEventContent, StateEventType,
room::{
canonical_alias::RoomCanonicalAliasEventContent,
history_visibility::{HistoryVisibility, RoomHistoryVisibilityEventContent},
join_rules::{JoinRule, RoomJoinRulesEventContent},
member::{MembershipState, RoomMemberEventContent},
},
AnyStateEventContent, StateEventType,
},
serde::Raw,
OwnedEventId, RoomId, UserId,
};
use service::Services;

View file

@ -3,25 +3,25 @@ mod v4;
mod v5;
use conduwuit::{
utils::{
stream::{BroadbandExt, ReadyExt, TryIgnore},
IterStream,
},
PduCount,
utils::{
IterStream,
stream::{BroadbandExt, ReadyExt, TryIgnore},
},
};
use futures::{pin_mut, StreamExt};
use futures::{StreamExt, pin_mut};
use ruma::{
RoomId, UserId,
directory::RoomTypeFilter,
events::TimelineEventType::{
self, Beacon, CallInvite, PollStart, RoomEncrypted, RoomMessage, Sticker,
},
RoomId, UserId,
};
pub(crate) use self::{
v3::sync_events_route, v4::sync_events_v4_route, v5::sync_events_v5_route,
};
use crate::{service::Services, Error, PduEvent, Result};
use crate::{Error, PduEvent, Result, service::Services};
pub(crate) const DEFAULT_BUMP_TYPES: &[TimelineEventType; 6] =
&[CallInvite, PollStart, Beacon, RoomEncrypted, RoomMessage, Sticker];

View file

@ -6,57 +6,55 @@ use std::{
use axum::extract::State;
use conduwuit::{
at, err, error, extract_variant, is_equal_to, pair_of,
PduCount, PduEvent, Result, at, err, error, extract_variant, is_equal_to, pair_of,
pdu::{Event, EventHash},
ref_at,
result::FlatOk,
utils::{
self,
self, BoolExt, IterStream, ReadyExt, TryFutureExtExt,
math::ruma_from_u64,
stream::{BroadbandExt, Tools, TryExpect, WidebandExt},
BoolExt, IterStream, ReadyExt, TryFutureExtExt,
},
PduCount, PduEvent, Result,
};
use conduwuit_service::{
Services,
rooms::{
lazy_loading,
lazy_loading::{Options, Witness},
short::ShortStateHash,
},
Services,
};
use futures::{
future::{join, join3, join4, join5, try_join, try_join4, OptionFuture},
FutureExt, StreamExt, TryFutureExt, TryStreamExt,
future::{OptionFuture, join, join3, join4, join5, try_join, try_join4},
};
use ruma::{
DeviceId, EventId, OwnedEventId, OwnedRoomId, OwnedUserId, RoomId, UserId,
api::client::{
filter::FilterDefinition,
sync::sync_events::{
self,
self, DeviceLists, UnreadNotificationsCount,
v3::{
Ephemeral, Filter, GlobalAccountData, InviteState, InvitedRoom, JoinedRoom,
KnockState, KnockedRoom, LeftRoom, Presence, RoomAccountData, RoomSummary, Rooms,
State as RoomState, Timeline, ToDevice,
},
DeviceLists, UnreadNotificationsCount,
},
uiaa::UiaaResponse,
},
events::{
presence::{PresenceEvent, PresenceEventContent},
room::member::{MembershipState, RoomMemberEventContent},
AnyRawAccountDataEvent, AnySyncEphemeralRoomEvent, StateEventType,
TimelineEventType::*,
presence::{PresenceEvent, PresenceEventContent},
room::member::{MembershipState, RoomMemberEventContent},
},
serde::Raw,
uint, DeviceId, EventId, OwnedEventId, OwnedRoomId, OwnedUserId, RoomId, UserId,
uint,
};
use service::rooms::short::{ShortEventId, ShortStateKey};
use super::{load_timeline, share_encrypted_room};
use crate::{client::ignored_filter, Ruma, RumaResponse};
use crate::{Ruma, RumaResponse, client::ignored_filter};
#[derive(Default)]
struct StateChanges {
@ -168,8 +166,8 @@ pub(crate) async fn build_sync_events(
let full_state = body.body.full_state;
let filter = match body.body.filter.as_ref() {
| None => FilterDefinition::default(),
| Some(Filter::FilterDefinition(ref filter)) => filter.clone(),
| Some(Filter::FilterId(ref filter_id)) => services
| Some(Filter::FilterDefinition(filter)) => filter.clone(),
| Some(Filter::FilterId(filter_id)) => services
.users
.get_filter(sender_user, filter_id)
.await
@ -1016,34 +1014,37 @@ async fn calculate_state_incremental<'a>(
let lazy_state_ids: OptionFuture<_> = witness
.filter(|_| !full_state && !encrypted_room)
.map(|witness| {
witness
.iter()
.stream()
.broad_filter_map(|user_id| state_get_shorteventid(user_id))
.into_future()
StreamExt::into_future(
witness
.iter()
.stream()
.broad_filter_map(|user_id| state_get_shorteventid(user_id)),
)
})
.into();
let state_diff: OptionFuture<_> = (!full_state && state_changed)
.then(|| {
services
.rooms
.state_accessor
.state_added((since_shortstatehash, current_shortstatehash))
.boxed()
.into_future()
StreamExt::into_future(
services
.rooms
.state_accessor
.state_added((since_shortstatehash, current_shortstatehash))
.boxed(),
)
})
.into();
let current_state_ids: OptionFuture<_> = full_state
.then(|| {
services
.rooms
.state_accessor
.state_full_shortids(current_shortstatehash)
.expect_ok()
.boxed()
.into_future()
StreamExt::into_future(
services
.rooms
.state_accessor
.state_full_shortids(current_shortstatehash)
.expect_ok()
.boxed(),
)
})
.into();

View file

@ -6,37 +6,37 @@ use std::{
use axum::extract::State;
use conduwuit::{
debug, error, extract_variant,
Error, PduCount, Result, debug, error, extract_variant,
utils::{
math::{ruma_from_usize, usize_from_ruma, usize_from_u64_truncated},
BoolExt, IterStream, ReadyExt, TryFutureExtExt,
math::{ruma_from_usize, usize_from_ruma, usize_from_u64_truncated},
},
warn, Error, PduCount, Result,
warn,
};
use futures::{FutureExt, StreamExt, TryFutureExt};
use ruma::{
MilliSecondsSinceUnixEpoch, OwnedEventId, OwnedRoomId, RoomId, UInt, UserId,
api::client::{
error::ErrorKind,
sync::sync_events::{
self,
self, DeviceLists, UnreadNotificationsCount,
v4::{SlidingOp, SlidingSyncRoomHero},
DeviceLists, UnreadNotificationsCount,
},
},
events::{
room::member::{MembershipState, RoomMemberEventContent},
AnyRawAccountDataEvent, AnySyncEphemeralRoomEvent, StateEventType,
TimelineEventType::*,
room::member::{MembershipState, RoomMemberEventContent},
},
serde::Raw,
uint, MilliSecondsSinceUnixEpoch, OwnedEventId, OwnedRoomId, RoomId, UInt, UserId,
uint,
};
use service::rooms::read_receipt::pack_receipts;
use super::{load_timeline, share_encrypted_room};
use crate::{
client::{filter_rooms, ignored_filter, sync::v5::TodoRooms, DEFAULT_BUMP_TYPES},
Ruma,
client::{DEFAULT_BUMP_TYPES, filter_rooms, ignored_filter, sync::v5::TodoRooms},
};
pub(crate) const SINGLE_CONNECTION_SYNC: &str = "single_connection_sync";
@ -700,14 +700,13 @@ pub(crate) async fn sync_events_v4_route(
.await
.ok()
.or(name),
avatar: if let Some(heroes_avatar) = heroes_avatar {
ruma::JsOption::Some(heroes_avatar)
} else {
match services.rooms.state_accessor.get_avatar(room_id).await {
avatar: match heroes_avatar {
| Some(heroes_avatar) => ruma::JsOption::Some(heroes_avatar),
| _ => 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,
}
},
},
initial: Some(roomsince == &0),
is_dm: None,

View file

@ -6,32 +6,33 @@ use std::{
use axum::extract::State;
use conduwuit::{
debug, error, extract_variant, trace,
Error, Result, TypeStateKey, debug, error, extract_variant, trace,
utils::{
math::{ruma_from_usize, usize_from_ruma},
BoolExt, IterStream, ReadyExt, TryFutureExtExt,
math::{ruma_from_usize, usize_from_ruma},
},
warn, Error, Result, TypeStateKey,
warn,
};
use futures::{FutureExt, StreamExt, TryFutureExt};
use ruma::{
DeviceId, OwnedEventId, OwnedRoomId, RoomId, UInt, UserId,
api::client::{
error::ErrorKind,
sync::sync_events::{self, DeviceLists, UnreadNotificationsCount},
},
events::{
room::member::{MembershipState, RoomMemberEventContent},
AnyRawAccountDataEvent, AnySyncEphemeralRoomEvent, StateEventType, TimelineEventType,
room::member::{MembershipState, RoomMemberEventContent},
},
serde::Raw,
uint, DeviceId, OwnedEventId, OwnedRoomId, RoomId, UInt, UserId,
uint,
};
use service::{rooms::read_receipt::pack_receipts, PduCount};
use service::{PduCount, rooms::read_receipt::pack_receipts};
use super::{filter_rooms, share_encrypted_room};
use crate::{
client::{ignored_filter, sync::load_timeline, DEFAULT_BUMP_TYPES},
Ruma,
client::{DEFAULT_BUMP_TYPES, ignored_filter, sync::load_timeline},
};
type SyncInfo<'a> = (&'a UserId, &'a DeviceId, u64, &'a sync_events::v5::Request);
@ -572,14 +573,13 @@ async fn process_rooms(
.await
.ok()
.or(name),
avatar: if let Some(heroes_avatar) = heroes_avatar {
ruma::JsOption::Some(heroes_avatar)
} else {
match services.rooms.state_accessor.get_avatar(room_id).await {
avatar: match heroes_avatar {
| Some(heroes_avatar) => ruma::JsOption::Some(heroes_avatar),
| _ => 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,
}
},
},
initial: Some(roomsince == &0),
is_dm: None,

View file

@ -4,8 +4,8 @@ use axum::extract::State;
use ruma::{
api::client::tag::{create_tag, delete_tag, get_tags},
events::{
tag::{TagEvent, TagEventContent},
RoomAccountDataEventType,
tag::{TagEvent, TagEventContent},
},
};

View file

@ -1,5 +1,5 @@
use axum::extract::State;
use conduwuit::{at, PduCount, PduEvent};
use conduwuit::{PduCount, PduEvent, at};
use futures::StreamExt;
use ruma::{api::client::threads::get_threads, uint};

View file

@ -1,8 +1,8 @@
use axum::extract::State;
use conduwuit::{utils::math::Tried, Err};
use conduwuit::{Err, utils::math::Tried};
use ruma::api::client::typing::create_typing_event;
use crate::{utils, Result, Ruma};
use crate::{Result, Ruma, utils};
/// # `PUT /_matrix/client/r0/rooms/{roomId}/typing/{userId}`
///
@ -27,37 +27,40 @@ pub(crate) async fn create_typing_event_route(
return Err!(Request(Forbidden("You are not in this room.")));
}
if let Typing::Yes(duration) = body.state {
let duration = utils::clamp(
duration.as_millis().try_into().unwrap_or(u64::MAX),
match body.state {
| Typing::Yes(duration) => {
let duration = utils::clamp(
duration.as_millis().try_into().unwrap_or(u64::MAX),
services
.server
.config
.typing_client_timeout_min_s
.try_mul(1000)?,
services
.server
.config
.typing_client_timeout_max_s
.try_mul(1000)?,
);
services
.server
.config
.typing_client_timeout_min_s
.try_mul(1000)?,
.rooms
.typing
.typing_add(
sender_user,
&body.room_id,
utils::millis_since_unix_epoch()
.checked_add(duration)
.expect("user typing timeout should not get this high"),
)
.await?;
},
| _ => {
services
.server
.config
.typing_client_timeout_max_s
.try_mul(1000)?,
);
services
.rooms
.typing
.typing_add(
sender_user,
&body.room_id,
utils::millis_since_unix_epoch()
.checked_add(duration)
.expect("user typing timeout should not get this high"),
)
.await?;
} else {
services
.rooms
.typing
.typing_remove(sender_user, &body.room_id)
.await?;
.rooms
.typing
.typing_remove(sender_user, &body.room_id)
.await?;
},
}
// ping presence

View file

@ -5,6 +5,7 @@ use axum_client_ip::InsecureClientIp;
use conduwuit::Err;
use futures::StreamExt;
use ruma::{
OwnedRoomId,
api::{
client::{
error::ErrorKind,
@ -19,7 +20,6 @@ use ruma::{
},
events::room::member::MembershipState,
presence::PresenceState,
OwnedRoomId,
};
use super::{update_avatar_url, update_displayname};
@ -499,15 +499,18 @@ pub(crate) async fn get_profile_key_route(
.users
.set_timezone(&body.user_id, response.tz.clone());
if let Some(value) = response.custom_profile_fields.get(&body.key_name) {
profile_key_value.insert(body.key_name.clone(), value.clone());
services.users.set_profile_key(
&body.user_id,
&body.key_name,
Some(value.clone()),
);
} else {
return Err!(Request(NotFound("The requested profile key does not exist.")));
match response.custom_profile_fields.get(&body.key_name) {
| Some(value) => {
profile_key_value.insert(body.key_name.clone(), value.clone());
services.users.set_profile_key(
&body.user_id,
&body.key_name,
Some(value.clone()),
);
},
| _ => {
return Err!(Request(NotFound("The requested profile key does not exist.")));
},
}
if profile_key_value.is_empty() {
@ -524,14 +527,17 @@ pub(crate) async fn get_profile_key_route(
return Err!(Request(NotFound("Profile was not found.")));
}
if let Ok(value) = services
match services
.users
.profile_key(&body.user_id, &body.key_name)
.await
{
profile_key_value.insert(body.key_name.clone(), value);
} else {
return Err!(Request(NotFound("The requested profile key does not exist.")));
| Ok(value) => {
profile_key_value.insert(body.key_name.clone(), value);
},
| _ => {
return Err!(Request(NotFound("The requested profile key does not exist.")));
},
}
if profile_key_value.is_empty() {

View file

@ -1,6 +1,6 @@
use std::collections::BTreeMap;
use axum::{extract::State, response::IntoResponse, Json};
use axum::{Json, extract::State, response::IntoResponse};
use futures::StreamExt;
use ruma::api::client::discovery::get_supported_versions;

View file

@ -1,11 +1,11 @@
use axum::extract::State;
use conduwuit::utils::TryFutureExtExt;
use futures::{pin_mut, StreamExt};
use futures::{StreamExt, pin_mut};
use ruma::{
api::client::user_directory::search_users,
events::{
room::join_rules::{JoinRule, RoomJoinRulesEventContent},
StateEventType,
room::join_rules::{JoinRule, RoomJoinRulesEventContent},
},
};

View file

@ -1,10 +1,10 @@
use std::time::{Duration, SystemTime};
use axum::extract::State;
use base64::{engine::general_purpose, Engine as _};
use conduwuit::{utils, Err};
use base64::{Engine as _, engine::general_purpose};
use conduwuit::{Err, utils};
use hmac::{Hmac, Mac};
use ruma::{api::client::voip::get_turn_server_info, SecondsSinceUnixEpoch, UserId};
use ruma::{SecondsSinceUnixEpoch, UserId, api::client::voip::get_turn_server_info};
use sha1::Sha1;
use crate::{Result, Ruma};

View file

@ -1,4 +1,4 @@
use axum::{extract::State, response::IntoResponse, Json};
use axum::{Json, extract::State, response::IntoResponse};
use ruma::api::client::{
discovery::{
discover_homeserver::{self, HomeserverInfo, SlidingSyncProxyInfo},