2024-06-06 18:04:29 +00:00
|
|
|
use std::{mem, ops::Deref};
|
2024-03-05 19:48:54 -05:00
|
|
|
|
2024-06-06 18:04:29 +00:00
|
|
|
use axum::{async_trait, body::Body, extract::FromRequest};
|
|
|
|
use bytes::{BufMut, BytesMut};
|
2024-07-16 08:05:25 +00:00
|
|
|
use conduit::{debug, err, trace, utils::string::EMPTY, Error, Result};
|
2024-07-15 04:19:43 +00:00
|
|
|
use ruma::{api::IncomingRequest, CanonicalJsonValue, OwnedDeviceId, OwnedServerName, OwnedUserId, UserId};
|
2024-07-16 08:05:25 +00:00
|
|
|
use service::Services;
|
2024-03-05 19:48:54 -05:00
|
|
|
|
2024-07-14 23:46:03 +00:00
|
|
|
use super::{auth, auth::Auth, request, request::Request};
|
2024-07-16 08:05:25 +00:00
|
|
|
use crate::service::appservice::RegistrationInfo;
|
2020-02-15 22:42:21 +01:00
|
|
|
|
2022-01-20 11:51:31 +01:00
|
|
|
/// Extractor for Ruma request structs
|
2024-07-14 23:46:03 +00:00
|
|
|
pub(crate) struct Args<T> {
|
2024-05-26 14:29:56 -04:00
|
|
|
/// Request struct body
|
2024-04-22 23:48:57 -04:00
|
|
|
pub(crate) body: T,
|
2024-06-06 18:04:29 +00:00
|
|
|
|
|
|
|
/// Federation server authentication: X-Matrix origin
|
|
|
|
/// None when not a federation server.
|
|
|
|
pub(crate) origin: Option<OwnedServerName>,
|
|
|
|
|
|
|
|
/// Local user authentication: user_id.
|
|
|
|
/// None when not an authenticated local user.
|
2024-04-22 23:48:57 -04:00
|
|
|
pub(crate) sender_user: Option<OwnedUserId>,
|
2024-06-06 18:04:29 +00:00
|
|
|
|
|
|
|
/// Local user authentication: device_id.
|
|
|
|
/// None when not an authenticated local user or no device.
|
2024-04-22 23:48:57 -04:00
|
|
|
pub(crate) sender_device: Option<OwnedDeviceId>,
|
2024-06-06 18:04:29 +00:00
|
|
|
|
|
|
|
/// Appservice authentication; registration info.
|
|
|
|
/// None when not an appservice.
|
2024-04-22 23:48:57 -04:00
|
|
|
pub(crate) appservice_info: Option<RegistrationInfo>,
|
2024-06-06 18:04:29 +00:00
|
|
|
|
|
|
|
/// Parsed JSON content.
|
|
|
|
/// None when body is not a valid string
|
|
|
|
pub(crate) json_body: Option<CanonicalJsonValue>,
|
|
|
|
}
|
|
|
|
|
|
|
|
#[async_trait]
|
2024-07-14 23:46:03 +00:00
|
|
|
impl<T, S> FromRequest<S, Body> for Args<T>
|
2024-06-06 18:04:29 +00:00
|
|
|
where
|
|
|
|
T: IncomingRequest,
|
|
|
|
{
|
|
|
|
type Rejection = Error;
|
|
|
|
|
|
|
|
async fn from_request(request: hyper::Request<Body>, _: &S) -> Result<Self, Self::Rejection> {
|
2024-07-16 08:05:25 +00:00
|
|
|
let services = service::services(); // ???
|
|
|
|
let mut request = request::from(services, request).await?;
|
2024-06-06 18:04:29 +00:00
|
|
|
let mut json_body = serde_json::from_slice::<CanonicalJsonValue>(&request.body).ok();
|
2024-07-16 08:05:25 +00:00
|
|
|
let auth = auth::auth(services, &mut request, &json_body, &T::METADATA).await?;
|
2024-06-09 10:23:06 +00:00
|
|
|
Ok(Self {
|
2024-07-16 08:05:25 +00:00
|
|
|
body: make_body::<T>(services, &mut request, &mut json_body, &auth)?,
|
2024-06-06 18:04:29 +00:00
|
|
|
origin: auth.origin,
|
|
|
|
sender_user: auth.sender_user,
|
|
|
|
sender_device: auth.sender_device,
|
|
|
|
appservice_info: auth.appservice_info,
|
|
|
|
json_body,
|
|
|
|
})
|
|
|
|
}
|
2020-03-28 18:50:02 +01:00
|
|
|
}
|
2020-03-28 23:08:59 +01:00
|
|
|
|
2024-07-14 23:46:03 +00:00
|
|
|
impl<T> Deref for Args<T> {
|
2024-03-05 19:48:54 -05:00
|
|
|
type Target = T;
|
2020-02-15 22:42:21 +01:00
|
|
|
|
2024-03-05 19:48:54 -05:00
|
|
|
fn deref(&self) -> &Self::Target { &self.body }
|
2020-03-28 18:50:02 +01:00
|
|
|
}
|
2024-06-06 18:04:29 +00:00
|
|
|
|
2024-07-16 08:05:25 +00:00
|
|
|
fn make_body<T>(
|
|
|
|
services: &Services, request: &mut Request, json_body: &mut Option<CanonicalJsonValue>, auth: &Auth,
|
|
|
|
) -> Result<T>
|
2024-06-06 18:04:29 +00:00
|
|
|
where
|
|
|
|
T: IncomingRequest,
|
|
|
|
{
|
|
|
|
let body = if let Some(CanonicalJsonValue::Object(json_body)) = json_body {
|
|
|
|
let user_id = auth.sender_user.clone().unwrap_or_else(|| {
|
2024-07-16 08:05:25 +00:00
|
|
|
let server_name = services.globals.server_name();
|
|
|
|
UserId::parse_with_server_name(EMPTY, server_name).expect("valid user_id")
|
2024-06-06 18:04:29 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
let uiaa_request = json_body
|
|
|
|
.get("auth")
|
|
|
|
.and_then(|auth| auth.as_object())
|
|
|
|
.and_then(|auth| auth.get("session"))
|
|
|
|
.and_then(|session| session.as_str())
|
|
|
|
.and_then(|session| {
|
2024-07-16 08:05:25 +00:00
|
|
|
services.uiaa.get_uiaa_request(
|
2024-06-06 18:04:29 +00:00
|
|
|
&user_id,
|
2024-07-16 08:05:25 +00:00
|
|
|
&auth.sender_device.clone().unwrap_or_else(|| EMPTY.into()),
|
2024-06-06 18:04:29 +00:00
|
|
|
session,
|
|
|
|
)
|
|
|
|
});
|
|
|
|
|
|
|
|
if let Some(CanonicalJsonValue::Object(initial_request)) = uiaa_request {
|
|
|
|
for (key, value) in initial_request {
|
|
|
|
json_body.entry(key).or_insert(value);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
let mut buf = BytesMut::new().writer();
|
|
|
|
serde_json::to_writer(&mut buf, &json_body).expect("value serialization can't fail");
|
|
|
|
buf.into_inner().freeze()
|
|
|
|
} else {
|
|
|
|
mem::take(&mut request.body)
|
|
|
|
};
|
|
|
|
|
|
|
|
let mut http_request = hyper::Request::builder()
|
|
|
|
.uri(request.parts.uri.clone())
|
|
|
|
.method(request.parts.method.clone());
|
2024-07-15 04:19:43 +00:00
|
|
|
*http_request.headers_mut().expect("mutable http headers") = request.parts.headers.clone();
|
|
|
|
let http_request = http_request.body(body).expect("http request body");
|
|
|
|
|
|
|
|
let headers = http_request.headers();
|
|
|
|
let method = http_request.method();
|
|
|
|
let uri = http_request.uri();
|
|
|
|
debug!("{method:?} {uri:?} {headers:?}");
|
|
|
|
trace!("{method:?} {uri:?} {json_body:?}");
|
|
|
|
|
|
|
|
T::try_from_http_request(http_request, &request.path).map_err(|e| err!(Request(BadJson(debug_warn!("{e}")))))
|
2024-06-06 18:04:29 +00:00
|
|
|
}
|