Skip to content

Commit 0722879

Browse files
resolve review comments
1 parent 2c2e387 commit 0722879

File tree

9 files changed

+418
-273
lines changed

9 files changed

+418
-273
lines changed
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
package org.cardanofoundation.signify.app.credentialing.credentials;
2+
3+
import org.cardanofoundation.signify.cesr.Serder;
4+
5+
public class CredentialVerifyOptions {
6+
private final Serder acdc;
7+
private final Serder iss;
8+
private final String acdcAtc;
9+
private final String issAtc;
10+
11+
private CredentialVerifyOptions(Builder builder) {
12+
this.acdc = builder.acdc;
13+
this.iss = builder.iss;
14+
this.acdcAtc = builder.acdcAtc;
15+
this.issAtc = builder.issAtc;
16+
}
17+
18+
public Serder getAcdc() { return acdc; }
19+
public Serder getIss() { return iss; }
20+
public String getAcdcAtc() { return acdcAtc; }
21+
public String getIssAtc() { return issAtc; }
22+
23+
public static Builder builder() { return new Builder(); }
24+
25+
public static class Builder {
26+
private Serder acdc;
27+
private Serder iss;
28+
private String acdcAtc;
29+
private String issAtc;
30+
31+
public Builder acdc(Serder acdc) {
32+
this.acdc = acdc;
33+
return this;
34+
}
35+
public Builder iss(Serder iss) {
36+
this.iss = iss;
37+
return this;
38+
}
39+
public Builder acdcAtc(String acdcAtc) {
40+
this.acdcAtc = acdcAtc;
41+
return this;
42+
}
43+
public Builder issAtc(String issAtc) {
44+
this.issAtc = issAtc;
45+
return this;
46+
}
47+
public CredentialVerifyOptions build() {
48+
return new CredentialVerifyOptions(this);
49+
}
50+
}
51+
}

src/main/java/org/cardanofoundation/signify/app/credentialing/credentials/Credentials.java

Lines changed: 47 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -47,37 +47,58 @@ public Object list(CredentialFilter kargs) throws IOException, InterruptedExcept
4747
return Utils.fromJson(response.body(), Object.class);
4848
}
4949

50-
public Optional<Object> get(String said) throws IOException, InterruptedException, LibsodiumException {
51-
return this.get(said, false);
50+
/**
51+
* Get a credential as raw CESR string.
52+
*/
53+
public Optional<String> get(String said) throws IOException, InterruptedException, LibsodiumException {
54+
return this.getCESR(said);
5255
}
5356

5457
/**
55-
* Get a credential
56-
*
57-
* @param said - SAID of the credential
58-
* @param includeCESR - Optional flag export the credential in CESR format
59-
* @return Optional containing the credential if found, or empty if not found.
60-
* Returns String (raw CESR text) when includeCESR=true,
61-
* or Object (parsed JSON) when includeCESR=false
58+
* Get a credential as parsed JSON (Object) or raw CESR string depending on includeCESR.
6259
*/
6360
public Optional<Object> get(String said, boolean includeCESR) throws IOException, InterruptedException, LibsodiumException {
61+
if (includeCESR) {
62+
// For backward compatibility, but prefer getCESR for type safety
63+
Optional<String> cesr = getCESR(said);
64+
return cesr.map(s -> (Object) s);
65+
} else {
66+
return getJson(said);
67+
}
68+
}
69+
70+
/**
71+
* Get a credential as raw CESR string.
72+
*/
73+
public Optional<String> getCESR(String said) throws IOException, InterruptedException, LibsodiumException {
6474
final String path = "/credentials/" + said;
6575
final String method = "GET";
66-
6776
Map<String, String> extraHeaders = new LinkedHashMap<>();
68-
if (includeCESR) {
69-
extraHeaders.put("Accept", "application/json+cesr");
70-
} else {
71-
extraHeaders.put("Accept", "application/json");
77+
extraHeaders.put("Accept", "application/json+cesr");
78+
79+
HttpResponse<String> response = this.client.fetch(path, method, null, extraHeaders);
80+
81+
if (response.statusCode() == java.net.HttpURLConnection.HTTP_NOT_FOUND) {
82+
return Optional.empty();
7283
}
84+
return Optional.of(response.body());
85+
}
86+
87+
/**
88+
* Get a credential as parsed JSON (Object).
89+
*/
90+
private Optional<Object> getJson(String said) throws IOException, InterruptedException, LibsodiumException {
91+
final String path = "/credentials/" + said;
92+
final String method = "GET";
93+
Map<String, String> extraHeaders = new LinkedHashMap<>();
94+
extraHeaders.put("Accept", "application/json");
7395

7496
HttpResponse<String> response = this.client.fetch(path, method, null, extraHeaders);
75-
97+
7698
if (response.statusCode() == java.net.HttpURLConnection.HTTP_NOT_FOUND) {
7799
return Optional.empty();
78100
}
79-
80-
return Optional.of(includeCESR ? response.body() : Utils.fromJson(response.body(), Object.class));
101+
return Optional.of(Utils.fromJson(response.body(), Object.class));
81102
}
82103

83104
/**
@@ -198,7 +219,7 @@ public RevokeCredentialResult revoke(String name, String said, String datetime)
198219
final String vs = CoreUtil.versify(CoreUtil.Ident.KERI, null, CoreUtil.Serials.JSON, 0);
199220
final String dt = datetime != null ? datetime : Utils.currentDateTimeString();
200221

201-
Map<String, Object> cred = Utils.toMap(this.get(said)
222+
Map<String, Object> cred = Utils.toMap(this.get(said, false)
202223
.orElseThrow(() -> new IllegalArgumentException("Credential not found: " + said)));
203224

204225
// Create rev
@@ -262,26 +283,23 @@ public RevokeCredentialResult revoke(String name, String said, String datetime)
262283
/**
263284
* Verify a credential and issuing event
264285
*
265-
* @param acdc ACDC to process and verify
266-
* @param iss Issuing event for ACDC in TEL
267-
* @param acdcAtc Optional attachment string to be verified against the credential
268-
* @param issAtc Optional attachment string to be verified against the issuing event
286+
* @param options CredentialVerifyOptions containing all verification parameters
269287
* @return Operation containing the verification result
270288
*/
271-
public Operation<?> verify(Serder acdc, Serder iss, String acdcAtc, String issAtc) throws IOException, InterruptedException, LibsodiumException {
289+
public Operation<?> verify(CredentialVerifyOptions options) throws IOException, InterruptedException, LibsodiumException {
272290
final String path = "/credentials/verify";
273291
final String method = "POST";
274292

275293
Map<String, Object> body = new LinkedHashMap<>();
276-
body.put("acdc", acdc.getKed());
277-
body.put("iss", iss.getKed());
294+
body.put("acdc", options.getAcdc().getKed());
295+
body.put("iss", options.getIss().getKed());
278296

279-
if (acdcAtc != null && !acdcAtc.isEmpty()) {
280-
body.put("acdcAtc", acdcAtc);
297+
if (options.getAcdcAtc() != null && !options.getAcdcAtc().isEmpty()) {
298+
body.put("acdcAtc", options.getAcdcAtc());
281299
}
282300

283-
if (issAtc != null && !issAtc.isEmpty()) {
284-
body.put("issAtc", issAtc);
301+
if (options.getIssAtc() != null && !options.getIssAtc().isEmpty()) {
302+
body.put("issAtc", options.getIssAtc());
285303
}
286304

287305
HttpResponse<String> response = this.client.fetch(path, method, body);

src/main/java/org/cardanofoundation/signify/app/credentialing/registries/Registries.java

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -170,23 +170,22 @@ public Object rename(String name, String registryName, String newName) throws IO
170170
/**
171171
* Verify a registry with optional attachment
172172
*
173-
* @param vcp the VCP (Verifiable Credential Protocol) data to verify
174-
* @param atc the optional attachment data (metadata)
173+
* @param options RegistryVerifyOptions containing all verification parameters
175174
* @return Operation containing the verification result
176175
* @throws IOException if an I/O error occurs
177176
* @throws InterruptedException if the operation is interrupted
178177
* @throws LibsodiumException if a sodium exception occurs
179178
*/
180-
public Operation<?> verify(Serder vcp, String atc) throws IOException, InterruptedException, LibsodiumException {
179+
public Operation<?> verify(RegistryVerifyOptions options) throws IOException, InterruptedException, LibsodiumException {
181180
final String path = "/registries/verify";
182181
final String method = "POST";
183-
182+
184183
Map<String, Object> body = new LinkedHashMap<>();
185-
body.put("vcp", vcp.getKed());
186-
if (atc != null && !atc.isEmpty()) {
187-
body.put("atc", atc);
184+
body.put("vcp", options.getVcp().getKed());
185+
if (options.getAtc() != null && !options.getAtc().isEmpty()) {
186+
body.put("atc", options.getAtc());
188187
}
189-
188+
190189
HttpResponse<String> response = this.client.fetch(path, method, body);
191190
return Operation.fromObject(Utils.fromJson(response.body(), Map.class));
192191
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
package org.cardanofoundation.signify.app.credentialing.registries;
2+
3+
import org.cardanofoundation.signify.cesr.Serder;
4+
5+
public class RegistryVerifyOptions {
6+
private final Serder vcp;
7+
private final String atc;
8+
9+
private RegistryVerifyOptions(Builder builder) {
10+
this.vcp = builder.vcp;
11+
this.atc = builder.atc;
12+
}
13+
14+
public Serder getVcp() { return vcp; }
15+
public String getAtc() { return atc; }
16+
17+
public static Builder builder() { return new Builder(); }
18+
19+
public static class Builder {
20+
private Serder vcp;
21+
private String atc;
22+
23+
public Builder vcp(Serder vcp) {
24+
this.vcp = vcp;
25+
return this;
26+
}
27+
public Builder atc(String atc) {
28+
this.atc = atc;
29+
return this;
30+
}
31+
public RegistryVerifyOptions build() {
32+
return new RegistryVerifyOptions(this);
33+
}
34+
}
35+
}

src/test/java/org/cardanofoundation/signify/app/BaseMockServerTest.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,22 @@ void tearDown() throws Exception {
188188
"windexes": []
189189
}""";
190190

191+
public static final String MOCK_REGISTRY_STATE = """
192+
{
193+
"v": "KERI10JSON000135_",
194+
"i": "EMwcsEMUEruPXVwPCW7zmqmN8m0I3CihxolBm-RDrsJo",
195+
"s": "0",
196+
"d": "ENf3IEYwYtFmlq5ZzoI-zFzeR7E3ZNRN2YH_0KAFbdJW",
197+
"ri": "EGK216v1yguLfex4YRFnG7k1sXRjh3OKY7QqzdKsx7df",
198+
"ra": {},
199+
"a": {
200+
"s": 2,
201+
"d": "EIpgyKVF0z0Pcn2_HgbWhEKmJhOXFeD4SA62SrxYXOLt"
202+
},
203+
"dt": "2023-08-23T15:16:07.553000+00:00",
204+
"et": "iss"
205+
}""";
206+
191207
public static final String MOCK_CREDENTIAL = """
192208
{
193209
"sad": {

src/test/java/org/cardanofoundation/signify/app/CredentialingTest.java

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,14 @@ public MockResponse mockAllRequests(RecordedRequest req) throws LibsodiumExcepti
4747
null
4848
);
4949

50-
String body = reqUrl.startsWith(url + "/credentials")
51-
? MOCK_CREDENTIAL
52-
: MOCK_GET_AID;
50+
String body;
51+
if (reqUrl.startsWith(url + "/credentials")) {
52+
body = MOCK_CREDENTIAL;
53+
} else if (reqUrl.startsWith(url + "/registries")) {
54+
body = MOCK_REGISTRY_STATE;
55+
} else {
56+
body = MOCK_GET_AID;
57+
}
5358

5459
MockResponse mockResponse = new MockResponse()
5560
.setResponseCode(202)

src/test/java/org/cardanofoundation/signify/e2e/CredentialsTest.java

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -246,7 +246,7 @@ public void single_signature_credentials() throws Exception {
246246

247247
testSteps.step("Issuer get credential by id", () -> {
248248
try {
249-
Object issuerCredential = issuerClient.credentials().get(qviCredentialId).get();
249+
Object issuerCredential = issuerClient.credentials().get(qviCredentialId, false).get();
250250
LinkedHashMap<String, Object> issuerCredentialsList = castObjectToLinkedHashMap(issuerCredential);
251251
Object credentialsMap = issuerCredentialsList.get("sad");
252252
LinkedHashMap<String, Object> sad = castObjectToLinkedHashMap(credentialsMap);
@@ -264,7 +264,7 @@ public void single_signature_credentials() throws Exception {
264264
testSteps.step("Issuer IPEX grant", () -> {
265265
String dt = createTimestamp();
266266
try {
267-
Object issuerCredential = issuerClient.credentials().get(qviCredentialId).get();
267+
Object issuerCredential = issuerClient.credentials().get(qviCredentialId, false).get();
268268
LinkedHashMap<String, Object> issuerCredentialList = castObjectToLinkedHashMap(issuerCredential);
269269
Map<String, Object> getSAD = (Map<String, Object>) issuerCredentialList.get("sad");
270270
Map<String, Object> getANC = (Map<String, Object>) issuerCredentialList.get("anc");
@@ -340,7 +340,7 @@ public void single_signature_credentials() throws Exception {
340340
Map<String, Object> sad, status;
341341
String atc;
342342
try {
343-
Object holderCredential = holderClient.credentials().get(qviCredentialId).get();
343+
Object holderCredential = holderClient.credentials().get(qviCredentialId, false).get();
344344
LinkedHashMap<String, Object> holderCredentialList = castObjectToLinkedHashMap(holderCredential);
345345

346346
Object credentialsMap = holderCredentialList.get("sad");
@@ -490,7 +490,7 @@ public void single_signature_credentials() throws Exception {
490490

491491
markAndRemoveNotification(holderClient, holderAgreeNote);
492492

493-
Object holderCredential = holderClient.credentials().get(qviCredentialId).get();
493+
Object holderCredential = holderClient.credentials().get(qviCredentialId, false).get();
494494
LinkedHashMap<String, Object> holderCredentialBody = castObjectToLinkedHashMap(holderCredential);
495495
LinkedHashMap<String, Object> sad = castObjectToLinkedHashMap(holderCredentialBody.get("sad"));
496496
LinkedHashMap<String, Object> anc = castObjectToLinkedHashMap(holderCredentialBody.get("anc"));
@@ -550,7 +550,7 @@ public void single_signature_credentials() throws Exception {
550550
);
551551
waitOperation(verifierClient, op);
552552
markAndRemoveNotification(verifierClient, verifierGrantNote);
553-
Object verifierCredential = verifierClient.credentials().get(qviCredentialId).get();
553+
Object verifierCredential = verifierClient.credentials().get(qviCredentialId, false).get();
554554

555555
LinkedHashMap<String, Object> verifierCredentialBody = castObjectToLinkedHashMap(verifierCredential);
556556
LinkedHashMap<String, Object> sad = castObjectToLinkedHashMap(verifierCredentialBody.get("sad"));
@@ -599,7 +599,7 @@ public void single_signature_credentials() throws Exception {
599599

600600
String leCredentialId = testSteps.step("Holder create LE (chained) credential", () -> {
601601
try {
602-
Object qviCredential = holderClient.credentials().get(qviCredentialId).get();
602+
Object qviCredential = holderClient.credentials().get(qviCredentialId, false).get();
603603
LinkedHashMap<String, Object> qviCredentialBody = castObjectToLinkedHashMap(qviCredential);
604604
LinkedHashMap<String, Object> sadBody = castObjectToLinkedHashMap(qviCredentialBody.get("sad"));
605605

@@ -646,7 +646,7 @@ public void single_signature_credentials() throws Exception {
646646
testSteps.step("LE credential IPEX grant", () -> {
647647
String dt = createTimestamp();
648648
try {
649-
Object leCredential = holderClient.credentials().get(leCredentialId).get();
649+
Object leCredential = holderClient.credentials().get(leCredentialId, false).get();
650650

651651
LinkedHashMap<String, Object> leCredentialBody = castObjectToLinkedHashMap(leCredential);
652652
assertTrue(!leCredentialBody.isEmpty());
@@ -710,7 +710,7 @@ public void single_signature_credentials() throws Exception {
710710
Object legalEntityCredential = retry(() -> {
711711
try {
712712
assertNotNull(leCredentialId);
713-
return legalEntityClient.credentials().get(leCredentialId).get();
713+
return legalEntityClient.credentials().get(leCredentialId, false).get();
714714
} catch (Exception e) {
715715
throw new RuntimeException(e);
716716
}
@@ -736,7 +736,7 @@ public void single_signature_credentials() throws Exception {
736736
try {
737737
RevokeCredentialResult revokeOperation = issuerClient.credentials().revoke(issuerAid.name, qviCredentialId, null);
738738
waitOperation(issuerClient, revokeOperation.getOp());
739-
Object issuerCredential = issuerClient.credentials().get(qviCredentialId).get();
739+
Object issuerCredential = issuerClient.credentials().get(qviCredentialId, false).get();
740740

741741
LinkedHashMap<String, Object> issuerCredentialBody = castObjectToLinkedHashMap(issuerCredential);
742742
LinkedHashMap<String, Object> status = castObjectToLinkedHashMap(issuerCredentialBody.get("status"));

0 commit comments

Comments
 (0)