diff --git a/libindy/mac.build.sh b/libindy/mac.build.sh index 3611fb3fda..24782655bb 100755 --- a/libindy/mac.build.sh +++ b/libindy/mac.build.sh @@ -41,10 +41,7 @@ if [[ "$OSTYPE" == "darwin"* ]]; then export CARGO_INCREMENTAL=1 export RUST_LOG=indy=trace export RUST_TEST_THREADS=1 - for version in `ls -t /usr/local/Cellar/openssl/`; do - export OPENSSL_DIR=/usr/local/Cellar/openssl/$version - break - done + export OPENSSL_DIR=/usr/local/opt/`ls /usr/local/opt/ | grep openssl | sort | tail -1` cargo build export LIBRARY_PATH=$(pwd)/target/debug cd ../cli diff --git a/vcx/libvcx/src/api/connection.rs b/vcx/libvcx/src/api/connection.rs index 52188862cd..b0a80e1363 100644 --- a/vcx/libvcx/src/api/connection.rs +++ b/vcx/libvcx/src/api/connection.rs @@ -803,13 +803,13 @@ pub extern fn vcx_connection_send_message(command_handle: CommandHandle, msg: *const c_char, send_msg_options: *const c_char, cb: Option) -> u32 { - info!("vcx_message_send >>>"); + info!("vcx_connection_send_message >>>"); check_useful_c_callback!(cb, VcxErrorKind::InvalidOption); check_useful_c_str!(msg, VcxErrorKind::InvalidOption); check_useful_c_str!(send_msg_options, VcxErrorKind::InvalidOption); - trace!("vcx_message_send(command_handle: {}, connection_handle: {}, msg: {}, send_msg_options: {})", + trace!("vcx_connection_send_message(command_handle: {}, connection_handle: {}, msg: {}, send_msg_options: {})", command_handle, connection_handle, msg, send_msg_options); spawn(move || { diff --git a/vcx/libvcx/src/connection.rs b/vcx/libvcx/src/connection.rs index ff55285bb8..631e9a3b55 100644 --- a/vcx/libvcx/src/connection.rs +++ b/vcx/libvcx/src/connection.rs @@ -1242,7 +1242,7 @@ impl From<(Connection, ActorDidExchangeState)> for ConnectionV3 { } } -use v3::messages::a2a::{A2AMessage, MessageId}; +use v3::messages::a2a::A2AMessage; use v3::messages::connection::did_doc::DidDoc; pub fn get_messages(handle: u32) -> VcxResult> { @@ -1294,24 +1294,6 @@ pub fn send_message_to_self_endpoint(message: A2AMessage, did_doc: &DidDoc) -> V ConnectionV3::send_message_to_self_endpoint(&message, did_doc) } -pub fn add_pending_messages(handle: u32, messages: HashMap) -> VcxResult<()> { - CONNECTION_MAP.get(handle, |connection| { - match connection { - Connections::V1(_) => Err(VcxError::from(VcxErrorKind::InvalidConnectionHandle)), - Connections::V3(ref connection) => connection.add_pending_messages(messages.clone()) - } - }) -} - -pub fn remove_pending_message(handle: u32, id: &MessageId) -> VcxResult<()> { - CONNECTION_MAP.get(handle, |connection| { - match connection { - Connections::V1(_) => Err(VcxError::from(VcxErrorKind::InvalidConnectionHandle)), - Connections::V3(ref connection) => connection.remove_pending_message(id.clone()) - } - }) -} - pub fn is_v3_connection(connection_handle: u32) -> VcxResult { CONNECTION_MAP.get(connection_handle, |connection| { match connection { diff --git a/vcx/libvcx/src/messages/payload.rs b/vcx/libvcx/src/messages/payload.rs index 05f2e931b1..b5f8583cb5 100644 --- a/vcx/libvcx/src/messages/payload.rs +++ b/vcx/libvcx/src/messages/payload.rs @@ -169,7 +169,7 @@ pub enum PayloadTypes { #[derive(Clone, Deserialize, Serialize, Debug, PartialEq)] pub struct PayloadTypeV1 { - name: String, + pub name: String, ver: String, fmt: String, } diff --git a/vcx/libvcx/src/utils/mod.rs b/vcx/libvcx/src/utils/mod.rs index 520f7c9130..baeb665516 100644 --- a/vcx/libvcx/src/utils/mod.rs +++ b/vcx/libvcx/src/utils/mod.rs @@ -23,6 +23,7 @@ macro_rules! secret { ($val:expr) => {{ "_" }}; } +#[cfg(test)] macro_rules! map ( { $($key:expr => $value:expr),+ } => { { diff --git a/vcx/libvcx/src/v3/handlers/connection/connection.rs b/vcx/libvcx/src/v3/handlers/connection/connection.rs index f888d07406..4a9dc01f2b 100644 --- a/vcx/libvcx/src/v3/handlers/connection/connection.rs +++ b/vcx/libvcx/src/v3/handlers/connection/connection.rs @@ -4,7 +4,7 @@ use error::prelude::*; use v3::handlers::connection::states::{DidExchangeSM, Actor, ActorDidExchangeState}; use v3::handlers::connection::messages::DidExchangeMessages; use v3::handlers::connection::agent::AgentInfo; -use v3::messages::a2a::{A2AMessage, MessageId}; +use v3::messages::a2a::A2AMessage; use v3::messages::connection::invite::Invitation; use std::collections::HashMap; @@ -126,16 +126,11 @@ impl Connection { pub fn update_state_with_message(&mut self, message: &str) -> VcxResult<()> { trace!("Connection: update_state_with_message: {}", message); - let agent_info = self.agent_info().clone(); - - let message: Message = ::serde_json::from_str(&message) + let message: A2AMessage = ::serde_json::from_str(&message) .map_err(|err| VcxError::from_msg(VcxErrorKind::InvalidOption, format!("Cannot updated state with messages: Message deserialization failed: {:?}", err)))?; - let a2a_message = self.decode_message(&message)?; - self.handle_message(a2a_message.into())?; - - agent_info.update_message_status(message.uid)?; + self.handle_message(message.into())?; Ok(()) } @@ -183,16 +178,8 @@ impl Connection { AgentInfo::send_message_anonymously(message, did_doc) } - pub fn send_generic_message(&self, message: &str, _message_options: &str) -> VcxResult { - trace!("Connection::send_generic_message >>> message: {:?}", message); - - let message = match ::serde_json::from_str::(message) { - Ok(A2AMessage::Generic(message)) => { - BasicMessage::create() - .set_content(message.to_string()) - .set_time() - .to_a2a_message() - } + fn parse_generic_message(message: &str, _message_options: &str) -> A2AMessage { + match ::serde_json::from_str::(message) { Ok(a2a_message) => a2a_message, Err(_) => { BasicMessage::create() @@ -200,8 +187,13 @@ impl Connection { .set_time() .to_a2a_message() } - }; + } + } + + pub fn send_generic_message(&self, message: &str, _message_options: &str) -> VcxResult { + trace!("Connection::send_generic_message >>> message: {:?}", message); + let message = Connection::parse_generic_message(message, _message_options); self.send_message(&message).map(|_| String::new()) } @@ -220,16 +212,6 @@ impl Connection { Ok(()) } - pub fn add_pending_messages(&self, messages: HashMap) -> VcxResult<()> { - trace!("Connection::add_pending_messages >>> messages: {:?}", messages); - self.connection_sm.add_pending_messages(messages) - } - - pub fn remove_pending_message(&self, id: MessageId) -> VcxResult<()> { - trace!("Connection::remove_pending_message >>> id: {:?}", id); - self.connection_sm.remove_pending_message(id) - } - pub fn send_discovery_features(&mut self, query: Option, comment: Option) -> VcxResult<()> { trace!("Connection::send_discovery_features_query >>> query: {:?}, comment: {:?}", query, comment); self.handle_message(DidExchangeMessages::DiscoverFeatures((query, comment))) @@ -284,4 +266,40 @@ struct SideConnectionInfo { service_endpoint: String, #[serde(skip_serializing_if = "Option::is_none")] protocols: Option>, +} + +#[cfg(test)] +mod tests { + use v3::messages::a2a::A2AMessage; + use v3::handlers::connection::connection::Connection; + + #[test] + fn test_parse_generic_message_plain_string_should_be_parsed_as_basic_msg() -> Result<(), String> { + let message = "Some plain text message"; + let result = Connection::parse_generic_message(message, ""); + match result { + A2AMessage::BasicMessage(basic_msg) => { + assert_eq!(basic_msg.content, message); + Ok(()) + } + other => Err(format!("Result is not BasicMessage, but: {:?}", other)) + } + } + + #[test] + fn test_parse_generic_message_json_msg_should_be_parsed_as_generic() -> Result<(), String> { + let message = json!({ + "@id": "some id", + "@type": "some type", + "content": "some content" + }).to_string(); + let result = Connection::parse_generic_message(&message, ""); + match result { + A2AMessage::Generic(value) => { + assert_eq!(value.to_string(), message); + Ok(()) + } + other => Err(format!("Result is not Generic, but: {:?}", other)) + } + } } \ No newline at end of file diff --git a/vcx/libvcx/src/v3/handlers/connection/mod.rs b/vcx/libvcx/src/v3/handlers/connection/mod.rs index ce20949bc7..2209298fce 100644 --- a/vcx/libvcx/src/v3/handlers/connection/mod.rs +++ b/vcx/libvcx/src/v3/handlers/connection/mod.rs @@ -138,27 +138,6 @@ pub mod tests { ::connection::update_message_status(alice.connection_handle, uid).unwrap(); } - // Pending Message - { - faber.activate(); - - let message = _ack(); - ::connection::send_message(faber.connection_handle, message.to_a2a_message()).unwrap(); - - alice.activate(); - - let messages = ::connection::get_messages(alice.connection_handle).unwrap(); - assert_eq!(1, messages.len()); - let uid = messages.keys().next().unwrap().clone(); - - ::connection::add_pending_messages(alice.connection_handle, map!( message.id.clone() => uid )).unwrap(); - - ::connection::remove_pending_message(alice.connection_handle, &message.id).unwrap(); - - let messages = ::connection::get_messages(alice.connection_handle).unwrap(); - assert_eq!(0, messages.len()); - } - // Download Messages { use messages::get_message::{download_messages, MessageByConnection, Message}; diff --git a/vcx/libvcx/src/v3/handlers/connection/states.rs b/vcx/libvcx/src/v3/handlers/connection/states.rs index bd49646d58..d87589348c 100644 --- a/vcx/libvcx/src/v3/handlers/connection/states.rs +++ b/vcx/libvcx/src/v3/handlers/connection/states.rs @@ -13,13 +13,11 @@ use v3::messages::ack::Ack; use v3::messages::connection::did_doc::DidDoc; use v3::messages::discovery::query::Query; use v3::messages::discovery::disclose::{Disclose, ProtocolDescriptor}; -use v3::messages::a2a::MessageId; use v3::messages::a2a::protocol_registry::ProtocolRegistry; use std::collections::HashMap; use error::prelude::*; -use v3::utils::pending_message::PendingMessage; #[derive(Debug, Clone, Serialize, Deserialize)] pub struct DidExchangeSM { @@ -672,32 +670,6 @@ impl DidExchangeSM { ActorDidExchangeState::Invitee(_) => Actor::Invitee } } - - pub fn add_pending_messages(&self, messages: HashMap) -> VcxResult<()> { - match self.state { - ActorDidExchangeState::Inviter(DidExchangeState::Completed(ref _state)) | - ActorDidExchangeState::Invitee(DidExchangeState::Completed(ref _state)) => { - for (key, value) in messages { - PendingMessage::add(&key.0, &value).ok(); - } - } - _ => {} - }; - Ok(()) - } - - pub fn remove_pending_message(&self, id: MessageId) -> VcxResult<()> { - match self.state { - ActorDidExchangeState::Inviter(DidExchangeState::Completed(ref _state)) | - ActorDidExchangeState::Invitee(DidExchangeState::Completed(ref _state)) => { - if let Some(uid_) = PendingMessage::get(&id.0) { - self.agent_info.update_message_status(uid_.to_string()).ok(); - } - } - _ => {} - }; - Ok(()) - } } #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] diff --git a/vcx/libvcx/src/v3/handlers/issuance/holder.rs b/vcx/libvcx/src/v3/handlers/issuance/holder.rs index 27dc4d344e..f623e870b3 100644 --- a/vcx/libvcx/src/v3/handlers/issuance/holder.rs +++ b/vcx/libvcx/src/v3/handlers/issuance/holder.rs @@ -60,8 +60,10 @@ impl HolderSM { match self.find_message_to_handle(messages) { Some((uid, msg)) => { + let state = self.handle_message(msg.into())?; connection::update_message_status(conn_handle, uid)?; - self.handle_message(msg.into()) + Ok(state) + } None => Ok(self) } @@ -119,7 +121,6 @@ impl HolderSM { Ok((cred_request, req_meta, cred_def_json)) => { let cred_request = cred_request .set_thread_id(&thread_id); - connection::remove_pending_message(connection_handle, &state_data.offer.id)?; connection::send_message(connection_handle, cred_request.to_a2a_message())?; HolderState::RequestSent((state_data, req_meta, cred_def_json, connection_handle).into()) } diff --git a/vcx/libvcx/src/v3/handlers/issuance/issuer.rs b/vcx/libvcx/src/v3/handlers/issuance/issuer.rs index 23e4f92294..8008f43641 100644 --- a/vcx/libvcx/src/v3/handlers/issuance/issuer.rs +++ b/vcx/libvcx/src/v3/handlers/issuance/issuer.rs @@ -13,7 +13,7 @@ use issuer_credential::encode_attributes; use v3::messages::status::Status; use std::collections::HashMap; use connection::{send_message, get_messages}; -use connection::update_message_status; +use connection; #[derive(Serialize, Deserialize, Debug, Clone)] pub struct IssuerSM { @@ -54,8 +54,9 @@ impl IssuerSM { match self.find_message_to_handle(messages) { Some((uid, msg)) => { - update_message_status(conn_handle, uid)?; - self.handle_message(msg.into()) + let state = self.handle_message(msg.into())?; + connection::update_message_status(conn_handle, uid)?; + Ok(state) } None => Ok(self) } diff --git a/vcx/libvcx/src/v3/handlers/issuance/mod.rs b/vcx/libvcx/src/v3/handlers/issuance/mod.rs index 9fbed3faf3..c67807f024 100644 --- a/vcx/libvcx/src/v3/handlers/issuance/mod.rs +++ b/vcx/libvcx/src/v3/handlers/issuance/mod.rs @@ -3,10 +3,8 @@ pub mod states; pub mod messages; pub mod holder; -use std::collections::HashMap; use error::prelude::*; -use messages::get_message::Message; -use v3::messages::a2a::{A2AMessage, MessageId}; +use v3::messages::a2a::A2AMessage; use v3::handlers::issuance::issuer::IssuerSM; use v3::handlers::issuance::messages::CredentialIssuanceMessage; use v3::handlers::issuance::holder::HolderSM; @@ -51,10 +49,9 @@ impl Issuer { pub fn update_status(&mut self, msg: Option) -> VcxResult<()> { match msg { Some(msg) => { - let message: Message = ::serde_json::from_str(&msg) + let message: A2AMessage = ::serde_json::from_str(&msg) .map_err(|err| VcxError::from_msg(VcxErrorKind::InvalidOption, format!("Cannot deserialize Message: {:?}", err)))?; - let message = connection::decode_message(self.issuer_sm.get_connection_handle(), message)?; self.step(message.into()) } None => { @@ -97,10 +94,9 @@ impl Holder { pub fn update_state(&mut self, msg: Option) -> VcxResult<()> { match msg { Some(msg) => { - let message: Message = ::serde_json::from_str(&msg) + let message: A2AMessage = ::serde_json::from_str(&msg) .map_err(|err| VcxError::from_msg(VcxErrorKind::InvalidOption, format!("Cannot update state: Message deserialization failed: {:?}", err)))?; - let message = connection::decode_message(self.holder_sm.get_connection_handle(), message)?; self.step(message.into()) } None => { @@ -134,34 +130,30 @@ impl Holder { 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 (id, credential_offer): (MessageId, CredentialOffer) = match message { - A2AMessage::CredentialOffer(credential_offer) => (credential_offer.id.clone(), credential_offer), - msg => return Err(VcxError::from_msg(VcxErrorKind::InvalidMessages, format!("Message of different type was received: {:?}", msg))) + 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))); + } }; - connection::add_pending_messages(connection_handle, map! { id => msg_id.to_string() })?; - Ok(credential_offer) } pub fn get_credential_offer_messages(conn_handle: u32) -> VcxResult> { let messages = connection::get_messages(conn_handle)?; - let (uids, msgs): (HashMap, Vec) = messages + let msgs: Vec = messages .into_iter() - .filter_map(|(uid, a2a_message)| { + .filter_map(|(_, a2a_message)| { match a2a_message { A2AMessage::CredentialOffer(credential_offer) => { - Some((uid, credential_offer.id.clone(), credential_offer)) + Some(credential_offer) } _ => None } - }).fold((HashMap::new(), vec![]), |(mut uids, mut msgs), (uid, id, msg)| { - uids.insert(id, uid); - msgs.push(msg); - (uids, msgs) - }); - - connection::add_pending_messages(conn_handle, uids)?; + }) + .collect(); Ok(msgs) } diff --git a/vcx/libvcx/src/v3/handlers/proof_presentation/prover/prover.rs b/vcx/libvcx/src/v3/handlers/proof_presentation/prover/prover.rs index 3aeddb46d4..6b8e94e9ce 100644 --- a/vcx/libvcx/src/v3/handlers/proof_presentation/prover/prover.rs +++ b/vcx/libvcx/src/v3/handlers/proof_presentation/prover/prover.rs @@ -1,25 +1,18 @@ -use messages::get_message::Message; use error::prelude::*; use utils::libindy::anoncreds; use std::convert::TryInto; -use std::collections::HashMap; use v3::handlers::proof_presentation::prover::states::ProverSM; use v3::handlers::proof_presentation::prover::messages::ProverMessages; -use v3::messages::a2a::{A2AMessage, MessageId}; +use v3::messages::a2a::A2AMessage; use v3::messages::proof_presentation::presentation_proposal::PresentationPreview; use v3::messages::proof_presentation::presentation_request::PresentationRequest; use ::{connection, settings}; use messages::proofs::proof_message::ProofMessage; -use std::sync::Mutex; use v3::messages::proof_presentation::presentation::Presentation; -lazy_static! { - pub static ref PENDING_PRESENTATION_REQUESTS: Mutex> = Default::default(); -} - #[derive(Serialize, Deserialize, Debug, Clone)] pub struct Prover { prover_sm: ProverSM @@ -100,16 +93,10 @@ impl Prover { pub fn update_state_with_message(&mut self, message: &str) -> VcxResult<()> { trace!("Prover::update_state_with_message >>> message: {:?}", message); - let message: Message = ::serde_json::from_str(&message) + let a2a_message: A2AMessage = ::serde_json::from_str(&message) .map_err(|err| VcxError::from_msg(VcxErrorKind::InvalidOption, format!("Cannot updated state with message: Message deserialization failed: {:?}", err)))?; - let connection_handle = self.prover_sm.connection_handle()?; - - let uid = message.uid.clone(); - let a2a_message = connection::decode_message(connection_handle, message)?; - self.handle_message(a2a_message.into())?; - connection::update_message_status(connection_handle, uid)?; Ok(()) } @@ -124,36 +111,32 @@ impl Prover { let message = connection::get_message_by_id(connection_handle, msg_id.to_string())?; - let (id, presentation_request): (MessageId, PresentationRequest) = match message { - A2AMessage::PresentationRequest(presentation_request) => (presentation_request.id.clone(), presentation_request), - msg => return Err(VcxError::from_msg(VcxErrorKind::InvalidMessages, format!("Message of different type was received: {:?}", msg))) + let presentation_request: PresentationRequest = match message { + A2AMessage::PresentationRequest(presentation_request) => presentation_request, + msg => { + return Err(VcxError::from_msg(VcxErrorKind::InvalidMessages, + format!("Message of different type was received: {:?}", msg))); + } }; - connection::add_pending_messages(connection_handle, map! { id => msg_id.to_string() })?; - Ok(presentation_request) } pub fn get_presentation_request_messages(connection_handle: u32, match_name: Option<&str>) -> VcxResult> { trace!("Prover::get_presentation_request_messages >>> connection_handle: {:?}, match_name: {:?}", connection_handle, match_name); - let (uids, presentation_requests): (HashMap, Vec) = + let presentation_requests: Vec = connection::get_messages(connection_handle)? .into_iter() - .filter_map(|(uid, message)| { + .filter_map(|(_, message)| { match message { A2AMessage::PresentationRequest(presentation_request) => { - Some((uid, presentation_request.id.clone(), presentation_request)) + Some(presentation_request) } _ => None, } - }).fold((HashMap::new(), Vec::new()), |(mut uids, mut messages), (uid, id, presentation_request)| { - uids.insert(id, uid); - messages.push(presentation_request); - (uids, messages) - }); - - connection::add_pending_messages(connection_handle, uids)?; + }) + .collect(); Ok(presentation_requests) } diff --git a/vcx/libvcx/src/v3/handlers/proof_presentation/prover/states.rs b/vcx/libvcx/src/v3/handlers/proof_presentation/prover/states.rs index 2e418b8ac2..9ab01cc64e 100644 --- a/vcx/libvcx/src/v3/handlers/proof_presentation/prover/states.rs +++ b/vcx/libvcx/src/v3/handlers/proof_presentation/prover/states.rs @@ -271,7 +271,6 @@ impl ProverSM { match state.presentation_request.service.clone() { None => { connection::send_message(connection_handle, state.presentation.to_a2a_message())?; - connection::remove_pending_message(connection_handle, &state.presentation_request.id)?; ProverState::PresentationSent((state, connection_handle).into()) } Some(service) => { @@ -344,7 +343,6 @@ impl ProverSM { Some(service) => connection::send_message_to_self_endpoint(problem_report.to_a2a_message(), &service.into())? } - connection::remove_pending_message(connection_handle, &presentation_request.id)?; Ok(()) } @@ -358,7 +356,6 @@ impl ProverSM { Some(service) => connection::send_message_to_self_endpoint(proposal.to_a2a_message(), &service.into())? } - connection::remove_pending_message(connection_handle, &presentation_request.id)?; Ok(()) } diff --git a/vcx/libvcx/src/v3/handlers/proof_presentation/verifier/verifier.rs b/vcx/libvcx/src/v3/handlers/proof_presentation/verifier/verifier.rs index 16eef8549b..8b1d06ba46 100644 --- a/vcx/libvcx/src/v3/handlers/proof_presentation/verifier/verifier.rs +++ b/vcx/libvcx/src/v3/handlers/proof_presentation/verifier/verifier.rs @@ -1,13 +1,12 @@ use error::prelude::*; use std::convert::TryInto; -use messages::get_message::Message; - use ::{connection, settings}; use v3::messages::proof_presentation::presentation_request::*; use v3::messages::proof_presentation::presentation::Presentation; use v3::handlers::proof_presentation::verifier::states::VerifierSM; use v3::handlers::proof_presentation::verifier::messages::VerifierMessages; +use v3::messages::a2a::A2AMessage; use messages::proofs::proof_request::ProofRequestMessage; use messages::proofs::proof_message::ProofMessage; @@ -74,16 +73,10 @@ impl Verifier { pub fn update_state_with_message(&mut self, message: &str) -> VcxResult<()> { trace!("Verifier::update_state_with_message >>> message: {:?}", message); - let message: Message = ::serde_json::from_str(&message) + let message: A2AMessage = ::serde_json::from_str(&message) .map_err(|err| VcxError::from_msg(VcxErrorKind::InvalidOption, format!("Cannot update state with message: Message deserialization failed: {:?}", err)))?; - let connection_handle = self.verifier_sm.connection_handle()?; - - let uid = message.uid.clone(); - let a2a_message = connection::decode_message(connection_handle, message)?; - - self.handle_message(a2a_message.into())?; - connection::update_message_status(connection_handle, uid)?; + self.handle_message(message.into())?; Ok(()) } diff --git a/vcx/libvcx/src/v3/messages/a2a/mod.rs b/vcx/libvcx/src/v3/messages/a2a/mod.rs index c8ecc94a95..0dbf2d5555 100644 --- a/vcx/libvcx/src/v3/messages/a2a/mod.rs +++ b/vcx/libvcx/src/v3/messages/a2a/mod.rs @@ -72,7 +72,7 @@ pub enum A2AMessage { BasicMessage(BasicMessage), /// Any Raw Message - Generic(String), + Generic(Value), } impl<'de> Deserialize<'de> for A2AMessage { @@ -81,7 +81,7 @@ impl<'de> Deserialize<'de> for A2AMessage { let message_type: MessageType = match serde_json::from_value(value["@type"].clone()) { Ok(message_type) => message_type, - Err(_) => return Ok(A2AMessage::Generic(value.to_string())) + Err(_) => return Ok(A2AMessage::Generic(value)) }; match (message_type.family, message_type.type_.as_str()) { @@ -192,7 +192,7 @@ impl<'de> Deserialize<'de> for A2AMessage { } (_, other_type) => { warn!("Unexpected @type field structure: {}", other_type); - Ok(A2AMessage::Generic(value.to_string())) + Ok(A2AMessage::Generic(value)) } } } @@ -229,7 +229,7 @@ impl Serialize for A2AMessage { A2AMessage::Query(msg) => set_a2a_message_type(msg, MessageFamilies::DiscoveryFeatures, A2AMessage::QUERY), A2AMessage::Disclose(msg) => set_a2a_message_type(msg, MessageFamilies::DiscoveryFeatures, A2AMessage::DISCLOSE), A2AMessage::BasicMessage(msg) => set_a2a_message_type(msg, MessageFamilies::Basicmessage, A2AMessage::BASIC_MESSAGE), - A2AMessage::Generic(msg) => ::serde_json::to_value(msg), + A2AMessage::Generic(msg) => Ok(msg.clone()) }.map_err(ser::Error::custom)?; value.serialize(serializer) diff --git a/vcx/libvcx/src/v3/mod.rs b/vcx/libvcx/src/v3/mod.rs index 1fcf96add1..0ee8195526 100644 --- a/vcx/libvcx/src/v3/mod.rs +++ b/vcx/libvcx/src/v3/mod.rs @@ -9,13 +9,12 @@ pub const SERIALIZE_VERSION: &'static str = "2.0"; pub mod test { use rand; use rand::Rng; - use utils::devsetup::config_with_wallet_handle; + use utils::devsetup::*; use messages::agent_utils::connect_register_provision; use utils::libindy::wallet::*; - use v3::messages::a2a::A2AMessage; use indy_sys::WalletHandle; use utils::plugins::init_plugin; - use messages::get_message::Message; + use messages::payload::PayloadV1; pub fn source_id() -> String { String::from("test source id") @@ -105,13 +104,27 @@ pub mod test { } } - fn download_message(did: String) -> ::messages::get_message::Message { + #[derive(Debug)] + pub struct Message { + uid: String, + message: String, + } + + fn download_message(did: String, type_: &str) -> Message { let mut messages = ::messages::get_message::download_messages(Some(vec![did]), Some(vec![String::from("MS-103")]), None).unwrap(); assert_eq!(1, messages.len()); - let mut messages = messages.pop().unwrap(); - assert_eq!(1, messages.msgs.len()); - let message = messages.msgs.pop().unwrap(); - message + let messages = messages.pop().unwrap(); + + for message in messages.msgs.into_iter(){ + let payload: PayloadV1 = serde_json::from_str(&message.decrypted_payload.clone().unwrap()).unwrap(); + if payload.type_.name == type_ { + return Message{ + uid: message.uid, + message: payload.msg + } + } + } + panic!("Message not found") } pub struct Faber { @@ -131,9 +144,9 @@ pub mod test { let wallet_name = "faber_wallet"; let config = json!({ - "agency_url": "http://localhost:8080", - "agency_did": "VsKV7grR1BUE29mG2Fm2kX", - "agency_verkey": "Hezce2UWMZ3wUhVkh2LfKSs8nDzWwzs2Win7EzNN3YaR", + "agency_url": AGENCY_ENDPOINT, + "agency_did": AGENCY_DID, + "agency_verkey": AGENCY_VERKEY, "wallet_name": wallet_name, "wallet_key": "123", "payment_method": "null", @@ -216,19 +229,6 @@ pub mod test { assert_eq!(expected_state, ::connection::get_state(self.connection_handle)); } - pub fn update_state_with_message(&self, expected_state: u32) -> A2AMessage { - self.activate(); - let did = ::connection::get_pw_did(self.connection_handle).unwrap(); - let message = download_message(did); - - let a2a_message = ::connection::decode_message(self.connection_handle, message.clone()).unwrap(); - - ::connection::update_state_with_message(self.connection_handle, message).unwrap(); - assert_eq!(expected_state, ::connection::get_state(self.connection_handle)); - - a2a_message - } - pub fn ping(&self) { self.activate(); ::connection::send_ping(self.connection_handle, None).unwrap(); @@ -324,9 +324,9 @@ pub mod test { let wallet_name = "alice_wallet"; let config = json!({ - "agency_url": "http://localhost:8080", - "agency_did": "VsKV7grR1BUE29mG2Fm2kX", - "agency_verkey": "Hezce2UWMZ3wUhVkh2LfKSs8nDzWwzs2Win7EzNN3YaR", + "agency_url": C_AGENCY_ENDPOINT, + "agency_did": C_AGENCY_DID, + "agency_verkey": C_AGENCY_VERKEY, "wallet_name": wallet_name, "wallet_key": "123", "payment_method": "null", @@ -368,21 +368,10 @@ pub mod test { assert_eq!(expected_state, ::connection::get_state(self.connection_handle)); } - pub fn download_message(&self) -> Message { + pub fn download_message(&self, message_type: &str) -> Message { self.activate(); let did = ::connection::get_pw_did(self.connection_handle).unwrap(); - download_message(did) - } - - pub fn update_state_with_message(&self, expected_state: u32) -> A2AMessage { - let message = self.download_message(); - - let a2a_message = ::connection::decode_message(self.connection_handle, message.clone()).unwrap(); - - ::connection::update_state_with_message(self.connection_handle, message).unwrap(); - assert_eq!(expected_state, ::connection::get_state(self.connection_handle)); - - a2a_message + download_message(did, message_type) } pub fn accept_offer(&mut self) { @@ -531,21 +520,11 @@ pub mod test { alice.send_presentation(); faber.verify_presentation(); alice.ensure_presentation_verified(); - - // Decline Presentation - faber.request_presentation(); - alice.decline_presentation_request(); - faber.update_proof_state(0, 2); - - // Propose Presentation - faber.request_presentation(); - alice.propose_presentation(); - faber.update_proof_state(0, 2); } #[cfg(feature = "aries")] #[test] - fn aries_demo_update_state_with_message_flow() { + fn aries_demo_handle_connection_related_messages() { PaymentPlugin::load(); let _pool = Pool::open(); @@ -563,18 +542,16 @@ pub mod test { let invite = faber.create_invite(); alice.accept_invite(&invite); - faber.update_state_with_message(3); - alice.update_state_with_message(4); - faber.update_state_with_message(4); + faber.update_state(3); + alice.update_state(4); + faber.update_state(4); // Ping faber.ping(); - let message = alice.update_state_with_message(4); - assert_match!(A2AMessage::Ping(_), message); + alice.update_state(4); - let message = faber.update_state_with_message(4); - assert_match!(A2AMessage::PingResponse(_), message); + faber.update_state(4); let faber_connection_info = faber.connection_info(); assert!(faber_connection_info["their"]["protocols"].as_array().is_none()); @@ -582,54 +559,12 @@ pub mod test { // Discovery Features faber.discovery_features(); - let message = alice.update_state_with_message(4); - assert_match!(A2AMessage::Query(_), message); + alice.update_state(4); - let message = faber.update_state_with_message(4); - assert_match!(A2AMessage::Disclose(_), message); + faber.update_state(4); let faber_connection_info = faber.connection_info(); assert!(faber_connection_info["their"]["protocols"].as_array().unwrap().len() > 0); - - /* - Create with message id flow - */ - - // Credential issuance - faber.offer_credential(); - - // Alice creates Credential object with message id - { - let message = alice.download_message(); - let (credential_handle, _credential_offer) = ::credential::credential_create_with_msgid("test", alice.connection_handle, &message.uid).unwrap(); - alice.credential_handle = credential_handle; - - ::credential::send_credential_request(alice.credential_handle, alice.connection_handle).unwrap(); - assert_eq!(2, ::credential::get_state(alice.credential_handle).unwrap()); - } - - faber.send_credential(); - alice.accept_credential(); - - // Credential Presentation - faber.request_presentation(); - - // Alice creates Presentation object with message id - { - let message = alice.download_message(); - let (presentation_handle, _presentation_request) = ::disclosed_proof::create_proof_with_msgid("test", alice.connection_handle, &message.uid).unwrap(); - alice.presentation_handle = presentation_handle; - - let credentials = alice.get_credentials_for_presentation(); - - ::disclosed_proof::generate_proof(alice.presentation_handle, credentials.to_string(), String::from("{}")).unwrap(); - assert_eq!(3, ::disclosed_proof::get_state(alice.presentation_handle).unwrap()); - - ::disclosed_proof::send_proof(alice.presentation_handle, alice.connection_handle).unwrap(); - assert_eq!(2, ::disclosed_proof::get_state(alice.presentation_handle).unwrap()); - } - - faber.verify_presentation(); } #[cfg(feature = "aries")] @@ -652,9 +587,9 @@ pub mod test { let invite = faber.create_invite(); alice.accept_invite(&invite); - faber.update_state_with_message(3); - alice.update_state_with_message(4); - faber.update_state_with_message(4); + faber.update_state(3); + alice.update_state(4); + faber.update_state(4); /* Create with message id flow @@ -665,7 +600,7 @@ pub mod test { // Alice creates Credential object with message id { - let message = alice.download_message(); + let message = alice.download_message("credential-offer"); let (credential_handle, _credential_offer) = ::credential::credential_create_with_msgid("test", alice.connection_handle, &message.uid).unwrap(); alice.credential_handle = credential_handle; @@ -681,7 +616,7 @@ pub mod test { // Alice creates Presentation object with message id { - let message = alice.download_message(); + let message = alice.download_message("presentation-request"); let (presentation_handle, _presentation_request) = ::disclosed_proof::create_proof_with_msgid("test", alice.connection_handle, &message.uid).unwrap(); alice.presentation_handle = presentation_handle; @@ -717,9 +652,9 @@ pub mod test { let invite = faber.create_invite(); alice.accept_invite(&invite); - faber.update_state_with_message(3); - alice.update_state_with_message(4); - faber.update_state_with_message(4); + faber.update_state(3); + alice.update_state(4); + faber.update_state(4); /* Create with message flow @@ -730,12 +665,9 @@ pub mod test { // Alice creates Credential object with Offer { - let message = alice.download_message(); + let message = alice.download_message("credential-offer"); - let msg: serde_json::Value = ::serde_json::from_str(&message.decrypted_payload.unwrap()).unwrap(); - let offer = msg["@msg"].as_str().unwrap(); - - alice.credential_handle = ::credential::credential_create_with_offer("test", &offer).unwrap(); + alice.credential_handle = ::credential::credential_create_with_offer("test", &message.message).unwrap(); ::connection::update_message_status(alice.connection_handle, message.uid).unwrap(); @@ -751,12 +683,9 @@ pub mod test { // Alice creates Presentation object with Proof Request { - let message = alice.download_message(); - - let msg: serde_json::Value = ::serde_json::from_str(&message.decrypted_payload.unwrap()).unwrap(); - let request = msg["@msg"].as_str().unwrap(); + let message = alice.download_message("presentation-request"); - alice.presentation_handle = ::disclosed_proof::create_proof("test", &request).unwrap(); + alice.presentation_handle = ::disclosed_proof::create_proof("test", &message.message).unwrap(); ::connection::update_message_status(alice.connection_handle, message.uid).unwrap(); diff --git a/vcx/libvcx/src/v3/utils/mod.rs b/vcx/libvcx/src/v3/utils/mod.rs index c7b41d1a41..834c22cadd 100644 --- a/vcx/libvcx/src/v3/utils/mod.rs +++ b/vcx/libvcx/src/v3/utils/mod.rs @@ -1,2 +1 @@ -pub mod encryption_envelope; -pub mod pending_message; \ No newline at end of file +pub mod encryption_envelope; \ No newline at end of file diff --git a/vcx/libvcx/src/v3/utils/pending_message.rs b/vcx/libvcx/src/v3/utils/pending_message.rs deleted file mode 100644 index 8ab550a9c2..0000000000 --- a/vcx/libvcx/src/v3/utils/pending_message.rs +++ /dev/null @@ -1,22 +0,0 @@ -use utils::libindy::wallet; -use error::VcxResult; - -pub struct PendingMessage; - -impl PendingMessage { - const TYPE: &'static str = "PENDING_MESSAGE"; - - pub fn add(id: &str, message: &str) -> VcxResult<()> { - wallet::add_record(Self::TYPE, id, &message, None) - } - - pub fn get(id: &str) -> Option { - match wallet::get_record(Self::TYPE, id, "{}") { - Ok(record) => { - let record: serde_json::Value = serde_json::from_str(&record).ok()?; - record["value"].as_str().map(String::from) - } - _ => None - } - } -} \ No newline at end of file diff --git a/vcx/wrappers/python3/demo/alice_create_with_message_flow.py b/vcx/wrappers/python3/demo/alice_create_with_message_flow.py index 3c15617e6b..b7053ad822 100644 --- a/vcx/wrappers/python3/demo/alice_create_with_message_flow.py +++ b/vcx/wrappers/python3/demo/alice_create_with_message_flow.py @@ -26,14 +26,14 @@ async def main(): elif answer == '1': print("Check agency for a credential offer") pw_did = await connection_to_faber.get_my_pw_did() - uid, offer, _ = await download_message(pw_did) + uid, offer, _ = await download_message(pw_did, 'credential-offer') credential = await Credential.create('credential', json.loads(offer)) await accept_offer(connection_to_faber, credential) await update_message_as_read(pw_did, uid) elif answer == '2': print("Check agency for a proof request") pw_did = await connection_to_faber.get_my_pw_did() - uid, request, _ = await download_message(pw_did) + uid, request, _ = await download_message(pw_did, 'presentation-request') print("#23 Create a Disclosed proof object from proof request") proof = await DisclosedProof.create('proof', json.loads(request)) await create_proof(connection_to_faber, proof) diff --git a/vcx/wrappers/python3/demo/alice_create_with_message_id_flow.py b/vcx/wrappers/python3/demo/alice_create_with_message_id_flow.py index 78af255dbf..e62a32a7ca 100644 --- a/vcx/wrappers/python3/demo/alice_create_with_message_id_flow.py +++ b/vcx/wrappers/python3/demo/alice_create_with_message_id_flow.py @@ -25,7 +25,8 @@ async def main(): elif answer == '1': print("Check agency for a credential offer") pw_did = await connection_to_faber.get_my_pw_did() - uid, offer, _ = await download_message(pw_did) + uid, offer, _ = await download_message(pw_did, 'credential-offer') + print(uid) credential = await Credential.create_with_msgid('credential', connection_to_faber, uid) print("Offer") print(credential.cred_offer) @@ -33,7 +34,7 @@ async def main(): elif answer == '2': print("Check agency for a proof request") pw_did = await connection_to_faber.get_my_pw_did() - uid, request, _ = await download_message(pw_did) + uid, request, _ = await download_message(pw_did, 'presentation-request') print("#23 Create a Disclosed proof object from proof request") proof = await DisclosedProof.create_with_msgid('proof', connection_to_faber, uid) await create_proof(connection_to_faber, proof) diff --git a/vcx/wrappers/python3/demo/demo_utils.py b/vcx/wrappers/python3/demo/demo_utils.py index 448723c0a5..db51cf870a 100644 --- a/vcx/wrappers/python3/demo/demo_utils.py +++ b/vcx/wrappers/python3/demo/demo_utils.py @@ -269,11 +269,12 @@ async def create_postgres_wallet(provisionConfig): print("Postgres wallet provisioned") -async def download_message(pw_did: str): +async def download_message(pw_did: str, msg_type: str): messages = await vcx_messages_download("MS-103", None, pw_did) - message = json.loads(messages.decode())[0]['msgs'][0] + messages = json.loads(messages.decode())[0]['msgs'] + print(messages) + message = [message for message in messages if json.loads(message["decryptedPayload"])["@type"]["name"] == msg_type][0] decryptedPayload = message["decryptedPayload"] - print(decryptedPayload) return message["uid"], json.loads(decryptedPayload)["@msg"], json.dumps(message)