Skip to content

Commit

Permalink
feat(mediator-client): complete connection
Browse files Browse the repository at this point in the history
Signed-off-by: nain-F49FF806 <[email protected]>
  • Loading branch information
nain-F49FF806 committed Sep 21, 2023
1 parent f2c04ac commit 54026f3
Show file tree
Hide file tree
Showing 6 changed files with 101 additions and 64 deletions.
67 changes: 18 additions & 49 deletions mediator/src/agent/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use aries_vcx::protocols::connection::invitee::states::initial::Initial as Clien
use aries_vcx::protocols::connection::invitee::states::requested::Requested as ClientRequestSent;
use aries_vcx::protocols::connection::invitee::InviteeConnection;

use aries_vcx::protocols::connection::invitee::states::completed::Completed;
use aries_vcx::protocols::mediated_connection::pairwise_info::PairwiseInfo;
use aries_vcx::utils::encryption_envelope::EncryptionEnvelope;
// use aries_vcx::protocols::oob;
Expand All @@ -15,39 +16,25 @@ use aries_vcx_core::ledger::base_ledger::IndyLedgerRead;
use aries_vcx_core::wallet::base_wallet::BaseWallet;
use aries_vcx_core::wallet::indy::IndySdkWallet;
use diddoc_legacy::aries::diddoc::AriesDidDoc;
use messages::msg_fields::protocols::connection::response::Response;
use messages::msg_fields::protocols::connection::Connection;
use messages::AriesMessage;
// use diddoc_legacy::aries::service::AriesService;
use messages::msg_fields::protocols::out_of_band::invitation::Invitation as OOBInvitation;
use messages::msg_fields::protocols::out_of_band::invitation::OobService;
use serde_json::Value;

use super::utils::MockTransport;
use super::Agent;
use crate::utils::prelude::*;

pub fn oob2did(oob: OOBInvitation) -> AriesDidDoc {
let mut did_doc: AriesDidDoc = AriesDidDoc::default();
did_doc.set_id(oob.id.clone());
let oob_service = oob.content.services.first().expect("OOB needs a service").clone();

match oob_service {
OobService::AriesService(service) => {
did_doc.set_service_endpoint(service.service_endpoint);
did_doc.set_recipient_keys(service.recipient_keys);
did_doc.set_routing_keys(service.routing_keys);
}
_ => panic!("Assuming fully clean AriesService variant only"),
}
did_doc
}

// client role utilities
impl Agent<IndySdkWallet> {
/// Starts a new connection object and tries to create request to the specified OOB invite endpoint
pub async fn client_connect_req(
pub async fn gen_client_connect_req(
&self,
oob_invite: OOBInvitation,
) -> Result<(InviteeConnection<ClientRequestSent>, Value), String> {
) -> Result<(InviteeConnection<ClientRequestSent>, EncryptionEnvelope), String> {
let (pw_did, pw_vk) = self.wallet.create_and_store_my_did(None, None).await.unwrap();

let mock_ledger: Arc<dyn IndyLedgerRead> = Arc::new(MockLedger {}); // not good. will be dealt later. (can see brutish attempt above)
Expand Down Expand Up @@ -76,37 +63,19 @@ impl Agent<IndySdkWallet> {
)
.await
.unwrap();
let packed_aries_msg_json: Value =
serde_json::from_slice(&packed_aries_msg_bytes[..]).expect("Envelope content should be serializable json");
info!(
"Sending Connection Request Envelope: {},",
serde_json::to_string_pretty(&packed_aries_msg_json).unwrap()
);
let oob_invited_endpoint = oob2did(oob_invite).get_endpoint().expect("Service needs an endpoint");
let http_client = reqwest::Client::new();
let res = http_client
.post(oob_invited_endpoint)
.json(&packed_aries_msg_json)
.send()
.await
.expect("Something went wrong while sending/receiving");
debug!("Received response {:#?}", res);
let Ok(_res_ref) = res.error_for_status_ref() else {
return Err(format!("{:#?} {:#?}", res.status().as_u16(), res.text().await));
};
let res_status = res.status().as_u16();
let res_body = res
.text()

Ok((client_conn, EncryptionEnvelope(packed_aries_msg_bytes)))
}

pub async fn handle_response(
&self,
state: InviteeConnection<ClientRequestSent>,
response: Response,
) -> Result<InviteeConnection<Completed>, String> {
let state = state
.handle_response(&self.get_wallet_ref(), response, &MockTransport)
.await
.expect("Reading response body is a trivial expectation");
info!("Response {:#?} {:#?}", res_status, res_body);
let Ok(res_json) = serde_json::from_str::<Value>(&res_body) else {
return Err(format!("Couldn't decode response body to json, got {:#?}", res_body));
};
debug!(
"Received response json: {},",
serde_json::to_string_pretty(&res_json).unwrap()
);
Ok((client_conn, res_json))
.map_err(|err| err.to_string());
state
}
}
2 changes: 1 addition & 1 deletion mediator/src/agent/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ use messages::AriesMessage;

use serde_json::Value;

mod utils;
pub mod utils;
// #[cfg(test)]
pub mod client;

Expand Down
37 changes: 33 additions & 4 deletions mediator/src/agent/utils.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
use std::sync::Arc;

use aries_vcx::{common::signing::sign_connection_response, errors::error::VcxResult};
use aries_vcx::{common::signing::sign_connection_response, errors::error::VcxResult, transport::Transport};
use aries_vcx_core::wallet::base_wallet::BaseWallet;
use axum::async_trait;
use diddoc_legacy::aries::diddoc::AriesDidDoc;
use messages::{
decorators::{thread::Thread, timing::Timing},
msg_fields::protocols::connection::{
response::{Response, ResponseContent, ResponseDecorators},
ConnectionData,
msg_fields::protocols::{
connection::{
response::{Response, ResponseContent, ResponseDecorators},
ConnectionData,
},
out_of_band::invitation::{Invitation as OOBInvitation, OobService},
},
};
use uuid::Uuid;
Expand Down Expand Up @@ -49,3 +53,28 @@ pub async fn build_response_content(
.decorators(decorators)
.build())
}

pub fn oob2did(oob: OOBInvitation) -> AriesDidDoc {
let mut did_doc: AriesDidDoc = AriesDidDoc::default();
did_doc.set_id(oob.id.clone());
let oob_service = oob.content.services.first().expect("OOB needs a service").clone();

match oob_service {
OobService::AriesService(service) => {
did_doc.set_service_endpoint(service.service_endpoint);
did_doc.set_recipient_keys(service.recipient_keys);
did_doc.set_routing_keys(service.routing_keys);
}
_ => panic!("Assuming fully clean AriesService variant only"),
}
did_doc
}

pub struct MockTransport;

#[async_trait]
impl Transport for MockTransport {
async fn send_message(&self, _msg: Vec<u8>, _service_endpoint: url::Url) -> VcxResult<()> {
Ok(())
}
}
48 changes: 44 additions & 4 deletions mediator/src/routes/client.rs
Original file line number Diff line number Diff line change
@@ -1,20 +1,60 @@
use super::*;
use crate::agent::utils::oob2did;
use crate::utils::prelude::*;
use futures::TryFutureExt;
use messages::msg_fields::protocols::out_of_band::invitation::Invitation as OOBInvitation;
use serde_json::json;

#[debug_handler]
pub async fn connection_request(
pub async fn handle_register(
State(agent): State<ArcAgent<IndySdkWallet>>,
Json(oob_invite): Json<OOBInvitation>,
) -> Result<Json<Value>, String> {
let (state, response) = agent.client_connect_req(oob_invite.clone()).await?;
todo!()
let (state, EncryptionEnvelope(packed_aries_msg_bytes)) = agent.gen_client_connect_req(oob_invite.clone()).await?;
let packed_aries_msg_json: Value =
serde_json::from_slice(&packed_aries_msg_bytes[..]).expect("Envelope content should be serializable json");
info!(
"Sending Connection Request Envelope: {},",
serde_json::to_string_pretty(&packed_aries_msg_json).unwrap()
);
let oob_invited_endpoint = oob2did(oob_invite).get_endpoint().expect("Service needs an endpoint");
let http_client = reqwest::Client::new();
let res = http_client
.post(oob_invited_endpoint)
.json(&packed_aries_msg_json)
.send()
.await
.map_err(|err| format!("Something went wrong while sending/receiving {:?}", err))?;
debug!("Received response to connection request, {:#?}", res);
let Ok(_res_ref) = res.error_for_status_ref() else {
return Err(format!("{:#?} {:#?}", res.status().as_u16(), res.text().await));
};
let res_status = res.status().as_u16();
let res_bytes = res.bytes().await.map_err(|err| err.to_string())?;
let res_json: Value = serde_json::from_slice(&res_bytes).map_err(|err| err.to_string())?;
info!(
"Received Response {:#?} {:#?}",
res_status,
serde_json::to_string_pretty(&res_json).unwrap()
);
let res_unpack = agent.unpack_didcomm(&res_bytes).await?;
let res_aries: AriesMessage = serde_json::from_str(&res_unpack.message).map_err(|err| err.to_string())?;
info!("Unpacked response {:#?}", res_aries);
let AriesMessage::Connection(Connection::Response(response)) = res_aries else {
return Err(format!("Expected connection response, got {:?}", res_aries));
};
let state = agent.handle_response(state, response).await?;
let state_json = serde_json::to_string_pretty(&state).map_err(|err| err.to_string())?;
Ok(Json(json!({
"status": "success",
"state": state
})))
}

pub async fn build_client_router() -> Router {
let agent = Agent::new_demo_agent().await.unwrap();
Router::default()
.route("/client/register", post(connection_request))
.route("/client/register", post(handle_register))
.layer(tower_http::catch_panic::CatchPanicLayer::new())
.with_state(Arc::new(agent))
}
7 changes: 3 additions & 4 deletions mediator/src/routes/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,19 +34,18 @@ pub async fn handle_aries_connection<T: BaseWallet>(
_ => Err(unhandled_aries(connection)),
}
}
pub async fn handle_didcomm(
pub async fn handle_aries(
State(agent): State<ArcAgent<IndySdkWallet>>,
didcomm_msg: Bytes,
) -> Result<Json<Value>, String> {
info!("processing message {:?}", &didcomm_msg);
let unpacked = agent.unpack_didcomm(&didcomm_msg).await.unwrap();
let my_key = unpacked.recipient_verkey;
let aries_message: AriesMessage =
serde_json::from_str(&unpacked.message).expect("Decoding unpacked message as AriesMessage");

let packed_response = match aries_message {
AriesMessage::Connection(conn) => handle_aries_connection(agent.clone(), conn).await?,
_ => return Err(unhandled_aries(aries_message)),
_ => Err(unhandled_aries(aries_message))?,
};
let EncryptionEnvelope(packed_message_bytes) = packed_response;
let packed_json = serde_json::from_slice(&packed_message_bytes[..]).unwrap();
Expand Down Expand Up @@ -83,7 +82,7 @@ pub async fn build_router(endpoint_root: &str) -> Router {
Router::default()
.route("/", get(readme))
.route("/register", get(oob_invite_qr))
.route("/aries", get(handle_didcomm).post(handle_didcomm))
.route("/aries", get(handle_aries).post(handle_aries))
.layer(tower_http::catch_panic::CatchPanicLayer::new())
.with_state(Arc::new(agent))
}
4 changes: 2 additions & 2 deletions mediator/src/tui.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use log::info;
use messages::msg_fields::protocols::out_of_band::invitation::Invitation as OOBInvitation;

use crate::agent::Agent;
use crate::routes::client::connection_request;
use crate::routes::client::handle_register;

pub async fn init_tui() {
let agent = Agent::new_demo_agent().await.unwrap();
Expand Down Expand Up @@ -88,7 +88,7 @@ pub fn client_register_connect_cb(s: &mut Cursive) {
info!("{:#?}", oob_invite);
s.with_user_data(|arc_agent: &mut Arc<Agent<IndySdkWallet>>| {
output.set_content(format!("{:#?}", oob_invite));
match block_on(connection_request(State(arc_agent.to_owned()), Json(oob_invite))) {
match block_on(handle_register(State(arc_agent.to_owned()), Json(oob_invite))) {
Ok(Json(res_json)) => output.set_content(serde_json::to_string_pretty(&res_json).unwrap()),
Err(err) => output.set_content(err),
};
Expand Down

0 comments on commit 54026f3

Please sign in to comment.