From 7be4794e98742c9f2f6b6bab3fbfa5859853fdfb Mon Sep 17 00:00:00 2001 From: Tim Schlagenhaufer Date: Tue, 13 Sep 2022 14:08:03 +0200 Subject: [PATCH 1/7] Use CredentialAttributes class instead of key value maps Signed-off-by: Tim Schlagenhaufer --- .../aries/api/credentials/Credential.java | 11 ++++++++--- .../api/credentials/CredentialAttributes.java | 13 ++++++++----- .../V1CredentialFreeOfferHelper.java | 0 .../V2ToV1IndyCredentialConverter.java | 4 +++- .../PresentProofProposalBuilder.java | 19 +++++++++++-------- .../V2ToV1IndyCredentialConverterTest.java | 4 ++-- .../PresentProofProposalTest.java | 5 +++-- .../PresentProofProposalV2Test.java | 5 +++-- 8 files changed, 38 insertions(+), 23 deletions(-) create mode 100644 src/main/java/org/hyperledger/aries/api/issue_credential_v1/V1CredentialFreeOfferHelper.java diff --git a/src/main/java/org/hyperledger/aries/api/credentials/Credential.java b/src/main/java/org/hyperledger/aries/api/credentials/Credential.java index 533f0053..d33ee6ea 100644 --- a/src/main/java/org/hyperledger/aries/api/credentials/Credential.java +++ b/src/main/java/org/hyperledger/aries/api/credentials/Credential.java @@ -16,14 +16,14 @@ import java.lang.reflect.Field; import java.security.AccessController; import java.security.PrivilegedAction; -import java.util.Map; +import java.util.List; import java.util.Set; @Slf4j @Data @NoArgsConstructor @AllArgsConstructor @Builder public class Credential { - private Map attrs; + private List attrs; @SerializedName(value = CredDefId.CREDENTIAL_DEFINITION_ID, alternate = {CredDefId.CRED_DEF_ID, CredDefId.CREDENTIALDEFINITIONID}) @@ -50,7 +50,12 @@ public T to(@NonNull Class type) { AccessController.doPrivileged((PrivilegedAction) () -> { for(Field field: fields) { String fieldName = PojoProcessor.fieldName(field); - String fieldValue = attrs.get(fieldName); + String fieldValue = attrs.stream().filter(attribute -> attribute + .getName() + .equals(fieldName)) + .findFirst() + .get() + .getValue(); try { field.setAccessible(true); field.set(result, fieldValue); diff --git a/src/main/java/org/hyperledger/aries/api/credentials/CredentialAttributes.java b/src/main/java/org/hyperledger/aries/api/credentials/CredentialAttributes.java index 6923adce..44948240 100644 --- a/src/main/java/org/hyperledger/aries/api/credentials/CredentialAttributes.java +++ b/src/main/java/org/hyperledger/aries/api/credentials/CredentialAttributes.java @@ -24,7 +24,7 @@ import java.util.stream.Collectors; @Slf4j -@Data @NoArgsConstructor @AllArgsConstructor @Builder +@Data @NoArgsConstructor @Builder public class CredentialAttributes { @SerializedName(value = "mime-type") @@ -32,10 +32,11 @@ public class CredentialAttributes { private String name; private String value; - public CredentialAttributes(String name, String value) { + public CredentialAttributes(String name, String value, String mimeType) { super(); this.name = name; this.value = value; + this.mimeType = mimeType; } public static List from(@NonNull T instance) { @@ -60,7 +61,9 @@ public static List from(@NonNull T instance) { } catch (IllegalAccessException | IllegalArgumentException e) { log.error("Could not get value of field: {}", fieldName, e); } - result.add(new CredentialAttributes(fieldName, fieldValue)); + + // TODO: Set mime-type instead of passing null + result.add(new CredentialAttributes(fieldName, fieldValue, null)); } } } @@ -72,13 +75,13 @@ public static List from(@NonNull T instance) { public static List from(@NonNull Map values) { List result = new ArrayList<>(); // TODO check if complex object - values.forEach( (k,v) -> result.add(new CredentialAttributes(k, v.toString()))); + values.forEach( (k,v) -> result.add(new CredentialAttributes(k, v.toString(), null))); return result; } public static List fromMap(@NonNull Map values) { List result = new ArrayList<>(); - values.forEach( (k,v) -> result.add(new CredentialAttributes(k, v))); + values.forEach( (k,v) -> result.add(new CredentialAttributes(k, v, null))); return result; } diff --git a/src/main/java/org/hyperledger/aries/api/issue_credential_v1/V1CredentialFreeOfferHelper.java b/src/main/java/org/hyperledger/aries/api/issue_credential_v1/V1CredentialFreeOfferHelper.java new file mode 100644 index 00000000..e69de29b diff --git a/src/main/java/org/hyperledger/aries/api/issue_credential_v2/V2ToV1IndyCredentialConverter.java b/src/main/java/org/hyperledger/aries/api/issue_credential_v2/V2ToV1IndyCredentialConverter.java index 258c7521..650d6a89 100644 --- a/src/main/java/org/hyperledger/aries/api/issue_credential_v2/V2ToV1IndyCredentialConverter.java +++ b/src/main/java/org/hyperledger/aries/api/issue_credential_v2/V2ToV1IndyCredentialConverter.java @@ -14,6 +14,7 @@ import lombok.Data; import lombok.NonNull; import org.hyperledger.aries.api.credentials.Credential; +import org.hyperledger.aries.api.credentials.CredentialAttributes; import org.hyperledger.aries.api.issue_credential_v1.V1CredentialExchange; import org.hyperledger.aries.config.GsonConfig; @@ -94,7 +95,8 @@ public Optional toV1Credential(@NonNull V20CredExRecord v2Record) { Map.Entry::getKey, v -> getRawValue(v.getValue()))); Credential v1Credential = gson.fromJson(typeIndy, Credential.class); - v1Credential.setAttrs(raw); + // TODO: Pass mime-type + v1Credential.setAttrs(CredentialAttributes.fromMap(raw)); return Optional.of(v1Credential); } } diff --git a/src/main/java/org/hyperledger/aries/api/present_proof/PresentProofProposalBuilder.java b/src/main/java/org/hyperledger/aries/api/present_proof/PresentProofProposalBuilder.java index 7ecc1bc3..6033e9cd 100644 --- a/src/main/java/org/hyperledger/aries/api/present_proof/PresentProofProposalBuilder.java +++ b/src/main/java/org/hyperledger/aries/api/present_proof/PresentProofProposalBuilder.java @@ -10,10 +10,12 @@ import com.google.gson.JsonObject; import lombok.NonNull; import org.hyperledger.aries.api.credentials.Credential; +import org.hyperledger.aries.api.credentials.CredentialAttributes; import org.hyperledger.aries.api.present_proof_v2.V20PresProposalByFormat; import org.hyperledger.aries.api.present_proof_v2.V20PresProposalRequest; import java.util.*; +import java.util.stream.Collectors; /** * Helper class to build a {@link PresentProofProposal} @@ -29,12 +31,13 @@ public class PresentProofProposalBuilder { * @return simple {@link PresentProofProposal} without any predicates set */ public static PresentProofProposal fromCredential(@NonNull String connectionId, @NonNull Credential cred) { - final Map attrs = cred.getAttrs(); + final List attrs = cred.getAttrs(); List presAttr = new ArrayList<>(); - attrs.forEach( (k, v) -> presAttr.add(PresentProofProposal.PresentationPreview.PresAttrSpec + attrs.forEach( attr -> presAttr.add(PresentProofProposal.PresentationPreview.PresAttrSpec .builder() - .name(k) - .value(v) + .name(attr.getName()) + .value(attr.getValue()) + .mimeType(attr.getMimeType()) .credentialDefinitionId(cred.getCredentialDefinitionId()) .referent(cred.getReferent()) .build())); @@ -56,19 +59,19 @@ public static PresentProofProposal fromCredential(@NonNull String connectionId, public static V20PresProposalRequest v2IndyFromCredential( @NonNull String connectionId, @NonNull Credential cred, String requestName) { - final Map attrs = cred.getAttrs(); + final List attrs = cred.getAttrs(); final List res = new ArrayList<>(); - attrs.forEach((name, value) -> res.add(PresentProofRequest.ProofRequest.ProofRestrictions + attrs.forEach(attr -> res.add(PresentProofRequest.ProofRequest.ProofRestrictions .builder() - .addAttributeValueRestriction(name, value) + .addAttributeValueRestriction(attr.getName(), attr.getValue()) .schemaId(cred.getSchemaId()) .credentialDefinitionId(cred.getCredentialDefinitionId()) .build().toJsonObject())); PresentProofRequest.ProofRequest.ProofRequestedAttributes requestedAttributes = PresentProofRequest.ProofRequest.ProofRequestedAttributes .builder() - .names(new ArrayList<>(attrs.keySet())) + .names(attrs.stream().map(CredentialAttributes::getName).collect(Collectors.toList())) .restrictions(res) .build(); diff --git a/src/test/java/org/hyperledger/aries/api/issue_credential_v2/V2ToV1IndyCredentialConverterTest.java b/src/test/java/org/hyperledger/aries/api/issue_credential_v2/V2ToV1IndyCredentialConverterTest.java index 9b05cc89..d7d8e640 100644 --- a/src/test/java/org/hyperledger/aries/api/issue_credential_v2/V2ToV1IndyCredentialConverterTest.java +++ b/src/test/java/org/hyperledger/aries/api/issue_credential_v2/V2ToV1IndyCredentialConverterTest.java @@ -25,7 +25,7 @@ void testSimpleV2ToV1() { Assertions.assertTrue(credential.isPresent()); Assertions.assertNotNull(credential.get().getAttrs()); Assertions.assertEquals(2, credential.get().getAttrs().size()); - Assertions.assertEquals("222", credential.get().getAttrs().get("iban")); - Assertions.assertEquals("1111", credential.get().getAttrs().get("bic")); + Assertions.assertEquals("222", credential.get().getAttrs().stream().filter(attr -> attr.getName().equals("iban")).findFirst().get().getValue()); + Assertions.assertEquals("1111", credential.get().getAttrs().stream().filter(attr -> attr.getName().equals("bic")).findFirst().get().getValue()); } } diff --git a/src/test/java/org/hyperledger/aries/api/present_proof/PresentProofProposalTest.java b/src/test/java/org/hyperledger/aries/api/present_proof/PresentProofProposalTest.java index e664145b..4087e65f 100644 --- a/src/test/java/org/hyperledger/aries/api/present_proof/PresentProofProposalTest.java +++ b/src/test/java/org/hyperledger/aries/api/present_proof/PresentProofProposalTest.java @@ -10,12 +10,13 @@ import lombok.extern.slf4j.Slf4j; import org.hyperledger.aries.IntegrationTestBase; import org.hyperledger.aries.api.credentials.Credential; +import org.hyperledger.aries.api.credentials.CredentialAttributes; import org.hyperledger.aries.api.exception.AriesException; import org.hyperledger.aries.config.GsonConfig; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; -import java.util.Map; +import java.util.List; import java.util.UUID; import static org.junit.jupiter.api.Assertions.assertThrows; @@ -27,7 +28,7 @@ public class PresentProofProposalTest extends IntegrationTestBase { @Test void testBuildPresentationProposal() { Credential cred = new Credential(); - cred.setAttrs(Map.of("street", "teststreet")); + cred.setAttrs(List.of(new CredentialAttributes("street", "teststreet", null))); cred.setCredentialDefinitionId("WgWxqztrNooG92RXvxSTWv:3:CL:20:tag"); cred.setReferent("referent"); diff --git a/src/test/java/org/hyperledger/aries/api/present_proof_v2/PresentProofProposalV2Test.java b/src/test/java/org/hyperledger/aries/api/present_proof_v2/PresentProofProposalV2Test.java index 4d6e0db2..9753ecdf 100644 --- a/src/test/java/org/hyperledger/aries/api/present_proof_v2/PresentProofProposalV2Test.java +++ b/src/test/java/org/hyperledger/aries/api/present_proof_v2/PresentProofProposalV2Test.java @@ -10,12 +10,13 @@ import lombok.extern.slf4j.Slf4j; import org.hyperledger.aries.IntegrationTestBase; import org.hyperledger.aries.api.credentials.Credential; +import org.hyperledger.aries.api.credentials.CredentialAttributes; import org.hyperledger.aries.api.exception.AriesException; import org.hyperledger.aries.api.present_proof.PresentProofProposalBuilder; import org.hyperledger.aries.config.GsonConfig; import org.junit.jupiter.api.Test; -import java.util.Map; +import java.util.List; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -26,7 +27,7 @@ public class PresentProofProposalV2Test extends IntegrationTestBase { @Test void testBuildPresentationProposalV2() { Credential cred = new Credential(); - cred.setAttrs(Map.of("street", "teststreet")); + cred.setAttrs(List.of(new CredentialAttributes("street", "teststreet", null))); cred.setCredentialDefinitionId("WgWxqztrNooG92RXvxSTWv:3:CL:20:tag"); cred.setReferent("referent"); From b9c234deed4a7a41ae9f17e4f75b2f68c5ce7d8e Mon Sep 17 00:00:00 2001 From: Tim Schlagenhaufer Date: Fri, 16 Sep 2022 09:20:25 +0200 Subject: [PATCH 2/7] Turn Maps to Lists Signed-off-by: Tim Schlagenhaufer --- .../issue_credential_v1/CredentialFreeOfferHelper.java | 10 ++++++---- .../api/issue_credential_v1/V1CredentialExchange.java | 7 +++---- .../present_proof/PresentationRequestCredentials.java | 5 +++-- .../api/present_proof/MockedPresentProofTest.java | 2 +- 4 files changed, 13 insertions(+), 11 deletions(-) diff --git a/src/main/java/org/hyperledger/aries/api/issue_credential_v1/CredentialFreeOfferHelper.java b/src/main/java/org/hyperledger/aries/api/issue_credential_v1/CredentialFreeOfferHelper.java index 51e16c21..3c59f44e 100644 --- a/src/main/java/org/hyperledger/aries/api/issue_credential_v1/CredentialFreeOfferHelper.java +++ b/src/main/java/org/hyperledger/aries/api/issue_credential_v1/CredentialFreeOfferHelper.java @@ -22,6 +22,8 @@ import org.hyperledger.aries.api.out_of_band.BaseOOBInvitationHelper; import java.io.IOException; +import java.util.ArrayList; +import java.util.List; import java.util.Map; /** @@ -50,7 +52,7 @@ public CredentialFreeOfferHelper(AriesClient acaPy) { */ public CredentialFreeOffer buildV1Indy( @NonNull String credentialDefinitionId, - @NonNull Map document) { + @NonNull List document) { CredentialFreeOffer.CredentialFreeOfferBuilder r = CredentialFreeOffer.builder(); try{ // issue-credential/create in conjunction with oob invitation attachment @@ -59,7 +61,7 @@ public CredentialFreeOffer buildV1Indy( .autoIssue(Boolean.TRUE) .autoRemove(Boolean.TRUE) .credDefId(credentialDefinitionId) - .credentialPreview(new CredentialPreview(CredentialAttributes.fromMap(document))) + .credentialPreview(new CredentialPreview(document)) .build(); V1CredentialExchange ex = acaPy.issueCredentialCreateOffer(create).orElseThrow(); // step 2 - create out-of-band invitation with attached credential offer @@ -78,7 +80,7 @@ public CredentialFreeOffer buildV1Indy( */ public CredentialFreeOffer buildV2Indy( @NonNull String credentialDefinitionId, - @NonNull Map document) { + @NonNull List document) { CredentialFreeOffer.CredentialFreeOfferBuilder r = CredentialFreeOffer.builder(); try { V2CredentialExchangeFree create = V2CredentialExchangeFree.builder() @@ -90,7 +92,7 @@ public CredentialFreeOffer buildV2Indy( .build()) .build()) .credentialPreview(V2CredentialExchangeFree.V2CredentialPreview.builder() - .attributes(CredentialAttributes.fromMap(document)) + .attributes(document) .build()) .build(); V1CredentialExchange ex = acaPy.issueCredentialV2CreateOffer(create) diff --git a/src/main/java/org/hyperledger/aries/api/issue_credential_v1/V1CredentialExchange.java b/src/main/java/org/hyperledger/aries/api/issue_credential_v1/V1CredentialExchange.java index 212fa43d..85651262 100644 --- a/src/main/java/org/hyperledger/aries/api/issue_credential_v1/V1CredentialExchange.java +++ b/src/main/java/org/hyperledger/aries/api/issue_credential_v1/V1CredentialExchange.java @@ -103,13 +103,12 @@ public static final class CredentialOfferDict { private List offersAttach = new ArrayList<>(); } - public Optional> findAttributesInCredentialOfferDict() { - Optional> result = Optional.empty(); + public Optional> findAttributesInCredentialOfferDict() { + Optional> result = Optional.empty(); if (credentialOfferDict != null && credentialOfferDict.credentialPreview != null) { List attributes = credentialOfferDict.getCredentialPreview().getAttributes(); if (attributes != null) { - return Optional.of(attributes.stream() - .collect(Collectors.toMap(CredentialAttributes::getName, CredentialAttributes::getValue))); + return Optional.of(attributes); } } return result; diff --git a/src/main/java/org/hyperledger/aries/api/present_proof/PresentationRequestCredentials.java b/src/main/java/org/hyperledger/aries/api/present_proof/PresentationRequestCredentials.java index 8c7d1524..230ad5ae 100644 --- a/src/main/java/org/hyperledger/aries/api/present_proof/PresentationRequestCredentials.java +++ b/src/main/java/org/hyperledger/aries/api/present_proof/PresentationRequestCredentials.java @@ -11,9 +11,10 @@ import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; +import org.hyperledger.aries.api.credentials.CredentialAttributes; +import java.util.ArrayList; import java.util.List; -import java.util.Map; /** * Model for: @@ -35,7 +36,7 @@ public static final class CredentialInfo { private String referent; - private Map attrs; + private List attrs; private String schemaId; diff --git a/src/test/java/org/hyperledger/aries/api/present_proof/MockedPresentProofTest.java b/src/test/java/org/hyperledger/aries/api/present_proof/MockedPresentProofTest.java index 45528cdf..d721a45d 100644 --- a/src/test/java/org/hyperledger/aries/api/present_proof/MockedPresentProofTest.java +++ b/src/test/java/org/hyperledger/aries/api/present_proof/MockedPresentProofTest.java @@ -69,7 +69,7 @@ void testGetPresentProofRecordsCredentials() throws Exception { Assertions.assertTrue(credentials.isPresent()); Assertions.assertEquals(2, credentials.get().size()); - Assertions.assertEquals("bpa", credentials.get().get(0).getCredentialInfo().getAttrs().get("name")); + Assertions.assertEquals("bpa", credentials.get().get(0).getCredentialInfo().getAttrs().stream().filter(attr -> attr.getName().equals("name")).findFirst().get().getValue()); } @Test From 4cb5e70b8582d4bd4c4906b147ae405421865f8e Mon Sep 17 00:00:00 2001 From: Tim Schlagenhaufer Date: Thu, 6 Oct 2022 11:46:48 +0200 Subject: [PATCH 3/7] Revert unnecessary changes and extend credential exchange interface Signed-off-by: Tim Schlagenhaufer --- .../aries/api/credentials/Credential.java | 11 +++-------- .../api/credentials/CredentialAttributes.java | 16 ++++------------ .../V1CredentialExchange.java | 10 +++++++++- .../V1CredentialFreeOfferHelper.java | 0 .../V2ToV1IndyCredentialConverter.java | 4 +--- .../PresentProofProposalBuilder.java | 19 ++++++++----------- .../PresentationRequestCredentials.java | 5 ++--- 7 files changed, 27 insertions(+), 38 deletions(-) delete mode 100644 src/main/java/org/hyperledger/aries/api/issue_credential_v1/V1CredentialFreeOfferHelper.java diff --git a/src/main/java/org/hyperledger/aries/api/credentials/Credential.java b/src/main/java/org/hyperledger/aries/api/credentials/Credential.java index d33ee6ea..533f0053 100644 --- a/src/main/java/org/hyperledger/aries/api/credentials/Credential.java +++ b/src/main/java/org/hyperledger/aries/api/credentials/Credential.java @@ -16,14 +16,14 @@ import java.lang.reflect.Field; import java.security.AccessController; import java.security.PrivilegedAction; -import java.util.List; +import java.util.Map; import java.util.Set; @Slf4j @Data @NoArgsConstructor @AllArgsConstructor @Builder public class Credential { - private List attrs; + private Map attrs; @SerializedName(value = CredDefId.CREDENTIAL_DEFINITION_ID, alternate = {CredDefId.CRED_DEF_ID, CredDefId.CREDENTIALDEFINITIONID}) @@ -50,12 +50,7 @@ public T to(@NonNull Class type) { AccessController.doPrivileged((PrivilegedAction) () -> { for(Field field: fields) { String fieldName = PojoProcessor.fieldName(field); - String fieldValue = attrs.stream().filter(attribute -> attribute - .getName() - .equals(fieldName)) - .findFirst() - .get() - .getValue(); + String fieldValue = attrs.get(fieldName); try { field.setAccessible(true); field.set(result, fieldValue); diff --git a/src/main/java/org/hyperledger/aries/api/credentials/CredentialAttributes.java b/src/main/java/org/hyperledger/aries/api/credentials/CredentialAttributes.java index 44948240..33f7d7f8 100644 --- a/src/main/java/org/hyperledger/aries/api/credentials/CredentialAttributes.java +++ b/src/main/java/org/hyperledger/aries/api/credentials/CredentialAttributes.java @@ -24,7 +24,7 @@ import java.util.stream.Collectors; @Slf4j -@Data @NoArgsConstructor @Builder +@Data @Builder public class CredentialAttributes { @SerializedName(value = "mime-type") @@ -32,13 +32,6 @@ public class CredentialAttributes { private String name; private String value; - public CredentialAttributes(String name, String value, String mimeType) { - super(); - this.name = name; - this.value = value; - this.mimeType = mimeType; - } - public static List from(@NonNull T instance) { List result = new ArrayList<>(); Field[] fields = instance.getClass().getDeclaredFields(); @@ -62,8 +55,7 @@ public static List from(@NonNull T instance) { log.error("Could not get value of field: {}", fieldName, e); } - // TODO: Set mime-type instead of passing null - result.add(new CredentialAttributes(fieldName, fieldValue, null)); + CredentialAttributes.builder().name(fieldName).value(fieldValue).build(); } } } @@ -75,13 +67,13 @@ public static List from(@NonNull T instance) { public static List from(@NonNull Map values) { List result = new ArrayList<>(); // TODO check if complex object - values.forEach( (k,v) -> result.add(new CredentialAttributes(k, v.toString(), null))); + values.forEach( (k,v) -> result.add(CredentialAttributes.builder().name(k).value(v.toString()).build())); return result; } public static List fromMap(@NonNull Map values) { List result = new ArrayList<>(); - values.forEach( (k,v) -> result.add(new CredentialAttributes(k, v, null))); + values.forEach( (k,v) -> result.add(CredentialAttributes.builder().name(k).value(v).build())); return result; } diff --git a/src/main/java/org/hyperledger/aries/api/issue_credential_v1/V1CredentialExchange.java b/src/main/java/org/hyperledger/aries/api/issue_credential_v1/V1CredentialExchange.java index 85651262..b4fb76c8 100644 --- a/src/main/java/org/hyperledger/aries/api/issue_credential_v1/V1CredentialExchange.java +++ b/src/main/java/org/hyperledger/aries/api/issue_credential_v1/V1CredentialExchange.java @@ -103,7 +103,15 @@ public static final class CredentialOfferDict { private List offersAttach = new ArrayList<>(); } - public Optional> findAttributesInCredentialOfferDict() { + public Optional> findAttributesInCredentialOfferDict() { + Map attributesMap = findAttributesInCredentialOfferDictList().orElse(List.of()) + .stream() + .collect(Collectors.toMap(CredentialAttributes::getName, CredentialAttributes::getValue)); + + return Optional.of(attributesMap); + } + + public Optional> findAttributesInCredentialOfferDictList() { Optional> result = Optional.empty(); if (credentialOfferDict != null && credentialOfferDict.credentialPreview != null) { List attributes = credentialOfferDict.getCredentialPreview().getAttributes(); diff --git a/src/main/java/org/hyperledger/aries/api/issue_credential_v1/V1CredentialFreeOfferHelper.java b/src/main/java/org/hyperledger/aries/api/issue_credential_v1/V1CredentialFreeOfferHelper.java deleted file mode 100644 index e69de29b..00000000 diff --git a/src/main/java/org/hyperledger/aries/api/issue_credential_v2/V2ToV1IndyCredentialConverter.java b/src/main/java/org/hyperledger/aries/api/issue_credential_v2/V2ToV1IndyCredentialConverter.java index 650d6a89..258c7521 100644 --- a/src/main/java/org/hyperledger/aries/api/issue_credential_v2/V2ToV1IndyCredentialConverter.java +++ b/src/main/java/org/hyperledger/aries/api/issue_credential_v2/V2ToV1IndyCredentialConverter.java @@ -14,7 +14,6 @@ import lombok.Data; import lombok.NonNull; import org.hyperledger.aries.api.credentials.Credential; -import org.hyperledger.aries.api.credentials.CredentialAttributes; import org.hyperledger.aries.api.issue_credential_v1.V1CredentialExchange; import org.hyperledger.aries.config.GsonConfig; @@ -95,8 +94,7 @@ public Optional toV1Credential(@NonNull V20CredExRecord v2Record) { Map.Entry::getKey, v -> getRawValue(v.getValue()))); Credential v1Credential = gson.fromJson(typeIndy, Credential.class); - // TODO: Pass mime-type - v1Credential.setAttrs(CredentialAttributes.fromMap(raw)); + v1Credential.setAttrs(raw); return Optional.of(v1Credential); } } diff --git a/src/main/java/org/hyperledger/aries/api/present_proof/PresentProofProposalBuilder.java b/src/main/java/org/hyperledger/aries/api/present_proof/PresentProofProposalBuilder.java index 6033e9cd..7ecc1bc3 100644 --- a/src/main/java/org/hyperledger/aries/api/present_proof/PresentProofProposalBuilder.java +++ b/src/main/java/org/hyperledger/aries/api/present_proof/PresentProofProposalBuilder.java @@ -10,12 +10,10 @@ import com.google.gson.JsonObject; import lombok.NonNull; import org.hyperledger.aries.api.credentials.Credential; -import org.hyperledger.aries.api.credentials.CredentialAttributes; import org.hyperledger.aries.api.present_proof_v2.V20PresProposalByFormat; import org.hyperledger.aries.api.present_proof_v2.V20PresProposalRequest; import java.util.*; -import java.util.stream.Collectors; /** * Helper class to build a {@link PresentProofProposal} @@ -31,13 +29,12 @@ public class PresentProofProposalBuilder { * @return simple {@link PresentProofProposal} without any predicates set */ public static PresentProofProposal fromCredential(@NonNull String connectionId, @NonNull Credential cred) { - final List attrs = cred.getAttrs(); + final Map attrs = cred.getAttrs(); List presAttr = new ArrayList<>(); - attrs.forEach( attr -> presAttr.add(PresentProofProposal.PresentationPreview.PresAttrSpec + attrs.forEach( (k, v) -> presAttr.add(PresentProofProposal.PresentationPreview.PresAttrSpec .builder() - .name(attr.getName()) - .value(attr.getValue()) - .mimeType(attr.getMimeType()) + .name(k) + .value(v) .credentialDefinitionId(cred.getCredentialDefinitionId()) .referent(cred.getReferent()) .build())); @@ -59,19 +56,19 @@ public static PresentProofProposal fromCredential(@NonNull String connectionId, public static V20PresProposalRequest v2IndyFromCredential( @NonNull String connectionId, @NonNull Credential cred, String requestName) { - final List attrs = cred.getAttrs(); + final Map attrs = cred.getAttrs(); final List res = new ArrayList<>(); - attrs.forEach(attr -> res.add(PresentProofRequest.ProofRequest.ProofRestrictions + attrs.forEach((name, value) -> res.add(PresentProofRequest.ProofRequest.ProofRestrictions .builder() - .addAttributeValueRestriction(attr.getName(), attr.getValue()) + .addAttributeValueRestriction(name, value) .schemaId(cred.getSchemaId()) .credentialDefinitionId(cred.getCredentialDefinitionId()) .build().toJsonObject())); PresentProofRequest.ProofRequest.ProofRequestedAttributes requestedAttributes = PresentProofRequest.ProofRequest.ProofRequestedAttributes .builder() - .names(attrs.stream().map(CredentialAttributes::getName).collect(Collectors.toList())) + .names(new ArrayList<>(attrs.keySet())) .restrictions(res) .build(); diff --git a/src/main/java/org/hyperledger/aries/api/present_proof/PresentationRequestCredentials.java b/src/main/java/org/hyperledger/aries/api/present_proof/PresentationRequestCredentials.java index 230ad5ae..8c7d1524 100644 --- a/src/main/java/org/hyperledger/aries/api/present_proof/PresentationRequestCredentials.java +++ b/src/main/java/org/hyperledger/aries/api/present_proof/PresentationRequestCredentials.java @@ -11,10 +11,9 @@ import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; -import org.hyperledger.aries.api.credentials.CredentialAttributes; -import java.util.ArrayList; import java.util.List; +import java.util.Map; /** * Model for: @@ -36,7 +35,7 @@ public static final class CredentialInfo { private String referent; - private List attrs; + private Map attrs; private String schemaId; From b3920f1c82f7282373176ec3e92851360dcafbf4 Mon Sep 17 00:00:00 2001 From: Tim Schlagenhaufer Date: Thu, 6 Oct 2022 16:34:09 +0200 Subject: [PATCH 4/7] Extend credential offer helper interface vor v1 and v2 Signed-off-by: Tim Schlagenhaufer --- .../CredentialFreeOfferHelper.java | 113 +++++++++++------- 1 file changed, 73 insertions(+), 40 deletions(-) diff --git a/src/main/java/org/hyperledger/aries/api/issue_credential_v1/CredentialFreeOfferHelper.java b/src/main/java/org/hyperledger/aries/api/issue_credential_v1/CredentialFreeOfferHelper.java index 3c59f44e..be39d692 100644 --- a/src/main/java/org/hyperledger/aries/api/issue_credential_v1/CredentialFreeOfferHelper.java +++ b/src/main/java/org/hyperledger/aries/api/issue_credential_v1/CredentialFreeOfferHelper.java @@ -22,7 +22,6 @@ import org.hyperledger.aries.api.out_of_band.BaseOOBInvitationHelper; import java.io.IOException; -import java.util.ArrayList; import java.util.List; import java.util.Map; @@ -50,26 +49,22 @@ public CredentialFreeOfferHelper(AriesClient acaPy) { * @param document credential document * @return {@link CredentialFreeOffer} */ + public CredentialFreeOffer buildV1Indy( + @NonNull String credentialDefinitionId, + @NonNull Map document) { + return getCredentialFreeOffer(credentialDefinitionId, CredentialAttributes.fromMap(document)); + } + + /** + * Build for v1/indy + * @param credentialDefinitionId credential definition id + * @param document list of credential attributes + * @return {@link CredentialFreeOffer} + */ public CredentialFreeOffer buildV1Indy( @NonNull String credentialDefinitionId, @NonNull List document) { - CredentialFreeOffer.CredentialFreeOfferBuilder r = CredentialFreeOffer.builder(); - try{ - // issue-credential/create in conjunction with oob invitation attachment - // step 1 - create credential offer - V1CredentialFreeOfferRequest create = V1CredentialFreeOfferRequest.builder() - .autoIssue(Boolean.TRUE) - .autoRemove(Boolean.TRUE) - .credDefId(credentialDefinitionId) - .credentialPreview(new CredentialPreview(document)) - .build(); - V1CredentialExchange ex = acaPy.issueCredentialCreateOffer(create).orElseThrow(); - // step 2 - create out-of-band invitation with attached credential offer - setAndBuildInvitation(r, ex); - } catch (IOException e) { - throw new AriesNetworkException(NETWORK_ERROR); - } - return r.build(); + return getCredentialFreeOffer(credentialDefinitionId, document); } /** @@ -78,31 +73,22 @@ public CredentialFreeOffer buildV1Indy( * @param document credential document * @return {@link CredentialFreeOffer} */ + public CredentialFreeOffer buildV2Indy( + @NonNull String credentialDefinitionId, + @NonNull Map document) { + return getCredentialFreeOfferV2(credentialDefinitionId, CredentialAttributes.fromMap(document)); + } + + /** + * Build for v2/indy + * @param credentialDefinitionId credential definition id + * @param document list of credential attributes + * @return {@link CredentialFreeOffer} + */ public CredentialFreeOffer buildV2Indy( @NonNull String credentialDefinitionId, @NonNull List document) { - CredentialFreeOffer.CredentialFreeOfferBuilder r = CredentialFreeOffer.builder(); - try { - V2CredentialExchangeFree create = V2CredentialExchangeFree.builder() - .autoIssue(Boolean.TRUE) - .autoRemove(Boolean.TRUE) - .filter(V2CredentialExchangeFree.V20CredFilter.builder() - .indy(V20CredFilterIndy.builder() - .credDefId(credentialDefinitionId) - .build()) - .build()) - .credentialPreview(V2CredentialExchangeFree.V2CredentialPreview.builder() - .attributes(document) - .build()) - .build(); - V1CredentialExchange ex = acaPy.issueCredentialV2CreateOffer(create) - .map(V2ToV1IndyCredentialConverter::toV1Offer) - .orElseThrow(); - setAndBuildInvitation(r, ex); - } catch (IOException e) { - throw new AriesNetworkException(NETWORK_ERROR); - } - return r.build(); + return getCredentialFreeOfferV2(credentialDefinitionId, document); } /** @@ -112,6 +98,7 @@ public CredentialFreeOffer buildV2Indy( */ public CredentialFreeOffer buildDif(@NonNull V2CredentialExchangeFree.LDProofVCDetail vc) { CredentialFreeOffer.CredentialFreeOfferBuilder r = CredentialFreeOffer.builder(); + try { V2CredentialExchangeFree create = V2CredentialExchangeFree.builder() .autoIssue(Boolean.TRUE) @@ -128,6 +115,52 @@ public CredentialFreeOffer buildDif(@NonNull V2CredentialExchangeFree.LDProofVCD return r.build(); } + private CredentialFreeOffer getCredentialFreeOffer(@NonNull String credentialDefinitionId, @NonNull List document) { + CredentialFreeOffer.CredentialFreeOfferBuilder r = CredentialFreeOffer.builder(); + + try{ + // issue-credential/create in conjunction with oob invitation attachment + // step 1 - create credential offer + V1CredentialFreeOfferRequest create = V1CredentialFreeOfferRequest.builder() + .autoIssue(Boolean.TRUE) + .autoRemove(Boolean.TRUE) + .credDefId(credentialDefinitionId) + .credentialPreview(new CredentialPreview(document)) + .build(); + V1CredentialExchange ex = acaPy.issueCredentialCreateOffer(create).orElseThrow(); + // step 2 - create out-of-band invitation with attached credential offer + setAndBuildInvitation(r, ex); + } catch (IOException e) { + throw new AriesNetworkException(NETWORK_ERROR); + } + return r.build(); + } + + private CredentialFreeOffer getCredentialFreeOfferV2(@NonNull String credentialDefinitionId, @NonNull List document) { + CredentialFreeOffer.CredentialFreeOfferBuilder r = CredentialFreeOffer.builder(); + try { + V2CredentialExchangeFree create = V2CredentialExchangeFree.builder() + .autoIssue(Boolean.TRUE) + .autoRemove(Boolean.TRUE) + .filter(V2CredentialExchangeFree.V20CredFilter.builder() + .indy(V20CredFilterIndy.builder() + .credDefId(credentialDefinitionId) + .build()) + .build()) + .credentialPreview(V2CredentialExchangeFree.V2CredentialPreview.builder() + .attributes(document) + .build()) + .build(); + V1CredentialExchange ex = acaPy.issueCredentialV2CreateOffer(create) + .map(V2ToV1IndyCredentialConverter::toV1Offer) + .orElseThrow(); + setAndBuildInvitation(r, ex); + } catch (IOException e) { + throw new AriesNetworkException(NETWORK_ERROR); + } + return r.build(); + } + private void setAndBuildInvitation( @NonNull CredentialFreeOffer.CredentialFreeOfferBuilder r, @NonNull BaseCredExRecord ex) From 21d854217077f53c1322c373ba28fd663f71782b Mon Sep 17 00:00:00 2001 From: Tim Schlagenhaufer Date: Thu, 6 Oct 2022 16:38:08 +0200 Subject: [PATCH 5/7] Re-add constructor annotations for jackson Signed-off-by: Tim Schlagenhaufer --- .../hyperledger/aries/api/credentials/CredentialAttributes.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/hyperledger/aries/api/credentials/CredentialAttributes.java b/src/main/java/org/hyperledger/aries/api/credentials/CredentialAttributes.java index 33f7d7f8..0750c7dc 100644 --- a/src/main/java/org/hyperledger/aries/api/credentials/CredentialAttributes.java +++ b/src/main/java/org/hyperledger/aries/api/credentials/CredentialAttributes.java @@ -24,7 +24,7 @@ import java.util.stream.Collectors; @Slf4j -@Data @Builder +@Data @NoArgsConstructor @AllArgsConstructor @Builder public class CredentialAttributes { @SerializedName(value = "mime-type") From a710df59ee2b3b82626080a3ae4cd53e342bfca6 Mon Sep 17 00:00:00 2001 From: Tim Schlagenhaufer Date: Thu, 6 Oct 2022 16:48:38 +0200 Subject: [PATCH 6/7] Use former test code Signed-off-by: Tim Schlagenhaufer --- .../V2ToV1IndyCredentialConverterTest.java | 4 ++-- .../aries/api/present_proof/MockedPresentProofTest.java | 2 +- .../aries/api/present_proof/PresentProofProposalTest.java | 5 ++--- .../api/present_proof_v2/PresentProofProposalV2Test.java | 5 ++--- 4 files changed, 7 insertions(+), 9 deletions(-) diff --git a/src/test/java/org/hyperledger/aries/api/issue_credential_v2/V2ToV1IndyCredentialConverterTest.java b/src/test/java/org/hyperledger/aries/api/issue_credential_v2/V2ToV1IndyCredentialConverterTest.java index d7d8e640..9b05cc89 100644 --- a/src/test/java/org/hyperledger/aries/api/issue_credential_v2/V2ToV1IndyCredentialConverterTest.java +++ b/src/test/java/org/hyperledger/aries/api/issue_credential_v2/V2ToV1IndyCredentialConverterTest.java @@ -25,7 +25,7 @@ void testSimpleV2ToV1() { Assertions.assertTrue(credential.isPresent()); Assertions.assertNotNull(credential.get().getAttrs()); Assertions.assertEquals(2, credential.get().getAttrs().size()); - Assertions.assertEquals("222", credential.get().getAttrs().stream().filter(attr -> attr.getName().equals("iban")).findFirst().get().getValue()); - Assertions.assertEquals("1111", credential.get().getAttrs().stream().filter(attr -> attr.getName().equals("bic")).findFirst().get().getValue()); + Assertions.assertEquals("222", credential.get().getAttrs().get("iban")); + Assertions.assertEquals("1111", credential.get().getAttrs().get("bic")); } } diff --git a/src/test/java/org/hyperledger/aries/api/present_proof/MockedPresentProofTest.java b/src/test/java/org/hyperledger/aries/api/present_proof/MockedPresentProofTest.java index d721a45d..45528cdf 100644 --- a/src/test/java/org/hyperledger/aries/api/present_proof/MockedPresentProofTest.java +++ b/src/test/java/org/hyperledger/aries/api/present_proof/MockedPresentProofTest.java @@ -69,7 +69,7 @@ void testGetPresentProofRecordsCredentials() throws Exception { Assertions.assertTrue(credentials.isPresent()); Assertions.assertEquals(2, credentials.get().size()); - Assertions.assertEquals("bpa", credentials.get().get(0).getCredentialInfo().getAttrs().stream().filter(attr -> attr.getName().equals("name")).findFirst().get().getValue()); + Assertions.assertEquals("bpa", credentials.get().get(0).getCredentialInfo().getAttrs().get("name")); } @Test diff --git a/src/test/java/org/hyperledger/aries/api/present_proof/PresentProofProposalTest.java b/src/test/java/org/hyperledger/aries/api/present_proof/PresentProofProposalTest.java index 4087e65f..e664145b 100644 --- a/src/test/java/org/hyperledger/aries/api/present_proof/PresentProofProposalTest.java +++ b/src/test/java/org/hyperledger/aries/api/present_proof/PresentProofProposalTest.java @@ -10,13 +10,12 @@ import lombok.extern.slf4j.Slf4j; import org.hyperledger.aries.IntegrationTestBase; import org.hyperledger.aries.api.credentials.Credential; -import org.hyperledger.aries.api.credentials.CredentialAttributes; import org.hyperledger.aries.api.exception.AriesException; import org.hyperledger.aries.config.GsonConfig; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; -import java.util.List; +import java.util.Map; import java.util.UUID; import static org.junit.jupiter.api.Assertions.assertThrows; @@ -28,7 +27,7 @@ public class PresentProofProposalTest extends IntegrationTestBase { @Test void testBuildPresentationProposal() { Credential cred = new Credential(); - cred.setAttrs(List.of(new CredentialAttributes("street", "teststreet", null))); + cred.setAttrs(Map.of("street", "teststreet")); cred.setCredentialDefinitionId("WgWxqztrNooG92RXvxSTWv:3:CL:20:tag"); cred.setReferent("referent"); diff --git a/src/test/java/org/hyperledger/aries/api/present_proof_v2/PresentProofProposalV2Test.java b/src/test/java/org/hyperledger/aries/api/present_proof_v2/PresentProofProposalV2Test.java index 9753ecdf..4d6e0db2 100644 --- a/src/test/java/org/hyperledger/aries/api/present_proof_v2/PresentProofProposalV2Test.java +++ b/src/test/java/org/hyperledger/aries/api/present_proof_v2/PresentProofProposalV2Test.java @@ -10,13 +10,12 @@ import lombok.extern.slf4j.Slf4j; import org.hyperledger.aries.IntegrationTestBase; import org.hyperledger.aries.api.credentials.Credential; -import org.hyperledger.aries.api.credentials.CredentialAttributes; import org.hyperledger.aries.api.exception.AriesException; import org.hyperledger.aries.api.present_proof.PresentProofProposalBuilder; import org.hyperledger.aries.config.GsonConfig; import org.junit.jupiter.api.Test; -import java.util.List; +import java.util.Map; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -27,7 +26,7 @@ public class PresentProofProposalV2Test extends IntegrationTestBase { @Test void testBuildPresentationProposalV2() { Credential cred = new Credential(); - cred.setAttrs(List.of(new CredentialAttributes("street", "teststreet", null))); + cred.setAttrs(Map.of("street", "teststreet")); cred.setCredentialDefinitionId("WgWxqztrNooG92RXvxSTWv:3:CL:20:tag"); cred.setReferent("referent"); From 035a55c13f3be31641705a97a69e16eac14d21aa Mon Sep 17 00:00:00 2001 From: Tim Schlagenhaufer Date: Fri, 7 Oct 2022 10:13:06 +0200 Subject: [PATCH 7/7] Add missing add Signed-off-by: Tim Schlagenhaufer --- .../hyperledger/aries/api/credentials/CredentialAttributes.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/hyperledger/aries/api/credentials/CredentialAttributes.java b/src/main/java/org/hyperledger/aries/api/credentials/CredentialAttributes.java index 0750c7dc..946594e8 100644 --- a/src/main/java/org/hyperledger/aries/api/credentials/CredentialAttributes.java +++ b/src/main/java/org/hyperledger/aries/api/credentials/CredentialAttributes.java @@ -55,7 +55,7 @@ public static List from(@NonNull T instance) { log.error("Could not get value of field: {}", fieldName, e); } - CredentialAttributes.builder().name(fieldName).value(fieldValue).build(); + result.add(CredentialAttributes.builder().name(fieldName).value(fieldValue).build()); } } }