mirror of
https://gitlab.com/famedly/conduit.git
synced 2024-12-27 04:53:50 +03:00
chore: update dependencies
This commit is contained in:
parent
bb234ca002
commit
23f81bfaf7
4 changed files with 215 additions and 2988 deletions
2752
Cargo.lock
generated
2752
Cargo.lock
generated
File diff suppressed because it is too large
Load diff
|
@ -14,7 +14,7 @@ edition = "2018"
|
|||
[dependencies]
|
||||
# Used to handle requests
|
||||
# TODO: This can become optional as soon as proper configs are supported
|
||||
rocket = { git = "https://github.com/SergioBenitez/Rocket.git", rev = "93e62c86eddf7cc9a7fc40b044182f83f0d7d92a", features = ["tls"] } # Used to handle requests
|
||||
rocket = { git = "https://github.com/SergioBenitez/Rocket.git", rev = "e1307ddf48dac14e6a37e526098732327bcb86f0", features = ["tls"] } # Used to handle requests
|
||||
#rocket = { git = "https://github.com/timokoesters/Rocket.git", branch = "empty_parameters", default-features = false, features = ["tls"] }
|
||||
|
||||
# Used for matrix spec type definitions and helpers
|
||||
|
|
49
src/main.rs
49
src/main.rs
|
@ -21,7 +21,6 @@ pub use ruma_wrapper::{ConduitResult, Ruma, RumaResponse};
|
|||
|
||||
use rocket::{
|
||||
catch, catchers,
|
||||
fairing::AdHoc,
|
||||
figment::{
|
||||
providers::{Env, Format, Toml},
|
||||
Figment,
|
||||
|
@ -31,9 +30,9 @@ use rocket::{
|
|||
use tracing::span;
|
||||
use tracing_subscriber::{prelude::*, Registry};
|
||||
|
||||
fn setup_rocket() -> (rocket::Rocket, Config) {
|
||||
async fn setup_rocket() -> (rocket::Rocket<rocket::Build>, Config) {
|
||||
// Force log level off, so we can use our own logger
|
||||
std::env::set_var("CONDUIT_LOG_LEVEL", "off");
|
||||
//std::env::set_var("CONDUIT_LOG_LEVEL", "off");
|
||||
|
||||
let config =
|
||||
Figment::from(rocket::Config::release_default())
|
||||
|
@ -48,9 +47,15 @@ fn setup_rocket() -> (rocket::Rocket, Config) {
|
|||
let parsed_config = config
|
||||
.extract::<Config>()
|
||||
.expect("It looks like your config is invalid. Please take a look at the error");
|
||||
let parsed_config2 = parsed_config.clone();
|
||||
|
||||
let data = Database::load_or_create(parsed_config.clone())
|
||||
.await
|
||||
.expect("config is valid");
|
||||
|
||||
data.sending.start_handler(&data);
|
||||
|
||||
let rocket = rocket::custom(config)
|
||||
.manage(data)
|
||||
.mount(
|
||||
"/",
|
||||
routes![
|
||||
|
@ -176,29 +181,23 @@ fn setup_rocket() -> (rocket::Rocket, Config) {
|
|||
server_server::get_profile_information_route,
|
||||
],
|
||||
)
|
||||
.register(catchers![
|
||||
not_found_catcher,
|
||||
forbidden_catcher,
|
||||
unknown_token_catcher,
|
||||
missing_token_catcher,
|
||||
bad_json_catcher
|
||||
])
|
||||
.attach(AdHoc::on_attach("Config", |rocket| async {
|
||||
let data = Database::load_or_create(parsed_config2)
|
||||
.await
|
||||
.expect("config is valid");
|
||||
|
||||
data.sending.start_handler(&data);
|
||||
|
||||
Ok(rocket.manage(data))
|
||||
}));
|
||||
.register(
|
||||
"/",
|
||||
catchers![
|
||||
not_found_catcher,
|
||||
forbidden_catcher,
|
||||
unknown_token_catcher,
|
||||
missing_token_catcher,
|
||||
bad_json_catcher
|
||||
],
|
||||
);
|
||||
|
||||
(rocket, parsed_config)
|
||||
}
|
||||
|
||||
#[rocket::main]
|
||||
async fn main() {
|
||||
let (rocket, config) = setup_rocket();
|
||||
let (rocket, config) = setup_rocket().await;
|
||||
|
||||
if config.allow_jaeger {
|
||||
let (tracer, _uninstall) = opentelemetry_jaeger::new_pipeline()
|
||||
|
@ -213,11 +212,11 @@ async fn main() {
|
|||
|
||||
rocket.launch().await.unwrap();
|
||||
} else {
|
||||
std::env::set_var("CONDUIT_LOG", config.log);
|
||||
pretty_env_logger::init_custom_env("CONDUIT_LOG");
|
||||
//std::env::set_var("CONDUIT_LOG", config.log);
|
||||
//pretty_env_logger::init_custom_env("CONDUIT_LOG");
|
||||
|
||||
let root = span!(tracing::Level::INFO, "app_start", work_units = 2);
|
||||
let _enter = root.enter();
|
||||
//let root = span!(tracing::Level::INFO, "app_start", work_units = 2);
|
||||
//let _enter = root.enter();
|
||||
|
||||
rocket.launch().await.unwrap();
|
||||
}
|
||||
|
|
|
@ -11,10 +11,7 @@ use {
|
|||
crate::{server_server, utils},
|
||||
log::{debug, warn},
|
||||
rocket::{
|
||||
data::{
|
||||
ByteUnit, Data, FromDataFuture, FromTransformedData, Transform, TransformFuture,
|
||||
Transformed,
|
||||
},
|
||||
data::{self, ByteUnit, Data, FromData},
|
||||
http::Status,
|
||||
outcome::Outcome::*,
|
||||
response::{self, Responder},
|
||||
|
@ -42,106 +39,92 @@ pub struct Ruma<T: Outgoing> {
|
|||
}
|
||||
|
||||
#[cfg(feature = "conduit_bin")]
|
||||
impl<'a, T: Outgoing> FromTransformedData<'a> for Ruma<T>
|
||||
#[rocket::async_trait]
|
||||
impl<'a, T: Outgoing> FromData<'a> for Ruma<T>
|
||||
where
|
||||
T::Incoming: IncomingRequest,
|
||||
{
|
||||
type Error = ();
|
||||
type Owned = Data;
|
||||
type Borrowed = Self::Owned;
|
||||
|
||||
fn transform<'r>(
|
||||
_req: &'r Request<'_>,
|
||||
data: Data,
|
||||
) -> TransformFuture<'r, Self::Owned, Self::Error> {
|
||||
Box::pin(async move { Transform::Owned(Success(data)) })
|
||||
}
|
||||
|
||||
fn from_data(
|
||||
request: &'a Request<'_>,
|
||||
outcome: Transformed<'a, Self>,
|
||||
) -> FromDataFuture<'a, Self, Self::Error> {
|
||||
async fn from_data(request: &'a Request<'_>, data: Data) -> data::Outcome<Self, Self::Error> {
|
||||
let metadata = T::Incoming::METADATA;
|
||||
let db = request
|
||||
.guard::<State<'_, crate::Database>>()
|
||||
.await
|
||||
.expect("database was loaded");
|
||||
|
||||
Box::pin(async move {
|
||||
let data = rocket::try_outcome!(outcome.owned());
|
||||
let db = request
|
||||
.guard::<State<'_, crate::Database>>()
|
||||
.await
|
||||
.expect("database was loaded");
|
||||
// Get token from header or query value
|
||||
let token = request
|
||||
.headers()
|
||||
.get_one("Authorization")
|
||||
.map(|s| s[7..].to_owned()) // Split off "Bearer "
|
||||
.or_else(|| request.query_value("access_token").and_then(|r| r.ok()));
|
||||
|
||||
// Get token from header or query value
|
||||
let token = request
|
||||
.headers()
|
||||
.get_one("Authorization")
|
||||
.map(|s| s[7..].to_owned()) // Split off "Bearer "
|
||||
.or_else(|| request.get_query_value("access_token").and_then(|r| r.ok()));
|
||||
let limit = db.globals.max_request_size();
|
||||
let mut handle = data.open(ByteUnit::Byte(limit.into()));
|
||||
let mut body = Vec::new();
|
||||
handle.read_to_end(&mut body).await.unwrap();
|
||||
|
||||
let limit = db.globals.max_request_size();
|
||||
let mut handle = data.open(ByteUnit::Byte(limit.into()));
|
||||
let mut body = Vec::new();
|
||||
handle.read_to_end(&mut body).await.unwrap();
|
||||
|
||||
let (sender_user, sender_device, from_appservice) = if let Some((_id, registration)) =
|
||||
db.appservice
|
||||
.iter_all()
|
||||
.filter_map(|r| r.ok())
|
||||
.find(|(_id, registration)| {
|
||||
registration
|
||||
.get("as_token")
|
||||
.and_then(|as_token| as_token.as_str())
|
||||
.map_or(false, |as_token| token.as_deref() == Some(as_token))
|
||||
}) {
|
||||
match metadata.authentication {
|
||||
AuthScheme::AccessToken | AuthScheme::QueryOnlyAccessToken => {
|
||||
let user_id = request.get_query_value::<String>("user_id").map_or_else(
|
||||
|| {
|
||||
UserId::parse_with_server_name(
|
||||
registration
|
||||
.get("sender_localpart")
|
||||
.unwrap()
|
||||
.as_str()
|
||||
.unwrap(),
|
||||
db.globals.server_name(),
|
||||
)
|
||||
.unwrap()
|
||||
},
|
||||
|string| {
|
||||
UserId::try_from(string.expect("parsing to string always works"))
|
||||
let (sender_user, sender_device, from_appservice) = if let Some((_id, registration)) = db
|
||||
.appservice
|
||||
.iter_all()
|
||||
.filter_map(|r| r.ok())
|
||||
.find(|(_id, registration)| {
|
||||
registration
|
||||
.get("as_token")
|
||||
.and_then(|as_token| as_token.as_str())
|
||||
.map_or(false, |as_token| token.as_deref() == Some(as_token))
|
||||
}) {
|
||||
match metadata.authentication {
|
||||
AuthScheme::AccessToken | AuthScheme::QueryOnlyAccessToken => {
|
||||
let user_id = request.query_value::<String>("user_id").map_or_else(
|
||||
|| {
|
||||
UserId::parse_with_server_name(
|
||||
registration
|
||||
.get("sender_localpart")
|
||||
.unwrap()
|
||||
},
|
||||
);
|
||||
.as_str()
|
||||
.unwrap(),
|
||||
db.globals.server_name(),
|
||||
)
|
||||
.unwrap()
|
||||
},
|
||||
|string| {
|
||||
UserId::try_from(string.expect("parsing to string always works"))
|
||||
.unwrap()
|
||||
},
|
||||
);
|
||||
|
||||
if !db.users.exists(&user_id).unwrap() {
|
||||
// Forbidden
|
||||
return Failure((Status::raw(580), ()));
|
||||
}
|
||||
|
||||
// TODO: Check if appservice is allowed to be that user
|
||||
(Some(user_id), None, true)
|
||||
if !db.users.exists(&user_id).unwrap() {
|
||||
// Forbidden
|
||||
return Failure((Status::raw(580), ()));
|
||||
}
|
||||
AuthScheme::ServerSignatures => (None, None, true),
|
||||
AuthScheme::None => (None, None, true),
|
||||
|
||||
// TODO: Check if appservice is allowed to be that user
|
||||
(Some(user_id), None, true)
|
||||
}
|
||||
} else {
|
||||
match metadata.authentication {
|
||||
AuthScheme::AccessToken | AuthScheme::QueryOnlyAccessToken => {
|
||||
if let Some(token) = token {
|
||||
match db.users.find_from_token(&token).unwrap() {
|
||||
// Unknown Token
|
||||
None => return Failure((Status::raw(581), ())),
|
||||
Some((user_id, device_id)) => {
|
||||
(Some(user_id), Some(device_id.into()), false)
|
||||
}
|
||||
AuthScheme::ServerSignatures => (None, None, true),
|
||||
AuthScheme::None => (None, None, true),
|
||||
}
|
||||
} else {
|
||||
match metadata.authentication {
|
||||
AuthScheme::AccessToken | AuthScheme::QueryOnlyAccessToken => {
|
||||
if let Some(token) = token {
|
||||
match db.users.find_from_token(&token).unwrap() {
|
||||
// Unknown Token
|
||||
None => return Failure((Status::raw(581), ())),
|
||||
Some((user_id, device_id)) => {
|
||||
(Some(user_id), Some(device_id.into()), false)
|
||||
}
|
||||
} else {
|
||||
// Missing Token
|
||||
return Failure((Status::raw(582), ()));
|
||||
}
|
||||
} else {
|
||||
// Missing Token
|
||||
return Failure((Status::raw(582), ()));
|
||||
}
|
||||
AuthScheme::ServerSignatures => {
|
||||
// Get origin from header
|
||||
let x_matrix = match request
|
||||
}
|
||||
AuthScheme::ServerSignatures => {
|
||||
// Get origin from header
|
||||
let x_matrix = match request
|
||||
.headers()
|
||||
.get_one("Authorization")
|
||||
.map(|s| {
|
||||
|
@ -158,153 +141,150 @@ where
|
|||
}
|
||||
};
|
||||
|
||||
let origin_str = match x_matrix.get(&Some("origin")) {
|
||||
Some(Some(o)) => *o,
|
||||
_ => {
|
||||
warn!("Invalid X-Matrix header origin field: {:?}", x_matrix);
|
||||
let origin_str = match x_matrix.get(&Some("origin")) {
|
||||
Some(Some(o)) => *o,
|
||||
_ => {
|
||||
warn!("Invalid X-Matrix header origin field: {:?}", x_matrix);
|
||||
|
||||
// Forbidden
|
||||
return Failure((Status::raw(580), ()));
|
||||
}
|
||||
};
|
||||
// Forbidden
|
||||
return Failure((Status::raw(580), ()));
|
||||
}
|
||||
};
|
||||
|
||||
let origin = match Box::<ServerName>::try_from(origin_str) {
|
||||
Ok(s) => s,
|
||||
_ => {
|
||||
warn!(
|
||||
"Invalid server name in X-Matrix header origin field: {:?}",
|
||||
x_matrix
|
||||
);
|
||||
let origin = match Box::<ServerName>::try_from(origin_str) {
|
||||
Ok(s) => s,
|
||||
_ => {
|
||||
warn!(
|
||||
"Invalid server name in X-Matrix header origin field: {:?}",
|
||||
x_matrix
|
||||
);
|
||||
|
||||
// Forbidden
|
||||
return Failure((Status::raw(580), ()));
|
||||
}
|
||||
};
|
||||
// Forbidden
|
||||
return Failure((Status::raw(580), ()));
|
||||
}
|
||||
};
|
||||
|
||||
let key = match x_matrix.get(&Some("key")) {
|
||||
Some(Some(k)) => *k,
|
||||
_ => {
|
||||
warn!("Invalid X-Matrix header key field: {:?}", x_matrix);
|
||||
let key = match x_matrix.get(&Some("key")) {
|
||||
Some(Some(k)) => *k,
|
||||
_ => {
|
||||
warn!("Invalid X-Matrix header key field: {:?}", x_matrix);
|
||||
|
||||
// Forbidden
|
||||
return Failure((Status::raw(580), ()));
|
||||
}
|
||||
};
|
||||
// Forbidden
|
||||
return Failure((Status::raw(580), ()));
|
||||
}
|
||||
};
|
||||
|
||||
let sig = match x_matrix.get(&Some("sig")) {
|
||||
Some(Some(s)) => *s,
|
||||
_ => {
|
||||
warn!("Invalid X-Matrix header sig field: {:?}", x_matrix);
|
||||
let sig = match x_matrix.get(&Some("sig")) {
|
||||
Some(Some(s)) => *s,
|
||||
_ => {
|
||||
warn!("Invalid X-Matrix header sig field: {:?}", x_matrix);
|
||||
|
||||
// Forbidden
|
||||
return Failure((Status::raw(580), ()));
|
||||
}
|
||||
};
|
||||
// Forbidden
|
||||
return Failure((Status::raw(580), ()));
|
||||
}
|
||||
};
|
||||
|
||||
let json_body = serde_json::from_slice::<CanonicalJsonValue>(&body);
|
||||
let json_body = serde_json::from_slice::<CanonicalJsonValue>(&body);
|
||||
|
||||
let mut request_map = BTreeMap::<String, CanonicalJsonValue>::new();
|
||||
let mut request_map = BTreeMap::<String, CanonicalJsonValue>::new();
|
||||
|
||||
if let Ok(json_body) = json_body {
|
||||
request_map.insert("content".to_owned(), json_body);
|
||||
};
|
||||
if let Ok(json_body) = json_body {
|
||||
request_map.insert("content".to_owned(), json_body);
|
||||
};
|
||||
|
||||
request_map.insert(
|
||||
"method".to_owned(),
|
||||
CanonicalJsonValue::String(request.method().to_string()),
|
||||
);
|
||||
request_map.insert(
|
||||
"uri".to_owned(),
|
||||
CanonicalJsonValue::String(request.uri().to_string()),
|
||||
);
|
||||
request_map.insert(
|
||||
"origin".to_owned(),
|
||||
CanonicalJsonValue::String(origin.as_str().to_owned()),
|
||||
);
|
||||
request_map.insert(
|
||||
"destination".to_owned(),
|
||||
CanonicalJsonValue::String(
|
||||
db.globals.server_name().as_str().to_owned(),
|
||||
),
|
||||
);
|
||||
request_map.insert(
|
||||
"method".to_owned(),
|
||||
CanonicalJsonValue::String(request.method().to_string()),
|
||||
);
|
||||
request_map.insert(
|
||||
"uri".to_owned(),
|
||||
CanonicalJsonValue::String(request.uri().to_string()),
|
||||
);
|
||||
|
||||
let mut origin_signatures = BTreeMap::new();
|
||||
origin_signatures
|
||||
.insert(key.to_owned(), CanonicalJsonValue::String(sig.to_owned()));
|
||||
println!("{}: {:?}", origin, request.uri().to_string());
|
||||
|
||||
let mut signatures = BTreeMap::new();
|
||||
signatures.insert(
|
||||
origin.as_str().to_owned(),
|
||||
CanonicalJsonValue::Object(origin_signatures),
|
||||
);
|
||||
request_map.insert(
|
||||
"origin".to_owned(),
|
||||
CanonicalJsonValue::String(origin.as_str().to_owned()),
|
||||
);
|
||||
request_map.insert(
|
||||
"destination".to_owned(),
|
||||
CanonicalJsonValue::String(db.globals.server_name().as_str().to_owned()),
|
||||
);
|
||||
|
||||
request_map.insert(
|
||||
"signatures".to_owned(),
|
||||
CanonicalJsonValue::Object(signatures),
|
||||
);
|
||||
let mut origin_signatures = BTreeMap::new();
|
||||
origin_signatures
|
||||
.insert(key.to_owned(), CanonicalJsonValue::String(sig.to_owned()));
|
||||
|
||||
let keys = match server_server::fetch_signing_keys(
|
||||
&db,
|
||||
&origin,
|
||||
vec![&key.to_owned()],
|
||||
)
|
||||
.await
|
||||
{
|
||||
Ok(b) => b,
|
||||
Err(e) => {
|
||||
warn!("Failed to fetch signing keys: {}", e);
|
||||
let mut signatures = BTreeMap::new();
|
||||
signatures.insert(
|
||||
origin.as_str().to_owned(),
|
||||
CanonicalJsonValue::Object(origin_signatures),
|
||||
);
|
||||
|
||||
// Forbidden
|
||||
return Failure((Status::raw(580), ()));
|
||||
}
|
||||
};
|
||||
request_map.insert(
|
||||
"signatures".to_owned(),
|
||||
CanonicalJsonValue::Object(signatures),
|
||||
);
|
||||
|
||||
let mut pub_key_map = BTreeMap::new();
|
||||
pub_key_map.insert(origin.as_str().to_owned(), keys);
|
||||
let keys = match server_server::fetch_signing_keys(
|
||||
&db,
|
||||
&origin,
|
||||
vec![&key.to_owned()],
|
||||
)
|
||||
.await
|
||||
{
|
||||
Ok(b) => b,
|
||||
Err(e) => {
|
||||
warn!("Failed to fetch signing keys: {}", e);
|
||||
|
||||
match ruma::signatures::verify_json(&pub_key_map, &request_map) {
|
||||
Ok(()) => (None, None, false),
|
||||
Err(e) => {
|
||||
warn!(
|
||||
"Failed to verify json request: {}: {:?} {:?}",
|
||||
e, pub_key_map, request_map
|
||||
);
|
||||
// Forbidden
|
||||
return Failure((Status::raw(580), ()));
|
||||
}
|
||||
};
|
||||
|
||||
// Forbidden
|
||||
return Failure((Status::raw(580), ()));
|
||||
}
|
||||
let mut pub_key_map = BTreeMap::new();
|
||||
pub_key_map.insert(origin.as_str().to_owned(), keys);
|
||||
|
||||
match ruma::signatures::verify_json(&pub_key_map, &request_map) {
|
||||
Ok(()) => (None, None, false),
|
||||
Err(e) => {
|
||||
warn!("Failed to verify json request from {}: {}", origin, e,);
|
||||
|
||||
// Forbidden
|
||||
return Failure((Status::raw(580), ()));
|
||||
}
|
||||
}
|
||||
AuthScheme::None => (None, None, false),
|
||||
}
|
||||
};
|
||||
|
||||
let mut http_request = http::Request::builder()
|
||||
.uri(request.uri().to_string())
|
||||
.method(&*request.method().to_string());
|
||||
for header in request.headers().iter() {
|
||||
http_request = http_request.header(header.name.as_str(), &*header.value);
|
||||
AuthScheme::None => (None, None, false),
|
||||
}
|
||||
};
|
||||
|
||||
let http_request = http_request.body(&*body).unwrap();
|
||||
debug!("{:?}", http_request);
|
||||
match <T::Incoming as IncomingRequest>::try_from_http_request(http_request) {
|
||||
Ok(t) => Success(Ruma {
|
||||
body: t,
|
||||
sender_user,
|
||||
sender_device,
|
||||
// TODO: Can we avoid parsing it again? (We only need this for append_pdu)
|
||||
json_body: utils::string_from_bytes(&body)
|
||||
.ok()
|
||||
.and_then(|s| serde_json::value::RawValue::from_string(s).ok()),
|
||||
from_appservice,
|
||||
}),
|
||||
Err(e) => {
|
||||
warn!("{:?}", e);
|
||||
Failure((Status::raw(583), ()))
|
||||
}
|
||||
let mut http_request = http::Request::builder()
|
||||
.uri(request.uri().to_string())
|
||||
.method(&*request.method().to_string());
|
||||
for header in request.headers().iter() {
|
||||
http_request = http_request.header(header.name.as_str(), &*header.value);
|
||||
}
|
||||
|
||||
let http_request = http_request.body(&*body).unwrap();
|
||||
debug!("{:?}", http_request);
|
||||
match <T::Incoming as IncomingRequest>::try_from_http_request(http_request) {
|
||||
Ok(t) => Success(Ruma {
|
||||
body: t,
|
||||
sender_user,
|
||||
sender_device,
|
||||
// TODO: Can we avoid parsing it again? (We only need this for append_pdu)
|
||||
json_body: utils::string_from_bytes(&body)
|
||||
.ok()
|
||||
.and_then(|s| serde_json::value::RawValue::from_string(s).ok()),
|
||||
from_appservice,
|
||||
}),
|
||||
Err(e) => {
|
||||
warn!("{:?}", e);
|
||||
Failure((Status::raw(583), ()))
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue