Skip to content

Commit

Permalink
Refactoring, eliminate usage of Transport arguments in Connection
Browse files Browse the repository at this point in the history
Signed-off-by: Patrik Stas <[email protected]>
  • Loading branch information
Patrik-Stas committed Sep 25, 2023
1 parent dc4a82f commit 97a5b15
Show file tree
Hide file tree
Showing 8 changed files with 37 additions and 166 deletions.
3 changes: 1 addition & 2 deletions agents/rust/aries-vcx-agent/src/services/connection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,6 @@ impl ServiceConnections {
request,
self.service_endpoint.clone(),
vec![],
&HttpClient,
)
.await?;

Expand All @@ -122,7 +121,7 @@ impl ServiceConnections {
pub async fn accept_response(&self, thread_id: &str, response: Response) -> AgentResult<()> {
let invitee: Connection<_, _> = self.connections.get(thread_id)?.try_into()?;
let invitee = invitee
.handle_response(&self.profile.inject_wallet(), response, &HttpClient)
.handle_response(&self.profile.inject_wallet(), response)
.await?;

self.connections.insert(thread_id, invitee.into())?;
Expand Down
29 changes: 10 additions & 19 deletions aries_vcx/src/protocols/connection/generic/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use diddoc_legacy::aries::diddoc::AriesDidDoc;
use messages::AriesMessage;

pub use self::thin_state::{State, ThinState};
use super::{trait_bounds::BootstrapDidDoc, wrap_and_send_msg};
use super::trait_bounds::BootstrapDidDoc;
use crate::{
errors::error::{AriesVcxError, AriesVcxErrorKind, VcxResult},
handlers::util::AnyInvitation,
Expand Down Expand Up @@ -172,9 +172,6 @@ impl GenericConnection {
}
}

// todo: GenericConnection deals with States - but we have bunch of useful methods implemented
// on Connection<I, S>, like in thies case, method "encrypt_message" - but we are unable
// to reuse that here and end up reimplementing the same logic. Think about how to solve that.
pub async fn encrypt_message(
&self,
wallet: &Arc<dyn BaseWallet>,
Expand All @@ -197,13 +194,16 @@ impl GenericConnection {
where
T: Transport,
{
let sender_verkey = &self.pairwise_info().pw_vk;
let did_doc = self.their_did_doc().ok_or(AriesVcxError::from_msg(
AriesVcxErrorKind::NotReady,
"No DidDoc present",
))?;

wrap_and_send_msg(wallet, message, sender_verkey, did_doc, transport).await
let msg = self.encrypt_message(wallet, message).await?.0;
let service_endpoint = did_doc.get_endpoint().ok_or_else(|| {
AriesVcxError::from_msg(AriesVcxErrorKind::InvalidUrl, "No URL in DID Doc")
})?;
transport.send_message(msg, service_endpoint).await
}
}

Expand Down Expand Up @@ -448,10 +448,7 @@ mod connection_serde_tests {
.decorators(decorators)
.build();

let con = con
.handle_response(&wallet, response, &MockTransport)
.await
.unwrap();
let con = con.handle_response(&wallet, response).await.unwrap();

con.send_message(&wallet, &con.get_ack().into(), &MockTransport)
.await
Expand Down Expand Up @@ -500,15 +497,9 @@ mod connection_serde_tests {
.decorators(decorators)
.build();

con.handle_request(
&wallet,
request,
new_service_endpoint,
new_routing_keys,
&MockTransport,
)
.await
.unwrap()
con.handle_request(&wallet, request, new_service_endpoint, new_routing_keys)
.await
.unwrap()
}

async fn make_inviter_completed() -> InviterConnection<InviterCompleted> {
Expand Down
33 changes: 7 additions & 26 deletions aries_vcx/src/protocols/connection/invitee/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ use crate::{
errors::error::{AriesVcxError, AriesVcxErrorKind, VcxResult},
handlers::util::{matches_thread_id, AnyInvitation},
protocols::connection::trait_bounds::ThreadId,
transport::Transport,
};

/// Convenience alias
Expand Down Expand Up @@ -169,15 +168,11 @@ impl InviteeConnection<Requested> {
/// * the thread ID of the response does not match the connection thread ID
/// * no recipient verkeys are provided in the response.
/// * decoding the signed response fails
pub async fn handle_response<T>(
pub async fn handle_response(
self,
wallet: &Arc<dyn BaseWallet>,
response: Response,
transport: &T,
) -> VcxResult<InviteeConnection<Completed>>
where
T: Transport,
{
) -> VcxResult<InviteeConnection<Completed>> {
let is_match = matches_thread_id!(response, self.state.thread_id());

if !is_match {
Expand All @@ -197,25 +192,11 @@ impl InviteeConnection<Requested> {
"Cannot handle response: remote verkey not found",
))?;

let did_doc =
match decode_signed_connection_response(wallet, response.content, their_vk).await {
Ok(con_data) => Ok(con_data.did_doc),
Err(err) => {
error!("Request DidDoc validation failed! Sending ProblemReport...");

self.send_problem_report(
wallet,
&err,
self.thread_id(),
&self.state.did_doc,
transport,
)
.await;

Err(err)
}
}?;

// todo: if response decoding fails, we should return error which can be easily
// distinguished by upper layer to possibly send problem report
let did_doc = decode_signed_connection_response(wallet, response.content, their_vk)
.await?
.did_doc;
let state = Completed::new(did_doc, self.state.did_doc, self.state.thread_id, None);

Ok(Connection {
Expand Down
34 changes: 7 additions & 27 deletions aries_vcx/src/protocols/connection/inviter/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -163,17 +163,13 @@ impl InviterConnection<Invited> {
/// invitation
/// * the [`Request`]'s DidDoc is not valid
/// * generating new [`PairwiseInfo`] fails
pub async fn handle_request<T>(
pub async fn handle_request(
self,
wallet: &Arc<dyn BaseWallet>,
request: Request,
new_service_endpoint: Url,
new_routing_keys: Vec<String>,
transport: &T,
) -> VcxResult<InviterConnection<Requested>>
where
T: Transport,
{
) -> VcxResult<InviterConnection<Requested>> {
trace!(
"Connection::process_request >>> request: {:?}, service_endpoint: {}, routing_keys: \
{:?}",
Expand All @@ -186,27 +182,11 @@ impl InviterConnection<Invited> {
// Request
verify_thread_id(self.thread_id(), &request.clone().into())?;

// If the request's DidDoc validation fails, we generate and send a ProblemReport.
// We then return early with the provided error.
if let Err(err) = request.content.connection.did_doc.validate() {
error!("Request DidDoc validation failed! Sending ProblemReport...");

self.send_problem_report(
wallet,
&err,
request
.decorators
.thread
.as_ref()
.map(|t| t.thid.as_str())
.unwrap_or(request.id.as_str()),
&request.content.connection.did_doc,
transport,
)
.await;

Err(err)?;
}
// todo: if request validation fails, we should return error which can be easily
// distinguished by upper layer to possibly send problem report
// Although in this case, since the did_doc itself is invalid, it's questionable if
// it's make any sense for caller to even try that.
request.content.connection.did_doc.validate()?;

// Generate new pairwise info that will be used from this point on
// and incorporate that into the response.
Expand Down
84 changes: 7 additions & 77 deletions aries_vcx/src/protocols/connection/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,8 @@ where
message: &AriesMessage,
) -> VcxResult<EncryptionEnvelope> {
let sender_verkey = &self.pairwise_info().pw_vk;
EncryptionEnvelope::create(wallet, message, Some(sender_verkey), &self.their_did_doc()).await
EncryptionEnvelope::create(wallet, message, Some(sender_verkey), &self.their_did_doc())
.await
}

pub fn remote_did(&self) -> &str {
Expand All @@ -135,63 +136,11 @@ where
where
T: Transport,
{
let sender_verkey = &self.pairwise_info().pw_vk;
let did_doc = self.their_did_doc();
wrap_and_send_msg(wallet, message, sender_verkey, did_doc, transport).await
}
}

impl<I, S> Connection<I, S>
where
S: HandleProblem,
{
fn create_problem_report<E>(&self, err: &E, thread_id: &str) -> ProblemReport
where
E: Error,
{
let content = ProblemReportContent::builder()
.explain(err.to_string())
.build();

let decorators = ProblemReportDecorators::builder()
.thread(Thread::builder().thid(thread_id.to_owned()).build())
.timing(Timing::builder().out_time(Utc::now()).build())
.build();

ProblemReport::builder()
.id(Uuid::new_v4().to_string())
.content(content)
.decorators(decorators)
.build()
}

async fn send_problem_report<E, T>(
&self,
wallet: &Arc<dyn BaseWallet>,
err: &E,
thread_id: &str,
did_doc: &AriesDidDoc,
transport: &T,
) where
E: Error,
T: Transport,
{
let sender_verkey = &self.pairwise_info().pw_vk;
let problem_report = self.create_problem_report(err, thread_id);
let res = wrap_and_send_msg(
wallet,
&problem_report.into(),
sender_verkey,
did_doc,
transport,
)
.await;

if let Err(e) = res {
trace!("Error encountered when sending ProblemReport: {}", e);
} else {
info!("Error report sent!");
}
let msg = self.encrypt_message(wallet, message).await?.0;
let service_endpoint = self.their_did_doc().get_endpoint().ok_or_else(|| {
AriesVcxError::from_msg(AriesVcxErrorKind::InvalidUrl, "No URL in DID Doc")
})?;
transport.send_message(msg, service_endpoint).await
}
}

Expand All @@ -207,22 +156,3 @@ where
self.state.handle_disclose(disclose)
}
}

pub(crate) async fn wrap_and_send_msg<T>(
wallet: &Arc<dyn BaseWallet>,
message: &AriesMessage,
sender_verkey: &str,
did_doc: &AriesDidDoc,
transport: &T,
) -> VcxResult<()>
where
T: Transport,
{
let env = EncryptionEnvelope::create(wallet, message, Some(sender_verkey), did_doc).await?;
let msg = env.0;
let service_endpoint = did_doc.get_endpoint().ok_or_else(|| {
AriesVcxError::from_msg(AriesVcxErrorKind::InvalidUrl, "No URL in DID Doc")
})?; // This, like many other things, shouldn't clone...

transport.send_message(msg, service_endpoint).await
}
5 changes: 2 additions & 3 deletions aries_vcx/tests/utils/scenarios/connection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,15 +58,14 @@ async fn establish_connection_from_invite(
&faber.profile.inject_wallet(),
request,
"http://dummy.org".parse().unwrap(),
vec![],
&DummyHttpClient,
vec![]
)
.await
.unwrap();
let response = inviter.get_connection_response_msg();

let invitee = invitee
.handle_response(&alice.profile.inject_wallet(), response, &DummyHttpClient)
.handle_response(&alice.profile.inject_wallet(), response)
.await
.unwrap();
let ack = invitee.get_ack();
Expand Down
5 changes: 1 addition & 4 deletions libvcx_core/src/api_vcx/api_handle/connection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,6 @@ pub async fn process_request(
LibvcxError::from_msg(LibvcxErrorKind::InvalidUrl, err.to_string())
})?,
routing_keys,
&HttpClient,
)
.await?;

Expand All @@ -300,9 +299,7 @@ pub async fn process_response(handle: u32, response: &str) -> LibvcxResult<()> {

let con = get_cloned_connection(&handle)?;
let response = deserialize(response)?;
let con = con
.handle_response(&get_main_wallet()?, response, &HttpClient)
.await?;
let con = con.handle_response(&get_main_wallet()?, response).await?;

insert_connection(handle, con)
}
Expand Down
10 changes: 2 additions & 8 deletions uniffi_aries_vcx/core/src/handlers/connection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -147,13 +147,7 @@ impl Connection {

block_on(async {
let new_conn = connection
.handle_request(
&profile.inner.inject_wallet(),
request,
url,
routing_keys,
&HttpClient,
)
.handle_request(&profile.inner.inject_wallet(), request, url, routing_keys)
.await?;

*handler = VcxGenericConnection::from(new_conn);
Expand All @@ -178,7 +172,7 @@ impl Connection {

block_on(async {
let new_conn = connection
.handle_response(&profile.inner.inject_wallet(), response, &HttpClient)
.handle_response(&profile.inner.inject_wallet(), response)
.await?;
*handler = VcxGenericConnection::from(new_conn);

Expand Down

0 comments on commit 97a5b15

Please sign in to comment.