Skip to content
This repository has been archived by the owner on Feb 29, 2024. It is now read-only.

IS-1381 -- adding new field "names" to proof request #1958

Merged
merged 17 commits into from
Nov 27, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions libindy/src/api/anoncreds.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1526,6 +1526,7 @@ pub extern fn indy_prover_close_credentials_search(command_handle: CommandHandl
/// attr_info: Describes requested attribute
/// {
/// "name": string, // attribute name, (case insensitive and ignore spaces)
/// "names": [string, string], // attribute names, (case insensitive and ignore spaces) -- should either be "name" or "names", not both and not none of them.
/// "restrictions": Optional<filter_json>, // see below
/// "non_revoked": Optional<<non_revoc_interval>>, // see below,
/// // If specified prover must proof non-revocation
Expand Down Expand Up @@ -1651,6 +1652,7 @@ pub extern fn indy_prover_get_credentials_for_proof_req(command_handle: CommandH
/// attr_info: Describes requested attribute
/// {
/// "name": string, // attribute name, (case insensitive and ignore spaces)
/// "names": [string, string], // attribute names, (case insensitive and ignore spaces) -- should either be "name" or "names", not both and not none of them.
/// "restrictions": Optional<wql query>, // see below
/// "non_revoked": Optional<<non_revoc_interval>>, // see below,
/// // If specified prover must proof non-revocation
Expand Down Expand Up @@ -1921,6 +1923,7 @@ pub extern fn indy_prover_close_credentials_search_for_proof_req(command_handle
/// attr_info: Describes requested attribute
/// {
/// "name": string, // attribute name, (case insensitive and ignore spaces)
/// "names": [string, string], // attribute names, (case insensitive and ignore spaces) -- should either be "name" or "names", not both and not none of them.
/// "restrictions": Optional<wql query>, // see below
/// "non_revoked": Optional<<non_revoc_interval>>, // see below,
/// // If specified prover must proof non-revocation
Expand Down Expand Up @@ -1966,6 +1969,16 @@ pub extern fn indy_prover_close_credentials_search_for_proof_req(command_handle
/// "requested_attr1_id": {sub_proof_index: number, raw: string, encoded: string},
/// "requested_attr4_id": {sub_proof_index: number: string, encoded: string},
/// },
/// "revealed_attr_groups": {
/// "requested_attr5_id": {
/// "sub_proof_index": number,
/// "values": [
/// {
/// "raw": string,
/// "encoded": string
/// }
/// ], // NOTE: check that `encoded` value match to `raw` value on application level
/// },
/// "unrevealed_attrs": {
/// "requested_attr3_id": {sub_proof_index: number}
/// },
Expand Down Expand Up @@ -2072,6 +2085,16 @@ pub extern fn indy_prover_create_proof(command_handle: CommandHandle,
/// "requested_attr1_id": {sub_proof_index: number, raw: string, encoded: string}, // NOTE: check that `encoded` value match to `raw` value on application level
/// "requested_attr4_id": {sub_proof_index: number: string, encoded: string}, // NOTE: check that `encoded` value match to `raw` value on application level
/// },
/// "revealed_attr_groups": {
/// "requested_attr5_id": {
/// "sub_proof_index": number,
/// "values": [
/// {
/// "raw": string,
/// "encoded": string
/// }
/// ], // NOTE: check that `encoded` value match to `raw` value on application level
/// },
/// "unrevealed_attrs": {
/// "requested_attr3_id": {sub_proof_index: number}
/// },
Expand Down Expand Up @@ -2125,6 +2148,7 @@ pub extern fn indy_prover_create_proof(command_handle: CommandHandle,
/// attr_info: Describes requested attribute
/// {
/// "name": string, // attribute name, (case insensitive and ignore spaces)
/// "names": [string, string], // attribute names, (case insensitive and ignore spaces) -- should either be "name" or "names", not both and not none of them.
/// "restrictions": Optional<wql query>, // see below
/// "non_revoked": Optional<<non_revoc_interval>>, // see below,
/// // If specified prover must proof non-revocation
Expand Down
8 changes: 6 additions & 2 deletions libindy/src/commands/anoncreds/prover.rs
Original file line number Diff line number Diff line change
Expand Up @@ -534,6 +534,7 @@ impl ProverCommandExecutor {
for (attr_id, requested_attr) in proof_req.requested_attributes.iter() {
let query = self.anoncreds_service.prover.extend_proof_request_restrictions(&proof_req_version,
&requested_attr.name,
&requested_attr.names,
&attr_id,
&requested_attr.restrictions,
&None)?;
Expand All @@ -546,7 +547,8 @@ impl ProverCommandExecutor {

for (predicate_id, requested_predicate) in proof_req.requested_predicates.iter() {
let query = self.anoncreds_service.prover.extend_proof_request_restrictions(&proof_req_version,
&requested_predicate.name,
&Some(requested_predicate.name.clone()),
&None,
&predicate_id,
&requested_predicate.restrictions,
&None)?;
Expand Down Expand Up @@ -581,6 +583,7 @@ impl ProverCommandExecutor {
for (attr_id, requested_attr) in proof_req.requested_attributes.iter() {
let query = self.anoncreds_service.prover.extend_proof_request_restrictions(&version,
&requested_attr.name,
&requested_attr.names,
&attr_id,
&requested_attr.restrictions,
&extra_query)?;
Expand All @@ -597,7 +600,8 @@ impl ProverCommandExecutor {

for (predicate_id, requested_predicate) in proof_req.requested_predicates.iter() {
let query = self.anoncreds_service.prover.extend_proof_request_restrictions(&version,
&requested_predicate.name,
&Some(requested_predicate.name.clone()),
&None,
&predicate_id,
&requested_predicate.restrictions,
&extra_query)?;
Expand Down
37 changes: 36 additions & 1 deletion libindy/src/domain/anoncreds/proof.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ pub struct Proof {
#[derive(Debug, Serialize, Deserialize)]
pub struct RequestedProof {
pub revealed_attrs: HashMap<String, RevealedAttributeInfo>,
#[serde(skip_serializing_if="HashMap::is_empty")]
#[serde(default)]
pub revealed_attr_groups: HashMap<String, RevealedAttributeGroupInfo>,
pub self_attested_attrs: HashMap<String, String>,
pub unrevealed_attrs: HashMap<String, SubProofReferent>,
pub predicates: HashMap<String, SubProofReferent>
Expand All @@ -26,6 +29,7 @@ impl Default for RequestedProof {
fn default() -> Self {
RequestedProof {
revealed_attrs: HashMap::new(),
revealed_attr_groups: HashMap::new(),
self_attested_attrs: HashMap::new(),
unrevealed_attrs: HashMap::new(),
predicates: HashMap::new(),
Expand All @@ -45,6 +49,17 @@ pub struct RevealedAttributeInfo {
pub encoded: String
}

#[derive(Debug, Deserialize, Serialize)]
pub struct RevealedAttributeGroupInfo {
pub sub_proof_index: u32,
pub values: HashMap<String /* attribute name */, AttributeValue>,
}

#[derive(Debug, Deserialize, Serialize)]
pub struct AttributeValue {
pub raw: String,
pub encoded: String
}

#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq, Hash)]
pub struct Identifier {
Expand All @@ -54,4 +69,24 @@ pub struct Identifier {
pub timestamp: Option<u64>
}

impl Validatable for Proof {}
impl Validatable for Proof {}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn deserialize_requested_proof_with_empty_revealed_attr_groups() {
let mut req_proof_old: RequestedProof = Default::default();
req_proof_old.revealed_attrs.insert("attr1".to_string(), RevealedAttributeInfo {
sub_proof_index: 0,
raw: "123".to_string(),
encoded: "123".to_string()
});
let json = json!(req_proof_old).to_string();
println!("{}", json);

let req_proof: RequestedProof = serde_json::from_str(&json).unwrap();
assert!(req_proof.revealed_attr_groups.is_empty())
}
}
20 changes: 16 additions & 4 deletions libindy/src/domain/anoncreds/proof_request.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,10 @@ pub struct NonRevocedInterval {

#[derive(Clone, Debug, Deserialize, Serialize, Eq, PartialEq)]
pub struct AttributeInfo {
pub name: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub name: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub names: Option<Vec<String>>,
pub restrictions: Option<Query>,
pub non_revoked: Option<NonRevocedInterval>
}
Expand Down Expand Up @@ -178,9 +181,16 @@ impl Validatable for ProofRequest {
}

for (_, requested_attribute) in value.requested_attributes.iter() {
if requested_attribute.name.is_empty() {
let has_name = !requested_attribute.name.as_ref().map(String::is_empty).unwrap_or(true);
let has_names = !requested_attribute.names.as_ref().map(Vec::is_empty).unwrap_or(true);
if !has_name && !has_names {
return Err(format!("Proof Request validation failed: there is empty requested attribute: {:?}", requested_attribute));
}

if has_name && has_names {
return Err(format!("Proof request validation failed: there is a requested attribute with both name and names: {:?}", requested_attribute));
}

if let Some(ref restrictions) = requested_attribute.restrictions {
_process_operator(&restrictions, &version)?;
}
Expand Down Expand Up @@ -327,7 +337,8 @@ mod tests {
fn proof_request_to_unqualified() {
let mut requested_attributes: HashMap<String, AttributeInfo> = HashMap::new();
requested_attributes.insert("attr1_referent".to_string(), AttributeInfo {
name: "name".to_string(),
name: Some("name".to_string()),
names: None,
restrictions: Some(Query::And(vec![
Query::Eq("issuer_did".to_string(), DID_QUALIFIED.to_string()),
Query::Eq("schema_id".to_string(), SCHEMA_ID_QUALIFIED.to_string()),
Expand Down Expand Up @@ -359,7 +370,8 @@ mod tests {

let mut expected_requested_attributes: HashMap<String, AttributeInfo> = HashMap::new();
expected_requested_attributes.insert("attr1_referent".to_string(), AttributeInfo {
name: "name".to_string(),
name: Some("name".to_string()),
names: None,
restrictions: Some(Query::And(vec![
Query::Eq("issuer_did".to_string(), DID_UNQUALIFIED.to_string()),
Query::Eq("schema_id".to_string(), SCHEMA_ID_UNQUALIFIED.to_string()),
Expand Down
13 changes: 12 additions & 1 deletion libindy/src/services/anoncreds/helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,18 @@ pub fn build_sub_proof_request(attrs_for_credential: &[AttributeInfo],
let mut sub_proof_request_builder = verifier::Verifier::new_sub_proof_request_builder()?;

for attr in attrs_for_credential {
sub_proof_request_builder.add_revealed_attr(&attr_common_view(&attr.name))?
let names = if let Some(name) = &attr.name {
vec![name.clone()]
} else if let Some(names) = &attr.names {
names.to_owned()
} else {
error!(r#"Attr for credential restriction should contain "name" or "names" param. Current attr: {:?}"#, attr);
return Err(IndyError::from_msg(IndyErrorKind::InvalidStructure, r#"Attr for credential restriction should contain "name" or "names" param."#));
};

for name in names {
sub_proof_request_builder.add_revealed_attr(&attr_common_view(&name))?
}
}

for predicate in predicates_for_credential {
Expand Down
Loading