switch to ruma's X-Matrix parser

Signed-off-by: strawberry <strawberry@puppygock.gay>
This commit is contained in:
strawberry 2024-07-03 03:53:50 -04:00
parent daa46a0dc4
commit deca2c52c6
5 changed files with 38 additions and 66 deletions

23
Cargo.lock generated
View file

@ -1552,6 +1552,15 @@ dependencies = [
"itoa",
]
[[package]]
name = "http-auth"
version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "643c9bbf6a4ea8a656d6b4cd53d34f79e3f841ad5203c1a55fb7d761923bc255"
dependencies = [
"memchr",
]
[[package]]
name = "http-body"
version = "0.4.6"
@ -2906,6 +2915,7 @@ dependencies = [
"ruma-federation-api",
"ruma-identity-service-api",
"ruma-push-gateway-api",
"ruma-server-util",
"ruma-signatures",
"ruma-state-res",
"web-time 1.1.0",
@ -3066,6 +3076,19 @@ dependencies = [
"serde_json",
]
[[package]]
name = "ruma-server-util"
version = "0.3.0"
source = "git+https://github.com/girlbossceo/ruwuma?rev=9a5bfad8494b7a4e6c40421c3d0675db4b434ec0#9a5bfad8494b7a4e6c40421c3d0675db4b434ec0"
dependencies = [
"headers",
"http 1.1.0",
"http-auth",
"ruma-common",
"thiserror",
"tracing",
]
[[package]]
name = "ruma-signatures"
version = "0.15.0"

View file

@ -284,6 +284,7 @@ features = [
"markdown",
"push-gateway-api-c",
"state-res",
"server-util",
"unstable-exhaustive-types",
"ring-compat",
"unstable-unspecified",

View file

@ -9,11 +9,12 @@ use axum_extra::{
use http::uri::PathAndQuery;
use ruma::{
api::{client::error::ErrorKind, AuthScheme, Metadata},
server_util::authorization::XMatrix,
CanonicalJsonValue, OwnedDeviceId, OwnedServerName, OwnedUserId, UserId,
};
use tracing::warn;
use super::{request::Request, xmatrix::XMatrix};
use super::request::Request;
use crate::{service::appservice::RegistrationInfo, services, Error, Result};
enum Token {
@ -202,8 +203,17 @@ async fn auth_server(request: &mut Request, json_body: &Option<CanonicalJsonValu
})?;
let origin = &x_matrix.origin;
let signatures = BTreeMap::from_iter([(x_matrix.key.clone(), CanonicalJsonValue::String(x_matrix.sig))]);
let signatures = BTreeMap::from_iter([(origin.as_str().to_owned(), CanonicalJsonValue::Object(signatures))]);
let signatures =
BTreeMap::from_iter([(x_matrix.key.clone(), CanonicalJsonValue::String(x_matrix.sig.to_string()))]);
let signatures = BTreeMap::from_iter([(
origin.as_str().to_owned(),
CanonicalJsonValue::Object(
signatures
.into_iter()
.map(|(k, v)| (k.to_string(), v))
.collect(),
),
)]);
let server_destination = services().globals.server_name().as_str().to_owned();
if let Some(destination) = x_matrix.destination.as_ref() {
@ -239,7 +249,7 @@ async fn auth_server(request: &mut Request, json_body: &Option<CanonicalJsonValu
let keys_result = services()
.rooms
.event_handler
.fetch_signing_keys_for_server(origin, vec![x_matrix.key.clone()])
.fetch_signing_keys_for_server(origin, vec![x_matrix.key.to_string()])
.await;
let keys = keys_result.map_err(|e| {

View file

@ -1,7 +1,6 @@
mod auth;
mod handler;
mod request;
mod xmatrix;
use std::{mem, ops::Deref};

View file

@ -1,61 +0,0 @@
use std::str;
use axum_extra::headers::authorization::Credentials;
use ruma::OwnedServerName;
use tracing::debug;
pub(crate) struct XMatrix {
pub(crate) origin: OwnedServerName,
pub(crate) destination: Option<String>,
pub(crate) key: String, // KeyName?
pub(crate) sig: String,
}
impl Credentials for XMatrix {
const SCHEME: &'static str = "X-Matrix";
fn decode(value: &http::HeaderValue) -> Option<Self> {
debug_assert!(
value.as_bytes().starts_with(b"X-Matrix "),
"HeaderValue to decode should start with \"X-Matrix ..\", received = {value:?}",
);
let parameters = str::from_utf8(&value.as_bytes()["X-Matrix ".len()..])
.ok()?
.trim_start();
let mut origin = None;
let mut destination = None;
let mut key = None;
let mut sig = None;
for entry in parameters.split_terminator(',') {
let (name, value) = entry.split_once('=')?;
// It's not at all clear why some fields are quoted and others not in the spec,
// let's simply accept either form for every field.
let value = value
.strip_prefix('"')
.and_then(|rest| rest.strip_suffix('"'))
.unwrap_or(value);
// FIXME: Catch multiple fields of the same name
match name {
"origin" => origin = Some(value.try_into().ok()?),
"key" => key = Some(value.to_owned()),
"sig" => sig = Some(value.to_owned()),
"destination" => destination = Some(value.to_owned()),
_ => debug!("Unexpected field `{name}` in X-Matrix Authorization header"),
}
}
Some(Self {
origin: origin?,
key: key?,
sig: sig?,
destination,
})
}
fn encode(&self) -> http::HeaderValue { todo!() }
}