Skip to content

Commit

Permalink
Prover: fix credx credential retrieval (#961)
Browse files Browse the repository at this point in the history
* Test code adjustments

Signed-off-by: Patrik Stas <patrik.stas@absa.africa>

* wip

Signed-off-by: Patrik Stas <patrik.stas@absa.africa>

* Rename 'requested_credentials' to 'preselected_credentials'

Signed-off-by: Patrik Stas <patrik.stas@absa.africa>

* Remove prover_select_credentials_and_fail_to_generate_proof in favor of simpler testing approach

Signed-off-by: Patrik Stas <patrik.stas@absa.africa>

* Simplify common testing case of sending proof

Signed-off-by: Patrik Stas <patrik.stas@absa.africa>

* Add test test_agency_pool_it_should_select_credentials_for_satisfiable_restriction

Signed-off-by: Patrik Stas <patrik.stas@absa.africa>

* Fix credential retrieval by prover

Signed-off-by: Patrik Stas <patrik.stas@absa.africa>

* Do not run test_agency_pool_it_should_fail_to_select_credentials_for_predicate for credx implementation

Signed-off-by: Patrik Stas <patrik.stas@absa.africa>

* Address code review

Signed-off-by: Patrik Stas <patrik.stas@absa.africa>

* Revert CI change

Signed-off-by: Patrik Stas <patrik.stas@absa.africa>

---------

Signed-off-by: Patrik Stas <patrik.stas@absa.africa>
Signed-off-by: Bogdan Mircea <mirceapetrebogdan@gmail.com>
  • Loading branch information
Patrik-Stas authored and bobozaur committed Sep 14, 2023
1 parent f8aaadc commit f5fcf2a
Show file tree
Hide file tree
Showing 4 changed files with 88 additions and 75 deletions.
2 changes: 1 addition & 1 deletion aries_vcx/src/handlers/proof_presentation/prover.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ impl Prover {
let json_retrieved_credentials = anoncreds
.prover_get_credentials_for_proof_req(&presentation_request)
.await?;

trace!("Prover::retrieve_credentials >>> presentation_request: {presentation_request}, json_retrieved_credentials: {json_retrieved_credentials}");
Ok(serde_json::from_str(&json_retrieved_credentials)?)
}

Expand Down
72 changes: 59 additions & 13 deletions aries_vcx/tests/test_creds_proofs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -587,10 +587,10 @@ mod tests {
accept_cred_proposal, accept_cred_proposal_1, accept_offer, accept_proof_proposal, attr_names,
create_and_send_nonrevocable_cred_offer, create_connected_connections, create_proof, decline_offer,
generate_and_send_proof, issue_address_credential, prover_select_credentials,
prover_select_credentials_and_fail_to_generate_proof, prover_select_credentials_and_send_proof,
receive_proof_proposal_rejection, reject_proof_proposal, retrieved_to_selected_credentials_simple,
send_cred_proposal, send_cred_proposal_1, send_cred_req, send_credential, send_proof_proposal,
send_proof_proposal_1, send_proof_request, verifier_create_proof_and_send_request, verify_proof,
prover_select_credentials_and_send_proof, receive_proof_proposal_rejection, reject_proof_proposal,
retrieved_to_selected_credentials_simple, send_cred_proposal, send_cred_proposal_1, send_cred_req,
send_credential, send_proof_proposal, send_proof_proposal_1, send_proof_request,
verifier_create_proof_and_send_request, verify_proof,
};

#[tokio::test]
Expand Down Expand Up @@ -733,6 +733,8 @@ mod tests {
.await;
}

// todo: credx implementation does not support checking credential value in respect to predicate
#[cfg(not(feature = "modular_libs"))]
#[tokio::test]
#[ignore]
async fn test_agency_pool_it_should_fail_to_select_credentials_for_predicate() {
Expand All @@ -753,19 +755,13 @@ mod tests {
#[cfg(feature = "migration")]
institution.migrate().await;

let requested_preds_string = serde_json::to_string(&json!([
{
let requested_preds_string = serde_json::to_string(&json!([{
"name": "zip",
"p_type": ">=",
"p_value": 85000
}]))
.unwrap();

info!(
"test_basic_proof :: Going to seng proof request with attributes {}",
&requested_preds_string
);

send_proof_request(
&mut institution,
&institution_to_consumer,
Expand All @@ -779,8 +775,58 @@ mod tests {
#[cfg(feature = "migration")]
consumer.migrate().await;

prover_select_credentials_and_fail_to_generate_proof(&mut consumer, &consumer_to_institution, None, None)
.await;
let mut prover = create_proof(&mut consumer, &consumer_to_institution, None).await;
let selected_credentials =
prover_select_credentials(&mut prover, &mut consumer, &consumer_to_institution, None).await;

assert!(selected_credentials.credential_for_referent.is_empty());
})
.await;
}

#[tokio::test]
#[ignore]
async fn test_agency_pool_it_should_select_credentials_for_satisfiable_restriction() {
SetupPoolDirectory::run(|setup| async move {
let mut institution = create_faber_trustee(setup.genesis_file_path.clone()).await;
let mut consumer = create_alice(setup.genesis_file_path).await;

let (consumer_to_institution, institution_to_consumer) =
create_connected_connections(&mut consumer, &mut institution).await;
issue_address_credential(
&mut consumer,
&mut institution,
&consumer_to_institution,
&institution_to_consumer,
)
.await;

let requested_attrs_string = serde_json::to_string(&json!([
{
"name": "address1",
"restrictions": [{
"issuer_did": "abcdef0000000000000000",
},
{
"issuer_did": institution.institution_did,
}]
}]))
.unwrap();

send_proof_request(
&mut institution,
&institution_to_consumer,
&requested_attrs_string,
"[]",
"{}",
None,
)
.await;

let mut prover = create_proof(&mut consumer, &consumer_to_institution, None).await;
let selected_credentials =
prover_select_credentials(&mut prover, &mut consumer, &consumer_to_institution, None).await;
assert_eq!(selected_credentials.credential_for_referent.is_empty(), false);
})
.await;
}
Expand Down
69 changes: 16 additions & 53 deletions aries_vcx/tests/utils/scenarios.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1121,7 +1121,7 @@ pub mod test_utils {
prover: &mut Prover,
alice: &mut Alice,
connection: &MediatedConnection,
requested_values: Option<&str>,
preselected_credentials: Option<&str>,
) -> SelectedCredentials {
prover_update_with_mediator(prover, &alice.agency_client, connection)
.await
Expand All @@ -1131,70 +1131,33 @@ pub mod test_utils {
.retrieve_credentials(&alice.profile.inject_anoncreds())
.await
.unwrap();
let selected_credentials = match requested_values {
Some(requested_values) => {
info!("prover_select_credentials >> retrieved_credentials: {retrieved_credentials:?}");
let selected_credentials = match preselected_credentials {
Some(preselected_credentials) => {
let credential_data = prover.presentation_request_data().unwrap();
retrieved_to_selected_credentials_specific(
&retrieved_credentials,
requested_values,
&credential_data,
true,
)
match_preselected_credentials(&retrieved_credentials, preselected_credentials, &credential_data, true)
}
_ => retrieved_to_selected_credentials_simple(&retrieved_credentials, true),
};

selected_credentials
}

pub async fn prover_select_credentials_and_send_proof_and_assert(
pub async fn prover_select_credentials_and_send_proof(
alice: &mut Alice,
consumer_to_institution: &MediatedConnection,
request_name: Option<&str>,
requested_values: Option<&str>,
expected_prover_state: ProverState,
preselected_credentials: Option<&str>,
) {
let mut prover = create_proof(alice, consumer_to_institution, request_name).await;
let selected_credentials =
prover_select_credentials(&mut prover, alice, consumer_to_institution, requested_values).await;
prover_select_credentials(&mut prover, alice, consumer_to_institution, preselected_credentials).await;
info!(
"Prover :: Retrieved credential converted to selected: {:?}",
&selected_credentials
);
generate_and_send_proof(alice, &mut prover, consumer_to_institution, selected_credentials).await;
assert_eq!(expected_prover_state, prover.get_state());
}

pub async fn prover_select_credentials_and_send_proof(
consumer: &mut Alice,
consumer_to_institution: &MediatedConnection,
request_name: Option<&str>,
requested_values: Option<&str>,
) {
prover_select_credentials_and_send_proof_and_assert(
consumer,
consumer_to_institution,
request_name,
requested_values,
ProverState::PresentationSent,
)
.await
}

pub async fn prover_select_credentials_and_fail_to_generate_proof(
consumer: &mut Alice,
consumer_to_institution: &MediatedConnection,
request_name: Option<&str>,
requested_values: Option<&str>,
) {
prover_select_credentials_and_send_proof_and_assert(
consumer,
consumer_to_institution,
request_name,
requested_values,
ProverState::PresentationPreparationFailed,
)
.await
assert_eq!(ProverState::PresentationSent, prover.get_state());
}

pub async fn connect_using_request_sent_to_public_agent(
Expand Down Expand Up @@ -1373,7 +1336,7 @@ pub mod test_utils {
with_tails: bool,
) -> SelectedCredentials {
info!(
"test_real_proof >>> retrieved matching credentials {:?}",
"retrieved_to_selected_credentials_simple >>> retrieved matching credentials {:?}",
retrieved_credentials
);
let mut selected_credentials = SelectedCredentials::default();
Expand All @@ -1392,18 +1355,18 @@ pub mod test_utils {
return selected_credentials;
}

pub fn retrieved_to_selected_credentials_specific(
pub fn match_preselected_credentials(
retrieved_credentials: &RetrievedCredentials,
requested_values: &str,
preselected_credentials: &str,
credential_data: &str,
with_tails: bool,
) -> SelectedCredentials {
info!(
"test_real_proof >>> retrieved matching credentials {:?}",
"retrieved_to_selected_credentials_specific >>> retrieved matching credentials {:?}",
retrieved_credentials
);
let credential_data: Value = serde_json::from_str(credential_data).unwrap();
let requested_values: Value = serde_json::from_str(requested_values).unwrap();
let preselected_credentials: Value = serde_json::from_str(preselected_credentials).unwrap();
let requested_attributes: &Value = &credential_data["requested_attributes"];

let mut selected_credentials = SelectedCredentials::default();
Expand All @@ -1414,8 +1377,8 @@ pub mod test_utils {
.into_iter()
.filter_map(|cred| {
let attribute_name = requested_attributes[referent]["name"].as_str().unwrap();
let requested_value = requested_values[attribute_name].as_str().unwrap();
if cred.cred_info.attributes[attribute_name] == requested_value {
let preselected_credential = preselected_credentials[attribute_name].as_str().unwrap();
if cred.cred_info.attributes[attribute_name] == preselected_credential {
Some(cred)
} else {
None
Expand Down
20 changes: 12 additions & 8 deletions aries_vcx_core/src/anoncreds/credx_anoncreds.rs
Original file line number Diff line number Diff line change
Expand Up @@ -160,18 +160,22 @@ impl IndyCredxAnonCreds {

let wql_query = if let Some(restrictions) = restrictions {
match restrictions {
Value::Array(mut arr) => {
arr.extend(attrs);
json!({ "$and": arr })
Value::Array(restrictions) => {
let restrictions_wql = json!({ "$or": restrictions });
attrs.push(restrictions_wql);
json!({ "$and": attrs })
}
Value::Object(obj) => {
attrs.push(Value::Object(obj));
Value::Object(restriction) => {
attrs.push(Value::Object(restriction));
json!({ "$and": attrs })
}
_ => json!(attrs),
_ => Err(AriesVcxCoreError::from_msg(
AriesVcxCoreErrorKind::InvalidInput,
"Invalid attribute restrictions (must be array or an object)",
))?,
}
} else {
json!(attrs)
json!({ "$and": attrs })
};

let wql_query = serde_json::to_string(&wql_query)?;
Expand Down Expand Up @@ -750,7 +754,7 @@ impl BaseAnonCreds for IndyCredxAnonCreds {
.map(|v| v.try_as_str().map(_normalize_attr_name))
.collect::<Result<_, _>>()?,
_ => Err(AriesVcxCoreError::from_msg(
AriesVcxCoreErrorKind::InvalidAttributesStructure,
AriesVcxCoreErrorKind::InvalidInput,
"exactly one of 'name' or 'names' must be present",
))?,
};
Expand Down

0 comments on commit f5fcf2a

Please sign in to comment.