Signing, basis for federation
This commit is contained in:
parent
9b79798e56
commit
b0d9ccdb2d
8 changed files with 137 additions and 35 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -1260,7 +1260,6 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "ruma-federation-api"
|
||||
version = "0.0.1"
|
||||
source = "git+https://github.com/ruma/ruma-federation-api.git#5448c650f0a583382152d0f43f2dcf720d495390"
|
||||
dependencies = [
|
||||
"js_int",
|
||||
"ruma-api",
|
||||
|
|
|
@ -18,7 +18,7 @@ ruma-identifiers = "0.15.1"
|
|||
ruma-api = "0.16.0-rc.1"
|
||||
ruma-events = "0.19.0"
|
||||
ruma-signatures = { git = "https://github.com/ruma/ruma-signatures.git" }
|
||||
ruma-federation-api = { git = "https://github.com/ruma/ruma-federation-api.git" }
|
||||
ruma-federation-api = { path = "../ruma-federation-api" }
|
||||
pretty_env_logger = "0.4.0"
|
||||
log = "0.4.8"
|
||||
sled = "0.31.0"
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use crate::{utils, Data, MatrixResult, Ruma};
|
||||
use crate::{server_server, utils, Data, MatrixResult, Ruma};
|
||||
|
||||
use log::debug;
|
||||
use rocket::{get, options, post, put, State};
|
||||
|
@ -674,7 +674,8 @@ pub fn join_room_by_id_or_alias_route(
|
|||
}
|
||||
}
|
||||
} else {
|
||||
body.room_id_or_alias.try_into().unwrap()
|
||||
todo!();
|
||||
//body.room_id_or_alias.try_into().unwrap()
|
||||
};
|
||||
|
||||
if data.room_join(
|
||||
|
@ -725,8 +726,8 @@ pub fn invite_user_route(
|
|||
}
|
||||
|
||||
#[post("/_matrix/client/r0/publicRooms", data = "<body>")]
|
||||
pub fn get_public_rooms_filtered_route(
|
||||
data: State<Data>,
|
||||
pub async fn get_public_rooms_filtered_route(
|
||||
data: State<'_, Data>,
|
||||
body: Ruma<get_public_rooms_filtered::Request>,
|
||||
) -> MatrixResult<get_public_rooms_filtered::Response> {
|
||||
let mut chunk = data
|
||||
|
@ -752,6 +753,25 @@ pub fn get_public_rooms_filtered_route(
|
|||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
chunk.extend_from_slice(
|
||||
&server_server::send_request(
|
||||
&data,
|
||||
"https://matrix.org".to_owned(),
|
||||
ruma_federation_api::v1::get_public_rooms::Request {
|
||||
limit: None,
|
||||
since: None,
|
||||
include_all_networks: None,
|
||||
third_party_instance_id: None,
|
||||
},
|
||||
)
|
||||
.await
|
||||
.unwrap()
|
||||
.chunk
|
||||
.into_iter()
|
||||
.map(|c| serde_json::from_str(&serde_json::to_string(dbg!(&c)).unwrap()).unwrap())
|
||||
.collect::<Vec<_>>(),
|
||||
);
|
||||
|
||||
chunk.sort_by(|l, r| r.num_joined_members.cmp(&l.num_joined_members));
|
||||
|
||||
let total_room_count_estimate = (chunk.len() as u32).into();
|
||||
|
|
|
@ -457,7 +457,7 @@ impl Data {
|
|||
))
|
||||
.expect("ruma's reference hashes are correct");
|
||||
|
||||
let mut pdu_json = serde_json::to_value(pdu).unwrap();
|
||||
let mut pdu_json = serde_json::to_value(&pdu).unwrap();
|
||||
ruma_signatures::hash_and_sign_event(self.hostname(), self.keypair(), &mut pdu_json);
|
||||
|
||||
self.pdu_leaves_replace(&room_id, &pdu.event_id);
|
||||
|
@ -483,7 +483,7 @@ impl Data {
|
|||
|
||||
self.db
|
||||
.pduid_pdu
|
||||
.insert(&pdu_id, &*serde_json::to_string(&pdu_json).unwrap())
|
||||
.insert(&pdu_id, &*pdu_json.to_string())
|
||||
.unwrap();
|
||||
|
||||
self.db
|
||||
|
@ -497,7 +497,10 @@ impl Data {
|
|||
key.extend_from_slice(pdu.kind.to_string().as_bytes());
|
||||
key.push(0xff);
|
||||
key.extend_from_slice(state_key.to_string().as_bytes());
|
||||
self.db.roomstateid_pdu.insert(key, &*pdu_json).unwrap();
|
||||
self.db
|
||||
.roomstateid_pdu
|
||||
.insert(key, &*pdu_json.to_string())
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
pdu.event_id
|
||||
|
|
|
@ -127,7 +127,7 @@ impl Database {
|
|||
&*db.update_and_fetch("keypair", utils::generate_keypair)
|
||||
.unwrap()
|
||||
.unwrap(),
|
||||
"0.0.0".to_owned(),
|
||||
"key1".to_owned(),
|
||||
)
|
||||
.unwrap(),
|
||||
_db: db,
|
||||
|
|
|
@ -1,25 +1,89 @@
|
|||
use std::convert::TryInto;
|
||||
use log::error;
|
||||
use http::header::{HeaderValue, AUTHORIZATION};
|
||||
use ruma_api::{
|
||||
error::{FromHttpRequestError, FromHttpResponseError},
|
||||
Endpoint, Outgoing,
|
||||
};
|
||||
use std::convert::{TryFrom, TryInto};
|
||||
|
||||
pub fn send_request<T: TryInto<http::Request<Vec<u8>>>>(
|
||||
pub async fn send_request<T: Endpoint>(
|
||||
data: &crate::Data,
|
||||
method: http::Method,
|
||||
uri: String,
|
||||
destination: String,
|
||||
request: T,
|
||||
) where
|
||||
) -> Option<<T::Response as Outgoing>::Incoming>
|
||||
where
|
||||
// We need to duplicate Endpoint's where clauses because the compiler is not smart enough yet.
|
||||
// See https://github.com/rust-lang/rust/issues/54149
|
||||
<T as Outgoing>::Incoming: TryFrom<http::Request<Vec<u8>>, Error = FromHttpRequestError>,
|
||||
<T::Response as Outgoing>::Incoming: TryFrom<
|
||||
http::Response<Vec<u8>>,
|
||||
Error = FromHttpResponseError<<T as Endpoint>::ResponseError>,
|
||||
>,
|
||||
T::Error: std::fmt::Debug,
|
||||
{
|
||||
let mut http_request: http::Request<_> = request.try_into().unwrap();
|
||||
let request_json = serde_json::to_value(http_request.body()).unwrap();
|
||||
let uri = destination.clone() + T::METADATA.path;
|
||||
*http_request.uri_mut() = uri.parse().unwrap();
|
||||
|
||||
let body = http_request.body();
|
||||
let mut request_json = if !body.is_empty() {
|
||||
serde_json::to_value(http_request.body()).unwrap()
|
||||
} else {
|
||||
serde_json::Map::new().into()
|
||||
};
|
||||
|
||||
let request_map = request_json.as_object_mut().unwrap();
|
||||
|
||||
request_map.insert("method".to_owned(), method.to_string().into());
|
||||
request_map.insert("uri".to_owned(), uri.to_string().into());
|
||||
//TODO: request_map.insert("origin".to_owned(), data.origin().to_string().into());
|
||||
request_map.insert("method".to_owned(), T::METADATA.method.to_string().into());
|
||||
request_map.insert("uri".to_owned(), uri.into());
|
||||
request_map.insert("origin".to_owned(), data.hostname().into());
|
||||
request_map.insert("destination".to_owned(), destination.to_string().into());
|
||||
|
||||
ruma_signatures::sign_json(data.hostname(), data.keypair(), &mut request_json).unwrap();
|
||||
let signature = request_json["signatures"];
|
||||
data.reqwest_client().execute(http_request.into());
|
||||
ruma_signatures::sign_json(data.hostname(), data.keypair(), dbg!(&mut request_json)).unwrap();
|
||||
let signatures = request_json["signatures"]
|
||||
.as_object()
|
||||
.unwrap()
|
||||
.values()
|
||||
.next()
|
||||
.unwrap()
|
||||
.as_object()
|
||||
.unwrap()
|
||||
.iter()
|
||||
.map(|(k, v)| (k, v.as_str().unwrap()));
|
||||
|
||||
for s in signatures {
|
||||
http_request.headers_mut().insert(AUTHORIZATION, HeaderValue::from_str(dbg!(&format!("X-Matrix origin={},key=\"{}\",sig=\"{}\"", data.hostname(), s.0, s.1))).unwrap());
|
||||
}
|
||||
|
||||
let reqwest_response = data
|
||||
.reqwest_client()
|
||||
.execute(dbg!(http_request.into()))
|
||||
.await;
|
||||
|
||||
// Because reqwest::Response -> http::Response is complicated:
|
||||
match reqwest_response {
|
||||
Ok(mut reqwest_response) => {
|
||||
let status = reqwest_response.status();
|
||||
let mut http_response = http::Response::builder().status(status);
|
||||
let headers = http_response.headers_mut().unwrap();
|
||||
|
||||
for (k, v) in reqwest_response.headers_mut().drain() {
|
||||
if let Some(key) = k {
|
||||
headers.insert(key, v);
|
||||
}
|
||||
}
|
||||
|
||||
let body = reqwest_response
|
||||
.bytes()
|
||||
.await
|
||||
.unwrap()
|
||||
.into_iter()
|
||||
.collect();
|
||||
Some(<T::Response as Outgoing>::Incoming::try_from(dbg!(http_response.body(body).unwrap())).ok().unwrap())
|
||||
}
|
||||
Err(e) => {
|
||||
println!("ERROR: {}", e);
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
38
src/test.rs
38
src/test.rs
|
@ -1,8 +1,7 @@
|
|||
use super::*;
|
||||
use rocket::{local::Client, http::Status};
|
||||
use serde_json::Value;
|
||||
use serde_json::json;
|
||||
use rocket::{http::Status, local::Client};
|
||||
use ruma_client_api::error::ErrorKind;
|
||||
use serde_json::{json, Value};
|
||||
use std::time::Duration;
|
||||
|
||||
fn setup_client() -> Client {
|
||||
|
@ -19,7 +18,8 @@ async fn register_login() {
|
|||
let mut response = client
|
||||
.post("/_matrix/client/r0/register?kind=user")
|
||||
.body(registration_init())
|
||||
.dispatch().await;
|
||||
.dispatch()
|
||||
.await;
|
||||
let body = serde_json::from_str::<Value>(&response.body_string().await.unwrap()).unwrap();
|
||||
|
||||
assert_eq!(response.status().code, 401);
|
||||
|
@ -33,14 +33,16 @@ async fn login_after_register_correct_password() {
|
|||
let mut response = client
|
||||
.post("/_matrix/client/r0/register?kind=user")
|
||||
.body(registration_init())
|
||||
.dispatch().await;
|
||||
.dispatch()
|
||||
.await;
|
||||
let body = serde_json::from_str::<Value>(&response.body_string().await.unwrap()).unwrap();
|
||||
let session = body["session"].clone();
|
||||
|
||||
let response = client
|
||||
.post("/_matrix/client/r0/register?kind=user")
|
||||
.body(registration(session.as_str().unwrap()))
|
||||
.dispatch().await;
|
||||
.dispatch()
|
||||
.await;
|
||||
assert_eq!(response.status().code, 200);
|
||||
|
||||
let login_response = client
|
||||
|
@ -57,14 +59,16 @@ async fn login_after_register_incorrect_password() {
|
|||
let mut response = client
|
||||
.post("/_matrix/client/r0/register?kind=user")
|
||||
.body(registration_init())
|
||||
.dispatch().await;
|
||||
.dispatch()
|
||||
.await;
|
||||
let body = serde_json::from_str::<Value>(&response.body_string().await.unwrap()).unwrap();
|
||||
let session = body["session"].clone();
|
||||
|
||||
let response = client
|
||||
.post("/_matrix/client/r0/register?kind=user")
|
||||
.body(registration(session.as_str().unwrap()))
|
||||
.dispatch().await;
|
||||
.dispatch()
|
||||
.await;
|
||||
assert_eq!(response.status().code, 200);
|
||||
|
||||
let mut login_response = client
|
||||
|
@ -73,7 +77,15 @@ async fn login_after_register_incorrect_password() {
|
|||
.dispatch()
|
||||
.await;
|
||||
let body = serde_json::from_str::<Value>(&login_response.body_string().await.unwrap()).unwrap();
|
||||
assert_eq!(body.as_object().unwrap().get("errcode").unwrap().as_str().unwrap(), "M_FORBIDDEN");
|
||||
assert_eq!(
|
||||
body.as_object()
|
||||
.unwrap()
|
||||
.get("errcode")
|
||||
.unwrap()
|
||||
.as_str()
|
||||
.unwrap(),
|
||||
"M_FORBIDDEN"
|
||||
);
|
||||
assert_eq!(login_response.status().code, 403);
|
||||
}
|
||||
|
||||
|
@ -98,7 +110,8 @@ fn registration(session: &str) -> String {
|
|||
"device_id": "GHTYAJCE",
|
||||
"initial_device_display_name": "Jungle Phone",
|
||||
"inhibit_login": false
|
||||
}).to_string()
|
||||
})
|
||||
.to_string()
|
||||
}
|
||||
|
||||
fn login_with_password(password: &str) -> String {
|
||||
|
@ -110,5 +123,6 @@ fn login_with_password(password: &str) -> String {
|
|||
},
|
||||
"password": password,
|
||||
"initial_device_display_name": "Jungle Phone"
|
||||
}).to_string()
|
||||
}
|
||||
})
|
||||
.to_string()
|
||||
}
|
||||
|
|
|
@ -27,8 +27,10 @@ pub fn increment(old: Option<&[u8]>) -> Option<Vec<u8>> {
|
|||
|
||||
pub fn generate_keypair(old: Option<&[u8]>) -> Option<Vec<u8>> {
|
||||
Some(
|
||||
/*
|
||||
old.map(|s| s.to_vec())
|
||||
.unwrap_or_else(|| ruma_signatures::Ed25519KeyPair::generate().unwrap()),
|
||||
.unwrap_or_else(|| */
|
||||
ruma_signatures::Ed25519KeyPair::generate().unwrap(),
|
||||
)
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue