2023-05-11 11:11:57 -04:00
|
|
|
use hyper::{body, header::HeaderValue, Body, Method, Request, Response, StatusCode};
|
|
|
|
|
|
|
|
use std::convert::Infallible;
|
|
|
|
|
|
|
|
use crate::lox_context;
|
|
|
|
use crate::lox_context::LoxServerContext;
|
|
|
|
|
|
|
|
// Lox Request handling logic for each Lox request/protocol
|
|
|
|
pub async fn handle(
|
|
|
|
cloned_context: LoxServerContext,
|
|
|
|
req: Request<Body>,
|
|
|
|
) -> Result<Response<Body>, Infallible> {
|
|
|
|
println!("Request: {:?}", req);
|
|
|
|
match req.method() {
|
|
|
|
&Method::OPTIONS => Ok(Response::builder()
|
|
|
|
.header("Access-Control-Allow-Origin", HeaderValue::from_static("*"))
|
|
|
|
.header("Access-Control-Allow-Headers", "accept, content-type")
|
|
|
|
.header("Access-Control-Allow-Methods", "POST")
|
|
|
|
.status(200)
|
|
|
|
.body(Body::from("Allow POST"))
|
|
|
|
.unwrap()),
|
|
|
|
_ => match (req.method(), req.uri().path()) {
|
|
|
|
(&Method::POST, "/invite") => {
|
|
|
|
Ok::<_, Infallible>(lox_context::generate_invite(cloned_context))
|
|
|
|
}
|
|
|
|
(&Method::POST, "/reachability") => {
|
|
|
|
Ok::<_, Infallible>(lox_context::send_reachability_cred(cloned_context))
|
|
|
|
}
|
|
|
|
(&Method::POST, "/pubkeys") => {
|
|
|
|
Ok::<_, Infallible>(lox_context::send_keys(cloned_context))
|
|
|
|
}
|
|
|
|
(&Method::POST, "/openreq") => Ok::<_, Infallible>({
|
|
|
|
let bytes = body::to_bytes(req.into_body()).await.unwrap();
|
|
|
|
lox_context::verify_and_send_open_cred(bytes, cloned_context)
|
|
|
|
}),
|
|
|
|
(&Method::POST, "/trustpromo") => Ok::<_, Infallible>({
|
|
|
|
let bytes = body::to_bytes(req.into_body()).await.unwrap();
|
|
|
|
lox_context::verify_and_send_trust_promo(bytes, cloned_context)
|
|
|
|
}),
|
|
|
|
(&Method::POST, "/trustmig") => Ok::<_, Infallible>({
|
|
|
|
let bytes = body::to_bytes(req.into_body()).await.unwrap();
|
|
|
|
lox_context::verify_and_send_trust_migration(bytes, cloned_context)
|
|
|
|
}),
|
|
|
|
(&Method::POST, "/levelup") => Ok::<_, Infallible>({
|
|
|
|
let bytes = body::to_bytes(req.into_body()).await.unwrap();
|
|
|
|
lox_context::verify_and_send_level_up(bytes, cloned_context)
|
|
|
|
}),
|
|
|
|
(&Method::POST, "/issueinvite") => Ok::<_, Infallible>({
|
|
|
|
let bytes = body::to_bytes(req.into_body()).await.unwrap();
|
|
|
|
lox_context::verify_and_send_issue_invite(bytes, cloned_context)
|
|
|
|
}),
|
|
|
|
(&Method::POST, "/redeem") => Ok::<_, Infallible>({
|
|
|
|
let bytes = body::to_bytes(req.into_body()).await.unwrap();
|
|
|
|
lox_context::verify_and_send_redeem_invite(bytes, cloned_context)
|
|
|
|
}),
|
|
|
|
(&Method::POST, "/checkblockage") => Ok::<_, Infallible>({
|
|
|
|
let bytes = body::to_bytes(req.into_body()).await.unwrap();
|
|
|
|
// TEST ONLY: Block all existing bridges and add new ones for migration
|
|
|
|
lox_context::verify_and_send_check_blockage(bytes, cloned_context)
|
|
|
|
}),
|
|
|
|
(&Method::POST, "/blockagemigration") => Ok::<_, Infallible>({
|
|
|
|
let bytes = body::to_bytes(req.into_body()).await.unwrap();
|
|
|
|
lox_context::verify_and_send_blockage_migration(bytes, cloned_context)
|
|
|
|
}),
|
|
|
|
_ => {
|
|
|
|
// Return 404 not found response.
|
|
|
|
Ok(Response::builder()
|
|
|
|
.status(StatusCode::NOT_FOUND)
|
|
|
|
.body(Body::from("Not found"))
|
|
|
|
.unwrap())
|
|
|
|
}
|
|
|
|
},
|
|
|
|
}
|
|
|
|
}
|
2023-06-05 18:26:59 -04:00
|
|
|
|
|
|
|
#[cfg(test)]
|
|
|
|
mod tests {
|
|
|
|
use super::*;
|
|
|
|
|
|
|
|
use lox::{BridgeAuth, BridgeDb};
|
|
|
|
use std::sync::{Arc, Mutex};
|
|
|
|
|
|
|
|
trait LoxClient {
|
|
|
|
fn invite(&self) -> Request<Body>;
|
|
|
|
fn reachability(&self) -> Request<Body>;
|
|
|
|
fn pubkeys(&self) -> Request<Body>;
|
|
|
|
}
|
|
|
|
|
|
|
|
struct LoxClientMock {}
|
|
|
|
|
|
|
|
impl LoxClient for LoxClientMock {
|
|
|
|
fn invite(&self) -> Request<Body> {
|
|
|
|
let req = Request::builder()
|
|
|
|
.method("POST")
|
|
|
|
.uri("http://localhost/invite")
|
|
|
|
.body(Body::empty())
|
|
|
|
.unwrap();
|
|
|
|
req
|
|
|
|
}
|
|
|
|
fn reachability(&self) -> Request<Body> {
|
|
|
|
let req = Request::builder()
|
|
|
|
.method("POST")
|
|
|
|
.uri("http://localhost/reachability")
|
|
|
|
.body(Body::empty())
|
|
|
|
.unwrap();
|
|
|
|
req
|
|
|
|
}
|
|
|
|
|
|
|
|
fn pubkeys(&self) -> Request<Body> {
|
|
|
|
let req = Request::builder()
|
|
|
|
.method("POST")
|
|
|
|
.uri("http://localhost/pubkeys")
|
|
|
|
.body(Body::empty())
|
|
|
|
.unwrap();
|
|
|
|
req
|
|
|
|
}
|
|
|
|
}
|
|
|
|
struct TestHarness {
|
|
|
|
context: LoxServerContext,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl TestHarness {
|
|
|
|
fn new() -> Self {
|
|
|
|
let mut bridgedb = BridgeDb::new();
|
|
|
|
let mut lox_auth = BridgeAuth::new(bridgedb.pubkey);
|
|
|
|
|
|
|
|
// Make 3 x num_buckets open invitation bridges, in sets of 3
|
|
|
|
for _ in 0..5 {
|
|
|
|
let bucket = [
|
|
|
|
lox_context::random(),
|
|
|
|
lox_context::random(),
|
|
|
|
lox_context::random(),
|
|
|
|
];
|
|
|
|
lox_auth.add_openinv_bridges(bucket, &mut bridgedb);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Add hot_spare more hot spare buckets
|
|
|
|
for _ in 0..5 {
|
|
|
|
let bucket = [
|
|
|
|
lox_context::random(),
|
|
|
|
lox_context::random(),
|
|
|
|
lox_context::random(),
|
|
|
|
];
|
|
|
|
lox_auth.add_spare_bucket(bucket);
|
|
|
|
}
|
|
|
|
// Create the encrypted bridge table
|
|
|
|
lox_auth.enc_bridge_table();
|
|
|
|
let context = lox_context::LoxServerContext {
|
|
|
|
db: Arc::new(Mutex::new(bridgedb)),
|
|
|
|
ba: Arc::new(Mutex::new(lox_auth)),
|
|
|
|
extra_bridges: Arc::new(Mutex::new(Vec::new())),
|
|
|
|
unreplaced_bridges: Arc::new(Mutex::new(Vec::new())),
|
|
|
|
};
|
|
|
|
Self { context }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[tokio::test]
|
|
|
|
async fn test_handle() {
|
|
|
|
let th = TestHarness::new();
|
|
|
|
let lc = LoxClientMock {};
|
|
|
|
// Test Invite
|
|
|
|
let invite_request = lc.invite();
|
|
|
|
let response = handle(th.context.clone(), invite_request).await.unwrap();
|
|
|
|
println!("Server response?: {:?}", response);
|
|
|
|
assert_eq!(response.status(), StatusCode::OK);
|
|
|
|
// Test Reachability
|
|
|
|
let reachability_request = lc.reachability();
|
|
|
|
let reachability_response = handle(th.context.clone(), reachability_request)
|
|
|
|
.await
|
|
|
|
.unwrap();
|
|
|
|
println!("Server response?: {:?}", reachability_response);
|
|
|
|
assert_eq!(reachability_response.status(), StatusCode::OK);
|
|
|
|
// Test Pubkeys
|
|
|
|
let pubkey_request = lc.pubkeys();
|
|
|
|
let pubkey_response = handle(th.context.clone(), pubkey_request).await.unwrap();
|
|
|
|
println!("Server response?: {:?}", pubkey_response);
|
|
|
|
assert_eq!(pubkey_response.status(), StatusCode::OK);
|
|
|
|
}
|
|
|
|
}
|