Skip to content

Commit cb824d7

Browse files
feat: add Verifier tests (VPP) (#25)
* introduce deeper package hierarchy * add verifier tests, update Readme * added references * removed references again * improved verifier tests * added credential revocation (Bitstring2021) * add more verifier tests * update README.md * add lic headers, make revocation type configurable * checkstyle
1 parent 93dc4a0 commit cb824d7

File tree

38 files changed

+1932
-214
lines changed

38 files changed

+1932
-214
lines changed

README.md

Lines changed: 150 additions & 39 deletions
Large diffs are not rendered by default.

config/tck/sample.tck.properties

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
11
# Contains sample configuration options
2-
#dataspacetck.test.package=org.eclipse.dataspacetck.dcp.verification.presentation
3-
dataspacetck.test.package=org.eclipse.dataspacetck.dcp.verification.issuance.issuer
2+
dataspacetck.test.package=org.eclipse.dataspacetck.dcp.verification.presentation.verifier,org.eclipse.dataspacetck.dcp.verification.presentation.cs,org.eclipse.dataspacetck.dcp.verification.issuance.issuer,org.eclipse.dataspacetck.dcp.verification.presentation.issuance.cs
43
dataspacetck.credentials.correlation.id=foobar
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/*
2+
* Copyright (c) 2025 Metaform Systems Inc.
3+
*
4+
* This program and the accompanying materials are made available under the
5+
* terms of the Apache License, Version 2.0 which is available at
6+
* https://www.apache.org/licenses/LICENSE-2.0
7+
*
8+
* SPDX-License-Identifier: Apache-2.0
9+
*
10+
* Contributors:
11+
* Metaform Systems Inc. - initial API and implementation
12+
*
13+
*/
14+
15+
package org.eclipse.dataspacetck.dcp.system.annotation;
16+
17+
import java.lang.annotation.Inherited;
18+
import java.lang.annotation.Retention;
19+
import java.lang.annotation.Target;
20+
21+
import static java.lang.annotation.ElementType.FIELD;
22+
import static java.lang.annotation.ElementType.PARAMETER;
23+
import static java.lang.annotation.RetentionPolicy.RUNTIME;
24+
25+
/**
26+
* Used to inject a configurable endpoint at which the Verifier-Under-Test expects the DCP Presentation Flow to be kicked off.
27+
*/
28+
@Inherited
29+
@Retention(RUNTIME)
30+
@Target({ FIELD, PARAMETER })
31+
public @interface TriggerEndpoint {
32+
}

dcp-api/src/main/java/org/eclipse/dataspacetck/dcp/system/cs/CredentialService.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,4 +47,11 @@ public interface CredentialService {
4747
* @return A collection of {@link VcContainer} objects representing the issued credentials.
4848
*/
4949
Collection<VcContainer> getCredentials();
50+
51+
/**
52+
* Sets a delegate, which could be a mock, and which is used in place of the real credential service until set to null
53+
*
54+
* @param delegate a delegate
55+
*/
56+
void withDelegate(CredentialService delegate);
5057
}

dcp-api/src/main/java/org/eclipse/dataspacetck/dcp/system/message/DcpConstants.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,4 +73,7 @@ public interface DcpConstants {
7373

7474
String CREDENTIAL_STATUS_PATH = "/requests/";
7575

76+
String NULL_BODY = "";
77+
78+
String JSON_CONTENT_TYPE = "application/json";
7679
}

dcp-api/src/main/java/org/eclipse/dataspacetck/dcp/system/model/did/DidDocument.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,13 @@
1818
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
1919
import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder;
2020
import org.eclipse.dataspacetck.dcp.system.model.ExtensibleModel;
21+
import org.eclipse.dataspacetck.dcp.system.service.Result;
2122

2223
import java.util.ArrayList;
2324
import java.util.List;
2425

2526
import static java.util.Objects.requireNonNull;
27+
import static org.eclipse.dataspacetck.dcp.system.service.Result.failure;
2628

2729
/**
2830
* Models a DID document.
@@ -59,12 +61,13 @@ public ServiceEntry getServiceEntry(String type) {
5961
.orElseThrow(() -> new IllegalArgumentException("No service found for type " + type));
6062
}
6163

62-
public VerificationMethod getVerificationMethod(String id) {
64+
public Result<VerificationMethod> getVerificationMethod(String id) {
6365

6466
return verificationMethods.stream()
6567
.filter(m -> m.getId().equals(id) || m.getId().equals(this.id + id) || m.getId().equals(this.id + "#" + id))
6668
.findFirst()
67-
.orElseThrow(() -> new IllegalArgumentException("No verification method found for id " + id));
69+
.map(Result::success)
70+
.orElseGet(() -> failure("No verification method found for id " + id));
6871
}
6972

7073
@JsonPOJOBuilder(withPrefix = "")

dcp-api/src/main/java/org/eclipse/dataspacetck/dcp/system/model/vc/MetadataReference.java

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder;
2121

2222
import java.util.LinkedHashMap;
23-
import java.util.List;
2423
import java.util.Map;
2524

2625
import static java.util.Objects.requireNonNull;
@@ -34,7 +33,7 @@
3433
public class MetadataReference {
3534
private String id;
3635
private String type;
37-
private Map<String, Object> extensibleProperties = new LinkedHashMap<>();
36+
private final Map<String, Object> extensibleProperties = new LinkedHashMap<>();
3837

3938
public String getId() {
4039
return id;
@@ -51,7 +50,7 @@ public Map<String, Object> getExtensibleProperties() {
5150
public Map<String, Object> toMap() {
5251
var map = new LinkedHashMap<String, Object>();
5352
map.put(ID, id);
54-
map.put(TYPE, List.of(type));
53+
map.put(TYPE, type);
5554
map.putAll(extensibleProperties);
5655
return map;
5756
}
@@ -61,7 +60,7 @@ private MetadataReference() {
6160

6261
@JsonPOJOBuilder(withPrefix = "")
6362
public static class Builder {
64-
private MetadataReference reference;
63+
private final MetadataReference reference;
6564

6665

6766
@JsonCreator

dcp-api/src/main/java/org/eclipse/dataspacetck/dcp/system/model/vc/VerifiableCredential.java

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,10 +39,11 @@
3939
public class VerifiableCredential extends ExtensibleModel {
4040

4141
private final List<String> type = new ArrayList<>();
42-
private final Map<String, Object> credentialSubject = new LinkedHashMap<>();
42+
private Map<String, Object> credentialSubject = new LinkedHashMap<>();
4343
private String id;
4444
private String issuer;
4545
private String issuanceDate;
46+
private String expirationDate;
4647
private MetadataReference credentialSchema;
4748
private MetadataReference credentialStatus;
4849

@@ -82,6 +83,7 @@ public Map<String, Object> toMap() {
8283
map.put(TYPE, type);
8384
map.put("issuer", issuer);
8485
map.put("issuanceDate", issuanceDate);
86+
map.put("expirationDate", expirationDate);
8587
if (credentialSchema != null) {
8688
map.put("credentialSchema", credentialSchema);
8789
}
@@ -95,6 +97,10 @@ public Map<String, Object> toMap() {
9597
return map;
9698
}
9799

100+
public String getExpirationDate() {
101+
return expirationDate;
102+
}
103+
98104
@JsonPOJOBuilder(withPrefix = "")
99105
public static class Builder extends ExtensibleModel.Builder<Builder> {
100106
private final VerifiableCredential credential;
@@ -129,6 +135,11 @@ public Builder issuanceDate(String date) {
129135
return this;
130136
}
131137

138+
public Builder expirationDate(String date) {
139+
credential.expirationDate = date;
140+
return this;
141+
}
142+
132143
public Builder credentialSchema(MetadataReference credentialSchema) {
133144
credential.credentialSchema = credentialSchema;
134145
return this;
@@ -140,7 +151,7 @@ public Builder credentialStatus(MetadataReference status) {
140151
}
141152

142153
public Builder credentialSubject(Map<String, Object> subject) {
143-
credential.credentialSubject.putAll(subject);
154+
credential.credentialSubject = subject;
144155
return this;
145156
}
146157

dcp-api/src/test/java/org/eclipse/dataspacetck/dcp/system/model/did/DidDocumentTest.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ void verifyDeserializeSerialize() throws JsonProcessingException {
5555
assertThat(deserialized.getServices()).allMatch(s -> s.id().equals("TCK-Credential-Service"));
5656
assertThat(deserialized.getVerificationMethods()).allMatch(v -> v.getId().equals("43cecd95-7a59-4a5f-b2d0-0ec73ae41a0c"));
5757
assertThat(deserialized.getVerificationMethod("43cecd95-7a59-4a5f-b2d0-0ec73ae41a0c")).isNotNull();
58+
assertThat(deserialized.getVerificationMethod("43cecd95-7a59-4a5f-b2d0-0ec73ae41a0c").succeeded()).isTrue();
5859
assertThat(deserialized.getServiceEntry("CredentialService")).isNotNull();
5960
}
6061
}

dcp-system/src/main/java/org/eclipse/dataspacetck/dcp/system/DcpSystemLauncher.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import org.eclipse.dataspacetck.dcp.system.annotation.IssueCredentials;
2727
import org.eclipse.dataspacetck.dcp.system.annotation.Issuer;
2828
import org.eclipse.dataspacetck.dcp.system.annotation.ThirdParty;
29+
import org.eclipse.dataspacetck.dcp.system.annotation.TriggerEndpoint;
2930
import org.eclipse.dataspacetck.dcp.system.annotation.Verifier;
3031
import org.eclipse.dataspacetck.dcp.system.assembly.BaseAssembly;
3132
import org.eclipse.dataspacetck.dcp.system.assembly.ServiceAssembly;
@@ -34,6 +35,7 @@
3435
import org.eclipse.dataspacetck.dcp.system.did.DidService;
3536
import org.eclipse.dataspacetck.dcp.system.generation.JwtCredentialGenerator;
3637
import org.eclipse.dataspacetck.dcp.system.model.vc.VcContainer;
38+
import org.eclipse.dataspacetck.dcp.system.revocation.CredentialRevocationService;
3739
import org.jetbrains.annotations.Nullable;
3840

3941
import java.lang.annotation.Annotation;
@@ -58,6 +60,7 @@ public void start(SystemConfiguration configuration) {
5860
@Override
5961
public <T> boolean providesService(Class<T> type) {
6062
return type.isAssignableFrom(CredentialService.class) ||
63+
type.isAssignableFrom(CredentialRevocationService.class) ||
6164
type.isAssignableFrom(DidService.class) ||
6265
type.isAssignableFrom(String.class) ||
6366
type.isAssignableFrom(KeyService.class) ||
@@ -71,6 +74,8 @@ public <T> T getService(Class<T> type, ServiceConfiguration configuration, Servi
7174
var assembly = serviceAssemblies.computeIfAbsent(scopeId, id -> new ServiceAssembly(baseAssembly, resolver, configuration));
7275
if (type.isAssignableFrom(CredentialService.class)) {
7376
return type.cast(assembly.getCredentialService());
77+
} else if (type.isAssignableFrom(CredentialRevocationService.class)) {
78+
return type.cast(assembly.getRevocationService());
7479
} else if (type.isAssignableFrom(VcContainer.class)) {
7580
if (hasAnnotation(Credential.class, configuration)) {
7681
var gen = new JwtCredentialGenerator(baseAssembly.getIssuerDid(), baseAssembly.getIssuerKeyService());
@@ -106,6 +111,9 @@ public <T> T getService(Class<T> type, ServiceConfiguration configuration, Servi
106111
if (hasAnnotation(HolderPid.class, configuration)) {
107112
return type.cast(baseAssembly.getHolderPid());
108113
}
114+
if (hasAnnotation(TriggerEndpoint.class, configuration)) {
115+
return type.cast(baseAssembly.getVerifierTriggerEndpoint());
116+
}
109117

110118
var did = getAnnotation(Did.class, configuration);
111119
if (did.isPresent()) {

0 commit comments

Comments
 (0)