refactor: let ruma-server-util handle X-Matrix parsing
This commit is contained in:
parent
3ad7675bbf
commit
9374b74e77
3 changed files with 29 additions and 68 deletions
18
Cargo.lock
generated
18
Cargo.lock
generated
|
@ -2039,6 +2039,7 @@ dependencies = [
|
||||||
"ruma-federation-api",
|
"ruma-federation-api",
|
||||||
"ruma-identity-service-api",
|
"ruma-identity-service-api",
|
||||||
"ruma-push-gateway-api",
|
"ruma-push-gateway-api",
|
||||||
|
"ruma-server-util",
|
||||||
"ruma-signatures",
|
"ruma-signatures",
|
||||||
"ruma-state-res",
|
"ruma-state-res",
|
||||||
]
|
]
|
||||||
|
@ -2184,6 +2185,17 @@ dependencies = [
|
||||||
"serde_json",
|
"serde_json",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ruma-server-util"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "git+https://github.com/ruma/ruma?rev=5495b85aa311c2805302edb0a7de40399e22b397#5495b85aa311c2805302edb0a7de40399e22b397"
|
||||||
|
dependencies = [
|
||||||
|
"headers",
|
||||||
|
"ruma-common",
|
||||||
|
"tracing",
|
||||||
|
"yap",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ruma-signatures"
|
name = "ruma-signatures"
|
||||||
version = "0.14.0"
|
version = "0.14.0"
|
||||||
|
@ -3453,6 +3465,12 @@ version = "1.0.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "cfe53a6657fd280eaa890a3bc59152892ffa3e30101319d168b781ed6529b049"
|
checksum = "cfe53a6657fd280eaa890a3bc59152892ffa3e30101319d168b781ed6529b049"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "yap"
|
||||||
|
version = "0.11.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ff4524214bc4629eba08d78ceb1d6507070cc0bcbbed23af74e19e6e924a24cf"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zerocopy"
|
name = "zerocopy"
|
||||||
version = "0.7.32"
|
version = "0.7.32"
|
||||||
|
|
|
@ -56,6 +56,7 @@ ruma = { git = "https://github.com/ruma/ruma", rev = "5495b85aa311c2805302edb0a7
|
||||||
"push-gateway-api-c",
|
"push-gateway-api-c",
|
||||||
"rand",
|
"rand",
|
||||||
"ring-compat",
|
"ring-compat",
|
||||||
|
"server-util",
|
||||||
"state-res",
|
"state-res",
|
||||||
"unstable-exhaustive-types",
|
"unstable-exhaustive-types",
|
||||||
"unstable-msc2448",
|
"unstable-msc2448",
|
||||||
|
|
|
@ -4,10 +4,7 @@ use axum::{
|
||||||
async_trait,
|
async_trait,
|
||||||
body::{Full, HttpBody},
|
body::{Full, HttpBody},
|
||||||
extract::{rejection::TypedHeaderRejectionReason, FromRequest, Path, TypedHeader},
|
extract::{rejection::TypedHeaderRejectionReason, FromRequest, Path, TypedHeader},
|
||||||
headers::{
|
headers::{authorization::Bearer, Authorization},
|
||||||
authorization::{Bearer, Credentials},
|
|
||||||
Authorization,
|
|
||||||
},
|
|
||||||
response::{IntoResponse, Response},
|
response::{IntoResponse, Response},
|
||||||
BoxError, RequestExt, RequestPartsExt,
|
BoxError, RequestExt, RequestPartsExt,
|
||||||
};
|
};
|
||||||
|
@ -15,7 +12,8 @@ use bytes::{Buf, BufMut, Bytes, BytesMut};
|
||||||
use http::{Request, StatusCode};
|
use http::{Request, StatusCode};
|
||||||
use ruma::{
|
use ruma::{
|
||||||
api::{client::error::ErrorKind, AuthScheme, IncomingRequest, OutgoingResponse},
|
api::{client::error::ErrorKind, AuthScheme, IncomingRequest, OutgoingResponse},
|
||||||
CanonicalJsonValue, OwnedDeviceId, OwnedServerName, OwnedUserId, UserId,
|
server_util::authorization::XMatrix,
|
||||||
|
CanonicalJsonValue, OwnedDeviceId, OwnedUserId, UserId,
|
||||||
};
|
};
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use tracing::{debug, error, warn};
|
use tracing::{debug, error, warn};
|
||||||
|
@ -191,7 +189,12 @@ where
|
||||||
|
|
||||||
let signatures = BTreeMap::from_iter([(
|
let signatures = BTreeMap::from_iter([(
|
||||||
x_matrix.origin.as_str().to_owned(),
|
x_matrix.origin.as_str().to_owned(),
|
||||||
CanonicalJsonValue::Object(origin_signatures),
|
CanonicalJsonValue::Object(
|
||||||
|
origin_signatures
|
||||||
|
.into_iter()
|
||||||
|
.map(|(k, v)| (k.to_string(), v))
|
||||||
|
.collect(),
|
||||||
|
),
|
||||||
)]);
|
)]);
|
||||||
|
|
||||||
let mut request_map = BTreeMap::from_iter([
|
let mut request_map = BTreeMap::from_iter([
|
||||||
|
@ -226,7 +229,7 @@ where
|
||||||
let keys_result = services()
|
let keys_result = services()
|
||||||
.rooms
|
.rooms
|
||||||
.event_handler
|
.event_handler
|
||||||
.fetch_signing_keys(&x_matrix.origin, vec![x_matrix.key.to_owned()])
|
.fetch_signing_keys(&x_matrix.origin, vec![x_matrix.key.to_string()])
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
let keys = match keys_result {
|
let keys = match keys_result {
|
||||||
|
@ -340,67 +343,6 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct XMatrix {
|
|
||||||
destination: Option<OwnedServerName>,
|
|
||||||
origin: OwnedServerName,
|
|
||||||
key: String, // KeyName?
|
|
||||||
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 key = None;
|
|
||||||
let mut sig = None;
|
|
||||||
let mut destination = 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.try_into().ok()?),
|
|
||||||
_ => debug!(
|
|
||||||
"Unexpected field `{}` in X-Matrix Authorization header",
|
|
||||||
name
|
|
||||||
),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Some(Self {
|
|
||||||
destination,
|
|
||||||
origin: origin?,
|
|
||||||
key: key?,
|
|
||||||
sig: sig?,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
fn encode(&self) -> http::HeaderValue {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: OutgoingResponse> IntoResponse for RumaResponse<T> {
|
impl<T: OutgoingResponse> IntoResponse for RumaResponse<T> {
|
||||||
fn into_response(self) -> Response {
|
fn into_response(self) -> Response {
|
||||||
match self.0.try_into_http_response::<BytesMut>() {
|
match self.0.try_into_http_response::<BytesMut>() {
|
||||||
|
|
Loading…
Add table
Reference in a new issue