You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by da...@apache.org on 2022/11/23 05:28:52 UTC

[camel] branch main updated: Hyperledger Aries - connectionless proofs (#8741)

This is an automated email from the ASF dual-hosted git repository.

davsclaus pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel.git


The following commit(s) were added to refs/heads/main by this push:
     new 35f042e2d74 Hyperledger Aries - connectionless proofs (#8741)
35f042e2d74 is described below

commit 35f042e2d74904418bd7c261290c64f27456854a
Author: vchernetskyi993 <36...@users.noreply.github.com>
AuthorDate: Wed Nov 23 07:28:46 2022 +0200

    Hyperledger Aries - connectionless proofs (#8741)
    
    * added create-request & get-did-endpoint
    
    * added create-request & get-did-endpoint tests
    
    * ran format&sourcecheck
    
    * added doc
    
    * trimmed space in added doc
---
 .../src/main/docs/hyperledger-aries-component.adoc | 56 +++++++++++++
 .../apache/camel/component/aries/Constants.java    |  2 +
 .../aries/handler/PresentProofServiceHandler.java  |  4 +
 .../aries/handler/WalletServiceHandler.java        |  8 ++
 .../component/aries/ConnectionlessProofTest.java   | 94 ++++++++++++++++++++++
 5 files changed, 164 insertions(+)

diff --git a/components/camel-hyperledger-aries/src/main/docs/hyperledger-aries-component.adoc b/components/camel-hyperledger-aries/src/main/docs/hyperledger-aries-component.adoc
index b585fdc200b..b7ec61eb0d4 100644
--- a/components/camel-hyperledger-aries/src/main/docs/hyperledger-aries-component.adoc
+++ b/components/camel-hyperledger-aries/src/main/docs/hyperledger-aries-component.adoc
@@ -401,3 +401,59 @@ verifierExchangeRecord = verifierEvents.presentationEx()
 
 Assertions.assertTrue(verifierExchangeRecord.isVerified(), "Not VERIFIED");
 ---------------------------------------------------------------------------------------------
+
+==== Connectionless proofs
+
+There is a possibility to request proof without securing the connection beforehand.
+It's similar to usual credential verification process with two changes:
+
+1. Verifier should use `/present-proof/create-request` instead of `send-request` service.
+
+2. Verifier should decorate proof presentation with `~service` decorator with their recipient key and endpoint.
+
+[source,java]
+---------------------------------------------------------------------------------------------
+/* 1. Acme creates Job Application Proof Request.
+ *
+ * Notice no connectionId and new service endpoint.
+ * Everything else is the same as for send-request process.
+ */
+PresentProofRequest proofRequest = PresentProofRequest.builder()
+        .proofRequest(...)
+        .build();
+
+String exchangeId = template.requestBodyAndHeader("direct:acme", proofRequest,
+        HEADER_SERVICE, "/present-proof/create-request",
+        PresentationExchangeRecord.class).getPresentationExchangeId();
+
+/* 2. Acme generates presentation JSON.
+ *
+ * This is a new step. Acme needs to decorate the presentation request with their service details.
+ */
+JsonObject presentation = template.requestBodyAndHeader("direct:acme", null,
+        HEADER_SERVICE, "/present-proof/records/" + exchangeId,
+        PresentationExchangeRecord.class).getPresentationRequestDict();
+
+DID did = template.requestBodyAndHeader("direct:acme", null,
+        HEADER_SERVICE, "/wallet/did/public",
+        DID.class);
+
+String endpoint = template.requestBodyAndHeaders("direct:acme", null,
+        Map.of(HEADER_SERVICE, "/wallet/get-did-endpoint", HEADER_DID, did.getDid()),
+        DIDEndpoint.class).getEndpoint();
+
+var decorator = new JsonObject();
+var recipients = new JsonArray();
+recipients.add(did.getVerkey());
+decorator.add("recipientKeys", recipients);
+decorator.addProperty("serviceEndpoint", endpoint);
+
+presentation.add("~service", decorator);
+
+/* 3. Acme shares presentation request with Alice.
+ *
+ * This step is not Camel-specific, thus there is no example.
+ * The easiest way to share this JSON is to generate QR code using it
+ * and let Alice scan this QR using her Aries mobile wallet.
+ */
+---------------------------------------------------------------------------------------------
diff --git a/components/camel-hyperledger-aries/src/main/java/org/apache/camel/component/aries/Constants.java b/components/camel-hyperledger-aries/src/main/java/org/apache/camel/component/aries/Constants.java
index 072ca2c5fa0..d8bc2e1d3a5 100644
--- a/components/camel-hyperledger-aries/src/main/java/org/apache/camel/component/aries/Constants.java
+++ b/components/camel-hyperledger-aries/src/main/java/org/apache/camel/component/aries/Constants.java
@@ -21,6 +21,8 @@ public final class Constants {
     // The ACA-Py API path 
     public static final String HEADER_SERVICE = "service";
 
+    public static final String HEADER_DID = "did";
+
     public static final String HEADER_WALLET_NAME = "WalletName";
     public static final String HEADER_WALLET_RECORD = "WalletRecord";
 
diff --git a/components/camel-hyperledger-aries/src/main/java/org/apache/camel/component/aries/handler/PresentProofServiceHandler.java b/components/camel-hyperledger-aries/src/main/java/org/apache/camel/component/aries/handler/PresentProofServiceHandler.java
index 59878def556..fea58cfa884 100644
--- a/components/camel-hyperledger-aries/src/main/java/org/apache/camel/component/aries/handler/PresentProofServiceHandler.java
+++ b/components/camel-hyperledger-aries/src/main/java/org/apache/camel/component/aries/handler/PresentProofServiceHandler.java
@@ -81,6 +81,10 @@ public class PresentProofServiceHandler extends AbstractServiceHandler {
                 throw new UnsupportedServiceException(service);
             }
 
+        } else if (service.equals("/present-proof/create-request")) {
+            PresentProofRequest reqObj = assertBody(exchange, PresentProofRequest.class);
+            PresentationExchangeRecord resObj = createClient().presentProofCreateRequest(reqObj).get();
+            exchange.getIn().setBody(resObj);
         } else {
             throw new UnsupportedServiceException(service);
         }
diff --git a/components/camel-hyperledger-aries/src/main/java/org/apache/camel/component/aries/handler/WalletServiceHandler.java b/components/camel-hyperledger-aries/src/main/java/org/apache/camel/component/aries/handler/WalletServiceHandler.java
index 79f6c5d1937..0299816b7a2 100644
--- a/components/camel-hyperledger-aries/src/main/java/org/apache/camel/component/aries/handler/WalletServiceHandler.java
+++ b/components/camel-hyperledger-aries/src/main/java/org/apache/camel/component/aries/handler/WalletServiceHandler.java
@@ -20,6 +20,9 @@ import org.apache.camel.Exchange;
 import org.apache.camel.component.aries.HyperledgerAriesEndpoint;
 import org.apache.camel.component.aries.UnsupportedServiceException;
 import org.hyperledger.acy_py.generated.model.DID;
+import org.hyperledger.acy_py.generated.model.DIDEndpoint;
+
+import static org.apache.camel.component.aries.Constants.HEADER_DID;
 
 public class WalletServiceHandler extends AbstractServiceHandler {
 
@@ -34,6 +37,11 @@ public class WalletServiceHandler extends AbstractServiceHandler {
             DID resObj = createClient().walletDidPublic().orElse(null);
             exchange.getIn().setBody(resObj);
 
+        } else if (service.equals("/wallet/get-did-endpoint")) {
+            String did = assertHeader(exchange, HEADER_DID, String.class);
+            DIDEndpoint resObj = createClient().walletGetDidEndpoint(did).orElse(null);
+            exchange.getIn().setBody(resObj);
+
         } else {
             throw new UnsupportedServiceException(service);
         }
diff --git a/components/camel-hyperledger-aries/src/test/java/org/apache/camel/component/aries/ConnectionlessProofTest.java b/components/camel-hyperledger-aries/src/test/java/org/apache/camel/component/aries/ConnectionlessProofTest.java
new file mode 100644
index 00000000000..78a91d80672
--- /dev/null
+++ b/components/camel-hyperledger-aries/src/test/java/org/apache/camel/component/aries/ConnectionlessProofTest.java
@@ -0,0 +1,94 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.aries;
+
+import java.io.IOException;
+import java.util.Map;
+
+import org.hyperledger.acy_py.generated.model.DID;
+import org.hyperledger.acy_py.generated.model.DIDEndpoint;
+import org.hyperledger.aries.api.present_proof.PresentProofRequest;
+import org.hyperledger.aries.api.present_proof.PresentProofRequest.ProofRequest;
+import org.hyperledger.aries.api.present_proof.PresentProofRequest.ProofRequest.ProofRequestedAttributes;
+import org.hyperledger.aries.api.present_proof.PresentationExchangeRecord;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.condition.EnabledIfSystemProperty;
+
+import static org.hyperledger.aries.api.ledger.IndyLedgerRoles.ENDORSER;
+import static org.hyperledger.aries.api.present_proof.PresentationExchangeRole.VERIFIER;
+import static org.hyperledger.aries.api.present_proof.PresentationExchangeState.REQUEST_SENT;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+
+/**
+ * docker compose up --detach && docker compose logs -f acapy
+ */
+@EnabledIfSystemProperty(named = "enable.hyperledger.aries.itests", matches = "true",
+                         disabledReason = "Requires distributed ledger (i.e. blockchain)")
+public class ConnectionlessProofTest extends AbstractCamelAriesTest {
+
+    @BeforeEach
+    void beforeEach() throws IOException {
+        setRemoveWalletsOnShutdown(true);
+        onboardWallet(FABER, ENDORSER);
+    }
+
+    /**
+     * Creating proof request without connection ID.
+     */
+    @Test
+    void shouldCreateProofRequest() {
+        var request = new PresentProofRequest();
+        var proofRequest = new ProofRequest();
+        var attribute = new ProofRequestedAttributes();
+        attribute.setName("first_name");
+        proofRequest.setRequestedAttributes(Map.of("0_first_name_uuid", attribute));
+        proofRequest.setRequestedPredicates(Map.of());
+        request.setProofRequest(proofRequest);
+
+        var result = template.requestBody(
+                "hyperledger-aries:faber?service=/present-proof/create-request",
+                request,
+                PresentationExchangeRecord.class);
+
+        assertNotNull(result.getPresentationExchangeId());
+        assertEquals(REQUEST_SENT, result.getState());
+        assertEquals(VERIFIER, result.getRole());
+    }
+
+    /**
+     * This endpoint is required to add service decorator to connectionless proof presentation.
+     */
+    @Test
+    void shouldReturnPublicDidEndpoint() {
+        var did = template.requestBody(
+                "hyperledger-aries:faber?service=/wallet/did/public",
+                null,
+                DID.class);
+
+        var result = template.requestBodyAndHeader(
+                "hyperledger-aries:faber?service=/wallet/get-did-endpoint",
+                null,
+                "did",
+                did.getDid(),
+                DIDEndpoint.class);
+
+        assertNotNull(result.getEndpoint());
+        assertEquals(did.getDid(), result.getDid());
+    }
+}