2023-05-11 11:11:57 -04:00
|
|
|
use crate::lox_context;
|
|
|
|
use crate::lox_context::LoxServerContext;
|
2023-06-06 20:27:49 -04:00
|
|
|
use hyper::{body, header::HeaderValue, Body, Method, Request, Response, StatusCode};
|
|
|
|
use std::convert::Infallible;
|
2023-05-11 11:11:57 -04:00
|
|
|
|
|
|
|
// Lox Request handling logic for each Lox request/protocol
|
|
|
|
pub async fn handle(
|
|
|
|
cloned_context: LoxServerContext,
|
|
|
|
req: Request<Body>,
|
|
|
|
) -> Result<Response<Body>, Infallible> {
|
|
|
|
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::*;
|
|
|
|
|
2023-06-06 20:27:49 -04:00
|
|
|
use chrono::{Duration, Utc};
|
|
|
|
use julianday::JulianDay;
|
2023-06-12 13:16:24 -04:00
|
|
|
use lox::{
|
|
|
|
bridge_table::{self, BridgeLine},
|
|
|
|
cred::BucketReachability,
|
|
|
|
proto, BridgeAuth, BridgeDb,
|
|
|
|
};
|
2023-06-06 20:27:49 -04:00
|
|
|
use lox_utils;
|
2023-06-12 13:16:24 -04:00
|
|
|
use rand::RngCore;
|
2023-06-05 18:26:59 -04:00
|
|
|
use std::sync::{Arc, Mutex};
|
|
|
|
|
|
|
|
trait LoxClient {
|
|
|
|
fn invite(&self) -> Request<Body>;
|
|
|
|
fn reachability(&self) -> Request<Body>;
|
|
|
|
fn pubkeys(&self) -> Request<Body>;
|
2023-06-06 20:27:49 -04:00
|
|
|
fn openinvite(&self, request: proto::open_invite::Request) -> Request<Body>;
|
|
|
|
fn trustpromo(&self, request: proto::trust_promotion::Request) -> Request<Body>;
|
|
|
|
fn trustmigration(&self, request: proto::migration::Request) -> Request<Body>;
|
|
|
|
fn levelup(&self, request: proto::level_up::Request) -> Request<Body>;
|
|
|
|
fn issueinvite(&self, request: proto::issue_invite::Request) -> Request<Body>;
|
|
|
|
fn redeeminvite(&self, request: proto::redeem_invite::Request) -> Request<Body>;
|
2023-06-12 13:16:24 -04:00
|
|
|
fn checkblockage(&self, request: proto::check_blockage::Request) -> Request<Body>;
|
|
|
|
fn blockagemigration(&self, request: proto::blockage_migration::Request) -> Request<Body>;
|
2023-06-05 18:26:59 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
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
|
|
|
|
}
|
2023-06-06 20:27:49 -04:00
|
|
|
|
|
|
|
fn openinvite(&self, request: proto::open_invite::Request) -> Request<Body> {
|
|
|
|
let req_str = serde_json::to_string(&request).unwrap();
|
|
|
|
let req = Request::builder()
|
|
|
|
.header("Content-Type", "application/json")
|
|
|
|
.method("POST")
|
|
|
|
.uri("http://localhost/openreq")
|
|
|
|
.body(Body::from(req_str))
|
|
|
|
.unwrap();
|
|
|
|
req
|
|
|
|
}
|
|
|
|
|
|
|
|
fn trustpromo(&self, request: proto::trust_promotion::Request) -> Request<Body> {
|
|
|
|
let req_str = serde_json::to_string(&request).unwrap();
|
|
|
|
let req = Request::builder()
|
|
|
|
.header("Content-Type", "application/json")
|
|
|
|
.method("POST")
|
|
|
|
.uri("http://localhost/trustpromo")
|
|
|
|
.body(Body::from(req_str))
|
|
|
|
.unwrap();
|
|
|
|
req
|
|
|
|
}
|
|
|
|
|
|
|
|
fn trustmigration(&self, request: proto::migration::Request) -> Request<Body> {
|
|
|
|
let req_str = serde_json::to_string(&request).unwrap();
|
|
|
|
let req = Request::builder()
|
|
|
|
.header("Content-Type", "application/json")
|
|
|
|
.method("POST")
|
|
|
|
.uri("http://localhost/trustmig")
|
|
|
|
.body(Body::from(req_str))
|
|
|
|
.unwrap();
|
|
|
|
req
|
|
|
|
}
|
|
|
|
|
|
|
|
fn levelup(&self, request: proto::level_up::Request) -> Request<Body> {
|
|
|
|
let req_str = serde_json::to_string(&request).unwrap();
|
|
|
|
let req = Request::builder()
|
|
|
|
.header("Content-Type", "application/json")
|
|
|
|
.method("POST")
|
|
|
|
.uri("http://localhost/levelup")
|
|
|
|
.body(Body::from(req_str))
|
|
|
|
.unwrap();
|
|
|
|
req
|
|
|
|
}
|
|
|
|
|
|
|
|
fn issueinvite(&self, request: proto::issue_invite::Request) -> Request<Body> {
|
|
|
|
let req_str = serde_json::to_string(&request).unwrap();
|
|
|
|
let req = Request::builder()
|
|
|
|
.header("Content-Type", "application/json")
|
|
|
|
.method("POST")
|
|
|
|
.uri("http://localhost/issueinvite")
|
|
|
|
.body(Body::from(req_str))
|
|
|
|
.unwrap();
|
|
|
|
req
|
|
|
|
}
|
|
|
|
|
|
|
|
fn redeeminvite(&self, request: proto::redeem_invite::Request) -> Request<Body> {
|
|
|
|
let req_str = serde_json::to_string(&request).unwrap();
|
|
|
|
let req = Request::builder()
|
|
|
|
.header("Content-Type", "application/json")
|
|
|
|
.method("POST")
|
|
|
|
.uri("http://localhost/redeem")
|
|
|
|
.body(Body::from(req_str))
|
|
|
|
.unwrap();
|
|
|
|
req
|
|
|
|
}
|
2023-06-12 13:16:24 -04:00
|
|
|
|
|
|
|
fn checkblockage(&self, request: proto::check_blockage::Request) -> Request<Body> {
|
|
|
|
let req_str = serde_json::to_string(&request).unwrap();
|
|
|
|
let req = Request::builder()
|
|
|
|
.header("Content-Type", "application/json")
|
|
|
|
.method("POST")
|
|
|
|
.uri("http://localhost/checkblockage")
|
|
|
|
.body(Body::from(req_str))
|
|
|
|
.unwrap();
|
|
|
|
req
|
|
|
|
}
|
|
|
|
|
|
|
|
fn blockagemigration(&self, request: proto::blockage_migration::Request) -> Request<Body> {
|
|
|
|
let req_str = serde_json::to_string(&request).unwrap();
|
|
|
|
let req = Request::builder()
|
|
|
|
.header("Content-Type", "application/json")
|
|
|
|
.method("POST")
|
|
|
|
.uri("http://localhost/blockagemigration")
|
|
|
|
.body(Body::from(req_str))
|
|
|
|
.unwrap();
|
|
|
|
req
|
|
|
|
}
|
2023-06-05 18:26:59 -04:00
|
|
|
}
|
2023-06-06 20:27:49 -04:00
|
|
|
|
2023-06-05 18:26:59 -04:00
|
|
|
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 {
|
2023-06-12 13:16:24 -04:00
|
|
|
let bucket = [random(), random(), random()];
|
2023-06-05 18:26:59 -04:00
|
|
|
lox_auth.add_openinv_bridges(bucket, &mut bridgedb);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Add hot_spare more hot spare buckets
|
|
|
|
for _ in 0..5 {
|
2023-06-12 13:16:24 -04:00
|
|
|
let bucket = [random(), random(), random()];
|
2023-06-05 18:26:59 -04:00
|
|
|
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 }
|
|
|
|
}
|
2023-06-06 20:27:49 -04:00
|
|
|
|
|
|
|
fn advance_days(&mut self, days: u16) {
|
2023-06-12 13:16:24 -04:00
|
|
|
self.context.advance_days_test(days)
|
2023-06-06 20:27:49 -04:00
|
|
|
}
|
2023-06-12 13:16:24 -04:00
|
|
|
|
|
|
|
fn simulate_blocking(&mut self, cred: lox::cred::Lox) -> (lox::cred::Lox, u32, [u8; 16]) {
|
|
|
|
let (id, key) = bridge_table::from_scalar(cred.bucket).unwrap();
|
|
|
|
let mut bdb = self.context.db.lock().unwrap();
|
|
|
|
let mut lox_auth = self.context.ba.lock().unwrap();
|
|
|
|
let encbuckets = lox_auth.enc_bridge_table();
|
|
|
|
let bucket =
|
|
|
|
bridge_table::BridgeTable::decrypt_bucket(id, &key, &encbuckets[id as usize])
|
|
|
|
.unwrap();
|
|
|
|
assert!(bucket.1.is_some());
|
|
|
|
// Block two of our bridges
|
|
|
|
lox_auth.bridge_unreachable(&bucket.0[0], &mut bdb);
|
|
|
|
lox_auth.bridge_unreachable(&bucket.0[2], &mut bdb);
|
|
|
|
|
|
|
|
(cred, id, key)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn prep_next_day(&mut self, id: u32, key: [u8; 16]) {
|
|
|
|
let mut lox_auth = self.context.ba.lock().unwrap();
|
|
|
|
let encbuckets2 = lox_auth.enc_bridge_table();
|
|
|
|
let bucket2 =
|
|
|
|
bridge_table::BridgeTable::decrypt_bucket(id, &key, &encbuckets2[id as usize])
|
|
|
|
.unwrap();
|
|
|
|
// We should no longer have a Bridge Reachability credential
|
|
|
|
assert!(bucket2.1.is_none());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn random() -> BridgeLine {
|
|
|
|
let mut rng = rand::thread_rng();
|
|
|
|
let mut res: BridgeLine = BridgeLine::default();
|
|
|
|
// Pick a random 4-byte address
|
|
|
|
let mut addr: [u8; 4] = [0; 4];
|
|
|
|
rng.fill_bytes(&mut addr);
|
|
|
|
// If the leading byte is 224 or more, that's not a valid IPv4
|
|
|
|
// address. Choose an IPv6 address instead (but don't worry too
|
|
|
|
// much about it being well formed).
|
|
|
|
if addr[0] >= 224 {
|
|
|
|
rng.fill_bytes(&mut res.addr);
|
|
|
|
} else {
|
|
|
|
// Store an IPv4 address as a v4-mapped IPv6 address
|
|
|
|
res.addr[10] = 255;
|
|
|
|
res.addr[11] = 255;
|
|
|
|
res.addr[12..16].copy_from_slice(&addr);
|
|
|
|
};
|
|
|
|
let ports: [u16; 4] = [443, 4433, 8080, 43079];
|
|
|
|
let portidx = (rng.next_u32() % 4) as usize;
|
|
|
|
res.port = ports[portidx];
|
|
|
|
res.uid_fingerprint = rng.next_u64();
|
|
|
|
let mut cert: [u8; 52] = [0; 52];
|
|
|
|
rng.fill_bytes(&mut cert);
|
|
|
|
let infostr: String = format!(
|
|
|
|
"obfs4 cert={}, iat-mode=0",
|
|
|
|
base64::encode_config(cert, base64::STANDARD_NO_PAD)
|
|
|
|
);
|
|
|
|
res.info[..infostr.len()].copy_from_slice(infostr.as_bytes());
|
|
|
|
res
|
2023-06-05 18:26:59 -04:00
|
|
|
}
|
2023-06-06 20:27:49 -04:00
|
|
|
|
|
|
|
// This should only be used for testing, use today in production
|
|
|
|
fn test_today(days: i64) -> u32 {
|
|
|
|
let naive_now_plus = (Utc::now() + Duration::days(days)).date_naive();
|
|
|
|
JulianDay::from(naive_now_plus).inner().try_into().unwrap()
|
|
|
|
}
|
|
|
|
|
|
|
|
async fn body_to_string(res: Response<Body>) -> String {
|
|
|
|
let body_bytes = hyper::body::to_bytes(res.into_body()).await.unwrap();
|
|
|
|
String::from_utf8(body_bytes.to_vec()).unwrap()
|
|
|
|
}
|
|
|
|
|
2023-06-05 18:26:59 -04:00
|
|
|
#[tokio::test]
|
2023-06-16 11:59:33 -04:00
|
|
|
async fn test_handle_not_found(){
|
|
|
|
let th = TestHarness::new();
|
2023-06-06 20:27:49 -04:00
|
|
|
// Test Random page
|
|
|
|
let four_oh_four_req = Request::builder()
|
2023-06-16 11:59:33 -04:00
|
|
|
.header("Content-Type", "application/json")
|
|
|
|
.method("POST")
|
|
|
|
.uri("http://localhost/givemecreds")
|
|
|
|
.body(Body::empty())
|
|
|
|
.unwrap();
|
2023-06-06 20:27:49 -04:00
|
|
|
let not_found_response = handle(th.context.clone(), four_oh_four_req).await.unwrap();
|
|
|
|
assert_eq!(not_found_response.status(), StatusCode::NOT_FOUND);
|
2023-06-16 11:59:33 -04:00
|
|
|
}
|
2023-06-06 20:27:49 -04:00
|
|
|
|
2023-06-16 11:59:33 -04:00
|
|
|
#[tokio::test]
|
|
|
|
async fn test_handle_bad_request(){
|
|
|
|
let th = TestHarness::new();
|
2023-06-13 12:03:06 -04:00
|
|
|
// Test that empty request to a credential issuing endpoint fails
|
|
|
|
let req = Request::builder()
|
|
|
|
.method("POST")
|
|
|
|
.uri("http://localhost/checkblockage")
|
|
|
|
.body(Body::empty())
|
|
|
|
.unwrap();
|
|
|
|
let not_found_response = handle(th.context.clone(), req).await.unwrap();
|
|
|
|
assert_eq!(not_found_response.status(), StatusCode::BAD_REQUEST);
|
2023-06-16 11:59:33 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
#[tokio::test]
|
|
|
|
async fn test_handle_invite(){
|
|
|
|
let th = TestHarness::new();
|
|
|
|
let lc = LoxClientMock {};
|
2023-06-13 12:03:06 -04:00
|
|
|
|
2023-06-05 18:26:59 -04:00
|
|
|
// Test Invite
|
|
|
|
let invite_request = lc.invite();
|
2023-06-06 20:27:49 -04:00
|
|
|
let invite_response = handle(th.context.clone(), invite_request).await.unwrap();
|
|
|
|
assert_eq!(invite_response.status(), StatusCode::OK);
|
2023-06-16 11:59:33 -04:00
|
|
|
}
|
2023-06-06 20:27:49 -04:00
|
|
|
|
2023-06-16 11:59:33 -04:00
|
|
|
#[tokio::test]
|
|
|
|
async fn test_handle_reachability(){
|
|
|
|
let th = TestHarness::new();
|
|
|
|
let lc = LoxClientMock {};
|
2023-06-05 18:26:59 -04:00
|
|
|
// Test Reachability
|
|
|
|
let reachability_request = lc.reachability();
|
|
|
|
let reachability_response = handle(th.context.clone(), reachability_request)
|
|
|
|
.await
|
|
|
|
.unwrap();
|
|
|
|
assert_eq!(reachability_response.status(), StatusCode::OK);
|
2023-06-16 11:59:33 -04:00
|
|
|
}
|
2023-06-06 20:27:49 -04:00
|
|
|
|
2023-06-16 11:59:33 -04:00
|
|
|
#[tokio::test]
|
|
|
|
async fn test_handle_pubkeys(){
|
|
|
|
let th = TestHarness::new();
|
|
|
|
let lc = LoxClientMock {};
|
2023-06-05 18:26:59 -04:00
|
|
|
// Test Pubkeys
|
|
|
|
let pubkey_request = lc.pubkeys();
|
|
|
|
let pubkey_response = handle(th.context.clone(), pubkey_request).await.unwrap();
|
|
|
|
assert_eq!(pubkey_response.status(), StatusCode::OK);
|
2023-06-16 11:59:33 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
#[tokio::test]
|
|
|
|
async fn test_handle_lox_protocols(){
|
|
|
|
let mut th = TestHarness::new();
|
|
|
|
let lc = LoxClientMock {};
|
|
|
|
// Request Invite and pubkeys required for protocol tests
|
2023-06-06 20:27:49 -04:00
|
|
|
|
2023-06-16 11:59:33 -04:00
|
|
|
// Get Open Invitation
|
|
|
|
let invite_request = lc.invite();
|
|
|
|
let invite_response = handle(th.context.clone(), invite_request).await.unwrap();
|
|
|
|
|
|
|
|
// Test Open Invite and get response
|
2023-06-06 20:27:49 -04:00
|
|
|
let invite_response_str = body_to_string(invite_response).await;
|
|
|
|
let response_data: lox_utils::Invite = serde_json::from_str(&invite_response_str).unwrap();
|
|
|
|
let token = match lox_utils::validate(&response_data.invite) {
|
|
|
|
Ok(token) => token,
|
|
|
|
Err(e) => panic!("Error: Invitation token error {:?}", e.to_string()),
|
|
|
|
};
|
|
|
|
let (request, state) = lox::proto::open_invite::request(&token);
|
|
|
|
let open_request = lc.openinvite(request);
|
|
|
|
let open_response = handle(th.context.clone(), open_request).await.unwrap();
|
|
|
|
assert_eq!(open_response.status(), StatusCode::OK);
|
|
|
|
let open_resp = body_to_string(open_response).await;
|
|
|
|
let open_response_obj = serde_json::from_str(&open_resp).unwrap();
|
2023-06-16 11:59:33 -04:00
|
|
|
|
|
|
|
// Get pubkeys
|
|
|
|
let pubkey_request = lc.pubkeys();
|
|
|
|
let pubkey_response = handle(th.context.clone(), pubkey_request).await.unwrap();
|
|
|
|
let pubkeys = body_to_string(pubkey_response).await;
|
|
|
|
let pubkeys_obj: lox_utils::PubKeys = serde_json::from_str(&pubkeys).unwrap();
|
|
|
|
|
|
|
|
// Test Trust Promotion and get response
|
|
|
|
let lox_cred = lox::proto::open_invite::handle_response(
|
2023-06-06 20:27:49 -04:00
|
|
|
state,
|
|
|
|
open_response_obj,
|
|
|
|
&pubkeys_obj.lox_pub,
|
2023-06-16 11:59:33 -04:00
|
|
|
).unwrap();
|
2023-06-06 20:27:49 -04:00
|
|
|
let lox_cred: lox_utils::LoxCredential = lox_utils::LoxCredential {
|
|
|
|
lox_credential: lox_cred.0,
|
|
|
|
bridgeline: Some(lox_cred.1),
|
|
|
|
invitation: None,
|
|
|
|
};
|
2023-06-16 11:59:33 -04:00
|
|
|
|
2023-06-06 20:27:49 -04:00
|
|
|
// Advance the context to a day after the credential becomes eligible to upgrade
|
|
|
|
th.advance_days(31);
|
|
|
|
let trust_result = match proto::trust_promotion::request(
|
|
|
|
&lox_cred.lox_credential,
|
|
|
|
&pubkeys_obj.lox_pub,
|
|
|
|
test_today(31),
|
|
|
|
) {
|
|
|
|
Ok(trust_result) => trust_result,
|
|
|
|
Err(e) => panic!(
|
|
|
|
"Error: Proof error from trust promotion {:?}",
|
|
|
|
e.to_string()
|
|
|
|
),
|
|
|
|
};
|
|
|
|
let trustpromo_request = lc.trustpromo(trust_result.0);
|
|
|
|
let trustpromo_response = handle(th.context.clone(), trustpromo_request)
|
|
|
|
.await
|
|
|
|
.unwrap();
|
|
|
|
assert_eq!(trustpromo_response.status(), StatusCode::OK);
|
|
|
|
let trustpromo_resp = body_to_string(trustpromo_response).await;
|
|
|
|
let trustpromo_response_obj = serde_json::from_str(&trustpromo_resp).unwrap();
|
2023-06-16 11:59:33 -04:00
|
|
|
|
|
|
|
// Test Trust Migration and get response
|
2023-06-06 20:27:49 -04:00
|
|
|
let mig_cred = match lox::proto::trust_promotion::handle_response(
|
|
|
|
trust_result.1,
|
|
|
|
trustpromo_response_obj,
|
|
|
|
) {
|
|
|
|
Ok(mig_cred) => mig_cred,
|
|
|
|
Err(e) => panic!("Error: Migration token error {:?}", e.to_string()),
|
|
|
|
};
|
|
|
|
let migration_result = match proto::migration::request(
|
|
|
|
&lox_cred.lox_credential,
|
|
|
|
&mig_cred,
|
|
|
|
&pubkeys_obj.lox_pub,
|
|
|
|
&pubkeys_obj.migration_pub,
|
|
|
|
) {
|
|
|
|
Ok(migration_result) => migration_result,
|
|
|
|
Err(e) => panic!(
|
|
|
|
"Error: Proof error from trust migration {:?}",
|
|
|
|
e.to_string()
|
|
|
|
),
|
|
|
|
};
|
|
|
|
let trustmig_request = lc.trustmigration(migration_result.0);
|
|
|
|
let trustmig_response = handle(th.context.clone(), trustmig_request).await.unwrap();
|
|
|
|
assert_eq!(trustmig_response.status(), StatusCode::OK);
|
|
|
|
let trustmig_resp = body_to_string(trustmig_response).await;
|
|
|
|
let trustmig_response_obj = serde_json::from_str(&trustmig_resp).unwrap();
|
2023-06-16 11:59:33 -04:00
|
|
|
|
|
|
|
// Test Level up and get response
|
2023-06-06 20:27:49 -04:00
|
|
|
let level_one_cred = match lox::proto::migration::handle_response(
|
|
|
|
migration_result.1,
|
|
|
|
trustmig_response_obj,
|
|
|
|
&pubkeys_obj.lox_pub,
|
|
|
|
) {
|
|
|
|
Ok(level_one_cred) => level_one_cred,
|
|
|
|
Err(e) => panic!("Error: Level one credential error {:?}", e.to_string()),
|
|
|
|
};
|
|
|
|
th.advance_days(14);
|
|
|
|
let new_reachability_request = lc.reachability();
|
|
|
|
let new_reachability_response = handle(th.context.clone(), new_reachability_request)
|
|
|
|
.await
|
|
|
|
.unwrap();
|
|
|
|
let encrypted_table = body_to_string(new_reachability_response).await;
|
|
|
|
let reachability_cred: BucketReachability =
|
|
|
|
lox_utils::generate_reachability_cred(&level_one_cred, encrypted_table);
|
|
|
|
let level_up_result = match proto::level_up::request(
|
|
|
|
&level_one_cred,
|
|
|
|
&reachability_cred,
|
|
|
|
&pubkeys_obj.lox_pub,
|
|
|
|
&pubkeys_obj.reachability_pub,
|
|
|
|
test_today(31 + 14),
|
|
|
|
) {
|
|
|
|
Ok(level_up_result) => level_up_result,
|
2023-06-12 13:16:24 -04:00
|
|
|
Err(e) => panic!("Error: Proof error from level up {:?}", e.to_string()),
|
2023-06-06 20:27:49 -04:00
|
|
|
};
|
|
|
|
let level_up_request = lc.levelup(level_up_result.0);
|
|
|
|
let level_up_response = handle(th.context.clone(), level_up_request).await.unwrap();
|
|
|
|
assert_eq!(level_up_response.status(), StatusCode::OK);
|
|
|
|
let levelup_resp = body_to_string(level_up_response).await;
|
|
|
|
let levelup_response_obj = serde_json::from_str(&levelup_resp).unwrap();
|
|
|
|
let level_two_cred = match lox::proto::level_up::handle_response(
|
|
|
|
level_up_result.1,
|
|
|
|
levelup_response_obj,
|
|
|
|
&pubkeys_obj.lox_pub,
|
|
|
|
) {
|
|
|
|
Ok(level_two_cred) => level_two_cred,
|
|
|
|
Err(e) => panic!("Error: Level two credential error {:?}", e.to_string()),
|
|
|
|
};
|
2023-06-16 11:59:33 -04:00
|
|
|
|
|
|
|
// Test Issue Invite and get response
|
2023-06-06 20:27:49 -04:00
|
|
|
let new_reachability_request = lc.reachability();
|
|
|
|
let new_reachability_response = handle(th.context.clone(), new_reachability_request)
|
|
|
|
.await
|
|
|
|
.unwrap();
|
|
|
|
let encrypted_table = body_to_string(new_reachability_response).await;
|
|
|
|
let reachability_cred: BucketReachability =
|
|
|
|
lox_utils::generate_reachability_cred(&level_two_cred, encrypted_table);
|
|
|
|
|
|
|
|
let issue_invite_result = match proto::issue_invite::request(
|
|
|
|
&level_two_cred,
|
|
|
|
&reachability_cred,
|
|
|
|
&pubkeys_obj.lox_pub,
|
|
|
|
&pubkeys_obj.reachability_pub,
|
|
|
|
test_today(31 + 14),
|
|
|
|
) {
|
|
|
|
Ok(issue_invite_result) => issue_invite_result,
|
|
|
|
Err(e) => panic!(
|
|
|
|
"Error: Proof error from issue invitation {:?}",
|
|
|
|
e.to_string()
|
|
|
|
),
|
|
|
|
};
|
|
|
|
let issue_invite_request = lc.issueinvite(issue_invite_result.0);
|
2023-06-12 13:16:24 -04:00
|
|
|
let issue_invite_response = handle(th.context.clone(), issue_invite_request)
|
|
|
|
.await
|
|
|
|
.unwrap();
|
2023-06-06 20:27:49 -04:00
|
|
|
assert_eq!(issue_invite_response.status(), StatusCode::OK);
|
|
|
|
let invite_resp = body_to_string(issue_invite_response).await;
|
|
|
|
let invite_response_obj = serde_json::from_str(&invite_resp).unwrap();
|
|
|
|
let issue_invite_cred = match lox::proto::issue_invite::handle_response(
|
|
|
|
issue_invite_result.1,
|
2023-06-12 13:16:24 -04:00
|
|
|
invite_response_obj,
|
2023-06-06 20:27:49 -04:00
|
|
|
&pubkeys_obj.lox_pub,
|
|
|
|
&pubkeys_obj.invitation_pub,
|
|
|
|
) {
|
|
|
|
Ok(issue_invite_cred) => issue_invite_cred,
|
|
|
|
Err(e) => panic!("Error: Issue invite credential error {:?}", e.to_string()),
|
|
|
|
};
|
2023-06-16 11:59:33 -04:00
|
|
|
|
|
|
|
// Test Redeem Invite
|
2023-06-06 20:27:49 -04:00
|
|
|
let new_invite = match proto::redeem_invite::request(
|
|
|
|
&issue_invite_cred.1,
|
|
|
|
&pubkeys_obj.invitation_pub,
|
|
|
|
test_today(31 + 14),
|
|
|
|
) {
|
|
|
|
Ok(new_invite) => new_invite,
|
2023-06-12 13:16:24 -04:00
|
|
|
Err(e) => panic!("Error: Proof error from level up {:?}", e.to_string()),
|
2023-06-06 20:27:49 -04:00
|
|
|
};
|
|
|
|
let new_redeem_invite_request = lc.redeeminvite(new_invite.0);
|
|
|
|
let new_redeem_invite_response = handle(th.context.clone(), new_redeem_invite_request)
|
|
|
|
.await
|
|
|
|
.unwrap();
|
|
|
|
assert_eq!(new_redeem_invite_response.status(), StatusCode::OK);
|
|
|
|
let redeemed_cred_resp = body_to_string(new_redeem_invite_response).await;
|
|
|
|
let redeemed_cred_resp_obj = serde_json::from_str(&redeemed_cred_resp).unwrap();
|
|
|
|
|
|
|
|
let redeemed_cred_result = match proto::redeem_invite::handle_response(
|
|
|
|
new_invite.1,
|
|
|
|
redeemed_cred_resp_obj,
|
|
|
|
&pubkeys_obj.lox_pub,
|
|
|
|
) {
|
|
|
|
Ok(redeemed_cred_result) => redeemed_cred_result,
|
|
|
|
Err(e) => panic!(
|
|
|
|
"Error: Proof error from issue invitation {:?}",
|
|
|
|
e.to_string()
|
|
|
|
),
|
|
|
|
};
|
|
|
|
|
2023-06-16 11:59:33 -04:00
|
|
|
// Prepare for check blockage request
|
2023-06-12 13:16:24 -04:00
|
|
|
th.advance_days(28); // First advance most recent credential to level 3
|
|
|
|
let new_reachability_request = lc.reachability();
|
|
|
|
let new_reachability_response = handle(th.context.clone(), new_reachability_request)
|
|
|
|
.await
|
|
|
|
.unwrap();
|
|
|
|
let encrypted_table = body_to_string(new_reachability_response).await;
|
|
|
|
let reachability_cred: BucketReachability =
|
|
|
|
lox_utils::generate_reachability_cred(&issue_invite_cred.0, encrypted_table);
|
|
|
|
let level_three_request = match proto::level_up::request(
|
|
|
|
&issue_invite_cred.0,
|
|
|
|
&reachability_cred,
|
|
|
|
&pubkeys_obj.lox_pub,
|
|
|
|
&pubkeys_obj.reachability_pub,
|
|
|
|
test_today(31 + 14 + 28),
|
|
|
|
) {
|
|
|
|
Ok(level_three_request) => level_three_request,
|
|
|
|
Err(e) => panic!("Error: Proof error from level up to 3 {:?}", e.to_string()),
|
|
|
|
};
|
|
|
|
let level_three_req = lc.levelup(level_three_request.0);
|
|
|
|
let level_three_response = handle(th.context.clone(), level_three_req).await.unwrap();
|
|
|
|
assert_eq!(level_three_response.status(), StatusCode::OK);
|
|
|
|
let levelup_resp = body_to_string(level_three_response).await;
|
|
|
|
let levelup_response_obj = serde_json::from_str(&levelup_resp).unwrap();
|
|
|
|
let level_three_cred = match lox::proto::level_up::handle_response(
|
|
|
|
level_three_request.1,
|
|
|
|
levelup_response_obj,
|
|
|
|
&pubkeys_obj.lox_pub,
|
|
|
|
) {
|
|
|
|
Ok(level_three_cred) => level_three_cred,
|
|
|
|
Err(e) => panic!("Error: Level two credential error {:?}", e.to_string()),
|
|
|
|
};
|
|
|
|
// Simulate blocking event
|
|
|
|
let passed_level_three_cred = th.simulate_blocking(level_three_cred);
|
|
|
|
th.advance_days(1);
|
|
|
|
th.prep_next_day(passed_level_three_cred.1, passed_level_three_cred.2);
|
|
|
|
|
2023-06-16 11:59:33 -04:00
|
|
|
//Test Check Blockage and get response
|
2023-06-12 13:16:24 -04:00
|
|
|
let migration_cred_request = match proto::check_blockage::request(
|
|
|
|
&passed_level_three_cred.0,
|
|
|
|
&pubkeys_obj.lox_pub,
|
|
|
|
) {
|
|
|
|
Ok(migration_cred_request) => migration_cred_request,
|
|
|
|
Err(e) => panic!("Error: Proof error from level up to 3 {:?}", e.to_string()),
|
|
|
|
};
|
|
|
|
let migration_cred_req = lc.checkblockage(migration_cred_request.0);
|
|
|
|
let migration_cred_response = handle(th.context.clone(), migration_cred_req)
|
|
|
|
.await
|
|
|
|
.unwrap();
|
|
|
|
assert_eq!(migration_cred_response.status(), StatusCode::OK);
|
|
|
|
let migration_resp = body_to_string(migration_cred_response).await;
|
|
|
|
let migration_response_obj = serde_json::from_str(&migration_resp).unwrap();
|
|
|
|
let mig_cred = match lox::proto::check_blockage::handle_response(
|
|
|
|
migration_cred_request.1,
|
|
|
|
migration_response_obj,
|
|
|
|
) {
|
|
|
|
Ok(mig_cred) => mig_cred,
|
|
|
|
Err(e) => panic!("Error: Migration token error {:?}", e.to_string()),
|
|
|
|
};
|
2023-06-16 11:59:33 -04:00
|
|
|
|
|
|
|
// Test Blockage Migration
|
|
|
|
|
2023-06-12 13:16:24 -04:00
|
|
|
let migration_result = match proto::blockage_migration::request(
|
|
|
|
&passed_level_three_cred.0,
|
|
|
|
&mig_cred,
|
|
|
|
&pubkeys_obj.lox_pub,
|
|
|
|
&pubkeys_obj.migration_pub,
|
|
|
|
) {
|
|
|
|
Ok(migration_result) => migration_result,
|
|
|
|
Err(e) => panic!(
|
|
|
|
"Error: Proof error from trust migration {:?}",
|
|
|
|
e.to_string()
|
|
|
|
),
|
|
|
|
};
|
|
|
|
let blockagemig_request = lc.blockagemigration(migration_result.0);
|
|
|
|
let blockagemig_response = handle(th.context.clone(), blockagemig_request)
|
|
|
|
.await
|
|
|
|
.unwrap();
|
|
|
|
assert_eq!(blockagemig_response.status(), StatusCode::OK);
|
2023-06-05 18:26:59 -04:00
|
|
|
}
|
|
|
|
}
|