diff --git a/aries_vcx/src/handlers/issuance/holder.rs b/aries_vcx/src/handlers/issuance/holder.rs index 00c56d2ed6..662e700b27 100644 --- a/aries_vcx/src/handlers/issuance/holder.rs +++ b/aries_vcx/src/handlers/issuance/holder.rs @@ -1,22 +1,19 @@ -use std::collections::HashMap; +use std::sync::Arc; +use aries_vcx_core::anoncreds::base_anoncreds::BaseAnonCreds; +use aries_vcx_core::ledger::base_ledger::AnoncredsLedgerRead; +use aries_vcx_core::wallet::base_wallet::BaseWallet; use messages::msg_fields::protocols::cred_issuance::issue_credential::IssueCredential; use messages::msg_fields::protocols::cred_issuance::offer_credential::OfferCredential; use messages::msg_fields::protocols::cred_issuance::propose_credential::ProposeCredential; +use messages::msg_fields::protocols::cred_issuance::CredentialIssuance; use messages::msg_fields::protocols::revocation::revoke::Revoke; use messages::AriesMessage; -use std::sync::Arc; - -use agency_client::agency_client::AgencyClient; -use aries_vcx_core::anoncreds::base_anoncreds::BaseAnonCreds; -use aries_vcx_core::ledger::base_ledger::AnoncredsLedgerRead; -use aries_vcx_core::wallet::base_wallet::BaseWallet; use crate::common::credentials::get_cred_rev_id; use crate::errors::error::prelude::*; use crate::handlers::connection::mediated_connection::MediatedConnection; use crate::handlers::revocation_notification::receiver::RevocationNotificationReceiver; -use crate::protocols::issuance::actions::CredentialIssuanceAction; use crate::protocols::issuance::holder::state_machine::{HolderSM, HolderState}; use crate::protocols::SendClosure; @@ -98,10 +95,6 @@ impl Holder { self.holder_sm.is_terminal_state() } - pub fn find_message_to_handle(&self, messages: HashMap) -> Option<(String, AriesMessage)> { - self.holder_sm.find_message_to_handle(messages) - } - pub fn get_state(&self) -> HolderState { self.holder_sm.get_state() } @@ -193,178 +186,31 @@ impl Holder { } } - pub async fn step( + pub async fn process_aries_msg( &mut self, ledger: &Arc, anoncreds: &Arc, - message: CredentialIssuanceAction, + message: AriesMessage, send_message: Option, ) -> VcxResult<()> { - self.holder_sm = self - .holder_sm - .clone() - .handle_message(ledger, anoncreds, message, send_message) - .await?; + let holder_sm = match message { + AriesMessage::CredentialIssuance(CredentialIssuance::OfferCredential(offer)) => { + self.holder_sm.clone().receive_offer(offer)? + } + AriesMessage::CredentialIssuance(CredentialIssuance::IssueCredential(credential)) => { + let send_message = send_message.ok_or(AriesVcxError::from_msg( + AriesVcxErrorKind::InvalidState, + "Attempted to call undefined send_message callback", + ))?; + self.holder_sm + .clone() + .receive_credential(ledger, anoncreds, credential, send_message) + .await? + } + AriesMessage::ReportProblem(report) => self.holder_sm.clone().receive_problem_report(report)?, + _ => self.holder_sm.clone(), + }; + self.holder_sm = holder_sm; Ok(()) } - - pub async fn update_state( - &mut self, - ledger: &Arc, - anoncreds: &Arc, - wallet: &Arc, - agency_client: &AgencyClient, - connection: &MediatedConnection, - ) -> VcxResult { - trace!("Holder::update_state >>>"); - if self.is_terminal_state() { - return Ok(self.get_state()); - } - let send_message = connection.send_message_closure(Arc::clone(wallet)).await?; - - let messages = connection.get_messages(agency_client).await?; - if let Some((uid, msg)) = self.find_message_to_handle(messages) { - self.step(ledger, anoncreds, msg.into(), Some(send_message)).await?; - connection.update_message_status(&uid, agency_client).await?; - } - Ok(self.get_state()) - } -} - -pub mod test_utils { - use agency_client::agency_client::AgencyClient; - use messages::msg_fields::protocols::cred_issuance::CredentialIssuance; - use messages::AriesMessage; - - use crate::errors::error::prelude::*; - use crate::handlers::connection::mediated_connection::MediatedConnection; - - pub async fn get_credential_offer_messages( - agency_client: &AgencyClient, - connection: &MediatedConnection, - ) -> VcxResult { - let credential_offers: Vec = connection - .get_messages(agency_client) - .await? - .into_iter() - .filter_map(|(_, a2a_message)| match a2a_message { - AriesMessage::CredentialIssuance(CredentialIssuance::OfferCredential(_)) => Some(a2a_message), - _ => None, - }) - .collect(); - - Ok(json!(credential_offers).to_string()) - } } - -// #[cfg(test)] -// pub mod unit_tests { - -// use crate::common::test_utils::mock_profile; -// use crate::utils::devsetup::SetupMocks; -// use messages::protocols::issuance::credential::test_utils::_credential; -// use messages::protocols::issuance::credential_offer::test_utils::_credential_offer; -// use messages::protocols::issuance::credential_proposal::test_utils::_credential_proposal_data; -// use messages::protocols::issuance::credential_request::test_utils::_my_pw_did; - -// use super::*; - -// pub fn _send_message() -> Option { -// Some(Box::new(|_: A2AMessage| Box::pin(async { VcxResult::Ok(()) }))) -// } - -// fn _holder_from_offer() -> Holder { -// Holder::create_from_offer("test_source_id", _credential_offer()).unwrap() -// } - -// fn _holder() -> Holder { -// Holder::create("test_source_id").unwrap() -// } - -// impl Holder { -// async fn to_finished_state(mut self) -> Holder { -// self.step( -// &mock_profile(), -// CredentialIssuanceAction::CredentialProposalSend(_credential_proposal_data()), -// _send_message(), -// ) -// .await -// .unwrap(); -// self.step( -// &mock_profile(), -// CredentialIssuanceAction::CredentialOffer(_credential_offer()), -// _send_message(), -// ) -// .await -// .unwrap(); -// self.step( -// &mock_profile(), -// CredentialIssuanceAction::CredentialRequestSend(_my_pw_did()), -// _send_message(), -// ) -// .await -// .unwrap(); -// self.step( -// &mock_profile(), -// CredentialIssuanceAction::Credential(_credential()), -// _send_message(), -// ) -// .await -// .unwrap(); -// self -// } -// } - -// #[tokio::test] -// async fn exchange_credential_from_proposal_without_negotiation() { -// let _setup = SetupMocks::init(); -// let holder = _holder().to_finished_state().await; -// assert_eq!(HolderState::Finished, holder.get_state()); -// } - -// #[tokio::test] -// async fn exchange_credential_from_proposal_with_negotiation() { -// let _setup = SetupMocks::init(); -// let mut holder = _holder(); -// assert_eq!(HolderState::Initial, holder.get_state()); - -// holder -// .send_proposal(_credential_proposal_data(), _send_message().unwrap()) -// .await -// .unwrap(); -// assert_eq!(HolderState::ProposalSent, holder.get_state()); - -// let messages = map!( -// "key_1".to_string() => A2AMessage::CredentialOffer(_credential_offer()) -// ); -// let (_, msg) = holder.find_message_to_handle(messages).unwrap(); -// holder.step(&mock_profile(), msg.into(), _send_message()).await.unwrap(); -// assert_eq!(HolderState::OfferReceived, holder.get_state()); - -// holder -// .send_proposal(_credential_proposal_data(), _send_message().unwrap()) -// .await -// .unwrap(); -// assert_eq!(HolderState::ProposalSent, holder.get_state()); - -// let messages = map!( -// "key_1".to_string() => A2AMessage::CredentialOffer(_credential_offer()) -// ); -// let (_, msg) = holder.find_message_to_handle(messages).unwrap(); -// holder.step(&mock_profile(), msg.into(), _send_message()).await.unwrap(); -// assert_eq!(HolderState::OfferReceived, holder.get_state()); - -// holder -// .send_request(&mock_profile(), _my_pw_did(), _send_message().unwrap()) -// .await -// .unwrap(); -// assert_eq!(HolderState::RequestSent, holder.get_state()); - -// let messages = map!( -// "key_1".to_string() => A2AMessage::Credential(_credential()) -// ); -// let (_, msg) = holder.find_message_to_handle(messages).unwrap(); -// holder.step(&mock_profile(), msg.into(), _send_message()).await.unwrap(); -// assert_eq!(HolderState::Finished, holder.get_state()); -// } -// } diff --git a/aries_vcx/src/handlers/issuance/issuer.rs b/aries_vcx/src/handlers/issuance/issuer.rs index 650e889210..5723abcb23 100644 --- a/aries_vcx/src/handlers/issuance/issuer.rs +++ b/aries_vcx/src/handlers/issuance/issuer.rs @@ -5,20 +5,19 @@ use messages::misc::MimeType; use messages::msg_fields::protocols::cred_issuance::ack::AckCredential; use messages::msg_fields::protocols::cred_issuance::propose_credential::ProposeCredential; use messages::msg_fields::protocols::cred_issuance::request_credential::RequestCredential; -use messages::msg_fields::protocols::cred_issuance::{CredentialAttr, CredentialPreview}; +use messages::msg_fields::protocols::cred_issuance::{CredentialAttr, CredentialIssuance, CredentialPreview}; use messages::AriesMessage; use std::sync::Arc; -use agency_client::agency_client::AgencyClient; use aries_vcx_core::anoncreds::base_anoncreds::BaseAnonCreds; use aries_vcx_core::ledger::base_ledger::AnoncredsLedgerRead; -use aries_vcx_core::wallet::base_wallet::BaseWallet; +use messages::msg_fields::protocols::notification::Notification; +use messages::msg_fields::protocols::report_problem::ProblemReport; +use messages::msg_parts::MsgParts; use crate::errors::error::prelude::*; -use crate::handlers::connection::mediated_connection::MediatedConnection; use crate::handlers::revocation_notification::sender::RevocationNotificationSender; use crate::handlers::util::OfferInfo; -use crate::protocols::issuance::actions::CredentialIssuanceAction; use crate::protocols::issuance::issuer::state_machine::{IssuerSM, IssuerState, RevocationInfoV1}; use crate::protocols::revocation_notification::sender::state_machine::SenderConfigBuilder; use crate::protocols::SendClosure; @@ -223,10 +222,6 @@ impl Issuer { self.issuer_sm.is_terminal_state() } - pub fn find_message_to_handle(&self, messages: HashMap) -> Option<(String, AriesMessage)> { - self.issuer_sm.find_message_to_handle(messages) - } - pub fn get_revocation_id(&self) -> VcxResult { self.issuer_sm .get_revocation_info() @@ -291,290 +286,60 @@ impl Issuer { self.issuer_sm.is_revoked(ledger).await } - pub async fn step( - &mut self, - anoncreds: &Arc, - message: CredentialIssuanceAction, - send_message: Option, - ) -> VcxResult<()> { - self.issuer_sm = self - .issuer_sm - .clone() - .handle_message(anoncreds, message, send_message) - .await?; + pub async fn receive_proposal(&mut self, proposal: ProposeCredential) -> VcxResult<()> { + self.issuer_sm = self.issuer_sm.clone().receive_proposal(proposal)?; Ok(()) } - pub async fn update_state( - &mut self, - wallet: &Arc, - anoncreds: &Arc, - agency_client: &AgencyClient, - connection: &MediatedConnection, - ) -> VcxResult { - trace!("Issuer::update_state >>>"); - if self.is_terminal_state() { - return Ok(self.get_state()); - } - let send_message = connection.send_message_closure(Arc::clone(wallet)).await?; - let messages = connection.get_messages(agency_client).await?; - if let Some((uid, msg)) = self.find_message_to_handle(messages) { - self.step(anoncreds, msg.into(), Some(send_message)).await?; - connection.update_message_status(&uid, agency_client).await?; - } - Ok(self.get_state()) + pub async fn receive_request(&mut self, request: RequestCredential) -> VcxResult<()> { + self.issuer_sm = self.issuer_sm.clone().receive_request(request)?; + Ok(()) } -} -pub mod test_utils { - use agency_client::agency_client::AgencyClient; - use messages::msg_fields::protocols::cred_issuance::propose_credential::ProposeCredential; - use messages::msg_fields::protocols::cred_issuance::CredentialIssuance; - use messages::AriesMessage; - - use crate::errors::error::prelude::*; - use crate::handlers::connection::mediated_connection::MediatedConnection; - - pub async fn get_credential_proposal_messages( - agency_client: &AgencyClient, - connection: &MediatedConnection, - ) -> VcxResult> { - let credential_proposals: Vec<(String, ProposeCredential)> = connection - .get_messages(agency_client) - .await? - .into_iter() - .filter_map(|(uid, message)| match message { - AriesMessage::CredentialIssuance(CredentialIssuance::ProposeCredential(proposal)) => { - Some((uid, proposal)) - } - _ => None, - }) - .collect(); - - Ok(credential_proposals) + pub async fn receive_ack(&mut self, ack: AckCredential) -> VcxResult<()> { + self.issuer_sm = self.issuer_sm.clone().receive_ack(ack)?; + Ok(()) } -} -// #[cfg(test)] -// pub mod unit_tests { -// use messages::msg_fields::protocols::cred_issuance::CredentialIssuance; - -// use crate::common::test_utils::mock_profile; -// use crate::protocols::issuance::issuer::state_machine::unit_tests::_send_message; -// use crate::utils::devsetup::SetupMocks; - -// use super::*; - -// fn _cred_data() -> String { -// json!({"name": "alice"}).to_string() -// } - -// fn _issuer() -> Issuer { -// Issuer::create("test_source_id").unwrap() -// } - -// fn _issuer_revokable_from_proposal() -> Issuer { -// Issuer::create_from_proposal("test_source_id", &_credential_proposal()).unwrap() -// } - -// fn _send_message_but_fail() -> Option { -// Some(Box::new(|_: AriesMessage| { -// Box::pin(async { Err(AriesVcxError::from_msg(AriesVcxErrorKind::IOError, "Mocked error")) }) -// })) -// } - -// impl Issuer { -// async fn to_offer_sent_state_unrevokable(mut self) -> Issuer { -// self.build_credential_offer_msg(&mock_profile(), _offer_info_unrevokable(), None) -// .await -// .unwrap(); -// self.mark_credential_offer_msg_sent().unwrap(); -// self -// } - -// async fn to_request_received_state(mut self) -> Issuer { -// self = self.to_offer_sent_state_unrevokable().await; -// self.step( -// &mock_profile(), -// CredentialIssuanceAction::CredentialRequest(_credential_request()), -// _send_message(), -// ) -// .await -// .unwrap(); -// self -// } - -// async fn to_finished_state_unrevokable(mut self) -> Issuer { -// self = self.to_request_received_state().await; -// self.step( -// &mock_profile(), -// CredentialIssuanceAction::CredentialSend(), -// _send_message(), -// ) -// .await -// .unwrap(); -// self.step( -// &mock_profile(), -// CredentialIssuanceAction::CredentialAck(_ack()), -// _send_message(), -// ) -// .await -// .unwrap(); -// self -// } -// } - -// #[tokio::test] -// async fn test_build_credential_preview() { -// fn verify_preview(preview: CredentialPreview) { -// let value_name = preview -// .attributes -// .clone() -// .into_iter() -// .find(|x| x.name == "name") -// .unwrap(); -// let value_age = preview -// .attributes -// .clone() -// .into_iter() -// .find(|x| x.name == "age") -// .unwrap(); -// assert_eq!(value_name.name, "name"); -// assert_eq!(value_name.value, "Alice"); -// assert_eq!(value_age.name, "age"); -// assert_eq!(value_age.value, "123"); -// } - -// let _setup = SetupMocks::init(); -// let input = json!({"name":"Alice","age":"123"}).to_string(); -// let preview = _build_credential_preview(&input).unwrap(); -// verify_preview(preview); - -// let input = json!([ -// {"name":"name", "value": "Alice"}, -// {"name": "age", "value": "123"} -// ]) -// .to_string(); -// let preview = _build_credential_preview(&input).unwrap(); -// verify_preview(preview); -// } - -// #[tokio::test] -// async fn test_cant_revoke_without_revocation_details() { -// let _setup = SetupMocks::init(); -// let issuer = _issuer().to_finished_state_unrevokable().await; -// assert_eq!(IssuerState::Finished, issuer.get_state()); -// let revoc_result = issuer.revoke_credential_local(&mock_profile()).await; -// assert_eq!(revoc_result.unwrap_err().kind(), AriesVcxErrorKind::InvalidState) -// } - -// #[tokio::test] -// async fn test_credential_can_be_resent_after_failure() { -// let _setup = SetupMocks::init(); -// let mut issuer = _issuer().to_request_received_state().await; -// assert_eq!(IssuerState::RequestReceived, issuer.get_state()); - -// let send_result = issuer -// .send_credential(&mock_profile(), _send_message_but_fail().unwrap()) -// .await; -// assert_eq!(send_result.is_err(), true); -// assert_eq!(IssuerState::RequestReceived, issuer.get_state()); - -// let send_result = issuer.send_credential(&mock_profile(), _send_message().unwrap()).await; -// assert_eq!(send_result.is_err(), false); -// assert_eq!(IssuerState::CredentialSent, issuer.get_state()); -// } - -// #[tokio::test] -// async fn exchange_credential_from_proposal_without_negotiation() { -// let _setup = SetupMocks::init(); -// let mut issuer = _issuer_revokable_from_proposal(); -// assert_eq!(IssuerState::ProposalReceived, issuer.get_state()); - -// issuer -// .build_credential_offer_msg(&mock_profile(), _offer_info(), Some("comment".into())) -// .await -// .unwrap(); -// issuer.send_credential_offer(_send_message().unwrap()).await.unwrap(); -// assert_eq!(IssuerState::OfferSent, issuer.get_state()); - -// let messages = map!( -// "key_1".to_string() => AriesMessage::CredentialIssuance(CredentialIssuance::RequestCredential(_credential_request())) -// ); -// let (_, msg) = issuer.find_message_to_handle(messages).unwrap(); -// issuer.step(&mock_profile(), msg.into(), _send_message()).await.unwrap(); -// assert_eq!(IssuerState::RequestReceived, issuer.get_state()); - -// issuer -// .send_credential(&mock_profile(), _send_message().unwrap()) -// .await -// .unwrap(); -// assert_eq!(IssuerState::CredentialSent, issuer.get_state()); - -// let messages = map!( -// "key_1".to_string() => AriesMessage::CredentialIssuance(CredentialIssuance::Ack(_ack())) -// ); -// let (_, msg) = issuer.find_message_to_handle(messages).unwrap(); -// issuer.step(&mock_profile(), msg.into(), _send_message()).await.unwrap(); -// assert_eq!(IssuerState::Finished, issuer.get_state()); -// } - -// #[tokio::test] -// async fn exchange_credential_from_proposal_with_negotiation() { -// let _setup = SetupMocks::init(); -// let mut issuer = _issuer_revokable_from_proposal(); -// assert_eq!(IssuerState::ProposalReceived, issuer.get_state()); - -// issuer -// .build_credential_offer_msg(&mock_profile(), _offer_info(), Some("comment".into())) -// .await -// .unwrap(); -// issuer.send_credential_offer(_send_message().unwrap()).await.unwrap(); -// assert_eq!(IssuerState::OfferSent, issuer.get_state()); - -// let messages = map!( -// "key_1".to_string() => AriesMessage::CredentialIssuance(CredentialIssuance::ProposeCredential(_credential_proposal()))() -// ); -// let (_, msg) = issuer.find_message_to_handle(messages).unwrap(); -// issuer.step(&mock_profile(), msg.into(), _send_message()).await.unwrap(); -// assert_eq!(IssuerState::ProposalReceived, issuer.get_state()); - -// issuer -// .build_credential_offer_msg(&mock_profile(), _offer_info(), Some("comment".into())) -// .await -// .unwrap(); -// issuer.send_credential_offer(_send_message().unwrap()).await.unwrap(); -// assert_eq!(IssuerState::OfferSent, issuer.get_state()); - -// let messages = map!( -// "key_1".to_string() => AriesMessage::CredentialIssuance(CredentialIssuance::RequestCredential(_credential_request())) -// ); -// let (_, msg) = issuer.find_message_to_handle(messages).unwrap(); -// issuer.step(&mock_profile(), msg.into(), _send_message()).await.unwrap(); -// assert_eq!(IssuerState::RequestReceived, issuer.get_state()); - -// issuer -// .send_credential(&mock_profile(), _send_message().unwrap()) -// .await -// .unwrap(); -// assert_eq!(IssuerState::CredentialSent, issuer.get_state()); - -// let messages = map!( -// "key_1".to_string() => AriesMessage::CredentialIssuance(CredentialIssuance::Ack(_ack())) -// ); -// let (_, msg) = issuer.find_message_to_handle(messages).unwrap(); -// issuer.step(&mock_profile(), msg.into(), _send_message()).await.unwrap(); -// assert_eq!(IssuerState::Finished, issuer.get_state()); -// } - -// #[tokio::test] -// async fn issuer_cant_send_offer_twice() { -// let _setup = SetupMocks::init(); -// let mut issuer = _issuer().to_offer_sent_state_unrevokable().await; -// assert_eq!(IssuerState::OfferSent, issuer.get_state()); - -// let res = issuer.send_credential_offer(_send_message_but_fail().unwrap()).await; -// assert_eq!(IssuerState::OfferSent, issuer.get_state()); -// assert!(res.is_err()); -// } -// } + pub async fn receive_problem_report(&mut self, problem_report: ProblemReport) -> VcxResult<()> { + self.issuer_sm = self.issuer_sm.clone().receive_problem_report(problem_report)?; + Ok(()) + } + + // todo: will ultimately end up in generic SM layer + pub async fn process_aries_msg(&mut self, msg: AriesMessage) -> VcxResult<()> { + let issuer_sm = match msg { + AriesMessage::CredentialIssuance(CredentialIssuance::ProposeCredential(proposal)) => { + self.issuer_sm.clone().receive_proposal(proposal)? + } + AriesMessage::CredentialIssuance(CredentialIssuance::RequestCredential(request)) => { + self.issuer_sm.clone().receive_request(request)? + } + AriesMessage::CredentialIssuance(CredentialIssuance::Ack(ack)) => { + self.issuer_sm.clone().receive_ack(ack)? + } + AriesMessage::ReportProblem(report) => self.issuer_sm.clone().receive_problem_report(report)?, + AriesMessage::Notification(Notification::ProblemReport(report)) => { + let MsgParts { + id, + content, + decorators, + } = report; + let report = ProblemReport::with_decorators(id, content.0, decorators); + self.issuer_sm.clone().receive_problem_report(report)? + } + AriesMessage::CredentialIssuance(CredentialIssuance::ProblemReport(report)) => { + let MsgParts { + id, + content, + decorators, + } = report; + let report = ProblemReport::with_decorators(id, content.0, decorators); + self.issuer_sm.clone().receive_problem_report(report)? + } + _ => self.issuer_sm.clone(), + }; + self.issuer_sm = issuer_sm; + Ok(()) + } +} diff --git a/aries_vcx/src/handlers/issuance/mediated_holder.rs b/aries_vcx/src/handlers/issuance/mediated_holder.rs new file mode 100644 index 0000000000..af892739ea --- /dev/null +++ b/aries_vcx/src/handlers/issuance/mediated_holder.rs @@ -0,0 +1,53 @@ +use std::collections::HashMap; + +use messages::msg_fields::protocols::cred_issuance::CredentialIssuance; +use messages::msg_fields::protocols::notification::Notification; +use messages::AriesMessage; + +use crate::handlers::issuance::holder::Holder; +use crate::handlers::util::{matches_opt_thread_id, matches_thread_id}; +use crate::protocols::issuance::holder::state_machine::HolderState; + +#[allow(clippy::unwrap_used)] +pub fn holder_find_message_to_handle( + sm: &Holder, + messages: HashMap, +) -> Option<(String, AriesMessage)> { + trace!("holder_find_message_to_handle >>>"); + for (uid, message) in messages { + match sm.get_state() { + HolderState::ProposalSent => { + if let AriesMessage::CredentialIssuance(CredentialIssuance::OfferCredential(offer)) = &message { + if matches_opt_thread_id!(offer, sm.get_thread_id().unwrap().as_str()) { + return Some((uid, message)); + } + } + } + HolderState::RequestSent => match &message { + AriesMessage::CredentialIssuance(CredentialIssuance::IssueCredential(credential)) => { + if matches_thread_id!(credential, sm.get_thread_id().unwrap().as_str()) { + return Some((uid, message)); + } + } + AriesMessage::CredentialIssuance(CredentialIssuance::ProblemReport(problem_report)) => { + if matches_opt_thread_id!(problem_report, sm.get_thread_id().unwrap().as_str()) { + return Some((uid, message)); + } + } + AriesMessage::ReportProblem(problem_report) => { + if matches_opt_thread_id!(problem_report, sm.get_thread_id().unwrap().as_str()) { + return Some((uid, message)); + } + } + AriesMessage::Notification(Notification::ProblemReport(msg)) => { + if matches_opt_thread_id!(msg, sm.get_thread_id().unwrap().as_str()) { + return Some((uid, message)); + } + } + _ => {} + }, + _ => {} + }; + } + None +} diff --git a/aries_vcx/src/handlers/issuance/mediated_issuer.rs b/aries_vcx/src/handlers/issuance/mediated_issuer.rs new file mode 100644 index 0000000000..a819d97e22 --- /dev/null +++ b/aries_vcx/src/handlers/issuance/mediated_issuer.rs @@ -0,0 +1,69 @@ +use std::collections::HashMap; + +use messages::msg_fields::protocols::cred_issuance::CredentialIssuance; +use messages::msg_fields::protocols::notification::Notification; +use messages::AriesMessage; + +use crate::handlers::issuance::issuer::Issuer; +use crate::handlers::util::{matches_opt_thread_id, matches_thread_id}; +use crate::protocols::issuance::issuer::state_machine::IssuerState; + +#[allow(clippy::unwrap_used)] +pub fn issuer_find_message_to_handle( + sm: &Issuer, + messages: HashMap, +) -> Option<(String, AriesMessage)> { + trace!( + "issuer_find_messages_to_handle >>> messages: {:?}, state: {:?}", + messages, + sm + ); + + for (uid, message) in messages { + match sm.get_state() { + IssuerState::Initial => { + if let AriesMessage::CredentialIssuance(CredentialIssuance::ProposeCredential(_)) = &message { + return Some((uid, message)); + } + } + IssuerState::OfferSent => match &message { + AriesMessage::CredentialIssuance(CredentialIssuance::RequestCredential(msg)) => { + if matches_opt_thread_id!(msg, sm.get_thread_id().unwrap().as_str()) { + return Some((uid, message)); + } + } + AriesMessage::CredentialIssuance(CredentialIssuance::ProposeCredential(msg)) => { + if matches_opt_thread_id!(msg, sm.get_thread_id().unwrap().as_str()) { + return Some((uid, message)); + } + } + AriesMessage::ReportProblem(msg) => { + if matches_opt_thread_id!(msg, sm.get_thread_id().unwrap().as_str()) { + return Some((uid, message)); + } + } + _ => {} + }, + IssuerState::CredentialSent => match &message { + AriesMessage::CredentialIssuance(CredentialIssuance::Ack(msg)) => { + if matches_thread_id!(msg, sm.get_thread_id().unwrap().as_str()) { + return Some((uid, message)); + } + } + AriesMessage::Notification(Notification::Ack(msg)) => { + if matches_thread_id!(msg, sm.get_thread_id().unwrap().as_str()) { + return Some((uid, message)); + } + } + AriesMessage::ReportProblem(msg) => { + if matches_opt_thread_id!(msg, sm.get_thread_id().unwrap().as_str()) { + return Some((uid, message)); + } + } + _ => {} + }, + _ => {} + }; + } + None +} diff --git a/aries_vcx/src/handlers/issuance/mod.rs b/aries_vcx/src/handlers/issuance/mod.rs index edadb99165..4472ba3799 100644 --- a/aries_vcx/src/handlers/issuance/mod.rs +++ b/aries_vcx/src/handlers/issuance/mod.rs @@ -1,2 +1,4 @@ pub mod holder; pub mod issuer; +pub mod mediated_holder; +pub mod mediated_issuer; diff --git a/aries_vcx/src/handlers/proof_presentation/mediated_prover.rs b/aries_vcx/src/handlers/proof_presentation/mediated_prover.rs new file mode 100644 index 0000000000..40826e1582 --- /dev/null +++ b/aries_vcx/src/handlers/proof_presentation/mediated_prover.rs @@ -0,0 +1,69 @@ +use std::collections::HashMap; + +use messages::msg_fields::protocols::notification::Notification; +use messages::msg_fields::protocols::present_proof::PresentProof; +use messages::AriesMessage; + +use crate::handlers::proof_presentation::prover::Prover; +use crate::handlers::util::{matches_opt_thread_id, matches_thread_id}; +use crate::protocols::proof_presentation::prover::state_machine::ProverState; + +#[allow(clippy::unwrap_used)] +pub fn prover_find_message_to_handle( + sm: &Prover, + messages: HashMap, +) -> Option<(String, AriesMessage)> { + trace!("prover_find_message_to_handle >>> messages: {:?}", messages); + for (uid, message) in messages { + match sm.get_state() { + ProverState::PresentationProposalSent => match &message { + AriesMessage::ReportProblem(msg) => { + if matches_opt_thread_id!(msg, sm.get_thread_id().unwrap().as_str()) { + return Some((uid, message)); + } + } + AriesMessage::Notification(Notification::ProblemReport(msg)) => { + if matches_opt_thread_id!(msg, sm.get_thread_id().unwrap().as_str()) { + return Some((uid, message)); + } + } + AriesMessage::PresentProof(PresentProof::RequestPresentation(msg)) => { + if matches_opt_thread_id!(msg, sm.get_thread_id().unwrap().as_str()) { + return Some((uid, message)); + } + } + _ => {} + }, + ProverState::PresentationSent => match &message { + AriesMessage::Notification(Notification::Ack(msg)) => { + if matches_thread_id!(msg, sm.get_thread_id().unwrap().as_str()) { + return Some((uid, message)); + } + } + AriesMessage::PresentProof(PresentProof::Ack(msg)) => { + if matches_thread_id!(msg, sm.get_thread_id().unwrap().as_str()) { + return Some((uid, message)); + } + } + AriesMessage::ReportProblem(msg) => { + if matches_opt_thread_id!(msg, sm.get_thread_id().unwrap().as_str()) { + return Some((uid, message)); + } + } + AriesMessage::Notification(Notification::ProblemReport(msg)) => { + if matches_opt_thread_id!(msg, sm.get_thread_id().unwrap().as_str()) { + return Some((uid, message)); + } + } + AriesMessage::PresentProof(PresentProof::ProblemReport(msg)) => { + if matches_opt_thread_id!(msg, sm.get_thread_id().unwrap().as_str()) { + return Some((uid, message)); + } + } + _ => {} + }, + _ => {} + }; + } + None +} diff --git a/aries_vcx/src/handlers/proof_presentation/mediated_verifier.rs b/aries_vcx/src/handlers/proof_presentation/mediated_verifier.rs new file mode 100644 index 0000000000..58d4bc8e71 --- /dev/null +++ b/aries_vcx/src/handlers/proof_presentation/mediated_verifier.rs @@ -0,0 +1,49 @@ +use std::collections::HashMap; + +use messages::msg_fields::protocols::present_proof::PresentProof; +use messages::AriesMessage; + +use crate::handlers::proof_presentation::verifier::Verifier; +use crate::handlers::util::{matches_opt_thread_id, matches_thread_id}; +use crate::protocols::proof_presentation::verifier::state_machine::VerifierState; + +#[allow(clippy::unwrap_used)] +pub fn verifier_find_message_to_handle( + sm: &Verifier, + messages: HashMap, +) -> Option<(String, AriesMessage)> { + trace!("verifier_find_message_to_handle >>> messages: {:?}", messages); + for (uid, message) in messages { + match sm.get_state() { + VerifierState::Initial => match &message { + AriesMessage::PresentProof(PresentProof::ProposePresentation(_)) => { + return Some((uid, message)); + } + AriesMessage::PresentProof(PresentProof::RequestPresentation(_)) => { + return Some((uid, message)); + } + _ => {} + }, + VerifierState::PresentationRequestSent => match &message { + AriesMessage::PresentProof(PresentProof::Presentation(presentation)) => { + if matches_thread_id!(presentation, sm.get_thread_id().unwrap().as_str()) { + return Some((uid, message)); + } + } + AriesMessage::PresentProof(PresentProof::ProposePresentation(proposal)) => { + if matches_opt_thread_id!(proposal, sm.get_thread_id().unwrap().as_str()) { + return Some((uid, message)); + } + } + AriesMessage::ReportProblem(problem_report) => { + if matches_opt_thread_id!(problem_report, sm.get_thread_id().unwrap().as_str()) { + return Some((uid, message)); + } + } + _ => {} + }, + _ => {} + }; + } + None +} diff --git a/aries_vcx/src/handlers/proof_presentation/mod.rs b/aries_vcx/src/handlers/proof_presentation/mod.rs index de46b54d40..815a46f87b 100644 --- a/aries_vcx/src/handlers/proof_presentation/mod.rs +++ b/aries_vcx/src/handlers/proof_presentation/mod.rs @@ -1,3 +1,5 @@ +pub mod mediated_prover; +pub mod mediated_verifier; pub mod prover; pub mod types; pub mod verifier; diff --git a/aries_vcx/src/handlers/proof_presentation/prover.rs b/aries_vcx/src/handlers/proof_presentation/prover.rs index 0dbd0aa8f0..ea078fbf12 100644 --- a/aries_vcx/src/handlers/proof_presentation/prover.rs +++ b/aries_vcx/src/handlers/proof_presentation/prover.rs @@ -1,21 +1,20 @@ use std::collections::HashMap; - use std::sync::Arc; -use agency_client::agency_client::AgencyClient; use aries_vcx_core::anoncreds::base_anoncreds::BaseAnonCreds; use aries_vcx_core::ledger::base_ledger::AnoncredsLedgerRead; -use aries_vcx_core::wallet::base_wallet::BaseWallet; +use messages::msg_fields::protocols::notification::Notification; use messages::msg_fields::protocols::present_proof::ack::AckPresentation; use messages::msg_fields::protocols::present_proof::present::Presentation; use messages::msg_fields::protocols::present_proof::propose::PresentationPreview; use messages::msg_fields::protocols::present_proof::request::RequestPresentation; +use messages::msg_fields::protocols::present_proof::PresentProof; +use messages::msg_fields::protocols::report_problem::ProblemReport; +use messages::msg_parts::MsgParts; use messages::AriesMessage; use crate::errors::error::prelude::*; -use crate::handlers::connection::mediated_connection::MediatedConnection; use crate::handlers::util::{get_attach_as_string, PresentationProposalData}; -use crate::protocols::proof_presentation::prover::messages::ProverMessages; use crate::protocols::proof_presentation::prover::state_machine::{ProverSM, ProverState}; use crate::protocols::SendClosure; @@ -123,21 +122,6 @@ impl Prover { self.prover_sm.progressable_by_message() } - pub fn find_message_to_handle(&self, messages: HashMap) -> Option<(String, AriesMessage)> { - self.prover_sm.find_message_to_handle(messages) - } - - pub async fn handle_message( - &mut self, - ledger: &Arc, - anoncreds: &Arc, - message: ProverMessages, - send_message: Option, - ) -> VcxResult<()> { - trace!("Prover::handle_message >>> message: {:?}", message); - self.step(ledger, anoncreds, message, send_message).await - } - pub fn presentation_request_data(&self) -> VcxResult { Ok(get_attach_as_string!( &self @@ -174,18 +158,36 @@ impl Prover { self.prover_sm.get_thread_id() } - pub async fn step( - &mut self, - ledger: &Arc, - anoncreds: &Arc, - message: ProverMessages, - send_message: Option, - ) -> VcxResult<()> { - self.prover_sm = self - .prover_sm - .clone() - .step(ledger, anoncreds, message, send_message) - .await?; + pub async fn process_aries_msg(&mut self, message: AriesMessage) -> VcxResult<()> { + let prover_sm = match message { + AriesMessage::PresentProof(PresentProof::RequestPresentation(request)) => { + self.prover_sm.clone().receive_presentation_request(request)? + } + AriesMessage::PresentProof(PresentProof::Ack(ack)) => { + self.prover_sm.clone().receive_presentation_ack(ack)? + } + AriesMessage::ReportProblem(report) => self.prover_sm.clone().receive_presentation_reject(report)?, + AriesMessage::Notification(Notification::ProblemReport(report)) => { + let MsgParts { + id, + content, + decorators, + } = report; + let report = ProblemReport::with_decorators(id, content.0, decorators); + self.prover_sm.clone().receive_presentation_reject(report)? + } + AriesMessage::PresentProof(PresentProof::ProblemReport(report)) => { + let MsgParts { + id, + content, + decorators, + } = report; + let report = ProblemReport::with_decorators(id, content.0, decorators); + self.prover_sm.clone().receive_presentation_reject(report)? + } + _ => self.prover_sm.clone(), + }; + self.prover_sm = prover_sm; Ok(()) } @@ -234,52 +236,4 @@ impl Prover { }; Ok(()) } - - pub async fn update_state( - &mut self, - ledger: &Arc, - anoncreds: &Arc, - wallet: &Arc, - agency_client: &AgencyClient, - connection: &MediatedConnection, - ) -> VcxResult { - trace!("Prover::update_state >>> "); - if !self.progressable_by_message() { - return Ok(self.get_state()); - } - let send_message = connection.send_message_closure(Arc::clone(wallet)).await?; - - let messages = connection.get_messages(agency_client).await?; - if let Some((uid, msg)) = self.find_message_to_handle(messages) { - self.step(ledger, anoncreds, msg.into(), Some(send_message)).await?; - connection.update_message_status(&uid, agency_client).await?; - } - Ok(self.get_state()) - } -} - -pub mod test_utils { - use agency_client::agency_client::AgencyClient; - use messages::msg_fields::protocols::present_proof::PresentProof; - use messages::AriesMessage; - - use crate::errors::error::prelude::*; - use crate::handlers::connection::mediated_connection::MediatedConnection; - - pub async fn get_proof_request_messages( - agency_client: &AgencyClient, - connection: &MediatedConnection, - ) -> VcxResult { - let presentation_requests: Vec = connection - .get_messages(agency_client) - .await? - .into_iter() - .filter_map(|(_, message)| match message { - AriesMessage::PresentProof(PresentProof::RequestPresentation(_)) => Some(message), - _ => None, - }) - .collect(); - - Ok(json!(presentation_requests).to_string()) - } } diff --git a/aries_vcx/src/handlers/proof_presentation/verifier.rs b/aries_vcx/src/handlers/proof_presentation/verifier.rs index 74478697a7..cac03326df 100644 --- a/aries_vcx/src/handlers/proof_presentation/verifier.rs +++ b/aries_vcx/src/handlers/proof_presentation/verifier.rs @@ -1,21 +1,19 @@ -use std::collections::HashMap; - use std::sync::Arc; -use agency_client::agency_client::AgencyClient; use aries_vcx_core::anoncreds::base_anoncreds::BaseAnonCreds; use aries_vcx_core::ledger::base_ledger::AnoncredsLedgerRead; -use aries_vcx_core::wallet::base_wallet::BaseWallet; +use messages::msg_fields::protocols::notification::Notification; use messages::msg_fields::protocols::present_proof::present::Presentation; use messages::msg_fields::protocols::present_proof::propose::ProposePresentation; use messages::msg_fields::protocols::present_proof::request::RequestPresentation; +use messages::msg_fields::protocols::present_proof::PresentProof; +use messages::msg_fields::protocols::report_problem::ProblemReport; +use messages::msg_parts::MsgParts; use messages::AriesMessage; use crate::common::proofs::proof_request::PresentationRequestData; use crate::errors::error::prelude::*; -use crate::handlers::connection::mediated_connection::MediatedConnection; use crate::handlers::util::get_attach_as_string; -use crate::protocols::proof_presentation::verifier::messages::VerifierMessages; use crate::protocols::proof_presentation::verifier::state_machine::{VerifierSM, VerifierState}; use crate::protocols::proof_presentation::verifier::verification_status::PresentationVerificationStatus; use crate::protocols::SendClosure; @@ -63,17 +61,6 @@ impl Verifier { self.verifier_sm.get_state() } - pub async fn handle_message( - &mut self, - ledger: &Arc, - anoncreds: &Arc, - message: VerifierMessages, - send_message: Option, - ) -> VcxResult<()> { - trace!("Verifier::handle_message >>> message: {:?}", message); - self.step(ledger, anoncreds, message, send_message).await - } - pub async fn send_presentation_request(&mut self, send_message: SendClosure) -> VcxResult<()> { if self.verifier_sm.get_state() == VerifierState::PresentationRequestSet { let offer = self.verifier_sm.presentation_request_msg()?.into(); @@ -163,18 +150,51 @@ impl Verifier { Ok(self.verifier_sm.thread_id()) } - pub async fn step( + pub async fn process_aries_msg( &mut self, ledger: &Arc, anoncreds: &Arc, - message: VerifierMessages, + message: AriesMessage, send_message: Option, ) -> VcxResult<()> { - self.verifier_sm = self - .verifier_sm - .clone() - .step(ledger, anoncreds, message, send_message) - .await?; + let verifier_sm = match message { + AriesMessage::PresentProof(PresentProof::ProposePresentation(proposal)) => { + self.verifier_sm.clone().receive_presentation_proposal(proposal)? + } + AriesMessage::PresentProof(PresentProof::Presentation(presentation)) => { + let send_message = send_message.ok_or(AriesVcxError::from_msg( + AriesVcxErrorKind::InvalidState, + "Attempted to call undefined send_message callback", + ))?; + self.verifier_sm + .clone() + .verify_presentation(ledger, anoncreds, presentation, send_message) + .await? + } + AriesMessage::ReportProblem(report) => { + self.verifier_sm.clone().receive_presentation_request_reject(report)? + } + AriesMessage::Notification(Notification::ProblemReport(report)) => { + let MsgParts { + id, + content, + decorators, + } = report; + let report = ProblemReport::with_decorators(id, content.0, decorators); + self.verifier_sm.clone().receive_presentation_request_reject(report)? + } + AriesMessage::PresentProof(PresentProof::ProblemReport(report)) => { + let MsgParts { + id, + content, + decorators, + } = report; + let report = ProblemReport::with_decorators(id, content.0, decorators); + self.verifier_sm.clone().receive_presentation_request_reject(report)? + } + _ => self.verifier_sm.clone(), + }; + self.verifier_sm = verifier_sm; Ok(()) } @@ -182,10 +202,6 @@ impl Verifier { self.verifier_sm.progressable_by_message() } - pub fn find_message_to_handle(&self, messages: HashMap) -> Option<(String, AriesMessage)> { - self.verifier_sm.find_message_to_handle(messages) - } - pub async fn decline_presentation_proposal<'a>( &'a mut self, send_message: SendClosure, @@ -199,84 +215,4 @@ impl Verifier { .await?; Ok(()) } - - pub async fn update_state( - &mut self, - wallet: &Arc, - ledger: &Arc, - anoncreds: &Arc, - agency_client: &AgencyClient, - connection: &MediatedConnection, - ) -> VcxResult { - trace!("Verifier::update_state >>> "); - if !self.progressable_by_message() { - return Ok(self.get_state()); - } - let send_message = connection.send_message_closure(Arc::clone(wallet)).await?; - - let messages = connection.get_messages(agency_client).await?; - if let Some((uid, msg)) = self.find_message_to_handle(messages) { - self.step(ledger, anoncreds, msg.into(), Some(send_message)).await?; - connection.update_message_status(&uid, agency_client).await?; - } - Ok(self.get_state()) - } } - -// #[cfg(test)] -// mod unit_tests { -// use crate::core::profile::vdrtools_profile::VdrtoolsProfile; -// use crate::utils::constants::{REQUESTED_ATTRS, REQUESTED_PREDICATES}; -// use crate::utils::devsetup::*; -// use crate::utils::mockdata::mock_settings::MockBuilder; -// use aries_vcx_core::{INVALID_POOL_HANDLE, INVALID_WALLET_HANDLE}; -// use messages::a2a::A2AMessage; -// use messages::protocols::proof_presentation::presentation::test_utils::_presentation; - -// use super::*; - -// async fn _verifier() -> Verifier { -// let presentation_request_data = PresentationRequestData::create(&_dummy_profile(), "1") -// .await -// .unwrap() -// .set_requested_attributes_as_string(REQUESTED_ATTRS.to_owned()) -// .unwrap() -// .set_requested_predicates_as_string(REQUESTED_PREDICATES.to_owned()) -// .unwrap() -// .set_not_revoked_interval(r#"{"support_revocation":false}"#.to_string()) -// .unwrap(); -// Verifier::create_from_request("1".to_string(), &presentation_request_data).unwrap() -// } - -// pub fn _send_message() -> Option { -// Some(Box::new(|_: A2AMessage| Box::pin(async { VcxResult::Ok(()) }))) -// } - -// impl Verifier { -// async fn to_presentation_request_sent_state(&mut self) { -// self.send_presentation_request(_send_message().unwrap()).await.unwrap(); -// } - -// async fn to_finished_state(&mut self) { -// self.to_presentation_request_sent_state().await; -// self.step( -// &_dummy_profile(), -// VerifierMessages::VerifyPresentation(_presentation()), -// _send_message(), -// ) -// .await -// .unwrap(); -// } -// } - -// #[tokio::test] -// async fn test_get_presentation() { -// let _setup = SetupMocks::init(); -// let _mock_builder = MockBuilder::init().set_mock_result_for_validate_indy_proof(Ok(true)); -// let mut verifier = _verifier().await; -// verifier.to_finished_state().await; -// let presentation = verifier.get_presentation_msg().unwrap(); -// assert_eq!(presentation, _presentation()); -// assert_eq!(verifier.get_state(), VerifierState::Finished); -// } -// } diff --git a/aries_vcx/src/handlers/util.rs b/aries_vcx/src/handlers/util.rs index 24a84261b2..f384690f10 100644 --- a/aries_vcx/src/handlers/util.rs +++ b/aries_vcx/src/handlers/util.rs @@ -71,12 +71,18 @@ macro_rules! make_attach_from_str { }}; } +use crate::global::settings; pub(crate) use get_attach_as_string; pub(crate) use make_attach_from_str; pub(crate) use matches_opt_thread_id; pub(crate) use matches_thread_id; pub fn verify_thread_id(thread_id: &str, message: &AriesMessage) -> VcxResult<()> { + // todo: ultimately remove this - improve tests + // libvcx_core unit tests are passing in hardcoded message which have mismatching thid + if settings::indy_mocks_enabled() { + return Ok(()); + } let is_match = match message { AriesMessage::BasicMessage(msg) => matches_opt_thread_id!(msg, thread_id), AriesMessage::Connection(Connection::Invitation(Invitation::Public(msg))) => msg.id == thread_id, diff --git a/aries_vcx/src/protocols/issuance/actions.rs b/aries_vcx/src/protocols/issuance/actions.rs deleted file mode 100644 index 643aaae3c7..0000000000 --- a/aries_vcx/src/protocols/issuance/actions.rs +++ /dev/null @@ -1,91 +0,0 @@ -use messages::msg_fields::protocols::cred_issuance::ack::{AckCredential, AckCredentialContent}; -use messages::msg_fields::protocols::cred_issuance::issue_credential::IssueCredential; -use messages::msg_fields::protocols::cred_issuance::offer_credential::OfferCredential; -use messages::msg_fields::protocols::cred_issuance::propose_credential::ProposeCredential; -use messages::msg_fields::protocols::cred_issuance::request_credential::RequestCredential; -use messages::msg_fields::protocols::cred_issuance::CredentialIssuance; -use messages::msg_fields::protocols::notification::Notification; -use messages::msg_fields::protocols::report_problem::ProblemReport; -use messages::msg_parts::MsgParts; -use messages::AriesMessage; - -use crate::handlers::util::{matches_opt_thread_id, matches_thread_id}; - -type OptionalComment = Option; - -#[derive(Debug, Clone)] -pub enum CredentialIssuanceAction { - CredentialSend(), - CredentialProposalSend(ProposeCredential), - CredentialProposal(ProposeCredential), - CredentialOffer(OfferCredential), - CredentialOfferReject(OptionalComment), - CredentialRequestSend(String), - CredentialRequest(RequestCredential), - Credential(IssueCredential), - CredentialAck(AckCredential), - ProblemReport(ProblemReport), - Unknown, -} - -impl CredentialIssuanceAction { - pub fn thread_id_matches(&self, thread_id: &str) -> bool { - match self { - Self::CredentialOffer(msg) => matches_opt_thread_id!(msg, thread_id), - Self::CredentialProposal(msg) => matches_opt_thread_id!(msg, thread_id), - Self::Credential(msg) => matches_thread_id!(msg, thread_id), - _ => true, // doesn't seem right... - } - } -} - -impl From for CredentialIssuanceAction { - fn from(msg: AriesMessage) -> Self { - match msg { - AriesMessage::CredentialIssuance(CredentialIssuance::ProposeCredential(proposal)) => { - CredentialIssuanceAction::CredentialProposal(proposal) - } - AriesMessage::CredentialIssuance(CredentialIssuance::OfferCredential(offer)) => { - CredentialIssuanceAction::CredentialOffer(offer) - } - AriesMessage::CredentialIssuance(CredentialIssuance::RequestCredential(request)) => { - CredentialIssuanceAction::CredentialRequest(request) - } - AriesMessage::CredentialIssuance(CredentialIssuance::IssueCredential(credential)) => { - CredentialIssuanceAction::Credential(credential) - } - AriesMessage::CredentialIssuance(CredentialIssuance::Ack(ack)) => { - CredentialIssuanceAction::CredentialAck(ack) - } - AriesMessage::Notification(Notification::Ack(ack)) => { - let MsgParts { - id, - content, - decorators, - } = ack; - let ack = AckCredential::with_decorators(id, AckCredentialContent(content), decorators); - CredentialIssuanceAction::CredentialAck(ack) - } - AriesMessage::ReportProblem(report) => CredentialIssuanceAction::ProblemReport(report), - AriesMessage::Notification(Notification::ProblemReport(report)) => { - let MsgParts { - id, - content, - decorators, - } = report; - let report = ProblemReport::with_decorators(id, content.0, decorators); - CredentialIssuanceAction::ProblemReport(report) - } - AriesMessage::CredentialIssuance(CredentialIssuance::ProblemReport(report)) => { - let MsgParts { - id, - content, - decorators, - } = report; - let report = ProblemReport::with_decorators(id, content.0, decorators); - CredentialIssuanceAction::ProblemReport(report) - } - _ => CredentialIssuanceAction::Unknown, - } - } -} diff --git a/aries_vcx/src/protocols/issuance/holder/state_machine.rs b/aries_vcx/src/protocols/issuance/holder/state_machine.rs index 70bafe343e..55bd861c8b 100644 --- a/aries_vcx/src/protocols/issuance/holder/state_machine.rs +++ b/aries_vcx/src/protocols/issuance/holder/state_machine.rs @@ -16,7 +16,6 @@ use messages::msg_fields::protocols::cred_issuance::request_credential::{ }; use messages::msg_fields::protocols::cred_issuance::CredentialIssuance; use messages::msg_fields::protocols::notification::ack::{AckDecorators, AckStatus}; -use messages::msg_fields::protocols::notification::Notification; use messages::msg_fields::protocols::report_problem::ProblemReport; use messages::AriesMessage; use uuid::Uuid; @@ -24,17 +23,13 @@ use uuid::Uuid; use crate::common::credentials::{get_cred_rev_id, is_cred_revoked}; use crate::errors::error::prelude::*; use crate::global::settings; -use crate::handlers::util::{ - get_attach_as_string, make_attach_from_str, matches_opt_thread_id, matches_thread_id, AttachmentId, Status, -}; +use crate::handlers::util::{get_attach_as_string, make_attach_from_str, verify_thread_id, AttachmentId, Status}; use crate::protocols::common::build_problem_report_msg; -use crate::protocols::issuance::actions::CredentialIssuanceAction; use crate::protocols::issuance::holder::states::finished::FinishedHolderState; use crate::protocols::issuance::holder::states::initial::InitialHolderState; use crate::protocols::issuance::holder::states::offer_received::OfferReceivedState; use crate::protocols::issuance::holder::states::proposal_sent::ProposalSentState; use crate::protocols::issuance::holder::states::request_sent::RequestSentState; -use crate::protocols::issuance::verify_thread_id; use crate::protocols::SendClosure; #[derive(Serialize, Deserialize, Debug, Clone)] @@ -58,9 +53,9 @@ pub enum HolderState { #[derive(Serialize, Deserialize, Debug, Clone)] pub struct HolderSM { - state: HolderFullState, - source_id: String, - thread_id: String, + pub(crate) state: HolderFullState, + pub(crate) source_id: String, + pub(crate) thread_id: String, } impl fmt::Display for HolderFullState { @@ -152,111 +147,20 @@ impl HolderSM { } } - pub fn find_message_to_handle(&self, messages: HashMap) -> Option<(String, AriesMessage)> { - trace!( - "Holder::find_message_to_handle >>> messages: {:?}, state: {:?}", - messages, - self.state - ); - for (uid, message) in messages { - match self.state { - HolderFullState::ProposalSent(_) => { - if let AriesMessage::CredentialIssuance(CredentialIssuance::OfferCredential(offer)) = &message { - if matches_opt_thread_id!(offer, self.thread_id.as_str()) { - return Some((uid, message)); - } - } - } - HolderFullState::RequestSent(_) => match &message { - AriesMessage::CredentialIssuance(CredentialIssuance::IssueCredential(credential)) => { - if matches_thread_id!(credential, self.thread_id.as_str()) { - return Some((uid, message)); - } - } - AriesMessage::CredentialIssuance(CredentialIssuance::ProblemReport(problem_report)) => { - if matches_opt_thread_id!(problem_report, self.thread_id.as_str()) { - return Some((uid, message)); - } - } - AriesMessage::ReportProblem(problem_report) => { - if matches_opt_thread_id!(problem_report, self.thread_id.as_str()) { - return Some((uid, message)); - } - } - AriesMessage::Notification(Notification::ProblemReport(msg)) => { - if matches_opt_thread_id!(msg, self.thread_id.as_str()) { - return Some((uid, message)); - } - } - _ => {} - }, - _ => {} - }; - } - None - } - - pub async fn handle_message( - self, - ledger: &Arc, - anoncreds: &Arc, - cim: CredentialIssuanceAction, - send_message: Option, - ) -> VcxResult { - trace!("Holder::handle_message >>> cim: {:?}, state: {:?}", cim, self.state); - let thread_id = self.get_thread_id()?; - verify_thread_id(&thread_id, &cim)?; - let holder_sm = match cim { - CredentialIssuanceAction::CredentialProposalSend(proposal_data) => { - let send_message = send_message.ok_or(AriesVcxError::from_msg( - AriesVcxErrorKind::InvalidState, - "Attempted to call undefined send_message callback", - ))?; - self.send_proposal(proposal_data, send_message).await? - } - CredentialIssuanceAction::CredentialOffer(offer) => self.receive_offer(offer)?, - CredentialIssuanceAction::CredentialRequestSend(my_pw_did) => { - let send_message = send_message.ok_or(AriesVcxError::from_msg( - AriesVcxErrorKind::InvalidState, - "Attempted to call undefined send_message callback", - ))?; - self.send_request(ledger, anoncreds, my_pw_did, send_message).await? - } - CredentialIssuanceAction::CredentialOfferReject(comment) => { - let send_message = send_message.ok_or(AriesVcxError::from_msg( - AriesVcxErrorKind::InvalidState, - "Attempted to call undefined send_message callback", - ))?; - self.decline_offer(comment, send_message).await? - } - CredentialIssuanceAction::Credential(credential) => { - let send_message = send_message.ok_or(AriesVcxError::from_msg( - AriesVcxErrorKind::InvalidState, - "Attempted to call undefined send_message callback", - ))?; - self.receive_credential(ledger, anoncreds, credential, send_message) - .await? - } - CredentialIssuanceAction::ProblemReport(problem_report) => self.receive_problem_report(problem_report)?, - _ => self, - }; - Ok(holder_sm) - } - - pub async fn send_proposal(self, proposal_data: ProposeCredential, send_message: SendClosure) -> VcxResult { + pub async fn send_proposal(self, proposal: ProposeCredential, send_message: SendClosure) -> VcxResult { verify_thread_id( &self.thread_id, - &CredentialIssuanceAction::CredentialProposalSend(proposal_data.clone()), + &AriesMessage::CredentialIssuance(CredentialIssuance::ProposeCredential(proposal.clone())), )?; let state = match self.state { HolderFullState::Initial(_) => { - let mut proposal = proposal_data; + let mut proposal = proposal; proposal.id = self.thread_id.clone(); send_message(proposal.clone().into()).await?; HolderFullState::ProposalSent(ProposalSentState::new(proposal)) } HolderFullState::OfferReceived(_) => { - let mut proposal = proposal_data; + let mut proposal = proposal; proposal.id = self.thread_id.clone(); send_message(proposal.clone().into()).await?; HolderFullState::ProposalSent(ProposalSentState::new(proposal)) @@ -272,7 +176,7 @@ impl HolderSM { pub fn receive_offer(self, offer: OfferCredential) -> VcxResult { verify_thread_id( &self.thread_id, - &CredentialIssuanceAction::CredentialOffer(offer.clone()), + &AriesMessage::CredentialIssuance(CredentialIssuance::OfferCredential(offer.clone())), )?; let state = match self.state { HolderFullState::ProposalSent(_) => HolderFullState::OfferReceived(OfferReceivedState::new(offer)), @@ -670,601 +574,3 @@ async fn _make_credential_request( let credential_request_msg = build_credential_request_msg(req, &thread_id)?; Ok((credential_request_msg, req_meta, cred_def_json)) } - -// #[cfg(test)] -// mod test { -// use messages::protocols::issuance::credential::test_utils::_credential; -// use messages::protocols::issuance::credential_offer::test_utils::_credential_offer; -// use messages::protocols::issuance::credential_proposal::test_utils::_credential_proposal; -// use messages::protocols::issuance::credential_request::test_utils::{_credential_request, _my_pw_did}; -// use messages::protocols::issuance::test_utils::{_credential_ack, _problem_report}; - -// use crate::common::test_utils::mock_profile; -// use crate::test::source_id; -// use crate::utils::constants; -// use crate::utils::devsetup::SetupMocks; - -// use super::*; - -// fn _holder_sm() -> HolderSM { -// HolderSM::from_offer(_credential_offer(), source_id()) -// } - -// pub fn _send_message() -> Option { -// Some(Box::new(|_: A2AMessage| Box::pin(async { VcxResult::Ok(()) }))) -// } - -// impl HolderSM { -// async fn to_request_sent_state(mut self) -> HolderSM { -// self = self -// .handle_message( -// &mock_profile(), -// CredentialIssuanceAction::CredentialRequestSend(_my_pw_did()), -// _send_message(), -// ) -// .await -// .unwrap(); -// self -// } - -// async fn to_finished_state(mut self) -> HolderSM { -// self = self -// .handle_message( -// &mock_profile(), -// CredentialIssuanceAction::CredentialRequestSend(_my_pw_did()), -// _send_message(), -// ) -// .await -// .unwrap(); -// self = self -// .handle_message( -// &mock_profile(), -// CredentialIssuanceAction::Credential(_credential()), -// _send_message(), -// ) -// .await -// .unwrap(); -// self -// } -// } - -// mod new { -// use super::*; - -// #[test] -// fn test_holder_new() { -// let _setup = SetupMocks::init(); - -// let holder_sm = _holder_sm(); - -// assert_match!(HolderFullState::OfferReceived(_), holder_sm.state); -// assert_eq!(source_id(), holder_sm.get_source_id()); -// } -// } - -// mod build_messages { -// use messages::a2a::MessageId; - -// use crate::protocols::issuance::holder::state_machine::{build_credential_ack, build_credential_request_msg}; -// use crate::utils::devsetup::{was_in_past, SetupMocks}; - -// #[test] -// fn test_holder_build_credential_request_msg() { -// let _setup = SetupMocks::init(); -// let msg = build_credential_request_msg("{}".into(), "12345").unwrap(); - -// assert_eq!(msg.id, MessageId::default()); -// assert_eq!(msg.thread.unwrap().thid.unwrap(), "12345"); -// assert!(was_in_past( -// &msg.timing.unwrap().out_time.unwrap(), -// chrono::Duration::milliseconds(100), -// ) -// .unwrap()); -// } - -// #[tokio::test] -// async fn test_holder_build_credential_ack() { -// let _setup = SetupMocks::init(); - -// let msg = build_credential_ack("12345"); - -// assert_eq!(msg.id, MessageId::default()); -// assert_eq!(msg.thread.thid.unwrap(), "12345"); -// assert!(was_in_past( -// &msg.timing.unwrap().out_time.unwrap(), -// chrono::Duration::milliseconds(100), -// ) -// .unwrap()); -// } -// } - -// mod step { -// use super::*; - -// #[test] -// fn test_holder_init() { -// let _setup = SetupMocks::init(); - -// let holder_sm = _holder_sm(); -// assert_match!(HolderFullState::OfferReceived(_), holder_sm.state); -// } - -// #[tokio::test] -// async fn test_issuer_handle_credential_request_sent_message_from_offer_received_state() { -// let _setup = SetupMocks::init(); - -// let mut holder_sm = _holder_sm(); -// holder_sm = holder_sm -// .handle_message( -// &mock_profile(), -// CredentialIssuanceAction::CredentialRequestSend(_my_pw_did()), -// _send_message(), -// ) -// .await -// .unwrap(); - -// assert_match!(HolderFullState::RequestSent(_), holder_sm.state); -// } - -// #[tokio::test] -// async fn test_issuer_handle_credential_request_sent_message_from_offer_received_state_for_invalid_offer() { -// let _setup = SetupMocks::init(); - -// let credential_offer = CredentialOffer::create() -// .set_offers_attach(r#"{"credential offer": {}}"#) -// .unwrap(); - -// let mut holder_sm = HolderSM::from_offer(credential_offer, "test source".to_string()); -// holder_sm = holder_sm -// .handle_message( -// &mock_profile(), -// CredentialIssuanceAction::CredentialRequestSend(_my_pw_did()), -// _send_message(), -// ) -// .await -// .unwrap(); - -// assert_match!(HolderFullState::Finished(_), holder_sm.state); -// assert_eq!( -// Status::Failed(ProblemReport::default()).code(), -// holder_sm.credential_status() -// ); -// } - -// #[tokio::test] -// async fn test_issuer_handle_other_messages_from_offer_received_state() { -// let _setup = SetupMocks::init(); - -// let mut holder_sm = _holder_sm(); -// holder_sm = holder_sm -// .handle_message( -// &mock_profile(), -// CredentialIssuanceAction::CredentialSend(), -// _send_message(), -// ) -// .await -// .unwrap(); -// assert_match!(HolderFullState::OfferReceived(_), holder_sm.state); - -// holder_sm = holder_sm -// .handle_message( -// &mock_profile(), -// CredentialIssuanceAction::ProblemReport(_problem_report()), -// _send_message(), -// ) -// .await -// .unwrap(); -// assert_match!(HolderFullState::OfferReceived(_), holder_sm.state); -// } - -// #[tokio::test] -// async fn test_issuer_handle_credential_message_from_request_sent_state() { -// let _setup = SetupMocks::init(); - -// let mut holder_sm = _holder_sm(); -// holder_sm = holder_sm -// .handle_message( -// &mock_profile(), -// CredentialIssuanceAction::CredentialRequestSend(_my_pw_did()), -// _send_message(), -// ) -// .await -// .unwrap(); -// holder_sm = holder_sm -// .handle_message( -// &mock_profile(), -// CredentialIssuanceAction::Credential(_credential()), -// _send_message(), -// ) -// .await -// .unwrap(); - -// assert_match!(HolderFullState::Finished(_), holder_sm.state); -// assert_eq!(Status::Success.code(), holder_sm.credential_status()); -// } - -// #[tokio::test] -// async fn test_issuer_handle_invalid_credential_message_from_request_sent_state() { -// let _setup = SetupMocks::init(); - -// let mut holder_sm = _holder_sm(); -// holder_sm = holder_sm -// .handle_message( -// &mock_profile(), -// CredentialIssuanceAction::CredentialRequestSend(_my_pw_did()), -// _send_message(), -// ) -// .await -// .unwrap(); -// holder_sm = holder_sm -// .handle_message( -// &mock_profile(), -// CredentialIssuanceAction::Credential(Credential::create()), -// _send_message(), -// ) -// .await -// .unwrap(); - -// assert_match!(HolderFullState::Finished(_), holder_sm.state); -// assert_eq!( -// Status::Failed(ProblemReport::default()).code(), -// holder_sm.credential_status() -// ); -// } - -// #[tokio::test] -// async fn test_issuer_handle_problem_report_from_request_sent_state() { -// let _setup = SetupMocks::init(); - -// let mut holder_sm = _holder_sm(); -// holder_sm = holder_sm -// .handle_message( -// &mock_profile(), -// CredentialIssuanceAction::CredentialRequestSend(_my_pw_did()), -// _send_message(), -// ) -// .await -// .unwrap(); -// holder_sm = holder_sm -// .handle_message( -// &mock_profile(), -// CredentialIssuanceAction::ProblemReport(_problem_report()), -// _send_message(), -// ) -// .await -// .unwrap(); - -// assert_match!(HolderFullState::Finished(_), holder_sm.state); -// assert_eq!( -// Status::Failed(ProblemReport::default()).code(), -// holder_sm.credential_status() -// ); -// } - -// #[tokio::test] -// async fn test_issuer_handle_other_messages_from_request_sent_state() { -// let _setup = SetupMocks::init(); - -// let mut holder_sm = _holder_sm(); -// holder_sm = holder_sm -// .handle_message( -// &mock_profile(), -// CredentialIssuanceAction::CredentialRequestSend(_my_pw_did()), -// _send_message(), -// ) -// .await -// .unwrap(); - -// holder_sm = holder_sm -// .handle_message( -// &mock_profile(), -// CredentialIssuanceAction::CredentialOffer(_credential_offer()), -// _send_message(), -// ) -// .await -// .unwrap(); -// assert_match!(HolderFullState::RequestSent(_), holder_sm.state); - -// holder_sm = holder_sm -// .handle_message( -// &mock_profile(), -// CredentialIssuanceAction::CredentialAck(_credential_ack()), -// _send_message(), -// ) -// .await -// .unwrap(); -// assert_match!(HolderFullState::RequestSent(_), holder_sm.state); -// } - -// #[tokio::test] -// async fn test_issuer_handle_message_from_finished_state() { -// let _setup = SetupMocks::init(); - -// let mut holder_sm = _holder_sm(); -// holder_sm = holder_sm -// .handle_message( -// &mock_profile(), -// CredentialIssuanceAction::CredentialRequestSend(_my_pw_did()), -// _send_message(), -// ) -// .await -// .unwrap(); -// assert_match!(HolderFullState::RequestSent(_), holder_sm.state); - -// holder_sm = holder_sm -// .handle_message( -// &mock_profile(), -// CredentialIssuanceAction::Credential(_credential()), -// _send_message(), -// ) -// .await -// .unwrap(); -// assert_match!(HolderFullState::Finished(_), holder_sm.state); - -// holder_sm = holder_sm -// .handle_message( -// &mock_profile(), -// CredentialIssuanceAction::CredentialOffer(_credential_offer()), -// _send_message(), -// ) -// .await -// .unwrap(); -// assert_match!(HolderFullState::Finished(_), holder_sm.state); - -// holder_sm = holder_sm -// .handle_message( -// &mock_profile(), -// CredentialIssuanceAction::Credential(_credential()), -// _send_message(), -// ) -// .await -// .unwrap(); -// assert_match!(HolderFullState::Finished(_), holder_sm.state); - -// holder_sm = holder_sm -// .handle_message( -// &mock_profile(), -// CredentialIssuanceAction::CredentialAck(_credential_ack()), -// _send_message(), -// ) -// .await -// .unwrap(); -// assert_match!(HolderFullState::Finished(_), holder_sm.state); -// } -// } - -// mod find_message_to_handle { -// use super::*; - -// #[test] -// fn test_holder_find_message_to_handle_from_offer_received_state() { -// let _setup = SetupMocks::init(); - -// let holder = _holder_sm(); - -// // No messages - -// { -// let messages = map!( -// "key_1".to_string() => A2AMessage::CredentialOffer(_credential_offer()), -// "key_2".to_string() => A2AMessage::CredentialRequest(_credential_request()), -// "key_3".to_string() => A2AMessage::CredentialProposal(_credential_proposal()), -// "key_4".to_string() => A2AMessage::Credential(_credential()), -// "key_5".to_string() => A2AMessage::CredentialAck(_credential_ack()), -// "key_6".to_string() => A2AMessage::CommonProblemReport(_problem_report()) -// ); - -// assert!(holder.find_message_to_handle(messages).is_none()); -// } -// } - -// #[tokio::test] -// async fn test_holder_find_message_to_handle_from_request_sent_state() { -// let _setup = SetupMocks::init(); - -// let holder = _holder_sm().to_request_sent_state().await; - -// // CredentialAck -// { -// let messages = map!( -// "key_1".to_string() => A2AMessage::CredentialOffer(_credential_offer()), -// "key_2".to_string() => A2AMessage::CredentialRequest(_credential_request()), -// "key_3".to_string() => A2AMessage::CredentialProposal(_credential_proposal()), -// "key_4".to_string() => A2AMessage::Credential(_credential()) -// ); - -// let (uid, message) = holder.find_message_to_handle(messages).unwrap(); -// assert_eq!("key_4", uid); -// assert_match!(A2AMessage::Credential(_), message); -// } - -// // Problem Report -// { -// let messages = map!( -// "key_1".to_string() => A2AMessage::CredentialOffer(_credential_offer()), -// "key_2".to_string() => A2AMessage::CredentialRequest(_credential_request()), -// "key_3".to_string() => A2AMessage::CredentialProposal(_credential_proposal()), -// "key_4".to_string() => A2AMessage::CredentialAck(_credential_ack()), -// "key_5".to_string() => A2AMessage::CommonProblemReport(_problem_report()) -// ); - -// let (uid, message) = holder.find_message_to_handle(messages).unwrap(); -// assert_eq!("key_5", uid); -// assert_match!(A2AMessage::CommonProblemReport(_), message); -// } - -// // No messages for different Thread ID -// { -// let messages = map!( -// "key_1".to_string() => A2AMessage::CredentialOffer(_credential_offer().set_thread_id("")), -// "key_2".to_string() => A2AMessage::CredentialRequest(_credential_request().set_thread_id("")), -// "key_3".to_string() => A2AMessage::CredentialProposal(_credential_proposal().set_thread_id("")), -// "key_4".to_string() => A2AMessage::Credential(_credential().set_thread_id("")), -// "key_5".to_string() => A2AMessage::CredentialAck(_credential_ack().set_thread_id("")), -// "key_6".to_string() => A2AMessage::CommonProblemReport(_problem_report().set_thread_id("")) -// ); - -// assert!(holder.find_message_to_handle(messages).is_none()); -// } - -// // No messages -// { -// let messages = map!( -// "key_1".to_string() => A2AMessage::CredentialOffer(_credential_offer()), -// "key_2".to_string() => A2AMessage::CredentialRequest(_credential_request()), -// "key_3".to_string() => A2AMessage::CredentialProposal(_credential_proposal()) -// ); - -// assert!(holder.find_message_to_handle(messages).is_none()); -// } -// } - -// #[tokio::test] -// async fn test_holder_find_message_to_handle_from_finished_state() { -// let _setup = SetupMocks::init(); - -// let holder = _holder_sm().to_finished_state().await; - -// // No messages -// { -// let messages = map!( -// "key_1".to_string() => A2AMessage::CredentialOffer(_credential_offer()), -// "key_2".to_string() => A2AMessage::CredentialRequest(_credential_request()), -// "key_3".to_string() => A2AMessage::CredentialProposal(_credential_proposal()), -// "key_4".to_string() => A2AMessage::Credential(_credential()), -// "key_5".to_string() => A2AMessage::CredentialAck(_credential_ack()), -// "key_6".to_string() => A2AMessage::CommonProblemReport(_problem_report()) -// ); - -// assert!(holder.find_message_to_handle(messages).is_none()); -// } -// } -// } - -// mod get_state { -// use super::*; - -// #[tokio::test] -// async fn test_get_state() { -// let _setup = SetupMocks::init(); - -// assert_eq!(HolderState::OfferReceived, _holder_sm().get_state()); -// assert_eq!( -// HolderState::RequestSent, -// _holder_sm().to_request_sent_state().await.get_state() -// ); -// assert_eq!( -// HolderState::Finished, -// _holder_sm().to_finished_state().await.get_state() -// ); -// } -// } - -// mod get_tails_location { -// use super::*; - -// #[tokio::test] -// async fn test_get_tails_location() { -// let _setup = SetupMocks::init(); - -// assert_eq!( -// Err(AriesVcxErrorKind::NotReady), -// _holder_sm().get_tails_location().map_err(|e| e.kind()) -// ); -// assert_eq!( -// Err(AriesVcxErrorKind::NotReady), -// _holder_sm() -// .to_request_sent_state() -// .await -// .get_tails_location() -// .map_err(|e| e.kind()) -// ); -// assert_eq!( -// constants::TEST_TAILS_LOCATION, -// _holder_sm().to_finished_state().await.get_tails_location().unwrap() -// ); -// } -// } - -// mod get_tails_hash { -// use super::*; - -// #[tokio::test] -// async fn test_get_tails_hash() { -// let _setup = SetupMocks::init(); - -// assert_eq!( -// Err(AriesVcxErrorKind::NotReady), -// _holder_sm().get_tails_hash().map_err(|e| e.kind()) -// ); -// assert_eq!( -// Err(AriesVcxErrorKind::NotReady), -// _holder_sm() -// .to_request_sent_state() -// .await -// .get_tails_hash() -// .map_err(|e| e.kind()) -// ); - -// assert_eq!( -// constants::TEST_TAILS_HASH, -// _holder_sm().to_finished_state().await.get_tails_hash().unwrap() -// ); -// } -// } - -// mod get_rev_reg_id { -// use super::*; - -// #[tokio::test] -// async fn test_get_rev_reg_id() { -// let _setup = SetupMocks::init(); - -// assert_eq!( -// Err(AriesVcxErrorKind::NotReady), -// _holder_sm().get_rev_reg_id().map_err(|e| e.kind()) -// ); -// assert_eq!( -// Err(AriesVcxErrorKind::NotReady), -// _holder_sm() -// .to_request_sent_state() -// .await -// .get_rev_reg_id() -// .map_err(|e| e.kind()) -// ); - -// assert_eq!( -// constants::REV_REG_ID, -// _holder_sm().to_finished_state().await.get_rev_reg_id().unwrap() -// ); -// } -// } - -// mod is_revokable { -// use super::*; - -// #[tokio::test] -// async fn test_is_revokable() { -// let _setup = SetupMocks::init(); -// assert_eq!(true, _holder_sm().is_revokable(&mock_profile()).await.unwrap()); -// assert_eq!( -// true, -// _holder_sm() -// .to_request_sent_state() -// .await -// .is_revokable(&mock_profile()) -// .await -// .unwrap() -// ); -// assert_eq!( -// true, -// _holder_sm() -// .to_finished_state() -// .await -// .is_revokable(&mock_profile()) -// .await -// .unwrap() -// ); -// } -// } -// } diff --git a/aries_vcx/src/protocols/issuance/issuer/state_machine.rs b/aries_vcx/src/protocols/issuance/issuer/state_machine.rs index 1c8afba3fd..4a9cead2cd 100644 --- a/aries_vcx/src/protocols/issuance/issuer/state_machine.rs +++ b/aries_vcx/src/protocols/issuance/issuer/state_machine.rs @@ -1,9 +1,8 @@ -use std::collections::HashMap; use std::fmt::Display; use std::sync::Arc; use crate::handlers::util::{ - get_attach_as_string, make_attach_from_str, matches_opt_thread_id, matches_thread_id, AttachmentId, OfferInfo, + get_attach_as_string, make_attach_from_str, matches_opt_thread_id, verify_thread_id, AttachmentId, OfferInfo, Status, }; use aries_vcx_core::anoncreds::base_anoncreds::BaseAnonCreds; @@ -22,7 +21,6 @@ use messages::msg_fields::protocols::cred_issuance::offer_credential::{ use messages::msg_fields::protocols::cred_issuance::propose_credential::ProposeCredential; use messages::msg_fields::protocols::cred_issuance::request_credential::RequestCredential; use messages::msg_fields::protocols::cred_issuance::{CredentialIssuance, CredentialPreview}; -use messages::msg_fields::protocols::notification::Notification; use messages::msg_fields::protocols::report_problem::ProblemReport; use messages::AriesMessage; use uuid::Uuid; @@ -31,7 +29,6 @@ use crate::common::credentials::encoding::encode_attributes; use crate::common::credentials::is_cred_revoked; use crate::errors::error::{AriesVcxError, AriesVcxErrorKind, VcxResult}; use crate::protocols::common::build_problem_report_msg; -use crate::protocols::issuance::actions::CredentialIssuanceAction; use crate::protocols::issuance::issuer::states::credential_sent::CredentialSentState; use crate::protocols::issuance::issuer::states::finished::FinishedState; use crate::protocols::issuance::issuer::states::initial::InitialIssuerState; @@ -39,7 +36,6 @@ use crate::protocols::issuance::issuer::states::offer_sent::OfferSentState; use crate::protocols::issuance::issuer::states::offer_set::OfferSetState; use crate::protocols::issuance::issuer::states::proposal_received::ProposalReceivedState; use crate::protocols::issuance::issuer::states::requested_received::RequestReceivedState; -use crate::protocols::issuance::verify_thread_id; use crate::protocols::SendClosure; #[derive(Serialize, Deserialize, Debug, Clone)] @@ -95,9 +91,9 @@ impl Default for IssuerFullState { #[derive(Serialize, Deserialize, Debug, Clone, Default)] pub struct IssuerSM { - source_id: String, - thread_id: String, - state: IssuerFullState, + pub(crate) source_id: String, + pub(crate) thread_id: String, + pub(crate) state: IssuerFullState, } fn build_credential_message(libindy_credential: String) -> VcxResult { @@ -263,63 +259,6 @@ impl IssuerSM { } } - pub fn find_message_to_handle(&self, messages: HashMap) -> Option<(String, AriesMessage)> { - trace!( - "IssuerSM::find_message_to_handle >>> messages: {:?}, state: {:?}", - messages, - self.state - ); - - for (uid, message) in messages { - match self.state { - IssuerFullState::Initial(_) => { - if let AriesMessage::CredentialIssuance(CredentialIssuance::ProposeCredential(_)) = &message { - return Some((uid, message)); - } - } - IssuerFullState::OfferSent(_) => match &message { - AriesMessage::CredentialIssuance(CredentialIssuance::RequestCredential(msg)) => { - if matches_opt_thread_id!(msg, self.thread_id.as_str()) { - return Some((uid, message)); - } - } - AriesMessage::CredentialIssuance(CredentialIssuance::ProposeCredential(msg)) => { - if matches_opt_thread_id!(msg, self.thread_id.as_str()) { - return Some((uid, message)); - } - } - AriesMessage::ReportProblem(msg) => { - if matches_opt_thread_id!(msg, self.thread_id.as_str()) { - return Some((uid, message)); - } - } - _ => {} - }, - IssuerFullState::CredentialSent(_) => match &message { - AriesMessage::CredentialIssuance(CredentialIssuance::Ack(msg)) => { - if matches_thread_id!(msg, self.thread_id.as_str()) { - return Some((uid, message)); - } - } - AriesMessage::Notification(Notification::Ack(msg)) => { - if matches_thread_id!(msg, self.thread_id.as_str()) { - return Some((uid, message)); - } - } - AriesMessage::ReportProblem(msg) => { - if matches_opt_thread_id!(msg, self.thread_id.as_str()) { - return Some((uid, message)); - } - } - _ => {} - }, - _ => {} - }; - } - - None - } - pub fn get_state(&self) -> IssuerState { match self.state { IssuerFullState::Initial(_) => IssuerState::Initial, @@ -411,7 +350,7 @@ impl IssuerSM { pub fn receive_proposal(self, proposal: ProposeCredential) -> VcxResult { verify_thread_id( &self.thread_id, - &CredentialIssuanceAction::CredentialProposal(proposal.clone()), + &AriesMessage::CredentialIssuance(CredentialIssuance::ProposeCredential(proposal.clone())), )?; let (state, thread_id) = match self.state { IssuerFullState::Initial(_) => { @@ -420,10 +359,6 @@ impl IssuerSM { (state, thread_id) } IssuerFullState::OfferSent(_) => { - verify_thread_id( - &self.thread_id, - &CredentialIssuanceAction::CredentialProposal(proposal.clone()), - )?; let state = IssuerFullState::ProposalReceived(ProposalReceivedState::new(proposal, None)); (state, self.thread_id.clone()) } @@ -455,7 +390,7 @@ impl IssuerSM { pub fn receive_request(self, request: RequestCredential) -> VcxResult { verify_thread_id( &self.thread_id, - &CredentialIssuanceAction::CredentialRequest(request.clone()), + &AriesMessage::CredentialIssuance(CredentialIssuance::RequestCredential(request.clone())), )?; let state = match self.state { IssuerFullState::OfferSent(state_data) => IssuerFullState::RequestReceived((state_data, request).into()), @@ -511,7 +446,10 @@ impl IssuerSM { } pub fn receive_ack(self, ack: AckCredential) -> VcxResult { - verify_thread_id(&self.thread_id, &CredentialIssuanceAction::CredentialAck(ack))?; + verify_thread_id( + &self.thread_id, + &AriesMessage::CredentialIssuance(CredentialIssuance::Ack(ack.clone())), + )?; let state = match self.state { IssuerFullState::CredentialSent(state_data) => IssuerFullState::Finished(state_data.into()), s => { @@ -523,10 +461,7 @@ impl IssuerSM { } pub fn receive_problem_report(self, problem_report: ProblemReport) -> VcxResult { - verify_thread_id( - &self.thread_id, - &CredentialIssuanceAction::ProblemReport(problem_report.clone()), - )?; + verify_thread_id(&self.thread_id, &AriesMessage::ReportProblem(problem_report.clone()))?; let state = match self.state { IssuerFullState::OfferSent(state_data) => IssuerFullState::Finished((state_data, problem_report).into()), IssuerFullState::CredentialSent(state_data) => IssuerFullState::Finished((state_data).into()), @@ -538,31 +473,6 @@ impl IssuerSM { Ok(Self { state, ..self }) } - pub async fn handle_message( - self, - anoncreds: &Arc, - cim: CredentialIssuanceAction, - send_message: Option, - ) -> VcxResult { - trace!("IssuerSM::handle_message >>> cim: {:?}, state: {:?}", cim, self.state); - verify_thread_id(&self.thread_id, &cim)?; - let issuer_sm = match cim { - CredentialIssuanceAction::CredentialProposal(proposal) => self.receive_proposal(proposal)?, - CredentialIssuanceAction::CredentialRequest(request) => self.receive_request(request)?, - CredentialIssuanceAction::CredentialSend() => { - let send_message = send_message.ok_or(AriesVcxError::from_msg( - AriesVcxErrorKind::InvalidState, - "Attempted to call undefined send_message callback", - ))?; - self.send_credential(anoncreds, send_message).await? - } - CredentialIssuanceAction::CredentialAck(ack) => self.receive_ack(ack)?, - CredentialIssuanceAction::ProblemReport(problem_report) => self.receive_problem_report(problem_report)?, - _ => self, - }; - Ok(issuer_sm) - } - pub fn credential_status(&self) -> u32 { trace!("Issuer::credential_status >>>"); @@ -609,730 +519,3 @@ async fn _create_credential( let credential = build_credential_message(libindy_credential)?; Ok((credential, cred_rev_id)) } - -// #[cfg(test)] -// pub mod unit_tests { -// use crate::common::test_utils::mock_profile; -// use crate::test::source_id; -// use crate::utils::constants::LIBINDY_CRED_OFFER; -// use crate::utils::devsetup::SetupMocks; -// use messages::a2a::A2AMessage; -// use messages::concepts::problem_report::ProblemReport; -// use messages::protocols::issuance::credential::test_utils::_credential; -// use messages::protocols::issuance::credential_offer::test_utils::{_credential_offer, _offer_info}; -// use messages::protocols::issuance::credential_proposal::test_utils::_credential_proposal; -// use messages::protocols::issuance::credential_request::test_utils::{_credential_request, _credential_request_1}; -// use messages::protocols::issuance::test_utils::{_credential_ack, _problem_report}; - -// use super::*; - -// pub fn _rev_reg_id() -> String { -// String::from("TEST_REV_REG_ID") -// } - -// pub fn _tails_file() -> String { -// String::from("TEST_TAILS_FILE") -// } - -// pub fn _send_message() -> Option { -// Some(Box::new(|_: A2AMessage| Box::pin(async { VcxResult::Ok(()) }))) -// } - -// fn _issuer_sm() -> IssuerSM { -// IssuerSM::new(&source_id()) -// } - -// fn _issuer_sm_from_proposal() -> IssuerSM { -// IssuerSM::from_proposal(&source_id(), &_credential_proposal()) -// } - -// impl IssuerSM { -// fn to_proposal_received_state(self) -> IssuerSM { -// Self::from_proposal(&source_id(), &_credential_proposal()) -// } - -// fn to_offer_sent_state(mut self) -> IssuerSM { -// let cred_info = _offer_info(); -// self = self -// .build_credential_offer_msg( -// LIBINDY_CRED_OFFER, -// CredentialPreviewData::new(), -// Some("foo".into()), -// &cred_info, -// ) -// .unwrap(); -// self = self.mark_credential_offer_msg_sent().unwrap(); -// self -// } - -// async fn to_request_received_state(mut self) -> IssuerSM { -// self = self.to_offer_sent_state(); -// self = self -// .handle_message( -// &mock_profile(), -// CredentialIssuanceAction::CredentialRequest(_credential_request()), -// _send_message(), -// ) -// .await -// .unwrap(); -// self -// } - -// async fn to_finished_state(mut self) -> IssuerSM { -// self = self.to_request_received_state().await; -// self = self -// .handle_message( -// &mock_profile(), -// CredentialIssuanceAction::CredentialSend(), -// _send_message(), -// ) -// .await -// .unwrap(); -// self = self -// .handle_message( -// &mock_profile(), -// CredentialIssuanceAction::CredentialAck(_credential_ack()), -// _send_message(), -// ) -// .await -// .unwrap(); -// self -// } -// } - -// mod build_messages { -// use crate::protocols::issuance::issuer::state_machine::{build_credential_message, build_credential_offer}; -// use crate::utils::constants::LIBINDY_CRED_OFFER; -// use crate::utils::devsetup::{was_in_past, SetupMocks}; -// use messages::a2a::MessageId; -// use messages::protocols::issuance::CredentialPreviewData; - -// #[test] -// fn test_issuer_build_credential_offer() { -// let _setup = SetupMocks::init(); -// let msg = build_credential_offer( -// "12345", -// LIBINDY_CRED_OFFER, -// CredentialPreviewData::new(), -// Some("foo".into()), -// ) -// .unwrap(); - -// assert_eq!(msg.id, MessageId("12345".into())); -// assert!(msg.thread.is_none()); -// assert!(was_in_past( -// &msg.timing.unwrap().out_time.unwrap(), -// chrono::Duration::milliseconds(100) -// ) -// .unwrap()); -// } - -// #[tokio::test] -// async fn test_issuer_build_credential_message() { -// let _setup = SetupMocks::init(); - -// let msg = build_credential_message("{}".into()).unwrap(); - -// assert_eq!(msg.id, MessageId::default()); -// assert!(msg.thread.thid.is_none()); // todo: should have thread_id -// assert!(was_in_past( -// &msg.timing.unwrap().out_time.unwrap(), -// chrono::Duration::milliseconds(100) -// ) -// .unwrap()); -// } -// } - -// mod new { -// use super::*; - -// #[test] -// fn test_issuer_new() { -// let _setup = SetupMocks::init(); - -// let issuer_sm = _issuer_sm(); - -// assert_match!(IssuerFullState::Initial(_), issuer_sm.state); -// assert_eq!(source_id(), issuer_sm.get_source_id()); -// } - -// #[test] -// fn test_issuer_from_proposal() { -// let _setup = SetupMocks::init(); - -// let issuer_sm = _issuer_sm_from_proposal(); - -// assert_match!(IssuerFullState::ProposalReceived(_), issuer_sm.state); -// assert_eq!(source_id(), issuer_sm.get_source_id()); -// } -// } - -// mod handle_message { -// use super::*; - -// #[tokio::test] -// async fn test_issuer_handle_credential_proposal_message_from_initial_state() { -// let _setup = SetupMocks::init(); - -// let mut issuer_sm = _issuer_sm(); -// issuer_sm = issuer_sm -// .handle_message( -// &mock_profile(), -// CredentialIssuanceAction::CredentialProposal(_credential_proposal()), -// None, -// ) -// .await -// .unwrap(); - -// assert_match!(IssuerFullState::ProposalReceived(_), issuer_sm.state); -// } - -// #[tokio::test] -// async fn test_issuer_set_credential_offer_message_in_initial_state() { -// let _setup = SetupMocks::init(); - -// let mut issuer_sm = _issuer_sm(); -// let _cred_offer = CredentialOffer::create().set_offers_attach(LIBINDY_CRED_OFFER).unwrap(); -// let cred_info = _offer_info(); -// issuer_sm = issuer_sm -// .build_credential_offer_msg( -// LIBINDY_CRED_OFFER, -// CredentialPreviewData::new(), -// Some("foo".into()), -// &cred_info, -// ) -// .unwrap(); -// issuer_sm = issuer_sm.mark_credential_offer_msg_sent().unwrap(); - -// assert_match!(IssuerFullState::OfferSent(_), issuer_sm.state); -// } - -// #[tokio::test] -// async fn test_issuer_handle_other_messages_from_initial_state() { -// let _setup = SetupMocks::init(); - -// let mut issuer_sm = _issuer_sm(); - -// issuer_sm = issuer_sm -// .handle_message( -// &mock_profile(), -// CredentialIssuanceAction::Credential(_credential()), -// _send_message(), -// ) -// .await -// .unwrap(); -// assert_match!(IssuerFullState::Initial(_), issuer_sm.state); - -// issuer_sm = issuer_sm -// .handle_message( -// &mock_profile(), -// CredentialIssuanceAction::CredentialRequest(_credential_request()), -// _send_message(), -// ) -// .await -// .unwrap(); -// assert_match!(IssuerFullState::Initial(_), issuer_sm.state); -// } - -// #[test] -// fn test_issuer_handle_credential_offer_send_message_from_proposal_received() { -// let _setup = SetupMocks::init(); - -// let mut issuer_sm = _issuer_sm_from_proposal(); -// issuer_sm = issuer_sm.to_offer_sent_state(); - -// assert_match!(IssuerFullState::OfferSent(_), issuer_sm.state); -// } - -// #[tokio::test] -// async fn test_issuer_handle_other_messages_from_proposal_received_state() { -// let _setup = SetupMocks::init(); - -// let mut issuer_sm = _issuer_sm_from_proposal(); - -// issuer_sm = issuer_sm -// .handle_message( -// &mock_profile(), -// CredentialIssuanceAction::Credential(_credential()), -// _send_message(), -// ) -// .await -// .unwrap(); -// assert_match!(IssuerFullState::ProposalReceived(_), issuer_sm.state); - -// issuer_sm = issuer_sm -// .handle_message( -// &mock_profile(), -// CredentialIssuanceAction::CredentialRequest(_credential_request()), -// _send_message(), -// ) -// .await -// .unwrap(); -// assert_match!(IssuerFullState::ProposalReceived(_), issuer_sm.state); -// } - -// #[tokio::test] -// async fn test_issuer_handle_credential_request_message_from_offer_sent_state() { -// let _setup = SetupMocks::init(); - -// let mut issuer_sm = _issuer_sm(); -// issuer_sm = issuer_sm.to_offer_sent_state(); -// issuer_sm = issuer_sm -// .handle_message( -// &mock_profile(), -// CredentialIssuanceAction::CredentialRequest(_credential_request()), -// _send_message(), -// ) -// .await -// .unwrap(); - -// assert_match!(IssuerFullState::RequestReceived(_), issuer_sm.state); -// } - -// #[tokio::test] -// async fn test_issuer_handle_credential_proposal_message_from_offer_sent_state() { -// let _setup = SetupMocks::init(); - -// let mut issuer_sm = _issuer_sm(); -// issuer_sm = issuer_sm.to_offer_sent_state(); -// issuer_sm = issuer_sm -// .handle_message( -// &mock_profile(), -// CredentialIssuanceAction::CredentialProposal(_credential_proposal()), -// _send_message(), -// ) -// .await -// .unwrap(); - -// assert_match!(IssuerFullState::ProposalReceived(_), issuer_sm.state); -// } - -// #[tokio::test] -// async fn test_issuer_handle_problem_report_message_from_offer_sent_state() { -// let _setup = SetupMocks::init(); - -// let mut issuer_sm = _issuer_sm(); -// issuer_sm = issuer_sm.to_offer_sent_state(); -// issuer_sm = issuer_sm -// .handle_message( -// &mock_profile(), -// CredentialIssuanceAction::ProblemReport(_problem_report()), -// _send_message(), -// ) -// .await -// .unwrap(); - -// assert_match!(IssuerFullState::Finished(_), issuer_sm.state); -// assert_eq!( -// Status::Failed(ProblemReport::default()).code(), -// issuer_sm.credential_status() -// ); -// } - -// #[tokio::test] -// async fn test_issuer_handle_other_messages_from_offer_sent_state() { -// let _setup = SetupMocks::init(); - -// let mut issuer_sm = _issuer_sm(); -// issuer_sm = issuer_sm.to_offer_sent_state(); -// issuer_sm = issuer_sm -// .handle_message( -// &mock_profile(), -// CredentialIssuanceAction::Credential(_credential()), -// _send_message(), -// ) -// .await -// .unwrap(); - -// assert_match!(IssuerFullState::OfferSent(_), issuer_sm.state); -// } - -// #[tokio::test] -// async fn test_issuer_handle_credential_send_message_from_request_received_state() { -// let _setup = SetupMocks::init(); - -// let mut issuer_sm = _issuer_sm(); -// issuer_sm = issuer_sm.to_offer_sent_state(); -// issuer_sm = issuer_sm -// .handle_message( -// &mock_profile(), -// CredentialIssuanceAction::CredentialRequest(_credential_request()), -// _send_message(), -// ) -// .await -// .unwrap(); -// issuer_sm = issuer_sm -// .handle_message( -// &mock_profile(), -// CredentialIssuanceAction::CredentialSend(), -// _send_message(), -// ) -// .await -// .unwrap(); - -// assert_match!(IssuerFullState::CredentialSent(_), issuer_sm.state); -// } - -// #[tokio::test] -// async fn test_issuer_handle_credential_send_message_from_request_received_state_with_invalid_request() { -// let _setup = SetupMocks::init(); - -// let mut issuer_sm = _issuer_sm(); -// issuer_sm = issuer_sm.to_offer_sent_state(); -// issuer_sm = issuer_sm -// .handle_message( -// &mock_profile(), -// CredentialIssuanceAction::CredentialRequest(CredentialRequest::create()), -// _send_message(), -// ) -// .await -// .unwrap(); -// issuer_sm = issuer_sm -// .handle_message( -// &mock_profile(), -// CredentialIssuanceAction::CredentialSend(), -// _send_message(), -// ) -// .await -// .unwrap(); - -// assert_match!(IssuerFullState::Finished(_), issuer_sm.state); -// assert_eq!( -// Status::Failed(ProblemReport::default()).code(), -// issuer_sm.credential_status() -// ); -// } - -// #[tokio::test] -// async fn test_issuer_handle_other_messages_from_request_received_state() { -// let _setup = SetupMocks::init(); - -// let mut issuer_sm = _issuer_sm(); -// issuer_sm = issuer_sm.to_offer_sent_state(); -// issuer_sm = issuer_sm -// .handle_message( -// &mock_profile(), -// CredentialIssuanceAction::CredentialRequest(_credential_request()), -// _send_message(), -// ) -// .await -// .unwrap(); -// issuer_sm = issuer_sm -// .handle_message( -// &mock_profile(), -// CredentialIssuanceAction::CredentialSend(), -// _send_message(), -// ) -// .await -// .unwrap(); -// assert_match!(IssuerFullState::CredentialSent(_), issuer_sm.state); -// issuer_sm = issuer_sm -// .handle_message( -// &mock_profile(), -// CredentialIssuanceAction::CredentialAck(_credential_ack()), -// _send_message(), -// ) -// .await -// .unwrap(); -// assert_match!(IssuerFullState::Finished(_), issuer_sm.state); -// } - -// #[tokio::test] -// async fn test_issuer_credential_send_fails_with_incorrect_thread_id() { -// let _setup = SetupMocks::init(); - -// let mut issuer_sm = _issuer_sm(); -// issuer_sm = issuer_sm.to_offer_sent_state(); -// issuer_sm = issuer_sm -// .handle_message( -// &mock_profile(), -// CredentialIssuanceAction::CredentialRequest(_credential_request_1()), -// _send_message(), -// ) -// .await -// .unwrap(); -// issuer_sm = issuer_sm -// .handle_message( -// &mock_profile(), -// CredentialIssuanceAction::CredentialSend(), -// _send_message(), -// ) -// .await -// .unwrap(); -// assert_match!(IssuerFullState::Finished(_), issuer_sm.state); -// assert_eq!( -// Status::Failed(ProblemReport::default()).code(), -// issuer_sm.credential_status() -// ); -// } - -// #[tokio::test] -// async fn test_issuer_handle_messages_from_finished_state() { -// let _setup = SetupMocks::init(); - -// let mut issuer_sm = _issuer_sm(); -// issuer_sm = issuer_sm.to_finished_state().await; -// assert_match!(IssuerFullState::Finished(_), issuer_sm.state); - -// issuer_sm = issuer_sm -// .handle_message( -// &mock_profile(), -// CredentialIssuanceAction::CredentialRequest(_credential_request()), -// _send_message(), -// ) -// .await -// .unwrap(); -// assert_match!(IssuerFullState::Finished(_), issuer_sm.state); - -// issuer_sm = issuer_sm -// .handle_message( -// &mock_profile(), -// CredentialIssuanceAction::Credential(_credential()), -// _send_message(), -// ) -// .await -// .unwrap(); -// assert_match!(IssuerFullState::Finished(_), issuer_sm.state); -// } - -// #[tokio::test] -// async fn test_issuer_in_finished_state_returns_error_on_set_offer() { -// let _setup = SetupMocks::init(); - -// let mut issuer_sm = _issuer_sm(); -// issuer_sm = issuer_sm.to_finished_state().await; -// assert_match!(IssuerFullState::Finished(_), issuer_sm.state); -// let _cred_offer = CredentialOffer::create().set_offers_attach(LIBINDY_CRED_OFFER).unwrap(); -// let cred_info = _offer_info(); - -// let res1 = issuer_sm.build_credential_offer_msg( -// LIBINDY_CRED_OFFER, -// CredentialPreviewData::new(), -// Some("foo".into()), -// &cred_info, -// ); -// assert!(res1.is_err()); -// } - -// #[tokio::test] -// async fn test_issuer_in_finished_state_returns_error_on_mark_credential_offer_msg_sent() { -// let _setup = SetupMocks::init(); - -// let mut issuer_sm = _issuer_sm(); -// issuer_sm = issuer_sm.to_finished_state().await; -// assert_match!(IssuerFullState::Finished(_), issuer_sm.state); - -// let res1 = issuer_sm.mark_credential_offer_msg_sent(); -// assert!(res1.is_err()); -// } -// } - -// mod find_message_to_handle { -// use super::*; - -// #[tokio::test] -// async fn test_issuer_find_message_to_handle_from_initial_state() { -// let _setup = SetupMocks::init(); - -// let issuer = _issuer_sm(); - -// let messages = map!( -// "key_1".to_string() => A2AMessage::CredentialProposal(_credential_proposal()), -// "key_2".to_string() => A2AMessage::CredentialOffer(_credential_offer()), -// "key_3".to_string() => A2AMessage::CredentialRequest(_credential_request()), -// "key_4".to_string() => A2AMessage::Credential(_credential()), -// "key_5".to_string() => A2AMessage::CredentialAck(_credential_ack()), -// "key_6".to_string() => A2AMessage::CommonProblemReport(_problem_report()) -// ); -// let (uid, message) = issuer.find_message_to_handle(messages).unwrap(); -// assert_eq!("key_1", uid); -// assert_match!(A2AMessage::CredentialProposal(_), message); -// } - -// #[tokio::test] -// async fn test_issuer_find_message_to_handle_from_offer_sent_state() { -// let _setup = SetupMocks::init(); - -// let issuer = _issuer_sm().to_offer_sent_state(); - -// // CredentialRequest -// { -// let messages = map!( -// "key_1".to_string() => A2AMessage::CredentialOffer(_credential_offer()), -// "key_2".to_string() => A2AMessage::Credential(_credential()), -// "key_3".to_string() => A2AMessage::CredentialRequest(_credential_request()) -// ); - -// let (uid, message) = issuer.find_message_to_handle(messages).unwrap(); -// assert_eq!("key_3", uid); -// assert_match!(A2AMessage::CredentialRequest(_), message); -// } - -// // CredentialProposal -// { -// let messages = map!( -// "key_1".to_string() => A2AMessage::CredentialOffer(_credential_offer()), -// "key_2".to_string() => A2AMessage::CredentialAck(_credential_ack()), -// "key_3".to_string() => A2AMessage::Credential(_credential()), -// "key_4".to_string() => A2AMessage::CredentialProposal(_credential_proposal()) -// ); - -// let (uid, message) = issuer.find_message_to_handle(messages).unwrap(); -// assert_eq!("key_4", uid); -// assert_match!(A2AMessage::CredentialProposal(_), message); -// } - -// // Problem Report -// { -// let messages = map!( -// "key_1".to_string() => A2AMessage::CredentialOffer(_credential_offer()), -// "key_2".to_string() => A2AMessage::CredentialAck(_credential_ack()), -// "key_3".to_string() => A2AMessage::CommonProblemReport(_problem_report()) -// ); - -// let (uid, message) = issuer.find_message_to_handle(messages).unwrap(); -// assert_eq!("key_3", uid); -// assert_match!(A2AMessage::CommonProblemReport(_), message); -// } - -// // No messages for different Thread ID -// { -// let messages = map!( -// "key_1".to_string() => A2AMessage::CredentialOffer(_credential_offer().set_thread_id("")), -// "key_2".to_string() => A2AMessage::CredentialRequest(_credential_request().set_thread_id("")), -// "key_3".to_string() => A2AMessage::CredentialProposal(_credential_proposal().set_thread_id("")), -// "key_4".to_string() => A2AMessage::Credential(_credential().set_thread_id("")), -// "key_5".to_string() => A2AMessage::CredentialAck(_credential_ack().set_thread_id("")), -// "key_6".to_string() => A2AMessage::CommonProblemReport(_problem_report().set_thread_id("")) -// ); - -// assert!(issuer.find_message_to_handle(messages).is_none()); -// } - -// // No messages -// { -// let messages = map!( -// "key_1".to_string() => A2AMessage::CredentialOffer(_credential_offer()), -// "key_2".to_string() => A2AMessage::CredentialAck(_credential_ack()) -// ); - -// assert!(issuer.find_message_to_handle(messages).is_none()); -// } -// } - -// #[tokio::test] -// async fn test_issuer_find_message_to_handle_from_request_state() { -// let _setup = SetupMocks::init(); - -// let issuer = _issuer_sm().to_finished_state().await; - -// // No messages -// { -// let messages = map!( -// "key_1".to_string() => A2AMessage::CredentialOffer(_credential_offer()), -// "key_2".to_string() => A2AMessage::CredentialRequest(_credential_request()), -// "key_3".to_string() => A2AMessage::CredentialProposal(_credential_proposal()), -// "key_4".to_string() => A2AMessage::Credential(_credential()), -// "key_5".to_string() => A2AMessage::CredentialAck(_credential_ack()), -// "key_6".to_string() => A2AMessage::CommonProblemReport(_problem_report()) -// ); - -// assert!(issuer.find_message_to_handle(messages).is_none()); -// } -// } - -// #[tokio::test] -// async fn test_issuer_find_message_to_handle_from_credential_sent_state() { -// let _setup = SetupMocks::init(); - -// let issuer = _issuer_sm().to_finished_state().await; - -// // No messages -// { -// let messages = map!( -// "key_1".to_string() => A2AMessage::CredentialOffer(_credential_offer()), -// "key_2".to_string() => A2AMessage::CredentialRequest(_credential_request()), -// "key_3".to_string() => A2AMessage::CredentialProposal(_credential_proposal()), -// "key_4".to_string() => A2AMessage::Credential(_credential()), -// "key_5".to_string() => A2AMessage::CredentialAck(_credential_ack()), -// "key_6".to_string() => A2AMessage::CommonProblemReport(_problem_report()) -// ); - -// assert!(issuer.find_message_to_handle(messages).is_none()); -// } -// } -// } - -// mod get_state { -// use super::*; - -// #[tokio::test] -// async fn test_get_state() { -// let _setup = SetupMocks::init(); - -// assert_eq!(IssuerState::Initial, _issuer_sm().get_state()); -// assert_eq!( -// IssuerState::ProposalReceived, -// _issuer_sm().to_proposal_received_state().get_state() -// ); -// assert_eq!(IssuerState::OfferSent, _issuer_sm().to_offer_sent_state().get_state()); -// assert_eq!( -// IssuerState::RequestReceived, -// _issuer_sm().to_request_received_state().await.get_state() -// ); -// assert_eq!( -// IssuerState::Finished, -// _issuer_sm().to_finished_state().await.get_state() -// ); -// } -// } - -// mod get_rev_reg_id { -// use super::*; - -// #[tokio::test] -// async fn test_get_rev_reg_id() { -// let _setup = SetupMocks::init(); - -// assert_eq!( -// AriesVcxErrorKind::InvalidState, -// _issuer_sm().get_rev_reg_id().unwrap_err().kind() -// ); -// assert_eq!( -// AriesVcxErrorKind::InvalidState, -// _issuer_sm() -// .to_proposal_received_state() -// .get_rev_reg_id() -// .unwrap_err() -// .kind() -// ); -// assert_eq!( -// _rev_reg_id(), -// _issuer_sm().to_offer_sent_state().get_rev_reg_id().unwrap() -// ); -// assert_eq!( -// _rev_reg_id(), -// _issuer_sm().to_request_received_state().await.get_rev_reg_id().unwrap() -// ); -// assert_eq!( -// _rev_reg_id(), -// _issuer_sm().to_finished_state().await.get_rev_reg_id().unwrap() -// ); -// } -// } - -// mod is_revokable { -// use super::*; - -// #[tokio::test] -// async fn test_is_revokable() { -// let _setup = SetupMocks::init(); - -// assert_eq!(false, _issuer_sm().is_revokable()); -// assert_eq!(false, _issuer_sm().to_proposal_received_state().is_revokable()); -// assert_eq!(false, _issuer_sm().to_offer_sent_state().is_revokable()); -// assert_eq!(false, _issuer_sm().to_request_received_state().await.is_revokable()); -// assert_eq!(false, _issuer_sm().to_finished_state().await.is_revokable()); -// } -// } -// } diff --git a/aries_vcx/src/protocols/issuance/mod.rs b/aries_vcx/src/protocols/issuance/mod.rs index 4bafe2d522..bacb5ec51d 100644 --- a/aries_vcx/src/protocols/issuance/mod.rs +++ b/aries_vcx/src/protocols/issuance/mod.rs @@ -2,26 +2,10 @@ use aries_vcx_core::ledger::base_ledger::AnoncredsLedgerRead; use std::sync::Arc; use crate::errors::error::prelude::*; -use crate::global::settings; -use crate::protocols::issuance::actions::CredentialIssuanceAction; -pub mod actions; pub mod holder; pub mod issuer; -pub fn verify_thread_id(thread_id: &str, message: &CredentialIssuanceAction) -> VcxResult<()> { - if !settings::indy_mocks_enabled() && !message.thread_id_matches(thread_id) { - return Err(AriesVcxError::from_msg( - AriesVcxErrorKind::InvalidJson, - format!( - "Cannot handle message {:?}: thread id does not match, expected {:?}", - message, thread_id - ), - )); - }; - Ok(()) -} - pub async fn is_cred_def_revokable(ledger: &Arc, cred_def_id: &str) -> VcxResult { let cred_def_json = ledger.get_cred_def(cred_def_id, None).await.map_err(|err| { AriesVcxError::from_msg( diff --git a/aries_vcx/src/protocols/proof_presentation/prover/messages.rs b/aries_vcx/src/protocols/proof_presentation/prover/messages.rs deleted file mode 100644 index 96ad310968..0000000000 --- a/aries_vcx/src/protocols/proof_presentation/prover/messages.rs +++ /dev/null @@ -1,87 +0,0 @@ -use std::collections::HashMap; - -use messages::{ - msg_fields::protocols::{ - notification::Notification, - present_proof::{ - ack::{AckPresentation, AckPresentationContent}, - present::Presentation, - propose::PresentationPreview, - request::RequestPresentation, - PresentProof, - }, - report_problem::ProblemReport, - }, - msg_parts::MsgParts, - AriesMessage, -}; - -use crate::handlers::{ - proof_presentation::types::SelectedCredentials, - util::{matches_opt_thread_id, matches_thread_id, PresentationProposalData}, -}; - -#[derive(Debug, Deserialize, Serialize, Clone, PartialEq)] -pub enum ProverMessages { - PresentationProposalSend(PresentationProposalData), - PresentationRequestReceived(RequestPresentation), - RejectPresentationRequest(String), - SetPresentation(Presentation), - PreparePresentation((SelectedCredentials, HashMap)), - SendPresentation, - PresentationAckReceived(AckPresentation), - PresentationRejectReceived(ProblemReport), - ProposePresentation(PresentationPreview), - Unknown, -} - -impl ProverMessages { - pub fn thread_id_matches(&self, thread_id: &str) -> bool { - match self { - Self::SetPresentation(msg) => matches_thread_id!(msg, thread_id), - Self::PresentationRejectReceived(msg) => matches_opt_thread_id!(msg, thread_id), - Self::PresentationAckReceived(msg) => matches_thread_id!(msg, thread_id), - _ => true, - } - } -} - -impl From for ProverMessages { - fn from(msg: AriesMessage) -> Self { - match msg { - AriesMessage::Notification(Notification::Ack(ack)) => { - let MsgParts { - id, - content, - decorators, - } = ack; - let ack = AckPresentation::with_decorators(id, AckPresentationContent(content), decorators); - ProverMessages::PresentationAckReceived(ack) - } - AriesMessage::PresentProof(PresentProof::Ack(ack)) => ProverMessages::PresentationAckReceived(ack), - AriesMessage::PresentProof(PresentProof::RequestPresentation(request)) => { - ProverMessages::PresentationRequestReceived(request) - } - AriesMessage::ReportProblem(report) => ProverMessages::PresentationRejectReceived(report), - AriesMessage::Notification(Notification::ProblemReport(report)) => { - let MsgParts { - id, - content, - decorators, - } = report; - let report = ProblemReport::with_decorators(id, content.0, decorators); - ProverMessages::PresentationRejectReceived(report) - } - AriesMessage::PresentProof(PresentProof::ProblemReport(report)) => { - let MsgParts { - id, - content, - decorators, - } = report; - let report = ProblemReport::with_decorators(id, content.0, decorators); - ProverMessages::PresentationRejectReceived(report) - } - _ => ProverMessages::Unknown, - } - } -} diff --git a/aries_vcx/src/protocols/proof_presentation/prover/mod.rs b/aries_vcx/src/protocols/proof_presentation/prover/mod.rs index aba2d1487b..abe5f05f66 100644 --- a/aries_vcx/src/protocols/proof_presentation/prover/mod.rs +++ b/aries_vcx/src/protocols/proof_presentation/prover/mod.rs @@ -1,20 +1,2 @@ -use crate::errors::error::{AriesVcxError, AriesVcxErrorKind, VcxResult}; -use crate::global::settings; -use crate::protocols::proof_presentation::prover::messages::ProverMessages; - -pub mod messages; pub mod state_machine; pub mod states; - -pub fn verify_thread_id(thread_id: &str, message: &ProverMessages) -> VcxResult<()> { - if !settings::indy_mocks_enabled() && !message.thread_id_matches(thread_id) { - return Err(AriesVcxError::from_msg( - AriesVcxErrorKind::InvalidJson, - format!( - "Cannot handle message {:?}: thread id does not match, expected {:?}", - message, thread_id - ), - )); - }; - Ok(()) -} diff --git a/aries_vcx/src/protocols/proof_presentation/prover/state_machine.rs b/aries_vcx/src/protocols/proof_presentation/prover/state_machine.rs index aac3886002..6cf5d41ad8 100644 --- a/aries_vcx/src/protocols/proof_presentation/prover/state_machine.rs +++ b/aries_vcx/src/protocols/proof_presentation/prover/state_machine.rs @@ -4,11 +4,8 @@ use std::sync::Arc; use crate::errors::error::prelude::*; use crate::handlers::proof_presentation::types::SelectedCredentials; -use crate::handlers::util::{ - make_attach_from_str, matches_opt_thread_id, matches_thread_id, AttachmentId, PresentationProposalData, Status, -}; +use crate::handlers::util::{make_attach_from_str, AttachmentId, PresentationProposalData, Status}; use crate::protocols::common::build_problem_report_msg; -use crate::protocols::proof_presentation::prover::messages::ProverMessages; use crate::protocols::proof_presentation::prover::states::finished::FinishedState; use crate::protocols::proof_presentation::prover::states::initial::InitialProverState; use crate::protocols::proof_presentation::prover::states::presentation_preparation_failed::PresentationPreparationFailedState; @@ -16,7 +13,6 @@ use crate::protocols::proof_presentation::prover::states::presentation_prepared: use crate::protocols::proof_presentation::prover::states::presentation_proposal_sent::PresentationProposalSent; use crate::protocols::proof_presentation::prover::states::presentation_request_received::PresentationRequestReceived; use crate::protocols::proof_presentation::prover::states::presentation_sent::PresentationSentState; -use crate::protocols::proof_presentation::prover::verify_thread_id; use crate::protocols::SendClosure; use aries_vcx_core::anoncreds::base_anoncreds::BaseAnonCreds; @@ -24,7 +20,6 @@ use aries_vcx_core::ledger::base_ledger::AnoncredsLedgerRead; use chrono::Utc; use messages::decorators::thread::Thread; use messages::decorators::timing::Timing; -use messages::msg_fields::protocols::notification::Notification; use messages::msg_fields::protocols::present_proof::ack::AckPresentation; use messages::msg_fields::protocols::present_proof::present::{ Presentation, PresentationContent, PresentationDecorators, @@ -33,9 +28,7 @@ use messages::msg_fields::protocols::present_proof::propose::{ PresentationPreview, ProposePresentation, ProposePresentationContent, ProposePresentationDecorators, }; use messages::msg_fields::protocols::present_proof::request::RequestPresentation; -use messages::msg_fields::protocols::present_proof::PresentProof; use messages::msg_fields::protocols::report_problem::ProblemReport; -use messages::AriesMessage; use uuid::Uuid; /// A state machine that tracks the evolution of states for a Prover during @@ -255,17 +248,6 @@ impl ProverSM { Ok(Self { state, ..self }) } - pub fn receive_presentation_ack(self, ack: AckPresentation) -> VcxResult { - let state = match self.state { - ProverFullState::PresentationSent(state) => ProverFullState::Finished((state, ack).into()), - s => { - warn!("Unable to process presentation ack in state {}", s); - s - } - }; - Ok(Self { state, ..self }) - } - pub async fn send_presentation(self, send_message: SendClosure) -> VcxResult { let state = match self.state { ProverFullState::PresentationPrepared(state) => { @@ -284,200 +266,77 @@ impl ProverSM { Ok(Self { state, ..self }) } - pub fn find_message_to_handle(&self, messages: HashMap) -> Option<(String, AriesMessage)> { - trace!("Prover::find_message_to_handle >>> messages: {:?}", messages); - for (uid, message) in messages { - match self.state { - ProverFullState::PresentationProposalSent(_) => match &message { - AriesMessage::ReportProblem(msg) => { - if matches_opt_thread_id!(msg, self.thread_id.as_str()) { - return Some((uid, message)); - } - } - AriesMessage::Notification(Notification::ProblemReport(msg)) => { - if matches_opt_thread_id!(msg, self.thread_id.as_str()) { - return Some((uid, message)); - } - } - AriesMessage::PresentProof(PresentProof::RequestPresentation(msg)) => { - if matches_opt_thread_id!(msg, self.thread_id.as_str()) { - return Some((uid, message)); - } - } - _ => {} - }, - ProverFullState::PresentationSent(_) => match &message { - AriesMessage::Notification(Notification::Ack(msg)) => { - if matches_thread_id!(msg, self.thread_id.as_str()) { - return Some((uid, message)); - } - } - AriesMessage::PresentProof(PresentProof::Ack(msg)) => { - if matches_thread_id!(msg, self.thread_id.as_str()) { - return Some((uid, message)); - } - } - AriesMessage::ReportProblem(msg) => { - if matches_opt_thread_id!(msg, self.thread_id.as_str()) { - return Some((uid, message)); - } - } - AriesMessage::Notification(Notification::ProblemReport(msg)) => { - if matches_opt_thread_id!(msg, self.thread_id.as_str()) { - return Some((uid, message)); - } - } - AriesMessage::PresentProof(PresentProof::ProblemReport(msg)) => { - if matches_opt_thread_id!(msg, self.thread_id.as_str()) { - return Some((uid, message)); - } - } - _ => {} - }, - _ => {} - }; - } - None - } - - pub async fn step( + pub async fn send_proposal( self, - ledger: &Arc, - anoncreds: &Arc, - message: ProverMessages, + proposal_data: PresentationProposalData, send_message: Option, ) -> VcxResult { - trace!("ProverSM::step >>> message: {:?}", message); - verify_thread_id(&self.thread_id, &message)?; let prover_sm = match &self.state { - ProverFullState::Initial(_) => match message { - ProverMessages::PresentationProposalSend(proposal_data) => { - let send_message = send_message.ok_or(AriesVcxError::from_msg( - AriesVcxErrorKind::InvalidState, - "Attempted to call undefined send_message callback", - ))?; - self.send_presentation_proposal(proposal_data, send_message).await? - } - _ => { - warn!("Unable to process received message in this state"); - self - } - }, + ProverFullState::Initial(_) => { + let send_message = send_message.ok_or(AriesVcxError::from_msg( + AriesVcxErrorKind::InvalidState, + "Attempted to call undefined send_message callback", + ))?; + self.send_presentation_proposal(proposal_data, send_message).await? + } + ProverFullState::PresentationRequestReceived(_) => { + let send_message = send_message.ok_or(AriesVcxError::from_msg( + AriesVcxErrorKind::InvalidState, + "Attempted to call undefined send_message callback", + ))?; + self.send_presentation_proposal(proposal_data, send_message).await? + } + _ => { + warn!("Not supported in this state"); + self + } + }; + Ok(prover_sm) + } + + pub fn receive_presentation_request(self, request: RequestPresentation) -> VcxResult { + let prover_sm = match &self.state { ProverFullState::PresentationProposalSent(_) => { - match message { - ProverMessages::PresentationRequestReceived(request) => { - let state = - ProverFullState::PresentationRequestReceived(PresentationRequestReceived::new(request)); - ProverSM { state, ..self } - } - // TODO: Perhaps use a different message type? - ProverMessages::PresentationRejectReceived(problem_report) => { - let state = ProverFullState::Finished(FinishedState::declined(problem_report)); - ProverSM { state, ..self } - } - _ => { - warn!("Unable to process received message in this state"); - self - } - } + let state = ProverFullState::PresentationRequestReceived(PresentationRequestReceived::new(request)); + ProverSM { state, ..self } + } + _ => { + warn!("Not supported in this state"); + self + } + }; + Ok(prover_sm) + } + + pub fn receive_presentation_reject(self, problem_report: ProblemReport) -> VcxResult { + let prover_sm = match &self.state { + ProverFullState::PresentationProposalSent(_) => { + let state = ProverFullState::Finished(FinishedState::declined(problem_report)); + ProverSM { state, ..self } + } + ProverFullState::PresentationSent(state) => { + let state = ProverFullState::Finished((state.clone(), problem_report).into()); + ProverSM { state, ..self } + } + _ => { + warn!("Not supported in this state"); + self } - ProverFullState::PresentationRequestReceived(_) => match message { - ProverMessages::PresentationProposalSend(proposal_data) => { - let send_message = send_message.ok_or(AriesVcxError::from_msg( - AriesVcxErrorKind::InvalidState, - "Attempted to call undefined send_message callback", - ))?; - self.send_presentation_proposal(proposal_data, send_message).await? - } - ProverMessages::SetPresentation(presentation) => self.set_presentation(presentation)?, - ProverMessages::PreparePresentation((credentials, self_attested_attrs)) => { - self.generate_presentation(ledger, anoncreds, credentials, self_attested_attrs) - .await? - } - ProverMessages::RejectPresentationRequest(reason) => { - let send_message = send_message.ok_or(AriesVcxError::from_msg( - AriesVcxErrorKind::InvalidState, - "Attempted to call undefined send_message callback", - ))?; - self.decline_presentation_request(reason, send_message).await? - } - ProverMessages::ProposePresentation(preview) => { - let send_message = send_message.ok_or(AriesVcxError::from_msg( - AriesVcxErrorKind::InvalidState, - "Attempted to call undefined send_message callback", - ))?; - self.negotiate_presentation(preview, send_message).await? - } - _ => { - warn!("Unable to process received message in this state"); - self - } - }, - ProverFullState::PresentationPrepared(_) => match message { - ProverMessages::SendPresentation => { - let send_message = send_message.ok_or(AriesVcxError::from_msg( - AriesVcxErrorKind::InvalidState, - "Attempted to call undefined send_message callback", - ))?; - self.send_presentation(send_message).await? - } - ProverMessages::RejectPresentationRequest(reason) => { - let send_message = send_message.ok_or(AriesVcxError::from_msg( - AriesVcxErrorKind::InvalidState, - "Attempted to call undefined send_message callback", - ))?; - self.decline_presentation_request(reason, send_message).await? - } - ProverMessages::ProposePresentation(preview) => { - let send_message = send_message.ok_or(AriesVcxError::from_msg( - AriesVcxErrorKind::InvalidState, - "Attempted to call undefined send_message callback", - ))?; - self.negotiate_presentation(preview, send_message).await? - } - _ => { - warn!("Unable to process received message in this state"); - self - } - }, - ProverFullState::PresentationPreparationFailed(_) => match message { - ProverMessages::SendPresentation => { - let send_message = send_message.ok_or(AriesVcxError::from_msg( - AriesVcxErrorKind::InvalidState, - "Attempted to call undefined send_message callback", - ))?; - self.send_presentation(send_message).await? - } - _ => { - warn!("Unable to process received message in this state"); - self - } - }, - ProverFullState::PresentationSent(state) => match message { - ProverMessages::PresentationAckReceived(ack) => { - let state = ProverFullState::Finished((state.clone(), ack).into()); - ProverSM { state, ..self } - } - ProverMessages::PresentationRejectReceived(problem_report) => { - let state = ProverFullState::Finished((state.clone(), problem_report).into()); - ProverSM { state, ..self } - } - ProverMessages::RejectPresentationRequest(_) => { - return Err(AriesVcxError::from_msg( - AriesVcxErrorKind::ActionNotSupported, - "Presentation is already sent", - )); - } - _ => { - warn!("Unable to process received message in this state"); - self - } - }, - ProverFullState::Finished(_) => self, }; Ok(prover_sm) } + pub fn receive_presentation_ack(self, ack: AckPresentation) -> VcxResult { + let state = match self.state { + ProverFullState::PresentationSent(state) => ProverFullState::Finished((state, ack).into()), + s => { + warn!("Unable to process presentation ack in state {}", s); + s + } + }; + Ok(Self { state, ..self }) + } + async fn _handle_reject_presentation_request<'a>( send_message: SendClosure, reason: &'a str, @@ -596,834 +455,3 @@ impl ProverSM { } } } - -// #[cfg(test)] -// pub mod unit_tests { -// use crate::common::test_utils::mock_profile; -// use crate::test::source_id; -// use crate::utils::devsetup::SetupMocks; -// use messages::protocols::proof_presentation::presentation::test_utils::_presentation; -// use messages::protocols::proof_presentation::presentation_proposal::test_utils::{ -// _presentation_preview, _presentation_proposal, _presentation_proposal_data, -// }; -// use messages::protocols::proof_presentation::presentation_request::test_utils::_presentation_request; -// use messages::protocols::proof_presentation::test_utils::{_ack, _problem_report}; - -// use super::*; - -// pub fn _prover_sm_from_request() -> ProverSM { -// ProverSM::from_request(_presentation_request(), source_id()) -// } - -// pub fn _send_message() -> Option { -// Some(Box::new(|_: A2AMessage| Box::pin(async { VcxResult::Ok(()) }))) -// } - -// pub fn _prover_sm() -> ProverSM { -// ProverSM::new(source_id()) -// } - -// impl ProverSM { -// async fn to_presentation_proposal_sent_state(mut self) -> ProverSM { -// self = self -// .step( -// &mock_profile(), -// ProverMessages::PresentationProposalSend(_presentation_proposal_data()), -// _send_message(), -// ) -// .await -// .unwrap(); -// self -// } - -// async fn to_presentation_prepared_state(mut self) -> ProverSM { -// self = self -// .step( -// &mock_profile(), -// ProverMessages::PreparePresentation((_credentials(), _self_attested())), -// None, -// ) -// .await -// .unwrap(); -// self -// } - -// async fn to_presentation_sent_state(mut self) -> ProverSM { -// self = self -// .step( -// &mock_profile(), -// ProverMessages::PreparePresentation((_credentials(), _self_attested())), -// _send_message(), -// ) -// .await -// .unwrap(); -// self = self -// .step(&mock_profile(), ProverMessages::SendPresentation, _send_message()) -// .await -// .unwrap(); -// self -// } - -// async fn to_finished_state(mut self) -> ProverSM { -// self = self -// .step( -// &mock_profile(), -// ProverMessages::PreparePresentation((_credentials(), _self_attested())), -// None, -// ) -// .await -// .unwrap(); -// self = self -// .step(&mock_profile(), ProverMessages::SendPresentation, _send_message()) -// .await -// .unwrap(); -// self = self -// .step( -// &mock_profile(), -// ProverMessages::PresentationAckReceived(_ack()), -// _send_message(), -// ) -// .await -// .unwrap(); -// self -// } -// } - -// fn _credentials() -> String { -// json!({ -// "attrs":{ -// "attribute_0":{ -// "credential":{ -// "cred_info":{ -// "attrs":{"name": "alice"}, -// "cred_def_id": "V4SGRU86Z58d6TV7PBUe6f:3:CL:419:tag", -// "referent": "a1991de8-8317-43fd-98b3-63bac40b9e8b", -// "schema_id": "V4SGRU86Z58d6TV7PBUe6f:2:QcimrRShWQniqlHUtIDddYP0n:1.0" -// } -// } -// } -// } -// }) -// .to_string() -// } - -// fn _self_attested() -> String { -// json!({}).to_string() -// } - -// mod build_messages { -// use crate::protocols::common::build_problem_report_msg; -// use messages::a2a::MessageId; - -// use crate::protocols::proof_presentation::prover::state_machine::build_presentation_msg; -// use crate::utils::devsetup::{was_in_past, SetupMocks}; - -// #[test] -// fn test_prover_build_presentation_message() { -// let _setup = SetupMocks::init(); - -// let msg = build_presentation_msg("12345", "{}".into()).unwrap(); - -// assert_eq!(msg.id, MessageId::default()); -// assert_eq!(msg.thread.thid, Some("12345".into())); -// assert!(was_in_past( -// &msg.timing.unwrap().out_time.unwrap(), -// chrono::Duration::milliseconds(100) -// ) -// .unwrap()); -// } - -// #[tokio::test] -// async fn test_prover_build_problem_report() { -// let _setup = SetupMocks::init(); - -// let msg = build_problem_report_msg(Some("foobar".into()), "12345"); - -// assert_eq!(msg.id, MessageId::default()); -// assert_eq!(msg.thread.unwrap().thid, Some("12345".into())); -// assert_eq!(msg.comment, Some("foobar".into())); -// assert!(was_in_past( -// &msg.timing.unwrap().out_time.unwrap(), -// chrono::Duration::milliseconds(100) -// ) -// .unwrap()); -// } -// } - -// mod new { -// use super::*; - -// #[tokio::test] -// async fn test_prover_new() { -// let _setup = SetupMocks::init(); - -// let prover_sm = _prover_sm(); - -// assert_match!(ProverFullState::Initial(_), prover_sm.state); -// assert_eq!(source_id(), prover_sm.source_id()); -// } - -// #[tokio::test] -// async fn test_prover_from_request() { -// let _setup = SetupMocks::init(); - -// let prover_sm = _prover_sm_from_request(); - -// assert_match!(ProverFullState::PresentationRequestReceived(_), prover_sm.state); -// assert_eq!(source_id(), prover_sm.source_id()); -// } -// } - -// mod step { -// use crate::utils::constants::CREDS_FROM_PROOF_REQ; -// use crate::utils::mockdata::mock_settings::MockBuilder; - -// use super::*; - -// #[tokio::test] -// async fn test_prover_init() { -// let _setup = SetupMocks::init(); - -// let prover_sm = _prover_sm_from_request(); -// assert_match!(ProverFullState::PresentationRequestReceived(_), prover_sm.state); -// } - -// #[tokio::test] -// async fn test_prover_handle_presentation_proposal_send_from_initial_state() { -// let _setup = SetupMocks::init(); - -// let mut prover_sm = _prover_sm(); -// prover_sm = prover_sm -// .step( -// &mock_profile(), -// ProverMessages::PresentationProposalSend(_presentation_proposal_data()), -// _send_message(), -// ) -// .await -// .unwrap(); - -// assert_match!(ProverFullState::PresentationProposalSent(_), prover_sm.state); -// } - -// #[tokio::test] -// async fn test_prover_handle_presentation_request_received_from_presentation_proposal_sent_state() { -// let _setup = SetupMocks::init(); - -// let mut prover_sm = _prover_sm_from_request().to_presentation_proposal_sent_state().await; -// prover_sm = prover_sm -// .step( -// &mock_profile(), -// ProverMessages::PresentationRequestReceived(_presentation_request()), -// _send_message(), -// ) -// .await -// .unwrap(); - -// assert_match!(ProverFullState::PresentationRequestReceived(_), prover_sm.state); -// } - -// #[tokio::test] -// async fn test_prover_handle_presentation_reject_received_from_presentation_proposal_sent_state() { -// let _setup = SetupMocks::init(); - -// let mut prover_sm = _prover_sm_from_request().to_presentation_proposal_sent_state().await; -// prover_sm = prover_sm -// .step( -// &mock_profile(), -// ProverMessages::PresentationRejectReceived(_problem_report()), -// _send_message(), -// ) -// .await -// .unwrap(); - -// assert_match!(ProverFullState::Finished(_), prover_sm.state); -// assert_eq!( -// Status::Declined(ProblemReport::default()).code(), -// prover_sm.get_presentation_status() -// ); -// } - -// #[tokio::test] -// async fn test_prover_handle_presentation_proposal_send_from_presentation_request_received_state() { -// let _setup = SetupMocks::init(); - -// let mut prover_sm = _prover_sm_from_request(); -// prover_sm = prover_sm -// .step( -// &mock_profile(), -// ProverMessages::PresentationProposalSend(_presentation_proposal_data()), -// _send_message(), -// ) -// .await -// .unwrap(); - -// assert_match!(ProverFullState::PresentationProposalSent(_), prover_sm.state); -// } - -// #[tokio::test] -// async fn test_prover_handle_set_presentation_from_presentation_request_received_state() { -// let _setup = SetupMocks::init(); - -// let mut prover_sm = _prover_sm_from_request(); -// prover_sm = prover_sm -// .step( -// &mock_profile(), -// ProverMessages::SetPresentation(_presentation()), -// _send_message(), -// ) -// .await -// .unwrap(); - -// assert_match!(ProverFullState::PresentationPrepared(_), prover_sm.state); -// } - -// #[tokio::test] -// async fn test_prover_handle_prepare_presentation_message_from_presentation_request_received_state_for_invalid_credentials( -// ) { -// let _setup = SetupMocks::init(); -// let _mock_builder = MockBuilder::init().set_mock_creds_retrieved_for_proof_request(CREDS_FROM_PROOF_REQ); - -// let mut prover_sm = _prover_sm_from_request(); -// prover_sm = prover_sm -// .step( -// &mock_profile(), -// ProverMessages::PreparePresentation(("invalid".to_string(), _self_attested())), -// _send_message(), -// ) -// .await -// .unwrap(); - -// assert_match!(ProverFullState::PresentationPreparationFailed(_), prover_sm.state); -// } - -// #[tokio::test] -// async fn test_prover_handle_reject_presentation_request_message_from_presentation_request_received_state() { -// let _setup = SetupMocks::init(); - -// let mut prover_sm = _prover_sm_from_request(); -// prover_sm = prover_sm -// .step( -// &mock_profile(), -// ProverMessages::RejectPresentationRequest(String::from("reject request")), -// _send_message(), -// ) -// .await -// .unwrap(); - -// assert_match!(ProverFullState::Finished(_), prover_sm.state); -// } - -// #[tokio::test] -// async fn test_prover_handle_propose_presentation_message_from_presentation_request_received_state() { -// let _setup = SetupMocks::init(); - -// let mut prover_sm = _prover_sm_from_request(); -// prover_sm = prover_sm -// .step( -// &mock_profile(), -// ProverMessages::ProposePresentation(_presentation_preview()), -// _send_message(), -// ) -// .await -// .unwrap(); - -// assert_match!(ProverFullState::Finished(_), prover_sm.state); -// } - -// #[tokio::test] -// async fn test_prover_handle_other_messages_from_presentation_request_received_state() { -// let _setup = SetupMocks::init(); - -// let mut prover_sm = _prover_sm_from_request(); - -// prover_sm = prover_sm -// .step(&mock_profile(), ProverMessages::SendPresentation, _send_message()) -// .await -// .unwrap(); -// assert_match!(ProverFullState::PresentationRequestReceived(_), prover_sm.state); - -// prover_sm = prover_sm -// .step( -// &mock_profile(), -// ProverMessages::PresentationAckReceived(_ack()), -// _send_message(), -// ) -// .await -// .unwrap(); -// assert_match!(ProverFullState::PresentationRequestReceived(_), prover_sm.state); -// } - -// #[tokio::test] -// async fn test_prover_handle_send_presentation_message_from_presentation_prepared_state() { -// let _setup = SetupMocks::init(); - -// let mut prover_sm = _prover_sm_from_request(); - -// prover_sm = prover_sm -// .step( -// &mock_profile(), -// ProverMessages::PreparePresentation((_credentials(), _self_attested())), -// _send_message(), -// ) -// .await -// .unwrap(); -// prover_sm = prover_sm -// .step(&mock_profile(), ProverMessages::SendPresentation, _send_message()) -// .await -// .unwrap(); - -// assert_match!(ProverFullState::PresentationSent(_), prover_sm.state); -// } - -// #[tokio::test] -// async fn test_prover_handle_other_messages_from_presentation_prepared_state() { -// let _setup = SetupMocks::init(); - -// let mut prover_sm = _prover_sm_from_request().to_presentation_prepared_state().await; - -// prover_sm = prover_sm -// .step( -// &mock_profile(), -// ProverMessages::PresentationRejectReceived(_problem_report()), -// _send_message(), -// ) -// .await -// .unwrap(); -// assert_match!(ProverFullState::PresentationPrepared(_), prover_sm.state); - -// prover_sm = prover_sm -// .step( -// &mock_profile(), -// ProverMessages::PresentationAckReceived(_ack()), -// _send_message(), -// ) -// .await -// .unwrap(); -// assert_match!(ProverFullState::PresentationPrepared(_), prover_sm.state); -// } - -// #[tokio::test] -// async fn test_prover_handle_reject_presentation_request_message_from_presentation_prepared_state() { -// let _setup = SetupMocks::init(); - -// let mut prover_sm = _prover_sm_from_request().to_presentation_prepared_state().await; - -// prover_sm = prover_sm -// .step( -// &mock_profile(), -// ProverMessages::RejectPresentationRequest(String::from("reject request")), -// _send_message(), -// ) -// .await -// .unwrap(); - -// assert_match!(ProverFullState::Finished(_), prover_sm.state); -// } - -// #[tokio::test] -// async fn test_prover_handle_propose_presentation_message_from_presentation_prepared_state() { -// let _setup = SetupMocks::init(); - -// let mut prover_sm = _prover_sm_from_request().to_presentation_prepared_state().await; -// prover_sm = prover_sm -// .step( -// &mock_profile(), -// ProverMessages::ProposePresentation(_presentation_preview()), -// _send_message(), -// ) -// .await -// .unwrap(); - -// assert_match!(ProverFullState::Finished(_), prover_sm.state); -// } - -// #[tokio::test] -// async fn test_prover_handle_send_presentation_message_from_presentation_preparation_failed_state() { -// let _setup = SetupMocks::init(); -// let _mock_builder = MockBuilder::init().set_mock_creds_retrieved_for_proof_request(CREDS_FROM_PROOF_REQ); - -// let mut prover_sm = _prover_sm_from_request(); -// prover_sm = prover_sm -// .step( -// &mock_profile(), -// ProverMessages::PreparePresentation(("invalid".to_string(), _self_attested())), -// _send_message(), -// ) -// .await -// .unwrap(); -// assert_match!(ProverFullState::PresentationPreparationFailed(_), prover_sm.state); - -// prover_sm = prover_sm -// .step(&mock_profile(), ProverMessages::SendPresentation, _send_message()) -// .await -// .unwrap(); -// assert_match!(ProverFullState::Finished(_), prover_sm.state); -// assert_eq!( -// Status::Failed(ProblemReport::default()).code(), -// prover_sm.get_presentation_status() -// ); -// } - -// #[tokio::test] -// async fn test_prover_handle_other_messages_from_presentation_preparation_failed_state() { -// let _setup = SetupMocks::init(); -// let _mock_builder = MockBuilder::init().set_mock_creds_retrieved_for_proof_request(CREDS_FROM_PROOF_REQ); - -// let mut prover_sm = _prover_sm_from_request(); -// prover_sm = prover_sm -// .step( -// &mock_profile(), -// ProverMessages::PreparePresentation(("invalid".to_string(), _self_attested())), -// _send_message(), -// ) -// .await -// .unwrap(); - -// prover_sm = prover_sm -// .step( -// &mock_profile(), -// ProverMessages::PresentationRejectReceived(_problem_report()), -// _send_message(), -// ) -// .await -// .unwrap(); -// assert_match!(ProverFullState::PresentationPreparationFailed(_), prover_sm.state); - -// prover_sm = prover_sm -// .step( -// &mock_profile(), -// ProverMessages::PresentationAckReceived(_ack()), -// _send_message(), -// ) -// .await -// .unwrap(); -// assert_match!(ProverFullState::PresentationPreparationFailed(_), prover_sm.state); -// } - -// #[tokio::test] -// async fn test_prover_handle_ack_message_from_presentation_sent_state() { -// let _setup = SetupMocks::init(); - -// let mut prover_sm = _prover_sm_from_request(); -// prover_sm = prover_sm -// .step( -// &mock_profile(), -// ProverMessages::PreparePresentation((_credentials(), _self_attested())), -// _send_message(), -// ) -// .await -// .unwrap(); -// prover_sm = prover_sm -// .step(&mock_profile(), ProverMessages::SendPresentation, _send_message()) -// .await -// .unwrap(); -// prover_sm = prover_sm -// .step( -// &mock_profile(), -// ProverMessages::PresentationAckReceived(_ack()), -// _send_message(), -// ) -// .await -// .unwrap(); - -// assert_match!(ProverFullState::Finished(_), prover_sm.state); -// assert_eq!(Status::Success.code(), prover_sm.get_presentation_status()); -// } - -// #[tokio::test] -// async fn test_prover_handle_reject_presentation_request_message_from_presentation_sent_state() { -// let _setup = SetupMocks::init(); - -// let prover_sm = _prover_sm_from_request().to_presentation_sent_state().await; -// let err = prover_sm -// .step( -// &mock_profile(), -// ProverMessages::RejectPresentationRequest(String::from("reject")), -// _send_message(), -// ) -// .await -// .unwrap_err(); -// assert_eq!(AriesVcxErrorKind::ActionNotSupported, err.kind()); -// } - -// #[tokio::test] -// async fn test_prover_handle_presentation_reject_message_from_presentation_sent_state() { -// let _setup = SetupMocks::init(); - -// let mut prover_sm = _prover_sm_from_request(); -// prover_sm = prover_sm -// .step( -// &mock_profile(), -// ProverMessages::PreparePresentation((_credentials(), _self_attested())), -// _send_message(), -// ) -// .await -// .unwrap(); -// prover_sm = prover_sm -// .step(&mock_profile(), ProverMessages::SendPresentation, _send_message()) -// .await -// .unwrap(); -// prover_sm = prover_sm -// .step( -// &mock_profile(), -// ProverMessages::PresentationRejectReceived(_problem_report()), -// _send_message(), -// ) -// .await -// .unwrap(); - -// assert_match!(ProverFullState::Finished(_), prover_sm.state); -// assert_eq!( -// Status::Failed(ProblemReport::create()).code(), -// prover_sm.get_presentation_status() -// ); -// } - -// #[tokio::test] -// async fn test_prover_handle_other_messages_from_presentation_sent_state() { -// let _setup = SetupMocks::init(); - -// let mut prover_sm = _prover_sm_from_request(); -// prover_sm = prover_sm -// .step( -// &mock_profile(), -// ProverMessages::PreparePresentation((_credentials(), _self_attested())), -// _send_message(), -// ) -// .await -// .unwrap(); -// prover_sm = prover_sm -// .step(&mock_profile(), ProverMessages::SendPresentation, _send_message()) -// .await -// .unwrap(); - -// prover_sm = prover_sm -// .step( -// &mock_profile(), -// ProverMessages::PreparePresentation((_credentials(), _self_attested())), -// _send_message(), -// ) -// .await -// .unwrap(); -// assert_match!(ProverFullState::PresentationSent(_), prover_sm.state); - -// prover_sm = prover_sm -// .step(&mock_profile(), ProverMessages::SendPresentation, _send_message()) -// .await -// .unwrap(); -// assert_match!(ProverFullState::PresentationSent(_), prover_sm.state); -// } - -// #[tokio::test] -// async fn test_prover_handle_messages_from_finished_state() { -// let _setup = SetupMocks::init(); - -// let mut prover_sm = _prover_sm_from_request(); -// prover_sm = prover_sm -// .step( -// &mock_profile(), -// ProverMessages::PreparePresentation((_credentials(), _self_attested())), -// _send_message(), -// ) -// .await -// .unwrap(); -// prover_sm = prover_sm -// .step(&mock_profile(), ProverMessages::SendPresentation, _send_message()) -// .await -// .unwrap(); -// prover_sm = prover_sm -// .step( -// &mock_profile(), -// ProverMessages::PresentationAckReceived(_ack()), -// _send_message(), -// ) -// .await -// .unwrap(); - -// prover_sm = prover_sm -// .step( -// &mock_profile(), -// ProverMessages::PresentationAckReceived(_ack()), -// _send_message(), -// ) -// .await -// .unwrap(); -// assert_match!(ProverFullState::Finished(_), prover_sm.state); - -// prover_sm = prover_sm -// .step( -// &mock_profile(), -// ProverMessages::PresentationRejectReceived(_problem_report()), -// _send_message(), -// ) -// .await -// .unwrap(); -// assert_match!(ProverFullState::Finished(_), prover_sm.state); -// } -// } - -// mod find_message_to_handle { -// use super::*; - -// #[test] -// fn test_prover_find_message_to_handle_from_intial_state() { -// let _setup = SetupMocks::init(); -// let prover = _prover_sm(); -// { -// let messages = map!( -// "key_1".to_string() => A2AMessage::PresentationProposal(_presentation_proposal()), -// "key_2".to_string() => A2AMessage::Presentation(_presentation()), -// "key_3".to_string() => A2AMessage::PresentationRequest(_presentation_request()), -// "key_4".to_string() => A2AMessage::PresentationAck(_ack()), -// "key_5".to_string() => A2AMessage::CommonProblemReport(_problem_report()) -// ); - -// assert!(prover.find_message_to_handle(messages).is_none()); -// } -// } - -// #[test] -// fn test_prover_find_message_to_handle_from_presentation_request_received_state() { -// let _setup = SetupMocks::init(); - -// let prover = _prover_sm_from_request(); - -// // No messages -// { -// let messages = map!( -// "key_1".to_string() => A2AMessage::PresentationProposal(_presentation_proposal()), -// "key_2".to_string() => A2AMessage::Presentation(_presentation()), -// "key_3".to_string() => A2AMessage::PresentationRequest(_presentation_request()), -// "key_4".to_string() => A2AMessage::PresentationAck(_ack()), -// "key_5".to_string() => A2AMessage::CommonProblemReport(_problem_report()) -// ); - -// assert!(prover.find_message_to_handle(messages).is_none()); -// } -// } - -// #[tokio::test] -// async fn test_prover_find_message_to_handle_from_presentation_prepared_state() { -// let _setup = SetupMocks::init(); - -// let prover = _prover_sm_from_request().to_presentation_prepared_state().await; - -// // No messages -// { -// let messages = map!( -// "key_1".to_string() => A2AMessage::PresentationProposal(_presentation_proposal()), -// "key_2".to_string() => A2AMessage::Presentation(_presentation()), -// "key_3".to_string() => A2AMessage::PresentationRequest(_presentation_request()), -// "key_4".to_string() => A2AMessage::PresentationAck(_ack()), -// "key_5".to_string() => A2AMessage::CommonProblemReport(_problem_report()) -// ); - -// assert!(prover.find_message_to_handle(messages).is_none()); -// } -// } - -// #[tokio::test] -// async fn test_prover_find_message_to_handle_from_presentation_sent_state() { -// let _setup = SetupMocks::init(); - -// let prover = _prover_sm_from_request().to_presentation_sent_state().await; - -// // Ack -// { -// let messages = map!( -// "key_1".to_string() => A2AMessage::PresentationProposal(_presentation_proposal()), -// "key_2".to_string() => A2AMessage::Presentation(_presentation()), -// "key_3".to_string() => A2AMessage::PresentationAck(_ack()) -// ); - -// let (uid, message) = prover.find_message_to_handle(messages).unwrap(); -// assert_eq!("key_3", uid); -// assert_match!(A2AMessage::PresentationAck(_), message); -// } - -// // Problem Report -// { -// let messages = map!( -// "key_1".to_string() => A2AMessage::PresentationProposal(_presentation_proposal()), -// "key_2".to_string() => A2AMessage::PresentationRequest(_presentation_request()), -// "key_3".to_string() => A2AMessage::CommonProblemReport(_problem_report()) -// ); - -// let (uid, message) = prover.find_message_to_handle(messages).unwrap(); -// assert_eq!("key_3", uid); -// assert_match!(A2AMessage::CommonProblemReport(_), message); -// } - -// // No messages for different Thread ID -// { -// let messages = map!( -// "key_1".to_string() => A2AMessage::PresentationProposal(_presentation_proposal().set_thread_id("")), -// "key_2".to_string() => A2AMessage::Presentation(_presentation().set_thread_id("")), -// "key_3".to_string() => A2AMessage::PresentationAck(_ack().set_thread_id("")), -// "key_4".to_string() => A2AMessage::CommonProblemReport(_problem_report().set_thread_id("")) -// ); - -// assert!(prover.find_message_to_handle(messages).is_none()); -// } - -// // No messages -// { -// let messages = map!( -// "key_1".to_string() => A2AMessage::PresentationProposal(_presentation_proposal()), -// "key_2".to_string() => A2AMessage::PresentationRequest(_presentation_request()) -// ); - -// assert!(prover.find_message_to_handle(messages).is_none()); -// } -// } - -// #[tokio::test] -// async fn test_prover_find_message_to_handle_from_finished_state() { -// let _setup = SetupMocks::init(); - -// let prover = _prover_sm_from_request().to_finished_state().await; - -// // No messages -// { -// let messages = map!( -// "key_1".to_string() => A2AMessage::PresentationProposal(_presentation_proposal()), -// "key_2".to_string() => A2AMessage::Presentation(_presentation()), -// "key_3".to_string() => A2AMessage::PresentationRequest(_presentation_request()), -// "key_4".to_string() => A2AMessage::PresentationAck(_ack()), -// "key_5".to_string() => A2AMessage::CommonProblemReport(_problem_report()) -// ); - -// assert!(prover.find_message_to_handle(messages).is_none()); -// } -// } -// } - -// mod get_state { -// use super::*; - -// #[tokio::test] -// async fn test_get_state() { -// let _setup = SetupMocks::init(); - -// assert_eq!( -// ProverState::PresentationRequestReceived, -// _prover_sm_from_request().get_state() -// ); -// assert_eq!( -// ProverState::PresentationPrepared, -// _prover_sm_from_request() -// .to_presentation_prepared_state() -// .await -// .get_state() -// ); -// assert_eq!( -// ProverState::PresentationSent, -// _prover_sm_from_request().to_presentation_sent_state().await.get_state() -// ); -// assert_eq!( -// ProverState::Finished, -// _prover_sm_from_request().to_finished_state().await.get_state() -// ); -// } -// } -// } diff --git a/aries_vcx/src/protocols/proof_presentation/verifier/messages.rs b/aries_vcx/src/protocols/proof_presentation/verifier/messages.rs deleted file mode 100644 index 8a4463920d..0000000000 --- a/aries_vcx/src/protocols/proof_presentation/verifier/messages.rs +++ /dev/null @@ -1,70 +0,0 @@ -use messages::{ - msg_fields::protocols::{ - notification::Notification, - present_proof::{ - present::Presentation, propose::ProposePresentation, request::RequestPresentation, PresentProof, - }, - report_problem::ProblemReport, - }, - msg_parts::MsgParts, - AriesMessage, -}; - -use crate::handlers::util::{matches_opt_thread_id, matches_thread_id}; - -type Reason = String; - -#[derive(Debug, Deserialize, Serialize, Clone, PartialEq)] -pub enum VerifierMessages { - VerifyPresentation(Presentation), - RejectPresentationProposal(Reason), - SetPresentationRequest(RequestPresentation), - PresentationProposalReceived(ProposePresentation), - PresentationRejectReceived(ProblemReport), - SendPresentationAck(), - Unknown, -} - -impl VerifierMessages { - pub fn thread_id_matches(&self, thread_id: &str) -> bool { - match self { - Self::VerifyPresentation(msg) => matches_thread_id!(msg, thread_id), - Self::PresentationProposalReceived(msg) => matches_opt_thread_id!(msg, thread_id), - Self::PresentationRejectReceived(msg) => matches_opt_thread_id!(msg, thread_id), - _ => true, - } - } -} - -impl From for VerifierMessages { - fn from(msg: AriesMessage) -> Self { - match msg { - AriesMessage::PresentProof(PresentProof::Presentation(presentation)) => { - VerifierMessages::VerifyPresentation(presentation) - } - AriesMessage::PresentProof(PresentProof::ProposePresentation(presentation_proposal)) => { - VerifierMessages::PresentationProposalReceived(presentation_proposal) - } - AriesMessage::ReportProblem(report) => VerifierMessages::PresentationRejectReceived(report), - AriesMessage::Notification(Notification::ProblemReport(report)) => { - let MsgParts { - id, - content, - decorators, - } = report; - let report = ProblemReport::with_decorators(id, content.0, decorators); - VerifierMessages::PresentationRejectReceived(report) - } - AriesMessage::PresentProof(PresentProof::ProblemReport(report)) => { - let MsgParts { - id, - content, - decorators, - } = report; - let report = ProblemReport::with_decorators(id, content.0, decorators); - VerifierMessages::PresentationRejectReceived(report) - } - _ => VerifierMessages::Unknown, - } - } -} diff --git a/aries_vcx/src/protocols/proof_presentation/verifier/mod.rs b/aries_vcx/src/protocols/proof_presentation/verifier/mod.rs index 03d300e4a9..fa27d15e17 100644 --- a/aries_vcx/src/protocols/proof_presentation/verifier/mod.rs +++ b/aries_vcx/src/protocols/proof_presentation/verifier/mod.rs @@ -1,21 +1,3 @@ -use crate::errors::error::prelude::*; -use crate::global::settings; -use crate::protocols::proof_presentation::verifier::messages::VerifierMessages; - -pub mod messages; pub mod state_machine; pub mod states; pub mod verification_status; - -pub fn verify_thread_id(thread_id: &str, message: &VerifierMessages) -> VcxResult<()> { - if !settings::indy_mocks_enabled() && !message.thread_id_matches(thread_id) { - return Err(AriesVcxError::from_msg( - AriesVcxErrorKind::InvalidJson, - format!( - "Cannot handle message {:?}: thread id does not match, expected {:?}", - message, thread_id - ), - )); - }; - Ok(()) -} diff --git a/aries_vcx/src/protocols/proof_presentation/verifier/state_machine.rs b/aries_vcx/src/protocols/proof_presentation/verifier/state_machine.rs index dc823dc561..78b0a6da5c 100644 --- a/aries_vcx/src/protocols/proof_presentation/verifier/state_machine.rs +++ b/aries_vcx/src/protocols/proof_presentation/verifier/state_machine.rs @@ -1,23 +1,11 @@ -use std::collections::HashMap; use std::fmt::Display; use std::sync::Arc; -use crate::common::proofs::proof_request::PresentationRequestData; -use crate::errors::error::prelude::*; -use crate::handlers::util::{make_attach_from_str, matches_opt_thread_id, matches_thread_id, AttachmentId, Status}; -use crate::protocols::common::build_problem_report_msg; -use crate::protocols::proof_presentation::verifier::messages::VerifierMessages; -use crate::protocols::proof_presentation::verifier::states::finished::FinishedState; -use crate::protocols::proof_presentation::verifier::states::initial::InitialVerifierState; -use crate::protocols::proof_presentation::verifier::states::presentation_proposal_received::PresentationProposalReceivedState; -use crate::protocols::proof_presentation::verifier::states::presentation_request_sent::PresentationRequestSentState; -use crate::protocols::proof_presentation::verifier::states::presentation_request_set::PresentationRequestSetState; -use crate::protocols::proof_presentation::verifier::verification_status::PresentationVerificationStatus; -use crate::protocols::proof_presentation::verifier::verify_thread_id; -use crate::protocols::SendClosure; +use chrono::Utc; +use uuid::Uuid; + use aries_vcx_core::anoncreds::base_anoncreds::BaseAnonCreds; use aries_vcx_core::ledger::base_ledger::AnoncredsLedgerRead; -use chrono::Utc; use messages::decorators::thread::Thread; use messages::decorators::timing::Timing; use messages::msg_fields::protocols::notification::ack::{AckDecorators, AckStatus}; @@ -28,12 +16,24 @@ use messages::msg_fields::protocols::present_proof::problem_report::{ use messages::msg_fields::protocols::present_proof::request::{ RequestPresentation, RequestPresentationContent, RequestPresentationDecorators, }; -use messages::msg_fields::protocols::present_proof::PresentProof; -use messages::msg_fields::protocols::present_proof::{present::Presentation, propose::ProposePresentation}; +use messages::msg_fields::protocols::present_proof::{ + present::Presentation, propose::ProposePresentation, PresentProof, +}; use messages::msg_fields::protocols::report_problem::ProblemReport; use messages::msg_parts::MsgParts; use messages::AriesMessage; -use uuid::Uuid; + +use crate::common::proofs::proof_request::PresentationRequestData; +use crate::errors::error::prelude::*; +use crate::handlers::util::{make_attach_from_str, verify_thread_id, AttachmentId, Status}; +use crate::protocols::common::build_problem_report_msg; +use crate::protocols::proof_presentation::verifier::states::finished::FinishedState; +use crate::protocols::proof_presentation::verifier::states::initial::InitialVerifierState; +use crate::protocols::proof_presentation::verifier::states::presentation_proposal_received::PresentationProposalReceivedState; +use crate::protocols::proof_presentation::verifier::states::presentation_request_sent::PresentationRequestSentState; +use crate::protocols::proof_presentation::verifier::states::presentation_request_set::PresentationRequestSetState; +use crate::protocols::proof_presentation::verifier::verification_status::PresentationVerificationStatus; +use crate::protocols::SendClosure; #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Default)] pub struct VerifierSM { @@ -142,7 +142,7 @@ impl VerifierSM { pub fn receive_presentation_proposal(self, proposal: ProposePresentation) -> VcxResult { verify_thread_id( &self.thread_id, - &VerifierMessages::PresentationProposalReceived(proposal.clone()), + &AriesMessage::PresentProof(PresentProof::ProposePresentation(proposal.clone())), )?; let (state, thread_id) = match self.state { VerifierFullState::Initial(_) => { @@ -155,16 +155,10 @@ impl VerifierSM { thread_id, ) } - VerifierFullState::PresentationRequestSent(_) => { - verify_thread_id( - &self.thread_id, - &VerifierMessages::PresentationProposalReceived(proposal.clone()), - )?; - ( - VerifierFullState::PresentationProposalReceived(PresentationProposalReceivedState::new(proposal)), - self.thread_id.clone(), - ) - } + VerifierFullState::PresentationRequestSent(_) => ( + VerifierFullState::PresentationProposalReceived(PresentationProposalReceivedState::new(proposal)), + self.thread_id.clone(), + ), s => { warn!("Unable to receive presentation proposal in state {}", s); (s, self.thread_id.clone()) @@ -178,10 +172,7 @@ impl VerifierSM { } pub fn receive_presentation_request_reject(self, problem_report: ProblemReport) -> VcxResult { - verify_thread_id( - &self.thread_id, - &VerifierMessages::PresentationRejectReceived(problem_report.clone()), - )?; + verify_thread_id(&self.thread_id, &AriesMessage::ReportProblem(problem_report.clone()))?; let state = match self.state { VerifierFullState::PresentationRequestSent(state) => { VerifierFullState::Finished((state, problem_report).into()) @@ -229,7 +220,7 @@ impl VerifierSM { ) -> VcxResult { verify_thread_id( &self.thread_id, - &VerifierMessages::VerifyPresentation(presentation.clone()), + &AriesMessage::PresentProof(PresentProof::Presentation(presentation.clone())), )?; let state = match self.state { VerifierFullState::PresentationRequestSent(state) => { @@ -296,43 +287,6 @@ impl VerifierSM { Ok(Self { state, ..self }) } - pub fn find_message_to_handle(&self, messages: HashMap) -> Option<(String, AriesMessage)> { - trace!("VerifierSM::find_message_to_handle >>> messages: {:?}", messages); - for (uid, message) in messages { - match &self.state { - VerifierFullState::Initial(_) => match &message { - AriesMessage::PresentProof(PresentProof::ProposePresentation(_)) => { - return Some((uid, message)); - } - AriesMessage::PresentProof(PresentProof::RequestPresentation(_)) => { - return Some((uid, message)); - } - _ => {} - }, - VerifierFullState::PresentationRequestSent(_) => match &message { - AriesMessage::PresentProof(PresentProof::Presentation(presentation)) => { - if matches_thread_id!(presentation, self.thread_id.as_str()) { - return Some((uid, message)); - } - } - AriesMessage::PresentProof(PresentProof::ProposePresentation(proposal)) => { - if matches_opt_thread_id!(proposal, self.thread_id.as_str()) { - return Some((uid, message)); - } - } - AriesMessage::ReportProblem(problem_report) => { - if matches_opt_thread_id!(problem_report, self.thread_id.as_str()) { - return Some((uid, message)); - } - } - _ => {} - }, - _ => {} - }; - } - None - } - pub fn set_request(self, request_data: &PresentationRequestData, comment: Option) -> VcxResult { let Self { source_id, @@ -375,7 +329,7 @@ impl VerifierSM { return Err(AriesVcxError::from_msg( AriesVcxErrorKind::InvalidState, "Can not mark_presentation_request_msg_sent in current state.", - )) + )); } }; Ok(Self { @@ -385,49 +339,6 @@ impl VerifierSM { }) } - pub async fn step( - self, - ledger: &Arc, - anoncreds: &Arc, - message: VerifierMessages, - send_message: Option, - ) -> VcxResult { - trace!("VerifierSM::step >>> message: {:?}", message); - let verifier_sm = match message { - VerifierMessages::PresentationProposalReceived(proposal) => self.receive_presentation_proposal(proposal)?, - VerifierMessages::RejectPresentationProposal(reason) => { - let send_message = send_message.ok_or(AriesVcxError::from_msg( - AriesVcxErrorKind::InvalidState, - "Attempted to call undefined send_message callback", - ))?; - self.reject_presentation_proposal(reason, send_message).await? - } - VerifierMessages::VerifyPresentation(presentation) => { - let send_message = send_message.ok_or(AriesVcxError::from_msg( - AriesVcxErrorKind::InvalidState, - "Attempted to call undefined send_message callback", - ))?; - self.verify_presentation(ledger, anoncreds, presentation, send_message) - .await? - } - VerifierMessages::SendPresentationAck() => { - let send_message = send_message.ok_or(AriesVcxError::from_msg( - AriesVcxErrorKind::InvalidState, - "Attempted to call undefined send_message callback", - ))?; - self.send_presentation_ack(send_message).await? - } - // TODO: Rename to PresentationRequestRejectReceived - VerifierMessages::PresentationRejectReceived(problem_report) => { - self.receive_presentation_request_reject(problem_report)? - } - // TODO: This code path is not used currently; would need to convert ProofRequest to - // ProofRequestData - VerifierMessages::SetPresentationRequest(_) | VerifierMessages::Unknown => self, - }; - Ok(verifier_sm) - } - pub fn source_id(&self) -> String { self.source_id.clone() } @@ -511,600 +422,3 @@ impl VerifierSM { } } } - -// #[cfg(test)] -// pub mod unit_tests { -// use crate::common::proofs::proof_request::test_utils::_presentation_request_data; -// use crate::common::test_utils::mock_profile; -// use crate::test::source_id; -// use crate::utils::devsetup::{SetupEmpty, SetupMocks}; -// use messages::protocols::proof_presentation::presentation::test_utils::{_presentation, _presentation_1}; -// use messages::protocols::proof_presentation::presentation_proposal::test_utils::_presentation_proposal; -// use messages::protocols::proof_presentation::presentation_request::test_utils::_presentation_request; -// use messages::protocols::proof_presentation::test_utils::{_ack, _problem_report}; - -// use super::*; - -// pub fn _verifier_sm() -> VerifierSM { -// VerifierSM::new(&source_id()) -// } - -// pub fn _verifier_sm_from_request() -> VerifierSM { -// VerifierSM::from_request(&source_id(), &_presentation_request_data()).unwrap() -// } - -// pub fn _send_message() -> Option { -// Some(Box::new(|_: A2AMessage| Box::pin(async { VcxResult::Ok(()) }))) -// } - -// pub fn _reason() -> String { -// String::from("Unqualified") -// } - -// impl VerifierSM { -// async fn to_presentation_proposal_received_state(mut self) -> VerifierSM { -// self = self -// .step( -// &mock_profile(), -// VerifierMessages::PresentationProposalReceived(_presentation_proposal()), -// None, -// ) -// .await -// .unwrap(); -// self -// } - -// async fn to_presentation_proposal_received_state_with_request(mut self) -> VerifierSM { -// self = self -// .step( -// &mock_profile(), -// VerifierMessages::PresentationProposalReceived(_presentation_proposal()), -// None, -// ) -// .await -// .unwrap(); -// self = self -// .set_request(&_presentation_request_data(), Some("foo".into())) -// .unwrap(); -// self -// } - -// fn to_presentation_request_sent_state(mut self) -> VerifierSM { -// self = self.mark_presentation_request_msg_sent().unwrap(); -// self -// } - -// async fn to_finished_state(mut self) -> VerifierSM { -// self = self.to_presentation_request_sent_state(); -// self = self -// .step( -// &mock_profile(), -// VerifierMessages::VerifyPresentation(_presentation()), -// _send_message(), -// ) -// .await -// .unwrap(); -// self -// } -// } - -// mod build_messages { -// use super::*; - -// use crate::protocols::proof_presentation::verifier::state_machine::{ -// build_starting_presentation_request, build_verification_ack, -// }; -// use crate::utils::devsetup::{was_in_past, SetupMocks}; -// use messages::a2a::MessageId; - -// #[test] -// fn test_verifier_build_verification_ack() { -// let _setup = SetupMocks::init(); - -// let msg = build_verification_ack("12345"); - -// assert_eq!(msg.id, MessageId::default()); // todo: it should generate random uuid even in test -// assert_eq!(msg.thread.thid, Some("12345".into())); -// assert!(was_in_past( -// &msg.timing.unwrap().out_time.unwrap(), -// chrono::Duration::milliseconds(100) -// ) -// .unwrap()); -// } - -// #[tokio::test] -// async fn test_verifier_build_presentation_request() { -// let _setup = SetupMocks::init(); - -// let presentation_request_data = PresentationRequestData::create(&mock_profile(), "1").await.unwrap(); -// let msg = build_starting_presentation_request("12345", &presentation_request_data, Some("foobar".into())) -// .unwrap(); - -// assert_eq!(msg.id, MessageId("12345".into())); -// assert!(msg.thread.is_none()); -// assert_eq!(msg.comment, Some("foobar".into())); -// assert!(was_in_past( -// &msg.timing.unwrap().out_time.unwrap(), -// chrono::Duration::milliseconds(100) -// ) -// .unwrap()); -// } -// } - -// mod new { -// use super::*; - -// #[test] -// fn test_verifier_from_request() { -// let _setup = SetupMocks::init(); - -// let verifier_sm = _verifier_sm_from_request(); - -// assert_match!(VerifierFullState::PresentationRequestSet(_), verifier_sm.state); -// assert_eq!(source_id(), verifier_sm.source_id()); -// } - -// #[test] -// fn test_verifier_new() { -// let _setup = SetupMocks::init(); - -// let verifier_sm = _verifier_sm(); - -// assert_match!(VerifierFullState::Initial(_), verifier_sm.state); -// assert_eq!(source_id(), verifier_sm.source_id()); -// } -// } - -// mod step { -// use crate::utils::devsetup::was_in_past; -// use crate::utils::mockdata::mock_settings::MockBuilder; - -// use super::*; - -// #[test] -// fn test_verifier_init() { -// let _setup = SetupMocks::init(); - -// let verifier_sm = _verifier_sm_from_request(); -// assert_match!(VerifierFullState::PresentationRequestSet(_), verifier_sm.state); -// } - -// #[test] -// fn test_prover_handle_set_presentation_request_message_from_initial_state() { -// let _setup = SetupMocks::init(); - -// let mut verifier_sm = _verifier_sm(); -// verifier_sm = verifier_sm.set_request(&_presentation_request_data(), None).unwrap(); - -// assert_match!(VerifierFullState::PresentationRequestSet(_), verifier_sm.state); -// } - -// #[test] -// fn test_presentation_request_should_have_set_timing() { -// let _setup = SetupMocks::init(); - -// let mut verifier_sm = _verifier_sm(); -// verifier_sm = verifier_sm.set_request(&_presentation_request_data(), None).unwrap(); - -// assert_match!(VerifierFullState::PresentationRequestSet(_), verifier_sm.state); - -// let msg_presentation_request = verifier_sm.presentation_request_msg().unwrap(); -// let out_time = msg_presentation_request.timing.unwrap().out_time.unwrap(); -// assert!(was_in_past(&out_time, chrono::Duration::milliseconds(100)).unwrap()); -// } - -// #[tokio::test] -// async fn test_prover_handle_set_presentation_proposal_received_from_initial_state() { -// let _setup = SetupMocks::init(); - -// let mut verifier_sm = _verifier_sm(); -// verifier_sm = verifier_sm -// .step( -// &mock_profile(), -// VerifierMessages::PresentationProposalReceived(_presentation_proposal()), -// _send_message(), -// ) -// .await -// .unwrap(); - -// assert_match!(VerifierFullState::PresentationProposalReceived(_), verifier_sm.state); -// } - -// #[test] -// fn test_prover_handle_send_presentation_request_message_from_presentation_request_set_state() { -// let _setup = SetupMocks::init(); - -// let mut verifier_sm = _verifier_sm_from_request(); -// verifier_sm = verifier_sm.mark_presentation_request_msg_sent().unwrap(); - -// assert_match!(VerifierFullState::PresentationRequestSent(_), verifier_sm.state); -// } - -// #[tokio::test] -// async fn test_prover_handle_other_messages_from_presentation_request_set_state() { -// let _setup = SetupMocks::init(); - -// let mut verifier_sm = _verifier_sm_from_request(); - -// verifier_sm = verifier_sm -// .step( -// &mock_profile(), -// VerifierMessages::PresentationRejectReceived(_problem_report()), -// _send_message(), -// ) -// .await -// .unwrap(); -// assert_match!(VerifierFullState::PresentationRequestSet(_), verifier_sm.state); - -// verifier_sm = verifier_sm -// .step( -// &mock_profile(), -// VerifierMessages::VerifyPresentation(_presentation()), -// _send_message(), -// ) -// .await -// .unwrap(); -// assert_match!(VerifierFullState::PresentationRequestSet(_), verifier_sm.state); - -// verifier_sm = verifier_sm -// .step( -// &mock_profile(), -// VerifierMessages::PresentationProposalReceived(_presentation_proposal()), -// _send_message(), -// ) -// .await -// .unwrap(); - -// assert_match!(VerifierFullState::PresentationRequestSet(_), verifier_sm.state); -// } - -// #[tokio::test] -// async fn test_prover_handle_send_presentation_request_message_from_presentation_proposal_received_state() { -// let _setup = SetupMocks::init(); - -// let mut verifier_sm = _verifier_sm() -// .to_presentation_proposal_received_state_with_request() -// .await; -// verifier_sm = verifier_sm.mark_presentation_request_msg_sent().unwrap(); - -// assert_match!(VerifierFullState::PresentationRequestSent(_), verifier_sm.state); -// } - -// #[tokio::test] -// async fn test_prover_handle_send_presentation_request_from_presentation_proposal_received_state_fails_without_request( -// ) { -// let _setup = SetupMocks::init(); - -// let verifier_sm = _verifier_sm().to_presentation_proposal_received_state().await; -// let res = verifier_sm.mark_presentation_request_msg_sent(); - -// assert!(res.is_err()); -// } - -// #[tokio::test] -// async fn test_prover_handle_reject_presentation_proposal_message_from_presentation_proposal_received_state() { -// let _setup = SetupMocks::init(); - -// let mut verifier_sm = _verifier_sm().to_presentation_proposal_received_state().await; -// verifier_sm = verifier_sm -// .step( -// &mock_profile(), -// VerifierMessages::RejectPresentationProposal(_reason()), -// _send_message(), -// ) -// .await -// .unwrap(); - -// assert_match!(VerifierState::Failed, verifier_sm.get_state()); -// assert_match!( -// PresentationVerificationStatus::Unavailable, -// verifier_sm.get_verification_status() -// ); -// } - -// #[tokio::test] -// async fn test_prover_handle_other_messages_from_presentation_proposal_received_state() { -// let _setup = SetupMocks::init(); - -// let mut verifier_sm = _verifier_sm().to_presentation_proposal_received_state().await; -// assert_match!(VerifierFullState::PresentationProposalReceived(_), verifier_sm.state); - -// verifier_sm = verifier_sm -// .step( -// &mock_profile(), -// VerifierMessages::VerifyPresentation(_presentation()), -// _send_message(), -// ) -// .await -// .unwrap(); -// assert_match!(VerifierFullState::PresentationProposalReceived(_), verifier_sm.state); - -// verifier_sm = verifier_sm -// .step( -// &mock_profile(), -// VerifierMessages::PresentationRejectReceived(_problem_report()), -// _send_message(), -// ) -// .await -// .unwrap(); -// assert_match!(VerifierFullState::PresentationProposalReceived(_), verifier_sm.state); -// } - -// #[tokio::test] -// async fn test_prover_handle_verify_presentation_message_from_presentation_request_sent_state() { -// let _setup = SetupMocks::init(); -// let _mock_builder = MockBuilder::init().set_mock_result_for_validate_indy_proof(Ok(true)); - -// let mut verifier_sm = _verifier_sm_from_request(); -// verifier_sm = verifier_sm.mark_presentation_request_msg_sent().unwrap(); -// verifier_sm = verifier_sm -// .step( -// &mock_profile(), -// VerifierMessages::VerifyPresentation(_presentation()), -// _send_message(), -// ) -// .await -// .unwrap(); - -// assert_match!(VerifierFullState::Finished(_), verifier_sm.state); -// assert_eq!( -// PresentationVerificationStatus::Valid, -// verifier_sm.get_verification_status() -// ); -// } - -// #[tokio::test] -// async fn test_prover_handle_invalid_presentation_message() { -// let _setup = SetupMocks::init(); -// let _mock_builder = MockBuilder::init().set_mock_result_for_validate_indy_proof(Ok(false)); - -// let mut verifier_sm = _verifier_sm_from_request(); -// verifier_sm = verifier_sm.mark_presentation_request_msg_sent().unwrap(); -// verifier_sm = verifier_sm -// .step( -// &mock_profile(), -// VerifierMessages::VerifyPresentation(_presentation()), -// _send_message(), -// ) -// .await -// .unwrap(); - -// assert_match!(VerifierState::Finished, verifier_sm.get_state()); -// assert_match!( -// PresentationVerificationStatus::Invalid, -// verifier_sm.get_verification_status() -// ); -// } - -// #[tokio::test] -// async fn test_prover_presentation_verification_fails_with_incorrect_thread_id() { -// let _setup = SetupEmpty::init(); -// let _mock_builder = MockBuilder::init().set_mock_result_for_validate_indy_proof(Ok(false)); - -// let mut verifier_sm = _verifier_sm_from_request(); -// verifier_sm = verifier_sm.mark_presentation_request_msg_sent().unwrap(); -// let res = verifier_sm -// .clone() -// .step( -// &mock_profile(), -// VerifierMessages::VerifyPresentation(_presentation_1()), -// _send_message(), -// ) -// .await; -// assert!(res.is_err()); -// } - -// #[tokio::test] -// async fn test_prover_handle_presentation_proposal_message_from_presentation_request_sent_state() { -// let _setup = SetupMocks::init(); - -// let mut verifier_sm = _verifier_sm_from_request(); -// verifier_sm = verifier_sm.mark_presentation_request_msg_sent().unwrap(); -// verifier_sm = verifier_sm -// .step( -// &mock_profile(), -// VerifierMessages::PresentationProposalReceived(_presentation_proposal()), -// _send_message(), -// ) -// .await -// .unwrap(); - -// assert_match!(VerifierFullState::PresentationProposalReceived(_), verifier_sm.state); -// } - -// #[tokio::test] -// async fn test_prover_handle_presentation_reject_message_from_presentation_request_sent_state() { -// let _setup = SetupMocks::init(); - -// let mut verifier_sm = _verifier_sm_from_request(); -// verifier_sm = verifier_sm.mark_presentation_request_msg_sent().unwrap(); -// verifier_sm = verifier_sm -// .step( -// &mock_profile(), -// VerifierMessages::PresentationRejectReceived(_problem_report()), -// _send_message(), -// ) -// .await -// .unwrap(); - -// assert_match!(VerifierState::Failed, verifier_sm.get_state()); -// } - -// #[tokio::test] -// async fn test_prover_handle_messages_from_presentation_finished_state() { -// let _setup = SetupMocks::init(); -// let _mock_builder = MockBuilder::init().set_mock_result_for_validate_indy_proof(Ok(true)); - -// let mut verifier_sm = _verifier_sm_from_request(); -// verifier_sm = verifier_sm.mark_presentation_request_msg_sent().unwrap(); -// verifier_sm = verifier_sm -// .step( -// &mock_profile(), -// VerifierMessages::VerifyPresentation(_presentation()), -// _send_message(), -// ) -// .await -// .unwrap(); - -// verifier_sm = verifier_sm -// .step( -// &mock_profile(), -// VerifierMessages::PresentationRejectReceived(_problem_report()), -// _send_message(), -// ) -// .await -// .unwrap(); -// assert_match!(VerifierState::Finished, verifier_sm.get_state()); - -// verifier_sm = verifier_sm -// .step( -// &mock_profile(), -// VerifierMessages::PresentationProposalReceived(_presentation_proposal()), -// _send_message(), -// ) -// .await -// .unwrap(); -// assert_match!(VerifierState::Finished, verifier_sm.get_state()); -// } -// } - -// mod find_message_to_handle { -// use super::*; - -// #[test] -// fn test_verifier_find_message_to_handle_from_initial_state() { -// let _setup = SetupMocks::init(); - -// let verifier = _verifier_sm_from_request(); - -// // No messages -// { -// let messages = map!( -// "key_1".to_string() => A2AMessage::PresentationProposal(_presentation_proposal()), -// "key_2".to_string() => A2AMessage::Presentation(_presentation()), -// "key_3".to_string() => A2AMessage::PresentationRequest(_presentation_request()), -// "key_4".to_string() => A2AMessage::PresentationAck(_ack()), -// "key_5".to_string() => A2AMessage::CommonProblemReport(_problem_report()) -// ); - -// assert!(verifier.find_message_to_handle(messages).is_none()); -// } -// } - -// #[test] -// fn test_verifier_find_message_to_handle_from_presentation_request_sent_state() { -// let _setup = SetupMocks::init(); - -// let verifier = _verifier_sm_from_request().to_presentation_request_sent_state(); - -// // Presentation -// { -// let messages = map!( -// "key_1".to_string() => A2AMessage::PresentationRequest(_presentation_request()), -// "key_2".to_string() => A2AMessage::Presentation(_presentation()), -// "key_3".to_string() => A2AMessage::PresentationAck(_ack()) -// ); - -// let s = verifier.get_state(); -// warn!("State is = {:?}", s); -// let (uid, message) = verifier.find_message_to_handle(messages).unwrap(); -// assert_eq!("key_2", uid); -// assert_match!(A2AMessage::Presentation(_), message); -// } - -// // Presentation Proposal -// { -// let messages = map!( -// "key_1".to_string() => A2AMessage::PresentationRequest(_presentation_request()), -// "key_2".to_string() => A2AMessage::PresentationProposal(_presentation_proposal()), -// "key_3".to_string() => A2AMessage::PresentationAck(_ack()) -// ); - -// let (uid, message) = verifier.find_message_to_handle(messages).unwrap(); -// assert_eq!("key_2", uid); -// assert_match!(A2AMessage::PresentationProposal(_), message); -// } - -// // Problem Report -// { -// let messages = map!( -// "key_1".to_string() => A2AMessage::PresentationRequest(_presentation_request()), -// "key_2".to_string() => A2AMessage::PresentationAck(_ack()), -// "key_3".to_string() => A2AMessage::CommonProblemReport(_problem_report()) -// ); - -// let (uid, message) = verifier.find_message_to_handle(messages).unwrap(); -// assert_eq!("key_3", uid); -// assert_match!(A2AMessage::CommonProblemReport(_), message); -// } - -// // No messages for different Thread ID -// { -// let messages = map!( -// "key_1".to_string() => A2AMessage::PresentationProposal(_presentation_proposal().set_thread_id("")), -// "key_2".to_string() => A2AMessage::Presentation(_presentation().set_thread_id("")), -// "key_3".to_string() => A2AMessage::PresentationAck(_ack().set_thread_id("")), -// "key_4".to_string() => A2AMessage::CommonProblemReport(_problem_report().set_thread_id("")) -// ); - -// assert!(verifier.find_message_to_handle(messages).is_none()); -// } - -// // No messages -// { -// let messages = map!( -// "key_1".to_string() => A2AMessage::PresentationRequest(_presentation_request()) -// ); - -// assert!(verifier.find_message_to_handle(messages).is_none()); -// } -// } - -// #[tokio::test] -// async fn test_verifier_find_message_to_handle_from_finished_state() { -// let _setup = SetupMocks::init(); - -// let verifier = _verifier_sm_from_request().to_finished_state().await; - -// // No messages -// { -// let messages = map!( -// "key_1".to_string() => A2AMessage::PresentationProposal(_presentation_proposal()), -// "key_2".to_string() => A2AMessage::Presentation(_presentation()), -// "key_3".to_string() => A2AMessage::PresentationRequest(_presentation_request()), -// "key_4".to_string() => A2AMessage::PresentationAck(_ack()), -// "key_5".to_string() => A2AMessage::CommonProblemReport(_problem_report()) -// ); - -// assert!(verifier.find_message_to_handle(messages).is_none()); -// } -// } -// } - -// mod get_state { -// use crate::utils::mockdata::mock_settings::MockBuilder; - -// use super::*; - -// #[tokio::test] -// async fn test_get_state() { -// let _setup = SetupMocks::init(); -// let _mock_builder = MockBuilder::init().set_mock_result_for_validate_indy_proof(Ok(true)); - -// assert_eq!( -// VerifierState::PresentationRequestSet, -// _verifier_sm_from_request().get_state() -// ); -// assert_eq!( -// VerifierState::PresentationRequestSent, -// _verifier_sm_from_request() -// .to_presentation_request_sent_state() -// .get_state() -// ); -// assert_eq!( -// VerifierState::Finished, -// _verifier_sm_from_request().to_finished_state().await.get_state() -// ); -// } -// } -// } diff --git a/aries_vcx/tests/test_creds_proofs.rs b/aries_vcx/tests/test_creds_proofs.rs index 1cbdbcd6f1..ba2cf1b478 100644 --- a/aries_vcx/tests/test_creds_proofs.rs +++ b/aries_vcx/tests/test_creds_proofs.rs @@ -563,6 +563,8 @@ mod tests { use serde_json::Value; + use crate::utils::devsetup_util::issuer_update_with_mediator; + use crate::utils::devsetup_util::verifier_update_with_mediator; use aries_vcx::common::test_utils::create_and_store_nonrevocable_credential_def; use aries_vcx::handlers::issuance::holder::Holder; use aries_vcx::handlers::proof_presentation::prover::Prover; @@ -643,16 +645,16 @@ mod tests { prover_select_credentials_and_send_proof(&mut consumer, &consumer_to_institution, None, None).await; info!("test_proof_should_be_validated :: verifier :: going to verify proof"); - verifier - .update_state( - &institution.profile.inject_wallet(), - &institution.profile.inject_anoncreds_ledger_read(), - &institution.profile.inject_anoncreds(), - &institution.agency_client, - &institution_to_consumer, - ) - .await - .unwrap(); + verifier_update_with_mediator( + &mut verifier, + &institution.profile.inject_wallet(), + &institution.profile.inject_anoncreds_ledger_read(), + &institution.profile.inject_anoncreds(), + &institution.agency_client, + &institution_to_consumer, + ) + .await + .unwrap(); assert_eq!( verifier.get_verification_status(), PresentationVerificationStatus::Valid @@ -709,16 +711,16 @@ mod tests { prover_select_credentials_and_send_proof(&mut consumer, &consumer_to_institution, None, None).await; info!("test_proof_with_predicates_should_be_validated :: verifier :: going to verify proof"); - verifier - .update_state( - &institution.profile.inject_wallet(), - &institution.profile.inject_anoncreds_ledger_read(), - &institution.profile.inject_anoncreds(), - &institution.agency_client, - &institution_to_consumer, - ) - .await - .unwrap(); + verifier_update_with_mediator( + &mut verifier, + &institution.profile.inject_wallet(), + &institution.profile.inject_anoncreds_ledger_read(), + &institution.profile.inject_anoncreds(), + &institution.agency_client, + &institution_to_consumer, + ) + .await + .unwrap(); assert_eq!( verifier.get_verification_status(), PresentationVerificationStatus::Valid @@ -850,9 +852,14 @@ mod tests { consumer1.migrate().await; prover_select_credentials_and_send_proof(&mut consumer1, &consumer1_to_verifier, None, None).await; - proof_verifier - .update_state( - &verifier.profile.inject_wallet(), &verifier.profile.inject_anoncreds_ledger_read(), &verifier.profile.inject_anoncreds(), &verifier.agency_client, &verifier_to_consumer1) + verifier_update_with_mediator( + &mut proof_verifier, + &verifier.profile.inject_wallet(), + &verifier.profile.inject_anoncreds_ledger_read(), + &verifier.profile.inject_anoncreds(), + &verifier.agency_client, + &verifier_to_consumer1 + ) .await .unwrap(); assert_eq!( @@ -874,8 +881,8 @@ mod tests { consumer2.migrate().await; prover_select_credentials_and_send_proof(&mut consumer2, &consumer2_to_verifier, None, None).await; - proof_verifier - .update_state( + verifier_update_with_mediator( + &mut proof_verifier, &verifier.profile.inject_wallet(), &verifier.profile.inject_anoncreds_ledger_read(), &verifier.profile.inject_anoncreds(), @@ -924,16 +931,16 @@ mod tests { verifier.migrate().await; prover_select_credentials_and_send_proof(&mut consumer, &consumer_to_verifier, request_name1, None).await; - proof_verifier - .update_state( - &verifier.profile.inject_wallet(), - &verifier.profile.inject_anoncreds_ledger_read(), - &verifier.profile.inject_anoncreds(), - &verifier.agency_client, - &verifier_to_consumer, - ) - .await - .unwrap(); + verifier_update_with_mediator( + &mut proof_verifier, + &verifier.profile.inject_wallet(), + &verifier.profile.inject_anoncreds_ledger_read(), + &verifier.profile.inject_anoncreds(), + &verifier.agency_client, + &verifier_to_consumer, + ) + .await + .unwrap(); assert_eq!( proof_verifier.get_verification_status(), PresentationVerificationStatus::Valid @@ -953,16 +960,16 @@ mod tests { consumer.migrate().await; prover_select_credentials_and_send_proof(&mut consumer, &consumer_to_verifier, request_name2, None).await; - proof_verifier - .update_state( - &verifier.profile.inject_wallet(), - &verifier.profile.inject_anoncreds_ledger_read(), - &verifier.profile.inject_anoncreds(), - &verifier.agency_client, - &verifier_to_consumer, - ) - .await - .unwrap(); + verifier_update_with_mediator( + &mut proof_verifier, + &verifier.profile.inject_wallet(), + &verifier.profile.inject_anoncreds_ledger_read(), + &verifier.profile.inject_anoncreds(), + &verifier.agency_client, + &verifier_to_consumer, + ) + .await + .unwrap(); assert_eq!( proof_verifier.get_verification_status(), PresentationVerificationStatus::Valid @@ -1011,8 +1018,8 @@ mod tests { institution.migrate().await; prover_select_credentials_and_send_proof(&mut consumer, &consumer_to_institution, request_name1, None).await; - verifier - .update_state( + verifier_update_with_mediator( + &mut verifier, &institution.profile.inject_wallet(), &institution.profile.inject_anoncreds_ledger_read(), &institution.profile.inject_anoncreds(), @@ -1040,8 +1047,8 @@ mod tests { consumer.migrate().await; prover_select_credentials_and_send_proof(&mut consumer, &consumer_to_institution, request_name2, None).await; - verifier - .update_state( + verifier_update_with_mediator( + &mut verifier, &institution.profile.inject_wallet(), &institution.profile.inject_anoncreds_ledger_read(), &institution.profile.inject_anoncreds(), @@ -1171,16 +1178,16 @@ mod tests { assert_eq!(presentation_thread_id, verifier.get_thread_id().unwrap()); info!("test_real_proof :: AS INSTITUTION VALIDATE PROOF"); - verifier - .update_state( - &institution.profile.inject_wallet(), - &institution.profile.inject_anoncreds_ledger_read(), - &institution.profile.inject_anoncreds(), - &institution.agency_client, - &issuer_to_consumer, - ) - .await - .unwrap(); + verifier_update_with_mediator( + &mut verifier, + &institution.profile.inject_wallet(), + &institution.profile.inject_anoncreds_ledger_read(), + &institution.profile.inject_anoncreds(), + &institution.agency_client, + &issuer_to_consumer, + ) + .await + .unwrap(); assert_eq!( verifier.get_verification_status(), PresentationVerificationStatus::Valid @@ -1248,9 +1255,14 @@ mod tests { .await; prover_select_credentials_and_send_proof(&mut consumer, &consumer_to_verifier, req1, Some(&credential_data1)) .await; - proof_verifier - .update_state( - &verifier.profile.inject_wallet(), &verifier.profile.inject_anoncreds_ledger_read(), &verifier.profile.inject_anoncreds(), &verifier.agency_client, &verifier_to_consumer) + verifier_update_with_mediator( + &mut proof_verifier, + &verifier.profile.inject_wallet(), + &verifier.profile.inject_anoncreds_ledger_read(), + &verifier.profile.inject_anoncreds(), + &verifier.agency_client, + &verifier_to_consumer + ) .await .unwrap(); assert_eq!( @@ -1273,9 +1285,14 @@ mod tests { prover_select_credentials_and_send_proof(&mut consumer, &consumer_to_verifier, req2, Some(&credential_data2)) .await; - proof_verifier - .update_state( - &verifier.profile.inject_wallet(), &verifier.profile.inject_anoncreds_ledger_read(), &verifier.profile.inject_anoncreds(), &verifier.agency_client, &verifier_to_consumer) + verifier_update_with_mediator( + &mut proof_verifier, + &verifier.profile.inject_wallet(), + &verifier.profile.inject_anoncreds_ledger_read(), + &verifier.profile.inject_anoncreds(), + &verifier.agency_client, + &verifier_to_consumer + ) .await .unwrap(); assert_eq!( @@ -1347,13 +1364,7 @@ mod tests { decline_offer(&mut consumer, &consumer_to_institution, &mut holder).await; assert_eq!(IssuerState::OfferSent, issuer.get_state()); tokio::time::sleep(Duration::from_millis(1000)).await; - issuer - .update_state( - &institution.profile.inject_wallet(), - &institution.profile.inject_anoncreds(), - &institution.agency_client, - &institution_to_consumer, - ) + issuer_update_with_mediator(&mut issuer, &institution.agency_client, &institution_to_consumer) .await .unwrap(); assert_eq!(IssuerState::Failed, issuer.get_state()); diff --git a/aries_vcx/tests/test_creds_proofs_revocations.rs b/aries_vcx/tests/test_creds_proofs_revocations.rs index bfbaf0e708..09cd3dfc00 100644 --- a/aries_vcx/tests/test_creds_proofs_revocations.rs +++ b/aries_vcx/tests/test_creds_proofs_revocations.rs @@ -9,13 +9,14 @@ mod integration_tests { use std::thread; use std::time::Duration; + use crate::utils::devsetup_util::verifier_update_with_mediator; use aries_vcx::protocols::proof_presentation::prover::state_machine::ProverState; use aries_vcx::protocols::proof_presentation::verifier::state_machine::VerifierState; use aries_vcx::protocols::proof_presentation::verifier::verification_status::PresentationVerificationStatus; use aries_vcx::utils::devsetup::*; use crate::utils::devsetup_alice::create_alice; - use crate::utils::devsetup_faber::{create_faber_trustee, Faber}; + use crate::utils::devsetup_faber::create_faber_trustee; #[cfg(feature = "migration")] use crate::utils::migration::Migratable; use crate::utils::scenarios::test_utils::{ @@ -95,16 +96,16 @@ mod integration_tests { prover_select_credentials_and_send_proof(&mut consumer, &consumer_to_institution, None, None).await; info!("test_basic_revocation :: verifier :: going to verify proof"); - verifier - .update_state( - &institution.profile.inject_wallet(), - &institution.profile.inject_anoncreds_ledger_read(), - &institution.profile.inject_anoncreds(), - &institution.agency_client, - &institution_to_consumer, - ) - .await - .unwrap(); + verifier_update_with_mediator( + &mut verifier, + &institution.profile.inject_wallet(), + &institution.profile.inject_anoncreds_ledger_read(), + &institution.profile.inject_anoncreds(), + &institution.agency_client, + &institution_to_consumer, + ) + .await + .unwrap(); assert_eq!(verifier.get_state(), VerifierState::Finished); assert_eq!( verifier.get_verification_status(), @@ -227,16 +228,16 @@ mod integration_tests { prover_select_credentials_and_send_proof(&mut consumer, &consumer_to_institution, request_name1, None) .await; - verifier - .update_state( - &institution.profile.inject_wallet(), - &institution.profile.inject_anoncreds_ledger_read(), - &institution.profile.inject_anoncreds(), - &institution.agency_client, - &institution_to_consumer, - ) - .await - .unwrap(); + verifier_update_with_mediator( + &mut verifier, + &institution.profile.inject_wallet(), + &institution.profile.inject_anoncreds_ledger_read(), + &institution.profile.inject_anoncreds(), + &institution.agency_client, + &institution_to_consumer, + ) + .await + .unwrap(); assert_eq!(verifier.get_state(), VerifierState::Finished); assert_eq!( verifier.get_verification_status(), @@ -261,16 +262,16 @@ mod integration_tests { prover_select_credentials_and_send_proof(&mut consumer, &consumer_to_institution, request_name2, None) .await; - verifier - .update_state( - &institution.profile.inject_wallet(), - &institution.profile.inject_anoncreds_ledger_read(), - &institution.profile.inject_anoncreds(), - &institution.agency_client, - &institution_to_consumer, - ) - .await - .unwrap(); + verifier_update_with_mediator( + &mut verifier, + &institution.profile.inject_wallet(), + &institution.profile.inject_anoncreds_ledger_read(), + &institution.profile.inject_anoncreds(), + &institution.agency_client, + &institution_to_consumer, + ) + .await + .unwrap(); assert_eq!(verifier.get_state(), VerifierState::Finished); assert_eq!( verifier.get_verification_status(), @@ -371,34 +372,34 @@ mod integration_tests { let mut verifier3 = verifier_create_proof_and_send_request(&mut institution, &institution_to_consumer3, &schema_id, &cred_def_id, request_name1).await; prover_select_credentials_and_send_proof(&mut consumer3, &consumer_to_institution3, request_name1, None).await; - verifier1 - .update_state( - &institution.profile.inject_wallet(), - &institution.profile.inject_anoncreds_ledger_read(), - &institution.profile.inject_anoncreds(), - &institution.agency_client, - &institution_to_consumer1, - ) + verifier_update_with_mediator( + &mut verifier1, + &institution.profile.inject_wallet(), + &institution.profile.inject_anoncreds_ledger_read(), + &institution.profile.inject_anoncreds(), + &institution.agency_client, + &institution_to_consumer1, + ) .await .unwrap(); - verifier2 - .update_state( - &institution.profile.inject_wallet(), - &institution.profile.inject_anoncreds_ledger_read(), - &institution.profile.inject_anoncreds(), - &institution.agency_client, - &institution_to_consumer2, - ) + verifier_update_with_mediator( + &mut verifier2, + &institution.profile.inject_wallet(), + &institution.profile.inject_anoncreds_ledger_read(), + &institution.profile.inject_anoncreds(), + &institution.agency_client, + &institution_to_consumer2, + ) .await .unwrap(); - verifier3 - .update_state( - &institution.profile.inject_wallet(), - &institution.profile.inject_anoncreds_ledger_read(), - &institution.profile.inject_anoncreds(), - &institution.agency_client, - &institution_to_consumer3, - ) + verifier_update_with_mediator( + &mut verifier3, + &institution.profile.inject_wallet(), + &institution.profile.inject_anoncreds_ledger_read(), + &institution.profile.inject_anoncreds(), + &institution.agency_client, + &institution_to_consumer3, + ) .await .unwrap(); assert_eq!(verifier1.get_verification_status(), PresentationVerificationStatus::Valid); @@ -424,34 +425,34 @@ mod integration_tests { assert_ne!(verifier1, verifier3); assert_ne!(verifier2, verifier3); - verifier1 - .update_state( - &institution.profile.inject_wallet(), - &institution.profile.inject_anoncreds_ledger_read(), - &institution.profile.inject_anoncreds(), - &institution.agency_client, - &institution_to_consumer1, - ) + verifier_update_with_mediator( + &mut verifier1, + &institution.profile.inject_wallet(), + &institution.profile.inject_anoncreds_ledger_read(), + &institution.profile.inject_anoncreds(), + &institution.agency_client, + &institution_to_consumer1, + ) .await .unwrap(); - verifier2 - .update_state( - &institution.profile.inject_wallet(), - &institution.profile.inject_anoncreds_ledger_read(), - &institution.profile.inject_anoncreds(), - &institution.agency_client, - &institution_to_consumer2, - ) + verifier_update_with_mediator( + &mut verifier2, + &institution.profile.inject_wallet(), + &institution.profile.inject_anoncreds_ledger_read(), + &institution.profile.inject_anoncreds(), + &institution.agency_client, + &institution_to_consumer2, + ) .await .unwrap(); - verifier3 - .update_state( - &institution.profile.inject_wallet(), - &institution.profile.inject_anoncreds_ledger_read(), - &institution.profile.inject_anoncreds(), - &institution.agency_client, - &institution_to_consumer3, - ) + verifier_update_with_mediator( + &mut verifier3, + &institution.profile.inject_wallet(), + &institution.profile.inject_anoncreds_ledger_read(), + &institution.profile.inject_anoncreds(), + &institution.agency_client, + &institution_to_consumer3, + ) .await .unwrap(); assert_eq!(verifier1.get_verification_status(), PresentationVerificationStatus::Invalid); @@ -517,14 +518,14 @@ mod integration_tests { assert_eq!(ProverState::PresentationSent, prover.get_state()); info!("test_revoked_credential_might_still_work :: verifier :: going to verify proof"); - verifier - .update_state( - &institution.profile.inject_wallet(), - &institution.profile.inject_anoncreds_ledger_read(), - &institution.profile.inject_anoncreds(), - &institution.agency_client, - &institution_to_consumer, - ) + verifier_update_with_mediator( + &mut verifier, + &institution.profile.inject_wallet(), + &institution.profile.inject_anoncreds_ledger_read(), + &institution.profile.inject_anoncreds(), + &institution.agency_client, + &institution_to_consumer, + ) .await .unwrap(); assert_eq!(verifier.get_state(), VerifierState::Finished); @@ -588,14 +589,14 @@ mod integration_tests { let mut proof_verifier = verifier_create_proof_and_send_request(&mut verifier, &verifier_to_consumer, &schema_id, &cred_def_id, req1).await; prover_select_credentials_and_send_proof(&mut consumer, &consumer_to_verifier, req1, Some(&credential_data1)).await; - proof_verifier - .update_state( - &verifier.profile.inject_wallet(), - &verifier.profile.inject_anoncreds_ledger_read(), - &verifier.profile.inject_anoncreds(), - &verifier.agency_client, - &verifier_to_consumer, - ) + verifier_update_with_mediator( + &mut proof_verifier, + &verifier.profile.inject_wallet(), + &verifier.profile.inject_anoncreds_ledger_read(), + &verifier.profile.inject_anoncreds(), + &verifier.agency_client, + &verifier_to_consumer, + ) .await .unwrap(); assert_eq!(proof_verifier.get_state(), VerifierState::Finished); @@ -607,14 +608,14 @@ mod integration_tests { #[cfg(feature = "migration")] consumer.migrate().await; - proof_verifier - .update_state( - &verifier.profile.inject_wallet(), - &verifier.profile.inject_anoncreds_ledger_read(), - &verifier.profile.inject_anoncreds(), - &verifier.agency_client, - &verifier_to_consumer, - ) + verifier_update_with_mediator( + &mut proof_verifier, + &verifier.profile.inject_wallet(), + &verifier.profile.inject_anoncreds_ledger_read(), + &verifier.profile.inject_anoncreds(), + &verifier.agency_client, + &verifier_to_consumer, + ) .await .unwrap(); assert_eq!(proof_verifier.get_verification_status(), PresentationVerificationStatus::Valid); @@ -679,14 +680,14 @@ mod integration_tests { let mut proof_verifier = verifier_create_proof_and_send_request(&mut verifier, &verifier_to_consumer, &schema_id, &cred_def_id, req1).await; prover_select_credentials_and_send_proof(&mut consumer, &consumer_to_verifier, req1, Some(&credential_data1)).await; - proof_verifier - .update_state( - &verifier.profile.inject_wallet(), - &verifier.profile.inject_anoncreds_ledger_read(), - &verifier.profile.inject_anoncreds(), - &verifier.agency_client, - &verifier_to_consumer, - ) + verifier_update_with_mediator( + &mut proof_verifier, + &verifier.profile.inject_wallet(), + &verifier.profile.inject_anoncreds_ledger_read(), + &verifier.profile.inject_anoncreds(), + &verifier.agency_client, + &verifier_to_consumer, + ) .await .unwrap(); assert_eq!(proof_verifier.get_verification_status(), PresentationVerificationStatus::Valid); @@ -697,14 +698,14 @@ mod integration_tests { consumer.migrate().await; prover_select_credentials_and_send_proof(&mut consumer, &consumer_to_verifier, req2, Some(&credential_data2)).await; - proof_verifier - .update_state( - &verifier.profile.inject_wallet(), - &verifier.profile.inject_anoncreds_ledger_read(), - &verifier.profile.inject_anoncreds(), - &verifier.agency_client, - &verifier_to_consumer, - ) + verifier_update_with_mediator( + &mut proof_verifier, + &verifier.profile.inject_wallet(), + &verifier.profile.inject_anoncreds_ledger_read(), + &verifier.profile.inject_anoncreds(), + &verifier.agency_client, + &verifier_to_consumer, + ) .await .unwrap(); assert_eq!(proof_verifier.get_verification_status(), PresentationVerificationStatus::Invalid); @@ -762,14 +763,14 @@ mod integration_tests { let mut proof_verifier = verifier_create_proof_and_send_request(&mut verifier, &verifier_to_consumer, &schema_id, &cred_def_id, req1).await; prover_select_credentials_and_send_proof(&mut consumer, &consumer_to_verifier, req1, Some(&credential_data1)).await; - proof_verifier - .update_state( - &verifier.profile.inject_wallet(), - &verifier.profile.inject_anoncreds_ledger_read(), - &verifier.profile.inject_anoncreds(), - &verifier.agency_client, - &verifier_to_consumer, - ) + verifier_update_with_mediator( + &mut proof_verifier, + &verifier.profile.inject_wallet(), + &verifier.profile.inject_anoncreds_ledger_read(), + &verifier.profile.inject_anoncreds(), + &verifier.agency_client, + &verifier_to_consumer, + ) .await .unwrap(); assert_eq!(proof_verifier.get_verification_status(), PresentationVerificationStatus::Valid); @@ -783,14 +784,14 @@ mod integration_tests { consumer.migrate().await; prover_select_credentials_and_send_proof(&mut consumer, &consumer_to_verifier, req2, Some(&credential_data2)).await; - proof_verifier - .update_state( - &verifier.profile.inject_wallet(), - &verifier.profile.inject_anoncreds_ledger_read(), - &verifier.profile.inject_anoncreds(), - &verifier.agency_client, - &verifier_to_consumer, - ) + verifier_update_with_mediator( + &mut proof_verifier, + &verifier.profile.inject_wallet(), + &verifier.profile.inject_anoncreds_ledger_read(), + &verifier.profile.inject_anoncreds(), + &verifier.agency_client, + &verifier_to_consumer, + ) .await .unwrap(); assert_eq!(proof_verifier.get_verification_status(), PresentationVerificationStatus::Valid); @@ -856,14 +857,14 @@ mod integration_tests { let mut proof_verifier = verifier_create_proof_and_send_request(&mut verifier, &verifier_to_consumer, &schema_id, &cred_def_id, req1).await; prover_select_credentials_and_send_proof(&mut consumer, &consumer_to_verifier, req1, Some(&credential_data1)).await; - proof_verifier - .update_state( - &verifier.profile.inject_wallet(), - &verifier.profile.inject_anoncreds_ledger_read(), - &verifier.profile.inject_anoncreds(), - &verifier.agency_client, - &verifier_to_consumer, - ) + verifier_update_with_mediator( + &mut proof_verifier, + &verifier.profile.inject_wallet(), + &verifier.profile.inject_anoncreds_ledger_read(), + &verifier.profile.inject_anoncreds(), + &verifier.agency_client, + &verifier_to_consumer, + ) .await .unwrap(); assert_eq!(proof_verifier.get_verification_status(), PresentationVerificationStatus::Invalid); @@ -873,14 +874,14 @@ mod integration_tests { let mut proof_verifier = verifier_create_proof_and_send_request(&mut verifier, &verifier_to_consumer, &schema_id, &cred_def_id, req2).await; prover_select_credentials_and_send_proof(&mut consumer, &consumer_to_verifier, req2, Some(&credential_data2)).await; - proof_verifier - .update_state( - &verifier.profile.inject_wallet(), - &verifier.profile.inject_anoncreds_ledger_read(), - &verifier.profile.inject_anoncreds(), - &verifier.agency_client, - &verifier_to_consumer, - ) + verifier_update_with_mediator( + &mut proof_verifier, + &verifier.profile.inject_wallet(), + &verifier.profile.inject_anoncreds_ledger_read(), + &verifier.profile.inject_anoncreds(), + &verifier.agency_client, + &verifier_to_consumer, + ) .await .unwrap(); assert_eq!(proof_verifier.get_verification_status(), PresentationVerificationStatus::Valid); @@ -947,14 +948,14 @@ mod integration_tests { #[cfg(feature = "migration")] verifier.migrate().await; - proof_verifier - .update_state( - &verifier.profile.inject_wallet(), - &verifier.profile.inject_anoncreds_ledger_read(), - &verifier.profile.inject_anoncreds(), - &verifier.agency_client, - &verifier_to_consumer, - ) + verifier_update_with_mediator( + &mut proof_verifier, + &verifier.profile.inject_wallet(), + &verifier.profile.inject_anoncreds_ledger_read(), + &verifier.profile.inject_anoncreds(), + &verifier.agency_client, + &verifier_to_consumer, + ) .await .unwrap(); assert_eq!(proof_verifier.get_verification_status(), PresentationVerificationStatus::Valid); @@ -965,14 +966,14 @@ mod integration_tests { consumer.migrate().await; prover_select_credentials_and_send_proof(&mut consumer, &consumer_to_verifier, req2, Some(&credential_data2)).await; - proof_verifier - .update_state( - &verifier.profile.inject_wallet(), - &verifier.profile.inject_anoncreds_ledger_read(), - &verifier.profile.inject_anoncreds(), - &verifier.agency_client, - &verifier_to_consumer, - ) + verifier_update_with_mediator( + &mut proof_verifier, + &verifier.profile.inject_wallet(), + &verifier.profile.inject_anoncreds_ledger_read(), + &verifier.profile.inject_anoncreds(), + &verifier.agency_client, + &verifier_to_consumer, + ) .await .unwrap(); assert_eq!(proof_verifier.get_verification_status(), PresentationVerificationStatus::Invalid); diff --git a/aries_vcx/tests/utils/devsetup_alice.rs b/aries_vcx/tests/utils/devsetup_alice.rs index b15bbe66e0..188f586f83 100644 --- a/aries_vcx/tests/utils/devsetup_alice.rs +++ b/aries_vcx/tests/utils/devsetup_alice.rs @@ -1,8 +1,9 @@ use std::collections::HashMap; use std::sync::Arc; -use futures::future::BoxFuture; - +use crate::utils::devsetup_util::{ + get_credential_offer_messages, get_proof_request_messages, holder_update_with_mediator, prover_update_with_mediator, +}; use agency_client::agency_client::AgencyClient; use agency_client::configuration::{AgencyClientConfig, AgentProvisionConfig}; use agency_client::MessageStatusCode; @@ -11,9 +12,7 @@ use aries_vcx::core::profile::profile::Profile; use aries_vcx::errors::error::{AriesVcxError, AriesVcxErrorKind, VcxResult}; use aries_vcx::global::settings::DEFAULT_LINK_SECRET_ALIAS; use aries_vcx::handlers::connection::mediated_connection::{ConnectionState, MediatedConnection}; -use aries_vcx::handlers::issuance::holder::test_utils::get_credential_offer_messages; use aries_vcx::handlers::issuance::holder::Holder; -use aries_vcx::handlers::proof_presentation::prover::test_utils::get_proof_request_messages; use aries_vcx::handlers::proof_presentation::prover::Prover; use aries_vcx::handlers::proof_presentation::types::SelectedCredentials; use aries_vcx::handlers::revocation_notification::receiver::RevocationNotificationReceiver; @@ -22,7 +21,7 @@ use aries_vcx::protocols::issuance::holder::state_machine::HolderState; use aries_vcx::protocols::mediated_connection::invitee::state_machine::InviteeState; use aries_vcx::protocols::proof_presentation::prover::state_machine::ProverState; use aries_vcx::utils::devsetup::{ - dev_build_featured_profile, dev_setup_wallet_indy, SetupProfile, AGENCY_DID, AGENCY_ENDPOINT, AGENCY_VERKEY, + dev_build_featured_profile, dev_setup_wallet_indy, AGENCY_DID, AGENCY_ENDPOINT, AGENCY_VERKEY, }; use aries_vcx::utils::provision::provision_cloud_agent; use aries_vcx::utils::random::generate_random_seed; @@ -194,16 +193,16 @@ impl Alice { } pub async fn accept_credential(&mut self) { - self.credential - .update_state( - &self.profile.inject_anoncreds_ledger_read(), - &self.profile.inject_anoncreds(), - &self.profile.inject_wallet(), - &self.agency_client, - &self.connection, - ) - .await - .unwrap(); + holder_update_with_mediator( + &mut self.credential, + &self.profile.inject_anoncreds_ledger_read(), + &self.profile.inject_anoncreds(), + &self.profile.inject_wallet(), + &self.agency_client, + &self.connection, + ) + .await + .unwrap(); assert_eq!(HolderState::Finished, self.credential.get_state()); assert_eq!(Status::Success.code(), self.credential.get_credential_status().unwrap()); } @@ -300,14 +299,7 @@ impl Alice { } pub async fn ensure_presentation_verified(&mut self) { - self.prover - .update_state( - &self.profile.inject_anoncreds_ledger_read(), - &self.profile.inject_anoncreds(), - &self.profile.inject_wallet(), - &self.agency_client, - &self.connection, - ) + prover_update_with_mediator(&mut self.prover, &self.agency_client, &self.connection) .await .unwrap(); assert_eq!(Status::Success.code(), self.prover.presentation_status()); diff --git a/aries_vcx/tests/utils/devsetup_faber.rs b/aries_vcx/tests/utils/devsetup_faber.rs index cf797ed13c..44cd5664f6 100644 --- a/aries_vcx/tests/utils/devsetup_faber.rs +++ b/aries_vcx/tests/utils/devsetup_faber.rs @@ -3,6 +3,8 @@ use std::sync::Arc; use futures::future::BoxFuture; use serde_json::json; +use crate::utils::devsetup_util::issuer_update_with_mediator; +use crate::utils::devsetup_util::verifier_update_with_mediator; use agency_client::agency_client::AgencyClient; use agency_client::configuration::{AgencyClientConfig, AgentProvisionConfig}; use aries_vcx::common::ledger::transactions::write_endpoint_legacy; @@ -10,7 +12,6 @@ use aries_vcx::common::primitives::credential_definition::{CredentialDef, Creden use aries_vcx::common::primitives::credential_schema::Schema; use aries_vcx::common::proofs::proof_request::PresentationRequestData; use aries_vcx::core::profile::profile::Profile; -use aries_vcx::core::profile::vdrtools_profile::VdrtoolsProfile; use aries_vcx::errors::error::VcxResult; use aries_vcx::global::settings; use aries_vcx::global::settings::{init_issuer_config, DEFAULT_LINK_SECRET_ALIAS}; @@ -27,11 +28,10 @@ use aries_vcx::protocols::proof_presentation::verifier::verification_status::Pre use aries_vcx::protocols::revocation_notification::sender::state_machine::SenderConfigBuilder; use aries_vcx::utils::constants::TRUSTEE_SEED; use aries_vcx::utils::devsetup::{ - dev_build_featured_profile, dev_setup_wallet_indy, SetupProfile, AGENCY_DID, AGENCY_ENDPOINT, AGENCY_VERKEY, + dev_build_featured_profile, dev_setup_wallet_indy, AGENCY_DID, AGENCY_ENDPOINT, AGENCY_VERKEY, }; use aries_vcx::utils::provision::provision_cloud_agent; use aries_vcx::utils::random::generate_random_seed; -use aries_vcx_core::errors::error::VcxCoreResult; use aries_vcx_core::wallet::indy::wallet::get_verkey_from_wallet; use aries_vcx_core::wallet::indy::IndySdkWallet; use diddoc_legacy::aries::service::AriesService; @@ -300,26 +300,14 @@ impl Faber { ) .await .unwrap(); - self.issuer_credential - .update_state( - &self.profile.inject_wallet(), - &self.profile.inject_anoncreds(), - &self.agency_client, - &self.connection, - ) + issuer_update_with_mediator(&mut self.issuer_credential, &self.agency_client, &self.connection) .await .unwrap(); assert_eq!(IssuerState::OfferSent, self.issuer_credential.get_state()); } pub async fn send_credential(&mut self) { - self.issuer_credential - .update_state( - &self.profile.inject_wallet(), - &self.profile.inject_anoncreds(), - &self.agency_client, - &self.connection, - ) + issuer_update_with_mediator(&mut self.issuer_credential, &self.agency_client, &self.connection) .await .unwrap(); assert_eq!(IssuerState::RequestReceived, self.issuer_credential.get_state()); @@ -334,13 +322,7 @@ impl Faber { ) .await .unwrap(); - self.issuer_credential - .update_state( - &self.profile.inject_wallet(), - &self.profile.inject_anoncreds(), - &self.agency_client, - &self.connection, - ) + issuer_update_with_mediator(&mut self.issuer_credential, &self.agency_client, &self.connection) .await .unwrap(); assert_eq!(IssuerState::CredentialSent, self.issuer_credential.get_state()); @@ -359,16 +341,16 @@ impl Faber { ) .await .unwrap(); - self.verifier - .update_state( - &self.profile.inject_wallet(), - &self.profile.inject_anoncreds_ledger_read(), - &self.profile.inject_anoncreds(), - &self.agency_client, - &self.connection, - ) - .await - .unwrap(); + verifier_update_with_mediator( + &mut self.verifier, + &self.profile.inject_wallet(), + &self.profile.inject_anoncreds_ledger_read(), + &self.profile.inject_anoncreds(), + &self.agency_client, + &self.connection, + ) + .await + .unwrap(); assert_eq!(VerifierState::PresentationRequestSent, self.verifier.get_state()); } @@ -383,16 +365,16 @@ impl Faber { expected_state: VerifierState, expected_verification_status: PresentationVerificationStatus, ) { - self.verifier - .update_state( - &self.profile.inject_wallet(), - &self.profile.inject_anoncreds_ledger_read(), - &self.profile.inject_anoncreds(), - &self.agency_client, - &self.connection, - ) - .await - .unwrap(); + verifier_update_with_mediator( + &mut self.verifier, + &self.profile.inject_wallet(), + &self.profile.inject_anoncreds_ledger_read(), + &self.profile.inject_anoncreds(), + &self.agency_client, + &self.connection, + ) + .await + .unwrap(); assert_eq!(expected_state, self.verifier.get_state()); assert_eq!(expected_verification_status, self.verifier.get_verification_status()); } diff --git a/aries_vcx/tests/utils/devsetup_util.rs b/aries_vcx/tests/utils/devsetup_util.rs index 4f097ce198..af9746e97d 100644 --- a/aries_vcx/tests/utils/devsetup_util.rs +++ b/aries_vcx/tests/utils/devsetup_util.rs @@ -1,13 +1,29 @@ -#[cfg(feature = "modular_libs")] -use aries_vcx::core::profile::modular_libs_profile::ModularLibsProfile; +use agency_client::agency_client::AgencyClient; use aries_vcx::core::profile::profile::Profile; +use aries_vcx::errors::error::VcxResult; +use aries_vcx::handlers::connection::mediated_connection::MediatedConnection; +use aries_vcx::handlers::issuance::holder::Holder; +use aries_vcx::handlers::issuance::issuer::Issuer; +use aries_vcx::handlers::issuance::{mediated_holder, mediated_issuer}; +use aries_vcx::handlers::proof_presentation::prover::Prover; +use aries_vcx::handlers::proof_presentation::verifier::Verifier; +use aries_vcx::handlers::proof_presentation::{mediated_prover, mediated_verifier}; +use aries_vcx::protocols::issuance::holder::state_machine::HolderState; +use aries_vcx::protocols::issuance::issuer::state_machine::IssuerState; +use aries_vcx::protocols::proof_presentation::prover::state_machine::ProverState; +use aries_vcx::protocols::proof_presentation::verifier::state_machine::VerifierState; +use aries_vcx_core::anoncreds::base_anoncreds::BaseAnonCreds; +use aries_vcx_core::ledger::base_ledger::AnoncredsLedgerRead; use aries_vcx_core::wallet::base_wallet::BaseWallet; +use messages::msg_fields::protocols::cred_issuance::propose_credential::ProposeCredential; +use messages::msg_fields::protocols::cred_issuance::CredentialIssuance; +use messages::msg_fields::protocols::present_proof::PresentProof; +use messages::AriesMessage; +use std::sync::Arc; #[cfg(test)] pub mod test_utils { use agency_client::api::downloaded_message::DownloadedMessage; - #[cfg(feature = "modular_libs")] - use aries_vcx::core::profile::modular_libs_profile::ModularLibsProfile; use aries_vcx::errors::error::{AriesVcxError, AriesVcxErrorKind, VcxResult}; use messages::msg_fields::protocols::connection::Connection; use messages::msg_fields::protocols::cred_issuance::CredentialIssuance; @@ -74,3 +90,136 @@ pub mod test_utils { None } } + +pub async fn get_proof_request_messages( + agency_client: &AgencyClient, + connection: &MediatedConnection, +) -> VcxResult { + let presentation_requests: Vec = connection + .get_messages(agency_client) + .await? + .into_iter() + .filter_map(|(_, message)| match message { + AriesMessage::PresentProof(PresentProof::RequestPresentation(_)) => Some(message), + _ => None, + }) + .collect(); + + Ok(json!(presentation_requests).to_string()) +} + +pub async fn prover_update_with_mediator( + sm: &mut Prover, + agency_client: &AgencyClient, + connection: &MediatedConnection, +) -> VcxResult { + trace!("prover_update_with_mediator >>> "); + if !sm.progressable_by_message() { + return Ok(sm.get_state()); + } + let messages = connection.get_messages(agency_client).await?; + if let Some((uid, msg)) = mediated_prover::prover_find_message_to_handle(sm, messages) { + sm.process_aries_msg(msg.into()).await?; + connection.update_message_status(&uid, agency_client).await?; + } + Ok(sm.get_state()) +} + +pub async fn verifier_update_with_mediator( + sm: &mut Verifier, + wallet: &Arc, + ledger: &Arc, + anoncreds: &Arc, + agency_client: &AgencyClient, + connection: &MediatedConnection, +) -> VcxResult { + trace!("verifier_update_with_mediator >>> "); + if !sm.progressable_by_message() { + return Ok(sm.get_state()); + } + let send_message = connection.send_message_closure(Arc::clone(wallet)).await?; + + let messages = connection.get_messages(agency_client).await?; + if let Some((uid, msg)) = mediated_verifier::verifier_find_message_to_handle(sm, messages) { + sm.process_aries_msg(ledger, anoncreds, msg.into(), Some(send_message)) + .await?; + connection.update_message_status(&uid, agency_client).await?; + } + Ok(sm.get_state()) +} + +pub async fn holder_update_with_mediator( + sm: &mut Holder, + ledger: &Arc, + anoncreds: &Arc, + wallet: &Arc, + agency_client: &AgencyClient, + connection: &MediatedConnection, +) -> VcxResult { + trace!("holder_update_with_mediator >>>"); + if sm.is_terminal_state() { + return Ok(sm.get_state()); + } + let send_message = connection.send_message_closure(Arc::clone(wallet)).await?; + + let messages = connection.get_messages(agency_client).await?; + if let Some((uid, msg)) = mediated_holder::holder_find_message_to_handle(sm, messages) { + sm.process_aries_msg(ledger, anoncreds, msg.into(), Some(send_message)) + .await?; + connection.update_message_status(&uid, agency_client).await?; + } + Ok(sm.get_state()) +} + +// todo: returns specific type +pub async fn get_credential_offer_messages( + agency_client: &AgencyClient, + connection: &MediatedConnection, +) -> VcxResult { + let credential_offers: Vec = connection + .get_messages(agency_client) + .await? + .into_iter() + .filter_map(|(_, a2a_message)| match a2a_message { + AriesMessage::CredentialIssuance(CredentialIssuance::OfferCredential(_)) => Some(a2a_message), + _ => None, + }) + .collect(); + + Ok(json!(credential_offers).to_string()) +} + +pub async fn issuer_update_with_mediator( + sm: &mut Issuer, + agency_client: &AgencyClient, + connection: &MediatedConnection, +) -> VcxResult { + trace!("issuer_update_with_mediator >>>"); + let messages = connection.get_messages(agency_client).await?; + if let Some((uid, msg)) = mediated_issuer::issuer_find_message_to_handle(sm, messages) { + trace!("Issuer::update_state >>> found msg to handle; uid: {uid}, msg: {msg:?}"); + sm.process_aries_msg(msg.into()).await?; + connection.update_message_status(&uid, agency_client).await?; + } else { + trace!("Issuer::update_state >>> found no msg to handle"); + } + Ok(sm.get_state()) +} + +// todo: returns specific type +pub async fn get_credential_proposal_messages( + agency_client: &AgencyClient, + connection: &MediatedConnection, +) -> VcxResult> { + let credential_proposals: Vec<(String, ProposeCredential)> = connection + .get_messages(agency_client) + .await? + .into_iter() + .filter_map(|(uid, message)| match message { + AriesMessage::CredentialIssuance(CredentialIssuance::ProposeCredential(proposal)) => Some((uid, proposal)), + _ => None, + }) + .collect(); + + Ok(credential_proposals) +} diff --git a/aries_vcx/tests/utils/scenarios.rs b/aries_vcx/tests/utils/scenarios.rs index 3e94a85c93..a0b6cf2c46 100644 --- a/aries_vcx/tests/utils/scenarios.rs +++ b/aries_vcx/tests/utils/scenarios.rs @@ -29,17 +29,20 @@ pub mod test_utils { use crate::utils::devsetup_alice::Alice; use crate::utils::devsetup_faber::Faber; + use crate::utils::devsetup_util::get_credential_proposal_messages; + use crate::utils::devsetup_util::verifier_update_with_mediator; + use crate::utils::devsetup_util::{ + get_credential_offer_messages, get_proof_request_messages, holder_update_with_mediator, + issuer_update_with_mediator, prover_update_with_mediator, + }; use aries_vcx::common::ledger::transactions::into_did_doc; use aries_vcx::common::primitives::credential_definition::CredentialDef; use aries_vcx::common::primitives::revocation_registry::RevocationRegistry; use aries_vcx::common::proofs::proof_request::PresentationRequestData; use aries_vcx::common::proofs::proof_request_internal::AttrInfo; use aries_vcx::handlers::connection::mediated_connection::{ConnectionState, MediatedConnection}; - use aries_vcx::handlers::issuance::holder::test_utils::get_credential_offer_messages; use aries_vcx::handlers::issuance::holder::Holder; - use aries_vcx::handlers::issuance::issuer::test_utils::get_credential_proposal_messages; use aries_vcx::handlers::issuance::issuer::Issuer; - use aries_vcx::handlers::proof_presentation::prover::test_utils::get_proof_request_messages; use aries_vcx::handlers::proof_presentation::prover::Prover; use aries_vcx::handlers::proof_presentation::verifier::Verifier; use aries_vcx::protocols::issuance::holder::state_machine::HolderState; @@ -352,16 +355,16 @@ pub mod test_utils { cred_def_id: &str, comment: &str, ) { - holder - .update_state( - &alice.profile.inject_anoncreds_ledger_read(), - &alice.profile.inject_anoncreds(), - &alice.profile.inject_wallet(), - &alice.agency_client, - connection, - ) - .await - .unwrap(); + holder_update_with_mediator( + holder, + &alice.profile.inject_anoncreds_ledger_read(), + &alice.profile.inject_anoncreds(), + &alice.profile.inject_wallet(), + &alice.agency_client, + connection, + ) + .await + .unwrap(); assert_eq!(HolderState::OfferReceived, holder.get_state()); assert!(holder.get_offer().is_ok()); let (address1, address2, city, state, zip) = attr_names(); @@ -460,13 +463,7 @@ pub mod test_utils { tails_dir: Option, ) { assert_eq!(IssuerState::OfferSent, issuer.get_state()); - issuer - .update_state( - &faber.profile.inject_wallet(), - &faber.profile.inject_anoncreds(), - &faber.agency_client, - connection, - ) + issuer_update_with_mediator(issuer, &faber.agency_client, connection) .await .unwrap(); assert_eq!(IssuerState::ProposalReceived, issuer.get_state()); @@ -495,16 +492,16 @@ pub mod test_utils { } pub async fn accept_offer(alice: &mut Alice, connection: &MediatedConnection, holder: &mut Holder) { - holder - .update_state( - &alice.profile.inject_anoncreds_ledger_read(), - &alice.profile.inject_anoncreds(), - &alice.profile.inject_wallet(), - &alice.agency_client, - connection, - ) - .await - .unwrap(); + holder_update_with_mediator( + holder, + &alice.profile.inject_anoncreds_ledger_read(), + &alice.profile.inject_anoncreds(), + &alice.profile.inject_wallet(), + &alice.agency_client, + connection, + ) + .await + .unwrap(); assert_eq!(HolderState::OfferReceived, holder.get_state()); assert!(holder.get_offer().is_ok()); let my_pw_did = connection.pairwise_info().pw_did.to_string(); @@ -524,16 +521,16 @@ pub mod test_utils { } pub async fn decline_offer(alice: &mut Alice, connection: &MediatedConnection, holder: &mut Holder) { - holder - .update_state( - &alice.profile.inject_anoncreds_ledger_read(), - &alice.profile.inject_anoncreds(), - &alice.profile.inject_wallet(), - &alice.agency_client, - connection, - ) - .await - .unwrap(); + holder_update_with_mediator( + holder, + &alice.profile.inject_anoncreds_ledger_read(), + &alice.profile.inject_anoncreds(), + &alice.profile.inject_wallet(), + &alice.agency_client, + connection, + ) + .await + .unwrap(); assert_eq!(HolderState::OfferReceived, holder.get_state()); holder .decline_offer( @@ -562,13 +559,7 @@ pub mod test_utils { assert_eq!(IssuerState::OfferSent, issuer_credential.get_state()); assert!(!issuer_credential.is_revokable()); - issuer_credential - .update_state( - &faber.profile.inject_wallet(), - &faber.profile.inject_anoncreds(), - &faber.agency_client, - issuer_to_consumer, - ) + issuer_update_with_mediator(issuer_credential, &faber.agency_client, issuer_to_consumer) .await .unwrap(); assert_eq!(IssuerState::RequestReceived, issuer_credential.get_state()); @@ -598,16 +589,16 @@ pub mod test_utils { .unwrap(), revokable ); - holder_credential - .update_state( - &alice.profile.inject_anoncreds_ledger_read(), - &alice.profile.inject_anoncreds(), - &alice.profile.inject_wallet(), - &alice.agency_client, - consumer_to_issuer, - ) - .await - .unwrap(); + holder_update_with_mediator( + holder_credential, + &alice.profile.inject_anoncreds_ledger_read(), + &alice.profile.inject_anoncreds(), + &alice.profile.inject_wallet(), + &alice.agency_client, + consumer_to_issuer, + ) + .await + .unwrap(); assert_eq!(HolderState::Finished, holder_credential.get_state()); assert_eq!( holder_credential @@ -655,14 +646,7 @@ pub mod test_utils { connection: &MediatedConnection, cred_def_id: &str, ) { - prover - .update_state( - &alice.profile.inject_anoncreds_ledger_read(), - &alice.profile.inject_anoncreds(), - &alice.profile.inject_wallet(), - &alice.agency_client, - connection, - ) + prover_update_with_mediator(prover, &alice.agency_client, connection) .await .unwrap(); assert_eq!(prover.get_state(), ProverState::PresentationRequestReceived); @@ -686,16 +670,16 @@ pub mod test_utils { } pub async fn accept_proof_proposal(faber: &mut Faber, verifier: &mut Verifier, connection: &MediatedConnection) { - verifier - .update_state( - &faber.profile.inject_wallet(), - &faber.profile.inject_anoncreds_ledger_read(), - &faber.profile.inject_anoncreds(), - &faber.agency_client, - connection, - ) - .await - .unwrap(); + verifier_update_with_mediator( + verifier, + &faber.profile.inject_wallet(), + &faber.profile.inject_anoncreds_ledger_read(), + &faber.profile.inject_anoncreds(), + &faber.agency_client, + connection, + ) + .await + .unwrap(); assert_eq!(verifier.get_state(), VerifierState::PresentationProposalReceived); let proposal = verifier.get_presentation_proposal().unwrap(); let attrs = proposal @@ -727,16 +711,16 @@ pub mod test_utils { pub async fn reject_proof_proposal(faber: &mut Faber, connection: &MediatedConnection) -> Verifier { let mut verifier = Verifier::create("1").unwrap(); - verifier - .update_state( - &faber.profile.inject_wallet(), - &faber.profile.inject_anoncreds_ledger_read(), - &faber.profile.inject_anoncreds(), - &faber.agency_client, - connection, - ) - .await - .unwrap(); + verifier_update_with_mediator( + &mut verifier, + &faber.profile.inject_wallet(), + &faber.profile.inject_anoncreds_ledger_read(), + &faber.profile.inject_anoncreds(), + &faber.agency_client, + connection, + ) + .await + .unwrap(); assert_eq!(verifier.get_state(), VerifierState::PresentationProposalReceived); verifier .decline_presentation_proposal( @@ -758,14 +742,7 @@ pub mod test_utils { connection: &MediatedConnection, ) { assert_eq!(prover.get_state(), ProverState::PresentationProposalSent); - prover - .update_state( - &alice.profile.inject_anoncreds_ledger_read(), - &alice.profile.inject_anoncreds(), - &alice.profile.inject_wallet(), - &alice.agency_client, - connection, - ) + prover_update_with_mediator(prover, &alice.agency_client, connection) .await .unwrap(); assert_eq!(prover.get_state(), ProverState::Failed); @@ -894,16 +871,16 @@ pub mod test_utils { } pub async fn verify_proof(faber: &mut Faber, verifier: &mut Verifier, connection: &MediatedConnection) { - verifier - .update_state( - &faber.profile.inject_wallet(), - &faber.profile.inject_anoncreds_ledger_read(), - &faber.profile.inject_anoncreds(), - &faber.agency_client, - &connection, - ) - .await - .unwrap(); + verifier_update_with_mediator( + verifier, + &faber.profile.inject_wallet(), + &faber.profile.inject_anoncreds_ledger_read(), + &faber.profile.inject_anoncreds(), + &faber.agency_client, + &connection, + ) + .await + .unwrap(); assert_eq!(verifier.get_state(), VerifierState::Finished); assert_eq!( verifier.get_verification_status(), @@ -1146,14 +1123,7 @@ pub mod test_utils { connection: &MediatedConnection, requested_values: Option<&str>, ) -> SelectedCredentials { - prover - .update_state( - &alice.profile.inject_anoncreds_ledger_read(), - &alice.profile.inject_anoncreds(), - &alice.profile.inject_wallet(), - &alice.agency_client, - connection, - ) + prover_update_with_mediator(prover, &alice.agency_client, connection) .await .unwrap(); assert_eq!(prover.get_state(), ProverState::PresentationRequestReceived); diff --git a/libvcx_core/src/api_vcx/api_handle/credential.rs b/libvcx_core/src/api_vcx/api_handle/credential.rs index a7cfa64bc7..bcd49f9cf0 100644 --- a/libvcx_core/src/api_vcx/api_handle/credential.rs +++ b/libvcx_core/src/api_vcx/api_handle/credential.rs @@ -5,6 +5,7 @@ use serde_json; use aries_vcx::agency_client::testing::mocking::AgencyMockDecrypted; use aries_vcx::handlers::issuance::holder::Holder; +use aries_vcx::handlers::issuance::mediated_holder::holder_find_message_to_handle; use aries_vcx::utils::constants::GET_MESSAGES_DECRYPTED_RESPONSE; use aries_vcx::{global::settings::indy_mocks_enabled, utils::mockdata::mockdata_credex::ARIES_CREDENTIAL_OFFER}; @@ -132,7 +133,7 @@ pub async fn update_state(credential_handle: u32, message: Option<&str>, connect ) })?; credential - .step( + .process_aries_msg( &get_main_anoncreds_ledger_read()?, &get_main_anoncreds()?, message.into(), @@ -141,9 +142,9 @@ pub async fn update_state(credential_handle: u32, message: Option<&str>, connect .await?; } else { let messages = mediated_connection::get_messages(connection_handle).await?; - if let Some((uid, msg)) = credential.find_message_to_handle(messages) { + if let Some((uid, msg)) = holder_find_message_to_handle(&credential, messages) { credential - .step( + .process_aries_msg( &get_main_anoncreds_ledger_read()?, &get_main_anoncreds()?, msg.into(), diff --git a/libvcx_core/src/api_vcx/api_handle/disclosed_proof.rs b/libvcx_core/src/api_vcx/api_handle/disclosed_proof.rs index 7470880b82..20d03f89c8 100644 --- a/libvcx_core/src/api_vcx/api_handle/disclosed_proof.rs +++ b/libvcx_core/src/api_vcx/api_handle/disclosed_proof.rs @@ -4,6 +4,7 @@ use aries_vcx::messages::AriesMessage; use serde_json; use aries_vcx::agency_client::testing::mocking::AgencyMockDecrypted; +use aries_vcx::handlers::proof_presentation::mediated_prover::prover_find_message_to_handle; use aries_vcx::handlers::proof_presentation::prover::Prover; use aries_vcx::utils::constants::GET_MESSAGES_DECRYPTED_RESPONSE; use aries_vcx::{ @@ -84,26 +85,12 @@ pub async fn update_state(handle: u32, message: Option<&str>, connection_handle: ) })?; trace!("disclosed_proof::update_state >>> updating using message {:?}", message); - proof - .handle_message( - &get_main_anoncreds_ledger_read()?, - &get_main_anoncreds()?, - message.into(), - Some(send_message), - ) - .await?; + proof.process_aries_msg(message.into()).await?; } else { let messages = mediated_connection::get_messages(connection_handle).await?; trace!("disclosed_proof::update_state >>> found messages: {:?}", messages); - if let Some((uid, message)) = proof.find_message_to_handle(messages) { - proof - .handle_message( - &get_main_anoncreds_ledger_read()?, - &get_main_anoncreds()?, - message.into(), - Some(send_message), - ) - .await?; + if let Some((uid, message)) = prover_find_message_to_handle(&proof, messages) { + proof.process_aries_msg(message).await?; mediated_connection::update_message_status(connection_handle, &uid).await?; }; } diff --git a/libvcx_core/src/api_vcx/api_handle/issuer_credential.rs b/libvcx_core/src/api_vcx/api_handle/issuer_credential.rs index e12c5cc301..cd8a939607 100644 --- a/libvcx_core/src/api_vcx/api_handle/issuer_credential.rs +++ b/libvcx_core/src/api_vcx/api_handle/issuer_credential.rs @@ -4,6 +4,7 @@ use aries_vcx::protocols::SendClosure; use serde_json; use aries_vcx::handlers::issuance::issuer::Issuer; +use aries_vcx::handlers::issuance::mediated_issuer::issuer_find_message_to_handle; use crate::api_vcx::api_global::profile::{get_main_anoncreds, get_main_wallet}; use crate::api_vcx::api_handle::connection; @@ -30,31 +31,24 @@ pub fn issuer_credential_create(source_id: String) -> LibvcxResult { ISSUER_CREDENTIAL_MAP.add(Issuer::create(&source_id)?) } -// todo: move connection_handle as second arg. pub async fn update_state(handle: u32, message: Option<&str>, connection_handle: u32) -> LibvcxResult { trace!("issuer_credential::update_state >>> "); let mut credential = ISSUER_CREDENTIAL_MAP.get_cloned(handle)?; if credential.is_terminal_state() { return Ok(credential.get_state().into()); } - let send_message = mediated_connection::send_message_closure(connection_handle).await?; - if let Some(message) = message { - let message: AriesMessage = serde_json::from_str(message).map_err(|err| { + let msg: AriesMessage = serde_json::from_str(message).map_err(|err| { LibvcxError::from_msg( LibvcxErrorKind::InvalidOption, format!("Cannot update state: Message deserialization failed: {:?}", err), ) })?; - credential - .step(&get_main_anoncreds()?, message.into(), Some(send_message)) - .await?; + credential.process_aries_msg(msg.into()).await?; } else { let messages = mediated_connection::get_messages(connection_handle).await?; - if let Some((uid, msg)) = credential.find_message_to_handle(messages) { - credential - .step(&get_main_anoncreds()?, msg.into(), Some(send_message)) - .await?; + if let Some((uid, msg)) = issuer_find_message_to_handle(&credential, messages) { + credential.process_aries_msg(msg.into()).await?; mediated_connection::update_message_status(connection_handle, &uid).await?; } } @@ -86,9 +80,7 @@ pub async fn update_state_with_message_nonmediated( format!("Cannot update state: Message deserialization failed: {:?}", err), ) })?; - credential - .step(&get_main_anoncreds()?, message.into(), Some(send_message)) - .await?; + credential.process_aries_msg(message.into()).await?; let res: u32 = credential.get_state().into(); ISSUER_CREDENTIAL_MAP.insert(handle, credential)?; diff --git a/libvcx_core/src/api_vcx/api_handle/proof.rs b/libvcx_core/src/api_vcx/api_handle/proof.rs index b8992ef5ca..b6ca264a4d 100644 --- a/libvcx_core/src/api_vcx/api_handle/proof.rs +++ b/libvcx_core/src/api_vcx/api_handle/proof.rs @@ -2,6 +2,7 @@ use aries_vcx::messages::AriesMessage; use serde_json; use aries_vcx::common::proofs::proof_request::PresentationRequestData; +use aries_vcx::handlers::proof_presentation::mediated_verifier::verifier_find_message_to_handle; use aries_vcx::handlers::proof_presentation::verifier::Verifier; use aries_vcx::protocols::proof_presentation::verifier::verification_status::PresentationVerificationStatus; use aries_vcx::protocols::SendClosure; @@ -72,7 +73,7 @@ pub async fn update_state(handle: u32, message: Option<&str>, connection_handle: })?; trace!("proof::update_state >>> updating using message {:?}", message); proof - .handle_message( + .process_aries_msg( &get_main_anoncreds_ledger_read()?, &get_main_anoncreds()?, message.into(), @@ -82,9 +83,9 @@ pub async fn update_state(handle: u32, message: Option<&str>, connection_handle: } else { let messages = mediated_connection::get_messages(connection_handle).await?; trace!("proof::update_state >>> found messages: {:?}", messages); - if let Some((uid, message)) = proof.find_message_to_handle(messages) { + if let Some((uid, message)) = verifier_find_message_to_handle(&proof, messages) { proof - .handle_message( + .process_aries_msg( &get_main_anoncreds_ledger_read()?, &get_main_anoncreds()?, message.into(), @@ -127,7 +128,7 @@ pub async fn update_state_nonmediated(handle: u32, connection_handle: u32, messa ) })?; proof - .handle_message( + .process_aries_msg( &get_main_anoncreds_ledger_read()?, &get_main_anoncreds()?, message.into(),