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

Commit

Permalink
Merge pull request #1916 from Artemkaaas/rc-1.12.0-updates
Browse files Browse the repository at this point in the history
Rc 1.12.0 Updates
  • Loading branch information
jovfer authored Oct 4, 2019
2 parents 9e042de + 40f440b commit 55b77ec
Show file tree
Hide file tree
Showing 16 changed files with 186 additions and 54 deletions.
4 changes: 2 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Changelog

## 1.12.0 - 2019-09-XX
* Minimal Support of Fully-Qualified identifiers:
* Minimal *EXPERIMENTAL* support of Fully-Qualified identifiers:
* general format of fully-qualified identifier is `<prefix>:<method>:<value>`.
* extended `did_info` parameter of `indy_create_and_store_my_did` function to accepts optional `method_name` filed. This field should be used to create fully qualified DID.
* all functions can work with fully-qualified identifiers (new way) as well as with unqualified.
Expand Down Expand Up @@ -66,7 +66,7 @@ Old `indy_build_get_payment_sources_request` and `indy_parse_get_payment_sources

Added correspondent `payment-address sign/verify` commands to Indy CLI.

* Added new *EXPEREMENTAL* functions to get requirements and price for a ledger request.
* Added new *EXPERIMENTAL* functions to get requirements and price for a ledger request.
* Libindy `indy_get_request_info` - returns request requirements (with minimal price) correspondent to specific auth rule in case the requester can perform this action.
* Libvcx `vcx_get_request_price` - returns request minimal request price for performing an action in case the requester can do it.
* Added a set of new Libvcx APIs around credentials and proofs that work with messages that should be exchanged without handling the transport of those messages.
Expand Down
10 changes: 7 additions & 3 deletions docs/migration-guides/migration-guide-1.11.0-1.12.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,16 +48,20 @@ This functions also updates all DID related entities stored in the wallet to poi

#### Anoncreds API

As we have released Fully-Qualified identifiers, we can work with both identifier formats in a compatible way.
As we have released *EXPERIMENTAL* Fully-Qualified identifiers, we can work with both identifier formats in a compatible way.

The new function [indy_to_unqualified](https://github.com/hyperledger/indy-sdk/blob/v1.12.0/libindy/src/api/did.rs#L729) was added.
The new function [indy_to_unqualified](https://github.com/hyperledger/indy-sdk/blob/v1.12.0/libindy/src/api/anoncreds.rs#L2378) was added.
This function gets unqualified form of a fully-qualified identifier.
This function can accept the following entities:
* DID
* SchemaId
* CredentialDefinitionId
* RevocationRegistryId
* CredentialOffer
* Schema
* CredentialDefinition
* RevocationRegistryDefinition
* CredentialOffer
* CredentialRequest
* ProofRequest

Let's consider Credential Issuance and Proof Presentation for different cases.
Expand Down
2 changes: 1 addition & 1 deletion libindy/debian/changelog
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ libindy (1.12.0) unstable; urgency=medium
[ Hyperledger ]

## 1.12.0
* Minimal Support of Fully-Qualified identifiers:
* Minimal *EXPERIMENTAL* support of Fully-Qualified identifiers:
* extended `did_info` parameter of `indy_create_and_store_my_did` function to accepts optional `method_name` filed. This field should be used to create fully qualified DID.
* all functions can work with fully-qualified identifiers (new way) as well as with unqualified.
* added a new function -- `indy_to_unqualified` -- that gets unqualified form of a fully qualified identifier.
Expand Down
4 changes: 4 additions & 0 deletions libindy/src/api/anoncreds.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2389,7 +2389,11 @@ pub extern fn indy_generate_nonce(command_handle: CommandHandle,
/// SchemaId
/// CredentialDefinitionId
/// RevocationRegistryId
/// Schema
/// CredentialDefinition
/// RevocationRegistryDefinition
/// CredentialOffer
/// CredentialRequest
/// ProofRequest
///
/// #Returns
Expand Down
16 changes: 16 additions & 0 deletions libindy/src/domain/anoncreds/credential_definition.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,22 @@ pub struct TemporaryCredentialDefinition {
pub cred_def_correctness_proof: CredentialDefinitionCorrectnessProof
}

impl CredentialDefinition {
pub fn to_unqualified(self) -> CredentialDefinition {
match self {
CredentialDefinition::CredentialDefinitionV1(cred_def) => {
CredentialDefinition::CredentialDefinitionV1(CredentialDefinitionV1 {
id: cred_def.id.to_unqualified(),
schema_id: cred_def.schema_id.to_unqualified(),
signature_type: cred_def.signature_type,
tag: cred_def.tag,
value: cred_def.value,
})
}
}
}
}

impl From<CredentialDefinition> for CredentialDefinitionV1 {
fn from(cred_def: CredentialDefinition) -> Self {
match cred_def {
Expand Down
12 changes: 12 additions & 0 deletions libindy/src/domain/anoncreds/credential_request.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,18 @@ pub struct CredentialRequestMetadata {
pub master_secret_name: String
}

impl CredentialRequest {
pub fn to_unqualified(self) -> CredentialRequest {
CredentialRequest {
prover_did: self.prover_did.to_unqualified(),
cred_def_id: self.cred_def_id.to_unqualified(),
blinded_ms: self.blinded_ms,
blinded_ms_correctness_proof: self.blinded_ms_correctness_proof,
nonce: self.nonce
}
}
}

impl Validatable for CredentialRequest {
fn validate(&self) -> Result<(), String> {
self.cred_def_id.validate()?;
Expand Down
16 changes: 16 additions & 0 deletions libindy/src/domain/anoncreds/revocation_registry_definition.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,22 @@ pub enum RevocationRegistryDefinition {
RevocationRegistryDefinitionV1(RevocationRegistryDefinitionV1)
}

impl RevocationRegistryDefinition {
pub fn to_unqualified(self) -> RevocationRegistryDefinition {
match self {
RevocationRegistryDefinition::RevocationRegistryDefinitionV1(rev_ref_def) => {
RevocationRegistryDefinition::RevocationRegistryDefinitionV1(RevocationRegistryDefinitionV1 {
id: rev_ref_def.id.to_unqualified(),
revoc_def_type: rev_ref_def.revoc_def_type,
tag: rev_ref_def.tag,
cred_def_id: rev_ref_def.cred_def_id.to_unqualified(),
value: rev_ref_def.value,
})
}
}
}
}

impl From<RevocationRegistryDefinition> for RevocationRegistryDefinitionV1 {
fn from(rev_reg_def: RevocationRegistryDefinition) -> Self {
match rev_reg_def {
Expand Down
16 changes: 16 additions & 0 deletions libindy/src/domain/anoncreds/schema.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,22 @@ pub enum Schema {
SchemaV1(SchemaV1)
}

impl Schema {
pub fn to_unqualified(self) -> Schema {
match self {
Schema::SchemaV1(schema) => {
Schema::SchemaV1(SchemaV1 {
id: schema.id.to_unqualified(),
name: schema.name,
version: schema.version,
attr_names: schema.attr_names,
seq_no: schema.seq_no,
})
}
}
}
}

impl From<Schema> for SchemaV1 {
fn from(schema: Schema) -> Self {
match schema {
Expand Down
62 changes: 33 additions & 29 deletions libindy/src/services/anoncreds/helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,11 @@ use domain::crypto::did::DidValue;
use domain::anoncreds::schema::SchemaId;
use domain::anoncreds::credential_definition::CredentialDefinitionId;
use domain::anoncreds::revocation_registry_definition::RevocationRegistryId;
use domain::anoncreds::schema::Schema;
use domain::anoncreds::credential_definition::CredentialDefinition;
use domain::anoncreds::revocation_registry_definition::RevocationRegistryDefinition;
use domain::anoncreds::credential_offer::CredentialOffer;
use domain::anoncreds::credential_request::CredentialRequest;
use domain::anoncreds::proof_request::ProofRequest;

use std::collections::{HashSet, HashMap};
Expand Down Expand Up @@ -105,42 +109,42 @@ pub fn get_non_revoc_interval(global_interval: &Option<NonRevocedInterval>, loca
interval
}

pub fn to_unqualified(entity: &str) -> IndyResult<String> {
info!("to_unqualified >>> entity: {:?}", entity);

if entity.starts_with(DidValue::PREFIX) {
return Ok(DidValue(entity.to_string()).to_unqualified().0);
}

if entity.starts_with(SchemaId::PREFIX) {
return Ok(SchemaId(entity.to_string()).to_unqualified().0);
}
macro_rules! _id_to_unqualified {
($entity:expr, $type_:ident) => ({
if $entity.starts_with($type_::PREFIX) {
return Ok($type_($entity.to_string()).to_unqualified().0);
}
})
}

if entity.starts_with(CredentialDefinitionId::PREFIX) {
return Ok(CredentialDefinitionId(entity.to_string()).to_unqualified().0);
}
macro_rules! _object_to_unqualified {
($entity:expr, $type_:ident) => ({
if let Ok(object) = ::serde_json::from_str::<$type_>(&$entity) {
return Ok(json!(object.to_unqualified()).to_string())
}
})
}

if entity.starts_with(RevocationRegistryId::PREFIX) {
return Ok(RevocationRegistryId(entity.to_string()).to_unqualified().0);
}
pub fn to_unqualified(entity: &str) -> IndyResult<String> {
info!("to_unqualified >>> entity: {:?}", entity);

if let Ok(cred_offer) = ::serde_json::from_str::<CredentialOffer>(&entity) {
let cred_offer = cred_offer.to_unqualified();
return serde_json::to_string(&cred_offer)
.map_err(|err| IndyError::from_msg(IndyErrorKind::InvalidState, format!("Cannot serialize Credential Offer: {:?}", err)));
}
_id_to_unqualified!(entity, DidValue);
_id_to_unqualified!(entity, SchemaId);
_id_to_unqualified!(entity, CredentialDefinitionId);
_id_to_unqualified!(entity, RevocationRegistryId);

if let Ok(proof_request) = ::serde_json::from_str::<ProofRequest>(&entity) {
let proof_request = proof_request.to_unqualified();
return serde_json::to_string(&proof_request)
.map_err(|err| IndyError::from_msg(IndyErrorKind::InvalidState, format!("Cannot serialize Proof Request: {:?}", err)));
}
_object_to_unqualified!(entity, Schema);
_object_to_unqualified!(entity, CredentialDefinition);
_object_to_unqualified!(entity, RevocationRegistryDefinition);
_object_to_unqualified!(entity, CredentialOffer);
_object_to_unqualified!(entity, CredentialRequest);
_object_to_unqualified!(entity, ProofRequest);

Ok(entity.to_string())
}

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

fn _interval() -> NonRevocedInterval { NonRevocedInterval { from: None, to: Some(123) } }
Expand All @@ -165,7 +169,7 @@ mod tests{

mod to_unqualified {
use super::*;

const DID_QUALIFIED: &str = "did:sov:NcYxiDXkpYi6ov5FcYDi1e";
const DID_UNQUALIFIED: &str = "NcYxiDXkpYi6ov5FcYDi1e";
const SCHEMA_ID_QUALIFIED: &str = "schema:sov:did:sov:NcYxiDXkpYi6ov5FcYDi1e:2:gvt:1.0";
Expand All @@ -176,7 +180,7 @@ mod tests{
const REV_REG_ID_UNQUALIFIED: &str = "NcYxiDXkpYi6ov5FcYDi1e:4:NcYxiDXkpYi6ov5FcYDi1e:3:CL:NcYxiDXkpYi6ov5FcYDi1e:2:gvt:1.0:tag:CL_ACCUM:TAG_1";
const SCHEMA_ID_WITH_SPACES_QUALIFIED: &str = "schema:sov:did:sov:NcYxiDXkpYi6ov5FcYDi1e:2:Passport Schema:1.0";
const SCHEMA_ID_WITH_SPACES_UNQUALIFIED: &str = "NcYxiDXkpYi6ov5FcYDi1e:2:Passport Schema:1.0";

#[test]
fn test_to_unqualified() {
// DID
Expand Down
53 changes: 48 additions & 5 deletions libindy/tests/anoncreds.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3452,14 +3452,57 @@ mod high_cases {

mod to_unqualified {
use super::*;
use utils::domain::anoncreds::schema::SchemaV1;
use utils::domain::anoncreds::credential_definition::CredentialDefinitionV1;
use utils::domain::anoncreds::credential_offer::CredentialOffer;
use utils::domain::anoncreds::credential_request::CredentialRequest;

#[test]
fn to_unqualified() {
let qualified = "did:sov:NcYxiDXkpYi6ov5FcYDi1e";
let unqualified = "NcYxiDXkpYi6ov5FcYDi1e";
fn to_unqualified_ids() {
assert_eq!(DID_MY1, anoncreds::to_unqualified(DID_MY1_V1).unwrap());
assert_eq!(DID_MY1, anoncreds::to_unqualified(DID_MY1).unwrap());

assert_eq!(unqualified, anoncreds::to_unqualified(qualified).unwrap());
assert_eq!(unqualified, anoncreds::to_unqualified(unqualified).unwrap());
assert_eq!(anoncreds::gvt_schema_id(), anoncreds::to_unqualified(&anoncreds::gvt_schema_id_fully_qualified()).unwrap());
assert_eq!(anoncreds::gvt_cred_def_id(), anoncreds::to_unqualified(&anoncreds::gvt_cred_def_id_fully_qualified()).unwrap());
assert_eq!(anoncreds::local_gvt_cred_def_id(), anoncreds::to_unqualified(&anoncreds::local_gvt_cred_def_id_fully_qualified()).unwrap());
}

#[test]
fn to_unqualified_objects() {
let setup = Setup::wallet();

let (schema_id, schema_json) = anoncreds::issuer_create_schema(ISSUER_DID_V1, GVT_SCHEMA_NAME, SCHEMA_VERSION, GVT_SCHEMA_ATTRIBUTES).unwrap();

assert_eq!(anoncreds::gvt_schema_id(), anoncreds::to_unqualified(&schema_id).unwrap());

let schema_json_un = anoncreds::to_unqualified(&schema_json).unwrap();
let schema: SchemaV1 = ::serde_json::from_str(&schema_json_un).unwrap();
assert_eq!(anoncreds::gvt_schema_id(), schema.id.0);

let (cred_def_id, cred_def_json) = anoncreds::issuer_create_credential_definition(setup.wallet_handle, ISSUER_DID_V1, &schema_json, TAG_1, None, None).unwrap();

assert_eq!(anoncreds::local_gvt_cred_def_id(), anoncreds::to_unqualified(&cred_def_id).unwrap());

let cred_def_json_un = anoncreds::to_unqualified(&cred_def_json).unwrap();
let cred_def: CredentialDefinitionV1 = ::serde_json::from_str(&cred_def_json_un).unwrap();
assert_eq!(anoncreds::local_gvt_cred_def_id(), cred_def.id.0);
assert_eq!(anoncreds::gvt_schema_id(), cred_def.schema_id.0);

let cred_offer_json = anoncreds::issuer_create_credential_offer(setup.wallet_handle, &cred_def_id).unwrap();

let cred_offer_json_un = anoncreds::to_unqualified(&cred_offer_json).unwrap();
let cred_offer: CredentialOffer = ::serde_json::from_str(&cred_offer_json_un).unwrap();
assert_eq!(anoncreds::local_gvt_cred_def_id(), cred_offer.cred_def_id.0);
assert_eq!(anoncreds::gvt_schema_id(), cred_offer.schema_id.0);

anoncreds::prover_create_master_secret(setup.wallet_handle, COMMON_MASTER_SECRET).unwrap();

let (cred_req_json, _) = anoncreds::prover_create_credential_req(setup.wallet_handle, DID_MY1_V1, &cred_offer_json, &cred_def_json_un, COMMON_MASTER_SECRET).unwrap();

let cred_req_json_un = anoncreds::to_unqualified(&cred_req_json).unwrap();
let cred_req: CredentialRequest = ::serde_json::from_str(&cred_req_json_un).unwrap();
assert_eq!(DID_MY1.to_string(), cred_req.prover_did.0);
assert_eq!(anoncreds::local_gvt_cred_def_id(), cred_req.cred_def_id.0);
}
}
}
Expand Down
3 changes: 2 additions & 1 deletion vcx/libvcx/debian/changelog
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ libvcx (0.4.2) unstable; urgency=medium
[ Hyperledger ]

## 0.4.2
* Extended provisioning config to accept optional `did_method` filed. This field should be used to create fully qualified DIDs.
* *EXPERIMENTAL*
Extended provisioning config to accept optional `did_method` filed. This field should be used to create fully qualified DIDs.
The format of identifiers used on CredentialIssuance and ProofPresentation will determine based on the type of remote DID.
* Bugfixes

Expand Down
16 changes: 10 additions & 6 deletions wrappers/ios/libindy-pod/Indy/Wrapper/IndyAnoncreds.h
Original file line number Diff line number Diff line change
Expand Up @@ -1106,12 +1106,16 @@ And is documented in this HIPE:
@param entity: utarget entity to disqualify.
Can be one of:
Did
SchemaId
CredentialDefinitionId
RevocationRegistryId
CredentialOffer
ProofRequest
Did
SchemaId
CredentialDefinitionId
RevocationRegistryId
Schema
CredentialDefinition
RevocationRegistryDefinition
CredentialOffer
CredentialRequest
ProofRequest
Returns entity either in unqualified form or original if casting isn't possible
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1555,7 +1555,11 @@ public static CompletableFuture<String> generateNonce() throws IndyException {
* SchemaId
* CredentialDefinitionId
* RevocationRegistryId
* Schema
* CredentialDefinition
* RevocationRegistryDefinition
* CredentialOffer
* CredentialRequest
* ProofRequest
* @return A future that resolves to entity either in unqualified form or original if casting isn't possible
* @throws IndyException Thrown if an error occurs when calling the underlying SDK.
Expand Down
2 changes: 1 addition & 1 deletion wrappers/nodejs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -931,7 +931,7 @@ This function should be used to the proper casting of fully qualified entity to
2) Verifier prepares a Proof Request based on fully qualified identifiers or Prover, which doesn't support fully qualified identifiers.
3) another case when casting to unqualified form needed

* `entity`: String - target entity to disqualify. Can be one of: Did, SchemaId, CredentialDefinitionId, RevocationRegistryId, CredentialOffer.
* `entity`: String - target entity to disqualify. Can be one of: Did, SchemaId, CredentialDefinitionId, RevocationRegistryId, Schema, CredentialDefinition, RevocationRegistryDefinition, CredentialOffer, CredentialRequest, ProofRequest.
* __->__ `res`: Json - entity either in unqualified form or original if casting isn't possible

### blob_storage
Expand Down
4 changes: 4 additions & 0 deletions wrappers/python/indy/anoncreds.py
Original file line number Diff line number Diff line change
Expand Up @@ -1873,7 +1873,11 @@ async def to_unqualified(entity: str) -> str:
SchemaId
CredentialDefinitionId
RevocationRegistryId
Schema
CredentialDefinition
RevocationRegistryDefinition
CredentialOffer
CredentialRequest
ProofRequest
:return: entity either in unqualified form or original if casting isn't possible
Expand Down
Loading

0 comments on commit 55b77ec

Please sign in to comment.