From 63b609b602a12514ec22f3c3c70b0f33a1d218b7 Mon Sep 17 00:00:00 2001 From: Miroslav Kovar Date: Wed, 14 Oct 2020 15:10:29 +0200 Subject: [PATCH 1/2] Return / accept strictly A2AMessages Signed-off-by: Miroslav Kovar --- .../aries/handlers/issuance/holder/holder.rs | 2 +- .../handlers/issuance/holder/state_machine.rs | 4 +- .../proof_presentation/verifier/verifier.rs | 2 +- libvcx/src/connection.rs | 20 ++-- libvcx/src/credential.rs | 24 ++--- libvcx/src/credential_request.rs | 93 ------------------- libvcx/src/disclosed_proof.rs | 5 +- libvcx/src/lib.rs | 1 - libvcx/src/proof.rs | 4 +- libvcx/src/utils/mockdata/mockdata_proof.rs | 4 + 10 files changed, 33 insertions(+), 126 deletions(-) delete mode 100644 libvcx/src/credential_request.rs diff --git a/libvcx/src/aries/handlers/issuance/holder/holder.rs b/libvcx/src/aries/handlers/issuance/holder/holder.rs index f7621ea5c3..7bcc02ab11 100644 --- a/libvcx/src/aries/handlers/issuance/holder/holder.rs +++ b/libvcx/src/aries/handlers/issuance/holder/holder.rs @@ -49,7 +49,7 @@ impl Holder { self.holder_sm.get_source_id() } - pub fn get_credential(&self) -> VcxResult<(String, Credential)> { + pub fn get_credential(&self) -> VcxResult<(String, A2AMessage)> { self.holder_sm.get_credential() } diff --git a/libvcx/src/aries/handlers/issuance/holder/state_machine.rs b/libvcx/src/aries/handlers/issuance/holder/state_machine.rs index 20864d9117..16800e293c 100644 --- a/libvcx/src/aries/handlers/issuance/holder/state_machine.rs +++ b/libvcx/src/aries/handlers/issuance/holder/state_machine.rs @@ -212,12 +212,12 @@ impl HolderSM { } } - pub fn get_credential(&self) -> VcxResult<(String, Credential)> { + pub fn get_credential(&self) -> VcxResult<(String, A2AMessage)> { match self.state { HolderState::Finished(ref state) => { let cred_id = state.cred_id.clone().ok_or(VcxError::from_msg(VcxErrorKind::InvalidState, "Cannot get credential: Credential Id not found"))?; let credential = state.credential.clone().ok_or(VcxError::from_msg(VcxErrorKind::InvalidState, "Cannot get credential: Credential not found"))?; - Ok((cred_id, credential)) + Ok((cred_id, credential.to_a2a_message())) } _ => Err(VcxError::from_msg(VcxErrorKind::NotReady, "Cannot get credential: Credential Issuance is not finished yet")) } diff --git a/libvcx/src/aries/handlers/proof_presentation/verifier/verifier.rs b/libvcx/src/aries/handlers/proof_presentation/verifier/verifier.rs index 98a9fa0903..ef5bdfcbd1 100644 --- a/libvcx/src/aries/handlers/proof_presentation/verifier/verifier.rs +++ b/libvcx/src/aries/handlers/proof_presentation/verifier/verifier.rs @@ -104,7 +104,7 @@ impl Verifier { pub fn get_presentation(&self) -> VcxResult { trace!("Verifier::get_presentation >>>"); - let proof = self.verifier_sm.presentation()?; + let proof = self.verifier_sm.presentation()?.to_a2a_message(); Ok(json!(proof).to_string()) } diff --git a/libvcx/src/connection.rs b/libvcx/src/connection.rs index f6660689e9..b63c808b04 100644 --- a/libvcx/src/connection.rs +++ b/libvcx/src/connection.rs @@ -3,7 +3,7 @@ use std::collections::HashMap; use serde_json; use aries::handlers::connection::agent_info::AgentInfo; -use aries::handlers::connection::connection::{Connection as ConnectionV3, SmConnectionState}; +use aries::handlers::connection::connection::{Connection, SmConnectionState}; use aries::messages::a2a::A2AMessage; use aries::messages::connection::did_doc::DidDoc; use aries::messages::connection::invite::Invitation as InvitationV3; @@ -17,7 +17,7 @@ use utils::error; use utils::object_cache::ObjectCache; lazy_static! { - static ref CONNECTION_MAP: ObjectCache = ObjectCache::::new("connections-cache"); + static ref CONNECTION_MAP: ObjectCache = ObjectCache::::new("connections-cache"); } pub fn create_agent_keys(source_id: &str, pw_did: &str, pw_verkey: &str) -> VcxResult<(String, String)> { @@ -90,21 +90,21 @@ pub fn get_source_id(handle: u32) -> VcxResult { }) } -fn store_connection(connection: ConnectionV3) -> VcxResult { +fn store_connection(connection: Connection) -> VcxResult { CONNECTION_MAP.add(connection) .or(Err(VcxError::from(VcxErrorKind::CreateConnection))) } pub fn create_connection(source_id: &str) -> VcxResult { trace!("create_connection >>> source_id: {}", source_id); - let connection = ConnectionV3::create(source_id); + let connection = Connection::create(source_id); return store_connection(connection); } pub fn create_connection_with_invite(source_id: &str, details: &str) -> VcxResult { debug!("create connection {} with invite {}", source_id, details); if let Some(invitation) = serde_json::from_str::(details).ok() { - let connection = ConnectionV3::create_with_invite(source_id, invitation)?; + let connection = Connection::create_with_invite(source_id, invitation)?; store_connection(connection) } else { Err(VcxError::from_msg(VcxErrorKind::InvalidJson, "Used invite has invalid structure")) // TODO: Specific error type @@ -188,15 +188,15 @@ pub fn get_invite_details(handle: u32) -> VcxResult { }).or(Err(VcxError::from(VcxErrorKind::InvalidConnectionHandle))) } -impl Into<(SmConnectionState, AgentInfo, String)> for ConnectionV3 { +impl Into<(SmConnectionState, AgentInfo, String)> for Connection { fn into(self) -> (SmConnectionState, AgentInfo, String) { (self.state_object(), self.agent_info().to_owned(), self.source_id()) } } -impl From<(SmConnectionState, AgentInfo, String)> for ConnectionV3 { - fn from((state, agent_info, source_id): (SmConnectionState, AgentInfo, String)) -> ConnectionV3 { - ConnectionV3::from_parts(source_id, agent_info, state) +impl From<(SmConnectionState, AgentInfo, String)> for Connection { + fn from((state, agent_info, source_id): (SmConnectionState, AgentInfo, String)) -> Connection { + Connection::from_parts(source_id, agent_info, state) } } @@ -232,7 +232,7 @@ pub fn send_message(handle: u32, message: A2AMessage) -> VcxResult<()> { } pub fn send_message_to_self_endpoint(message: A2AMessage, did_doc: &DidDoc) -> VcxResult<()> { - ConnectionV3::send_message_to_self_endpoint(&message, did_doc) + Connection::send_message_to_self_endpoint(&message, did_doc) } pub fn is_v3_connection(connection_handle: u32) -> VcxResult { diff --git a/libvcx/src/credential.rs b/libvcx/src/credential.rs index e99b131b3c..9f6f819c71 100644 --- a/libvcx/src/credential.rs +++ b/libvcx/src/credential.rs @@ -2,7 +2,7 @@ use serde_json; use aries::{ handlers::issuance::holder::holder::Holder, - messages::issuance::credential_offer::CredentialOffer as CredentialOfferV3, + messages::issuance::credential_offer::CredentialOffer, }; use error::prelude::*; use settings::indy_mocks_enabled; @@ -35,8 +35,8 @@ fn handle_err(err: VcxError) -> VcxError { } } -fn create_credential_v3(source_id: &str, offer: &str) -> VcxResult> { - trace!("create_credential_v3 >>> source_id: {}, offer: {}", source_id, secret!(&offer)); +fn create_credential(source_id: &str, offer: &str) -> VcxResult> { + trace!("create_credential >>> source_id: {}, offer: {}", source_id, secret!(&offer)); let offer_message = ::serde_json::from_str::(offer) .map_err(|err| VcxError::from_msg(VcxErrorKind::InvalidJson, format!("Cannot deserialize Message: {:?}", err)))?; @@ -46,7 +46,7 @@ fn create_credential_v3(source_id: &str, offer: &str) -> VcxResult offer }; - if let Ok(cred_offer) = serde_json::from_value::(offer_message) { + if let Ok(cred_offer) = serde_json::from_value::(offer_message) { return Ok(Some(Holder::create(cred_offer, source_id)?)); } @@ -57,7 +57,7 @@ fn create_credential_v3(source_id: &str, offer: &str) -> VcxResult VcxResult { trace!("credential_create_with_offer >>> source_id: {}, offer: {}", source_id, secret!(&offer)); - let cred_offer: CredentialOfferV3 = serde_json::from_str(offer) + let cred_offer: CredentialOffer = serde_json::from_str(offer) .map_err(|err| VcxError::from_msg(VcxErrorKind::InvalidJson, format!("Strict `aries` protocol is enabled. Can not parse `aries` formatted Credential Offer: {}", err)))?; @@ -71,7 +71,7 @@ pub fn credential_create_with_msgid(source_id: &str, connection_handle: u32, msg let offer = get_credential_offer_msg(connection_handle, &msg_id)?; trace!("credential_create_with_msgid ::: for msg_id {} found offer {}", msg_id, offer); - let credential = create_credential_v3(source_id, &offer)? + let credential = create_credential(source_id, &offer)? .ok_or(VcxError::from_msg(VcxErrorKind::InvalidConnectionHandle, format!("Connection can not be used for Proprietary Issuance protocol")))?; let handle = HANDLE_MAP.add(credential)?; @@ -214,9 +214,8 @@ pub fn get_credential_status(handle: u32) -> VcxResult { #[cfg(test)] pub mod tests { use api::VcxStateType; - use aries::messages::issuance::credential::Credential as CredentialV3; + use aries::messages::issuance::credential::Credential as Credential; use connection; - use credential_request::CredentialRequest; use utils::devsetup::*; use utils::mockdata::mockdata_credex::{ARIES_CREDENTIAL_RESPONSE, CREDENTIAL_SM_FINISHED, CREDENTIAL_SM_OFFER_RECEIVED}; @@ -295,10 +294,11 @@ pub mod tests { info!("full_credential_test:: going to get_credential"); let msg = get_credential(handle_cred).unwrap(); + info!("full_credential_test:: get_credential returned {}", msg); let msg_value: serde_json::Value = serde_json::from_str(&msg).unwrap(); info!("full_credential_test:: going to deserialize credential: {:?}", msg_value); - let _credential_struct: CredentialV3 = serde_json::from_str(msg_value.to_string().as_str()).unwrap(); + let _credential_struct: Credential = serde_json::from_str(msg_value.to_string().as_str()).unwrap(); } #[test] @@ -318,7 +318,7 @@ pub mod tests { assert_eq!(VcxStateType::VcxStateRequestReceived as u32, get_state(c_h).unwrap()); let msg = generate_credential_request_msg(c_h, &my_pw_did, &their_pw_did).unwrap(); - ::serde_json::from_str::(&msg).unwrap(); + // ::serde_json::from_str::(&msg).unwrap(); } #[test] @@ -331,7 +331,7 @@ pub mod tests { let offer = get_credential_offer_messages(connection_h).unwrap(); let o: serde_json::Value = serde_json::from_str(&offer).unwrap(); println!("Serialized credential offer: {:?}", &o[0]); - let _credential_offer: CredentialOfferV3 = serde_json::from_str(&o[0].to_string()).unwrap(); + let _credential_offer: CredentialOffer = serde_json::from_str(&o[0].to_string()).unwrap(); } #[test] @@ -353,6 +353,6 @@ pub mod tests { let handle = from_string(CREDENTIAL_SM_FINISHED).unwrap(); let cred_string: String = get_credential(handle).unwrap(); let cred_value: serde_json::Value = serde_json::from_str(&cred_string).unwrap(); - let _credential_struct: CredentialV3 = serde_json::from_str(cred_value.to_string().as_str()).unwrap(); + let _credential_struct: Credential = serde_json::from_str(cred_value.to_string().as_str()).unwrap(); } } diff --git a/libvcx/src/credential_request.rs b/libvcx/src/credential_request.rs deleted file mode 100644 index bd6f4000fb..0000000000 --- a/libvcx/src/credential_request.rs +++ /dev/null @@ -1,93 +0,0 @@ -#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)] -pub struct CredentialRequest { - pub libindy_cred_req: String, - pub libindy_cred_req_meta: String, - pub cred_def_id: String, - pub tid: String, - pub to_did: String, - pub from_did: String, - pub version: String, - pub mid: String, - pub msg_ref_id: Option, -} - -impl CredentialRequest { - pub fn new(did: &str) -> CredentialRequest { - CredentialRequest { - to_did: String::new(), - from_did: did.to_string(), - mid: String::new(), - tid: String::new(), - version: String::new(), - libindy_cred_req: String::new(), - libindy_cred_req_meta: String::new(), - cred_def_id: String::new(), - msg_ref_id: None, - } - } -} - - -#[cfg(test)] -mod tests { - use serde_json; - - use utils::constants::{CRED_REQ, CRED_REQ_META, CREDENTIAL_REQ_STRING}; - use utils::devsetup::*; - - use super::*; - - fn create_credential_req() -> CredentialRequest { - let _setup = SetupDefaults::init(); - - ::settings::set_defaults(); - let issuer_did = ::settings::get_config_value(::settings::CONFIG_INSTITUTION_DID).unwrap(); - CredentialRequest::new(&issuer_did) - } - - #[test] - #[cfg(feature = "general_test")] - fn test_credential_request_struct() { - let _setup = SetupDefaults::init(); - - let req = create_credential_req(); - let issuer_did = ::settings::get_config_value(::settings::CONFIG_INSTITUTION_DID).unwrap(); - assert_eq!(req.from_did, issuer_did); - } - - #[test] - #[cfg(feature = "general_test")] - fn test_serialize() { - let _setup = SetupDefaults::init(); - - let cred1: CredentialRequest = serde_json::from_str(CREDENTIAL_REQ_STRING).unwrap(); - let serialized = serde_json::to_string(&cred1).unwrap(); - assert_eq!(serialized, CREDENTIAL_REQ_STRING) - } - - #[test] - #[cfg(feature = "general_test")] - fn test_deserialize() { - let _setup = SetupDefaults::init(); - - let req: CredentialRequest = serde_json::from_str(CREDENTIAL_REQ_STRING).unwrap(); - assert_eq!(&req.libindy_cred_req, CRED_REQ); - } - - #[test] - #[cfg(feature = "general_test")] - fn test_create_credential_request_from_raw_message() { - let _setup = SetupDefaults::init(); - - let credential_req: CredentialRequest = serde_json::from_str(CREDENTIAL_REQ_STRING).unwrap(); - - assert_eq!(credential_req.tid, "cCanHnpFAD"); - assert_eq!(credential_req.to_did, "BnRXf8yDMUwGyZVDkSENeq"); - assert_eq!(credential_req.from_did, "GxtnGN6ypZYgEqcftSQFnC"); - assert_eq!(credential_req.version, "0.1"); - assert_eq!(credential_req.mid, ""); - assert_eq!(&credential_req.libindy_cred_req, CRED_REQ); - assert_eq!(&credential_req.libindy_cred_req_meta, CRED_REQ_META); - } -} - diff --git a/libvcx/src/disclosed_proof.rs b/libvcx/src/disclosed_proof.rs index ab5c6a3e7b..32ab233fa7 100644 --- a/libvcx/src/disclosed_proof.rs +++ b/libvcx/src/disclosed_proof.rs @@ -165,7 +165,6 @@ pub fn is_valid_handle(handle: u32) -> bool { HANDLE_MAP.has_handle(handle) } -//TODO one function with credential fn get_proof_request(connection_handle: u32, msg_id: &str) -> VcxResult { if !connection::is_v3_connection(connection_handle)? { return Err(VcxError::from_msg(VcxErrorKind::InvalidConnectionHandle, format!("Connection can not be used for Proprietary Issuance protocol"))); @@ -177,8 +176,8 @@ fn get_proof_request(connection_handle: u32, msg_id: &str) -> VcxResult } let presentation_request = Prover::get_presentation_request(connection_handle, msg_id)?; - return serde_json::to_string_pretty(&presentation_request) - .map_err(|err| VcxError::from_msg(VcxErrorKind::InvalidJson, format!("Cannot serialize message: {}", err))); + serde_json::to_string_pretty(&presentation_request) + .map_err(|err| VcxError::from_msg(VcxErrorKind::InvalidJson, format!("Cannot serialize message: {}", err))) } pub fn get_proof_request_messages(connection_handle: u32) -> VcxResult { diff --git a/libvcx/src/lib.rs b/libvcx/src/lib.rs index f63689aeb6..b14a27f140 100644 --- a/libvcx/src/lib.rs +++ b/libvcx/src/lib.rs @@ -39,7 +39,6 @@ pub mod messages; pub mod api; pub mod connection; pub mod issuer_credential; -pub mod credential_request; pub mod proof; pub mod schema; pub mod credential_def; diff --git a/libvcx/src/proof.rs b/libvcx/src/proof.rs index 8309f70017..ec1dea4ce7 100644 --- a/libvcx/src/proof.rs +++ b/libvcx/src/proof.rs @@ -293,9 +293,7 @@ pub mod tests { let handle = PROOF_MAP.add(proof).unwrap(); let proof_str = get_proof(handle).unwrap(); - // TODO: Fix A2AMessage serialization - // v3/messages A2AMessages do not serialize type and so following statement fails. - // assert_eq!(&proof_str, mockdata_proof::ARIES_PROOF_PRESENTATION); + assert_eq!(proof_str, mockdata_proof::ARIES_PROOF_PRESENTATION.replace("\n", "").replace(" ", "")); } #[test] diff --git a/libvcx/src/utils/mockdata/mockdata_proof.rs b/libvcx/src/utils/mockdata/mockdata_proof.rs index 6fa94b77bc..47c51e0c08 100644 --- a/libvcx/src/utils/mockdata/mockdata_proof.rs +++ b/libvcx/src/utils/mockdata/mockdata_proof.rs @@ -241,6 +241,7 @@ pub static PRESENTATION_REQUEST_MESSAGE_ARRAY: &str = r#" [ { "@id": "testid", + "@type": "did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/present-proof/1.0/request-presentation", "comment": "institution wants you to share request1", "request_presentations~attach": [ { @@ -254,6 +255,7 @@ pub static PRESENTATION_REQUEST_MESSAGE_ARRAY: &str = r#" }, { "@id": "testid", + "@type": "did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/present-proof/1.0/request-presentation", "comment": "institution wants you to share request2", "request_presentations~attach": [ { @@ -306,6 +308,7 @@ pub static PRESENTATION_REQUEST_MESSAGE_ARRAY_EMPTY_ATTACH: &str = r#" [ { "@id": "testid", + "@type": "did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/present-proof/1.0/request-presentation", "comment": "institution wants you to share request1", "request_presentations~attach": [ { @@ -319,6 +322,7 @@ pub static PRESENTATION_REQUEST_MESSAGE_ARRAY_EMPTY_ATTACH: &str = r#" }, { "@id": "testid", + "@type": "did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/present-proof/1.0/request-presentation", "comment": "institution wants you to share request2", "request_presentations~attach": [ { From b6a76f2b748724a988d4f598370e6693502ff45a Mon Sep 17 00:00:00 2001 From: Miroslav Kovar Date: Thu, 15 Oct 2020 14:03:43 +0200 Subject: [PATCH 2/2] Return a2a message for offer and proof request Signed-off-by: Miroslav Kovar --- .../aries/handlers/issuance/holder/holder.rs | 30 ++++++++----------- .../proof_presentation/prover/prover.rs | 6 ++-- 2 files changed, 16 insertions(+), 20 deletions(-) diff --git a/libvcx/src/aries/handlers/issuance/holder/holder.rs b/libvcx/src/aries/handlers/issuance/holder/holder.rs index 7bcc02ab11..0820353d7b 100644 --- a/libvcx/src/aries/handlers/issuance/holder/holder.rs +++ b/libvcx/src/aries/handlers/issuance/holder/holder.rs @@ -66,34 +66,30 @@ impl Holder { Ok(()) } - pub fn get_credential_offer_message(connection_handle: u32, msg_id: &str) -> VcxResult { - let message = connection::get_message_by_id(connection_handle, msg_id.to_string())?; - - let credential_offer: CredentialOffer = match message { - A2AMessage::CredentialOffer(credential_offer) => credential_offer, - msg => { - return Err(VcxError::from_msg(VcxErrorKind::InvalidMessages, - format!("Message of different type was received: {:?}", msg))); + pub fn get_credential_offer_message(connection_handle: u32, msg_id: &str) -> VcxResult { + match connection::get_message_by_id(connection_handle, msg_id.to_string()) { + Ok(message) => match message { + A2AMessage::CredentialOffer(_) => Ok(message), + msg => { + return Err(VcxError::from_msg(VcxErrorKind::InvalidMessages, + format!("Message of different type was received: {:?}", msg))); + } } - }; - - Ok(credential_offer) + Err(err) => Err(err) + } } - pub fn get_credential_offer_messages(conn_handle: u32) -> VcxResult> { + pub fn get_credential_offer_messages(conn_handle: u32) -> VcxResult> { let messages = connection::get_messages(conn_handle)?; - let msgs: Vec = messages + let msgs: Vec = messages .into_iter() .filter_map(|(_, a2a_message)| { match a2a_message { - A2AMessage::CredentialOffer(credential_offer) => { - Some(credential_offer) - } + A2AMessage::CredentialOffer(_) => Some(a2a_message), _ => None } }) .collect(); - Ok(msgs) } } diff --git a/libvcx/src/aries/handlers/proof_presentation/prover/prover.rs b/libvcx/src/aries/handlers/proof_presentation/prover/prover.rs index 7b3b8853e7..0775c82b62 100644 --- a/libvcx/src/aries/handlers/proof_presentation/prover/prover.rs +++ b/libvcx/src/aries/handlers/proof_presentation/prover/prover.rs @@ -117,15 +117,15 @@ impl Prover { Ok(presentation_request) } - pub fn get_presentation_request_messages(connection_handle: u32) -> VcxResult> { + pub fn get_presentation_request_messages(connection_handle: u32) -> VcxResult> { trace!("Prover::get_presentation_request_messages >>> connection_handle: {:?}", connection_handle); - let presentation_requests: Vec = + let presentation_requests: Vec = connection::get_messages(connection_handle)? .into_iter() .filter_map(|(_, message)| { match message { - A2AMessage::PresentationRequest(presentation_request) => Some(presentation_request), + A2AMessage::PresentationRequest(_) => Some(message), _ => None } })