From 412315e6b119d7985fa03525afcd0b9d4aad6bea Mon Sep 17 00:00:00 2001 From: Miroslav Kovar Date: Fri, 9 Oct 2020 13:43:30 +0200 Subject: [PATCH] Expose filter api and add a basic test Signed-off-by: Miroslav Kovar --- libvcx/src/api/filters.rs | 67 ++++++++++++++++++ libvcx/src/api/mod.rs | 1 + .../aries/handlers/connection/agent_info.rs | 10 +-- libvcx/src/filters.rs | 70 +++++++++++++++++++ libvcx/src/lib.rs | 1 + libvcx/src/utils/mockdata/mockdata_proof.rs | 62 ++++++++++++++++ 6 files changed, 206 insertions(+), 5 deletions(-) create mode 100644 libvcx/src/api/filters.rs create mode 100644 libvcx/src/filters.rs diff --git a/libvcx/src/api/filters.rs b/libvcx/src/api/filters.rs new file mode 100644 index 0000000000..c20b5deaf2 --- /dev/null +++ b/libvcx/src/api/filters.rs @@ -0,0 +1,67 @@ +use std::ptr; + +use error::prelude::*; +use utils::error; +use indy_sys::CommandHandle; +use libc::c_char; +use filters; +use utils::threadpool::spawn; +use utils::cstring::CStringUtils; + + +/// Filters proof requests based on name selected by verifier when creating the request. +/// +/// #Params +/// command_handle: command handle to map callback to user context. +/// requests: Serialized array of proof requests JSONs. +/// +/// # Example +/// +/// match_name: Name of the request to match. +/// #Returns +/// Error code as a u32 +#[no_mangle] +pub extern fn vcx_filter_proof_requests_by_name(command_handle: CommandHandle, + requests: *const c_char, + match_name: *const c_char, + cb: Option) -> u32 { + info!("vcx_filter_proof_requests_by_name >>>"); + + check_useful_c_str!(requests, VcxErrorKind::InvalidOption); + check_useful_c_str!(match_name, VcxErrorKind::InvalidOption); + check_useful_c_callback!(cb, VcxErrorKind::InvalidOption); + + trace!("vcx_filter_proof_requests_by_name(command_handle: {}, requests: {}, match_name: {})", + command_handle, requests, match_name); + + spawn(move || { + match filters::filter_proof_requests_by_name(&requests, &match_name) { + Ok(x) => { + trace!("vcx_filter_proof_requests_by_name_cb(command_handle: {}, requests: {}, rc: {}, requests: {})", + command_handle, requests, error::SUCCESS.message, x); + let x = CStringUtils::string_to_cstring(x); + cb(command_handle,error::SUCCESS.code_num, x.as_ptr()); + } + Err(err) => { + error!("vcx_filter_proof_requests_by_name_cb(command_handle: {}, rc: {}, msg: {})", + command_handle, error::SUCCESS.message, err); + cb(command_handle, err.into(), ptr::null_mut()); + } + }; + + Ok(()) + }); + + error::SUCCESS.code_num +} + + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + #[cfg(feature = "general_test")] + fn test_vcx_filter_proof_requests_by_name() {} + +} diff --git a/libvcx/src/api/mod.rs b/libvcx/src/api/mod.rs index cdd05bbb62..88bd6a92ef 100644 --- a/libvcx/src/api/mod.rs +++ b/libvcx/src/api/mod.rs @@ -10,6 +10,7 @@ pub mod disclosed_proof; pub mod wallet; pub mod logger; pub mod return_types_u32; +mod filters; use std::fmt; diff --git a/libvcx/src/aries/handlers/connection/agent_info.rs b/libvcx/src/aries/handlers/connection/agent_info.rs index 81a4d124bb..cf1ae29845 100644 --- a/libvcx/src/aries/handlers/connection/agent_info.rs +++ b/libvcx/src/aries/handlers/connection/agent_info.rs @@ -100,12 +100,12 @@ impl AgentInfo { } #[cfg(feature = "warnlog_fetched_messages")] - { - for message in a2a_messages.values() { - let serialized_msg = serde_json::to_string_pretty(message).unwrap_or_else(|_err| String::from("Failed to serialize A2AMessage.")); - warn!("Fetched decrypted connection messages:\n{}", serialized_msg); - } + { + for message in a2a_messages.values() { + let serialized_msg = serde_json::to_string_pretty(message).unwrap_or_else(|_err| String::from("Failed to serialize A2AMessage.")); + warn!("Fetched decrypted connection messages:\n{}", serialized_msg); } + } Ok(a2a_messages) } diff --git a/libvcx/src/filters.rs b/libvcx/src/filters.rs new file mode 100644 index 0000000000..ef003f9ae5 --- /dev/null +++ b/libvcx/src/filters.rs @@ -0,0 +1,70 @@ +use serde_json; + +use error::prelude::*; +use utils::error; + +use aries::messages::proof_presentation::presentation_request::PresentationRequest; + +// TODO: Log errors +fn _filter_proof_requests_by_name(requests: &str, match_name: &str) -> VcxResult> { + let presentation_requests: Vec = serde_json::from_str(requests) + .map_err(|err| VcxError::from_msg(VcxErrorKind::InvalidJson, format!("Failed to deserialize Vec: {}\nObtained error: {:?}", requests, err)))?; + let filtered = presentation_requests + .into_iter() + .filter_map(|presentation_request| { + match presentation_request.request_presentations_attach.content().ok() { + Some(content) => { + match serde_json::from_str(&content).map(|value: serde_json::Value| value.get("name").unwrap_or(&serde_json::Value::Null).as_str().unwrap_or("").to_string()) { + Ok(name) if name == String::from(match_name) => Some(presentation_request), + _ => None + } + } + _ => None + } + }) + .collect(); + Ok(filtered) +} + +pub fn filter_proof_requests_by_name(requests: &str, name: &str) -> VcxResult { + let presentation_requests: Vec = _filter_proof_requests_by_name(requests, name)?; + let filtered: String = serde_json::to_string(&presentation_requests) + .map_err(|err| VcxError::from_msg(VcxErrorKind::InvalidJson, format!("Failed to serialize filtered proof requests: {}\nObtained error: {:?}", requests, err)))?; + Ok(filtered) +} + +#[cfg(test)] +pub mod tests { + use super::*; + use utils::constants::*; + use utils::devsetup::*; + use utils::httpclient::HttpClientMockResponse; + use utils::mockdata::mockdata_proof; + + #[test] + #[cfg(feature = "general_test")] + fn test_filter_proof_requests_by_name() { + let filtered = _filter_proof_requests_by_name(mockdata_proof::presentation_request_message_array, "request1").unwrap(); + assert_eq!(filtered.len(), 1); + + let filtered = _filter_proof_requests_by_name(mockdata_proof::presentation_request_message_array, "request2").unwrap(); + assert_eq!(filtered.len(), 1); + + let filtered = _filter_proof_requests_by_name(mockdata_proof::presentation_request_message_array, "not there").unwrap(); + assert_eq!(filtered.len(), 0); + + let filtered = _filter_proof_requests_by_name(mockdata_proof::presentation_request_message_array, "").unwrap(); + assert_eq!(filtered.len(), 0); + + let filtered = _filter_proof_requests_by_name(mockdata_proof::presentation_request_message_array_empty_attach, "not there").unwrap(); + assert_eq!(filtered.len(), 0); + + // TODO: fix the behavior so that this passes + let filtered = _filter_proof_requests_by_name(mockdata_proof::presentation_request_message_array_empty_attach, "").unwrap(); + assert_eq!(filtered.len(), 0); + } + + #[test] + #[cfg(feature = "general_test")] + fn test_filter_proof_requests_by_name_serialize_deserialize() {} +} diff --git a/libvcx/src/lib.rs b/libvcx/src/lib.rs index d5445370f4..f1f99d9d2d 100644 --- a/libvcx/src/lib.rs +++ b/libvcx/src/lib.rs @@ -50,6 +50,7 @@ pub mod disclosed_proof; pub mod aries; mod proof_utils; mod disclosed_proof_utils; +mod filters; #[allow(unused_imports)] #[allow(dead_code)] diff --git a/libvcx/src/utils/mockdata/mockdata_proof.rs b/libvcx/src/utils/mockdata/mockdata_proof.rs index 070fb2d647..6e60be8cf0 100644 --- a/libvcx/src/utils/mockdata/mockdata_proof.rs +++ b/libvcx/src/utils/mockdata/mockdata_proof.rs @@ -236,3 +236,65 @@ pub static SERIALIZIED_PROOF_REVOKED: &str = r#" } } "#; + +pub static PRESENTATION_REQUEST_MESSAGE_ARRAY: &str = r#" +[ + { + "@id": "testid", + "comment": "institution wants you to share request1", + "request_presentations~attach": [ + { + "@id": "libindy-request-presentation-0", + "data": { + "base64": "eyJuYW1lIjoicmVxdWVzdDEiLCJub25fcmV2b2tlZCI6bnVsbCwibm9uY2UiOiI5OTQwMTI3MjM1MDE3MTg4NTgyMzI3MTEiLCJyZXF1ZXN0ZWRfYXR0cmlidXRlcyI6eyJhdHRyaWJ1dGVfMCI6eyJuYW1lIjoiQWRkcmVzczEiLCJub25fcmV2b2tlZCI6eyJmcm9tIjpudWxsLCJ0byI6bnVsbH0sInJlc3RyaWN0aW9ucyI6eyIkb3IiOlt7IiRhbmQiOlt7ImNyZWRfZGVmX2lkIjoiMjRVaHhMYWVRRU40cG1vQkNydkFScjozOkNMOjEyNzp0YWcxIn0seyJpc3N1ZXJfZGlkIjoiMjRVaHhMYWVRRU40cG1vQkNydkFSciJ9LHsic2NoZW1hX2lkIjoiMjRVaHhMYWVRRU40cG1vQkNydkFScjoyOnlzbHo5TnJqSG1pUlJ0Um1XdDhrdWZHZmU6Mzk0MjY3MDIuNTIzNDEzNzEwIn1dfV19fSwiYXR0cmlidXRlXzEiOnsibmFtZSI6ImFkZHJlc3MyIiwibm9uX3Jldm9rZWQiOnsiZnJvbSI6bnVsbCwidG8iOm51bGx9LCJyZXN0cmljdGlvbnMiOnsiJG9yIjpbeyIkYW5kIjpbeyJjcmVkX2RlZl9pZCI6IjI0VWh4TGFlUUVONHBtb0JDcnZBUnI6MzpDTDoxMjc6dGFnMSJ9LHsiaXNzdWVyX2RpZCI6IjI0VWh4TGFlUUVONHBtb0JDcnZBUnIifSx7InNjaGVtYV9pZCI6IjI0VWh4TGFlUUVONHBtb0JDcnZBUnI6Mjp5c2x6OU5yakhtaVJSdFJtV3Q4a3VmR2ZlOjM5NDI2NzAyLjUyMzQxMzcxMCJ9XX1dfX0sImF0dHJpYnV0ZV8yIjp7Im5hbWUiOiJDSVRZIiwibm9uX3Jldm9rZWQiOnsiZnJvbSI6bnVsbCwidG8iOm51bGx9LCJyZXN0cmljdGlvbnMiOnsiJG9yIjpbeyIkYW5kIjpbeyJjcmVkX2RlZl9pZCI6IjI0VWh4TGFlUUVONHBtb0JDcnZBUnI6MzpDTDoxMjc6dGFnMSJ9LHsiaXNzdWVyX2RpZCI6IjI0VWh4TGFlUUVONHBtb0JDcnZBUnIifSx7InNjaGVtYV9pZCI6IjI0VWh4TGFlUUVONHBtb0JDcnZBUnI6Mjp5c2x6OU5yakhtaVJSdFJtV3Q4a3VmR2ZlOjM5NDI2NzAyLjUyMzQxMzcxMCJ9XX1dfX0sImF0dHJpYnV0ZV8zIjp7Im5hbWUiOiJTdGF0ZSIsIm5vbl9yZXZva2VkIjp7ImZyb20iOm51bGwsInRvIjpudWxsfSwicmVzdHJpY3Rpb25zIjp7IiRvciI6W3siJGFuZCI6W3siY3JlZF9kZWZfaWQiOiIyNFVoeExhZVFFTjRwbW9CQ3J2QVJyOjM6Q0w6MTI3OnRhZzEifSx7Imlzc3Vlcl9kaWQiOiIyNFVoeExhZVFFTjRwbW9CQ3J2QVJyIn0seyJzY2hlbWFfaWQiOiIyNFVoeExhZVFFTjRwbW9CQ3J2QVJyOjI6eXNsejlOcmpIbWlSUnRSbVd0OGt1ZkdmZTozOTQyNjcwMi41MjM0MTM3MTAifV19XX19LCJhdHRyaWJ1dGVfNCI6eyJuYW1lIjoiemlwIiwibm9uX3Jldm9rZWQiOnsiZnJvbSI6bnVsbCwidG8iOm51bGx9LCJyZXN0cmljdGlvbnMiOnsiJG9yIjpbeyIkYW5kIjpbeyJjcmVkX2RlZl9pZCI6IjI0VWh4TGFlUUVONHBtb0JDcnZBUnI6MzpDTDoxMjc6dGFnMSJ9LHsiaXNzdWVyX2RpZCI6IjI0VWh4TGFlUUVONHBtb0JDcnZBUnIifSx7InNjaGVtYV9pZCI6IjI0VWh4TGFlUUVONHBtb0JDcnZBUnI6Mjp5c2x6OU5yakhtaVJSdFJtV3Q4a3VmR2ZlOjM5NDI2NzAyLjUyMzQxMzcxMCJ9XX1dfX19LCJyZXF1ZXN0ZWRfcHJlZGljYXRlcyI6e30sInZlciI6IjEuMCIsInZlcnNpb24iOiIxLjAifQ==" + }, + "mime-type": "application/json" + } + ] + }, + { + "@id": "testid", + "comment": "institution wants you to share request2", + "request_presentations~attach": [ + { + "@id": "libindy-request-presentation-0", + "data": { + "base64": "eyJuYW1lIjoicmVxdWVzdDIiLCJub25fcmV2b2tlZCI6bnVsbCwibm9uY2UiOiI3NjI0MTI1ODE0NDgxMDU3OTY1NjUxMTkiLCJyZXF1ZXN0ZWRfYXR0cmlidXRlcyI6eyJhdHRyaWJ1dGVfMCI6eyJuYW1lIjoiQWRkcmVzczEiLCJub25fcmV2b2tlZCI6eyJmcm9tIjpudWxsLCJ0byI6bnVsbH0sInJlc3RyaWN0aW9ucyI6eyIkb3IiOlt7IiRhbmQiOlt7ImNyZWRfZGVmX2lkIjoiMjRVaHhMYWVRRU40cG1vQkNydkFScjozOkNMOjEyNzp0YWcxIn0seyJpc3N1ZXJfZGlkIjoiMjRVaHhMYWVRRU40cG1vQkNydkFSciJ9LHsic2NoZW1hX2lkIjoiMjRVaHhMYWVRRU40cG1vQkNydkFScjoyOnlzbHo5TnJqSG1pUlJ0Um1XdDhrdWZHZmU6Mzk0MjY3MDIuNTIzNDEzNzEwIn1dfV19fSwiYXR0cmlidXRlXzEiOnsibmFtZSI6ImFkZHJlc3MyIiwibm9uX3Jldm9rZWQiOnsiZnJvbSI6bnVsbCwidG8iOm51bGx9LCJyZXN0cmljdGlvbnMiOnsiJG9yIjpbeyIkYW5kIjpbeyJjcmVkX2RlZl9pZCI6IjI0VWh4TGFlUUVONHBtb0JDcnZBUnI6MzpDTDoxMjc6dGFnMSJ9LHsiaXNzdWVyX2RpZCI6IjI0VWh4TGFlUUVONHBtb0JDcnZBUnIifSx7InNjaGVtYV9pZCI6IjI0VWh4TGFlUUVONHBtb0JDcnZBUnI6Mjp5c2x6OU5yakhtaVJSdFJtV3Q4a3VmR2ZlOjM5NDI2NzAyLjUyMzQxMzcxMCJ9XX1dfX0sImF0dHJpYnV0ZV8yIjp7Im5hbWUiOiJDSVRZIiwibm9uX3Jldm9rZWQiOnsiZnJvbSI6bnVsbCwidG8iOm51bGx9LCJyZXN0cmljdGlvbnMiOnsiJG9yIjpbeyIkYW5kIjpbeyJjcmVkX2RlZl9pZCI6IjI0VWh4TGFlUUVONHBtb0JDcnZBUnI6MzpDTDoxMjc6dGFnMSJ9LHsiaXNzdWVyX2RpZCI6IjI0VWh4TGFlUUVONHBtb0JDcnZBUnIifSx7InNjaGVtYV9pZCI6IjI0VWh4TGFlUUVONHBtb0JDcnZBUnI6Mjp5c2x6OU5yakhtaVJSdFJtV3Q4a3VmR2ZlOjM5NDI2NzAyLjUyMzQxMzcxMCJ9XX1dfX0sImF0dHJpYnV0ZV8zIjp7Im5hbWUiOiJTdGF0ZSIsIm5vbl9yZXZva2VkIjp7ImZyb20iOm51bGwsInRvIjpudWxsfSwicmVzdHJpY3Rpb25zIjp7IiRvciI6W3siJGFuZCI6W3siY3JlZF9kZWZfaWQiOiIyNFVoeExhZVFFTjRwbW9CQ3J2QVJyOjM6Q0w6MTI3OnRhZzEifSx7Imlzc3Vlcl9kaWQiOiIyNFVoeExhZVFFTjRwbW9CQ3J2QVJyIn0seyJzY2hlbWFfaWQiOiIyNFVoeExhZVFFTjRwbW9CQ3J2QVJyOjI6eXNsejlOcmpIbWlSUnRSbVd0OGt1ZkdmZTozOTQyNjcwMi41MjM0MTM3MTAifV19XX19LCJhdHRyaWJ1dGVfNCI6eyJuYW1lIjoiemlwIiwibm9uX3Jldm9rZWQiOnsiZnJvbSI6bnVsbCwidG8iOm51bGx9LCJyZXN0cmljdGlvbnMiOnsiJG9yIjpbeyIkYW5kIjpbeyJjcmVkX2RlZl9pZCI6IjI0VWh4TGFlUUVONHBtb0JDcnZBUnI6MzpDTDoxMjc6dGFnMSJ9LHsiaXNzdWVyX2RpZCI6IjI0VWh4TGFlUUVONHBtb0JDcnZBUnIifSx7InNjaGVtYV9pZCI6IjI0VWh4TGFlUUVONHBtb0JDcnZBUnI6Mjp5c2x6OU5yakhtaVJSdFJtV3Q4a3VmR2ZlOjM5NDI2NzAyLjUyMzQxMzcxMCJ9XX1dfX19LCJyZXF1ZXN0ZWRfcHJlZGljYXRlcyI6e30sInZlciI6IjEuMCIsInZlcnNpb24iOiIxLjAifQ==" + }, + "mime-type": "application/json" + } + ] + } +] +"#; + +pub static PRESENTATION_REQUEST_MESSAGE_ARRAY_EMPTY_ATTACH: &str = r#" +[ + { + "@id": "testid", + "comment": "institution wants you to share request1", + "request_presentations~attach": [ + { + "@id": "libindy-request-presentation-0", + "data": { + "base64": "e30=" + }, + "mime-type": "application/json" + } + ] + }, + { + "@id": "testid", + "comment": "institution wants you to share request2", + "request_presentations~attach": [ + { + "@id": "libindy-request-presentation-0", + "data": { + "base64": "e30=" + }, + "mime-type": "application/json" + } + ] + } +] +"#;