Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion config/tck/sample.tck.properties
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
# Contains sample configuration options
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
dataspacetck.test.package=org.eclipse.dataspacetck.dcp.verification.issuance.cs,org.eclipse.dataspacetck.dcp.verification.issuance.issuer,org.eclipse.dataspacetck.dcp.verification.presentation.cs,org.eclipse.dataspacetck.dcp.verification.presentation.issuer
dataspacetck.credentials.correlation.id=foobar
Original file line number Diff line number Diff line change
Expand Up @@ -76,4 +76,8 @@ public interface DcpConstants {
String NULL_BODY = "";

String JSON_CONTENT_TYPE = "application/json";

String ISSUER_METADATA_MESSAGE_TYPE = "IssuerMetadata";

String ISSUER_METADATA_PATH = "/metadata";
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import org.eclipse.dataspacetck.core.spi.system.ServiceConfiguration;
import org.eclipse.dataspacetck.core.spi.system.ServiceResolver;
import org.eclipse.dataspacetck.dcp.system.cs.CredentialApiHandler;
import org.eclipse.dataspacetck.dcp.system.cs.CredentialObject;
import org.eclipse.dataspacetck.dcp.system.cs.CredentialOfferHandler;
import org.eclipse.dataspacetck.dcp.system.cs.CredentialService;
import org.eclipse.dataspacetck.dcp.system.cs.CredentialServiceImpl;
Expand All @@ -36,6 +37,7 @@
import org.eclipse.dataspacetck.dcp.system.generation.JwtPresentationGenerator;
import org.eclipse.dataspacetck.dcp.system.handler.SchemaProvider;
import org.eclipse.dataspacetck.dcp.system.issuer.CredentialRequestHandler;
import org.eclipse.dataspacetck.dcp.system.issuer.IssuerMetadataHandler;
import org.eclipse.dataspacetck.dcp.system.issuer.IssuerService;
import org.eclipse.dataspacetck.dcp.system.issuer.IssuerServiceImpl;
import org.eclipse.dataspacetck.dcp.system.message.DcpMessageBuilder;
Expand All @@ -55,9 +57,11 @@
import java.time.Instant;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.stream.Stream;

import static java.time.Instant.now;
import static java.util.Objects.requireNonNull;
Expand All @@ -82,9 +86,10 @@ public ServiceAssembly(BaseAssembly baseAssembly, ServiceResolver resolver, Serv
var generator = new JwtPresentationGenerator(baseAssembly.getHolderDid(), baseAssembly.getHolderKeyService());
var mapper = baseAssembly.getMapper();

var supportedCredentials = buildSupportedCredentials();
secureTokenServer = new SecureTokenServerImpl(configuration);
credentialService = new CredentialServiceImpl(baseAssembly.getHolderDid(), List.of(generator), secureTokenServer, baseAssembly.getHolderTokenService(), mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES));
issuerService = new IssuerServiceImpl(baseAssembly.getIssuerKeyService(), baseAssembly.getIssuerTokenService());
issuerService = new IssuerServiceImpl(baseAssembly.getIssuerKeyService(), baseAssembly.getIssuerTokenService(), supportedCredentials);
revocationService = createRevocationService(baseAssembly);

var endpoint = (CallbackEndpoint) requireNonNull(resolver.resolve(CallbackEndpoint.class, configuration));
Expand All @@ -100,6 +105,7 @@ public ServiceAssembly(BaseAssembly baseAssembly, ServiceResolver resolver, Serv
endpoint.registerProtocolHandler("/credentials", new CredentialApiHandler(credentialService, mapper, issuerService));
endpoint.registerProtocolHandler("/offers", new CredentialOfferHandler(credentialService));
endpoint.registerProtocolHandler("/requests/.*", new CredentialRequestHandler(issuerService, mapper));
endpoint.registerProtocolHandler("/metadata", new IssuerMetadataHandler(supportedCredentials, mapper, baseAssembly.getIssuerDid()));

endpoint.registerHandler("/holder/did.json", new DidDocumentHandler(baseAssembly.getHolderDidService(), mapper));
endpoint.registerHandler("/verifier/did.json", new DidDocumentHandler(baseAssembly.getVerifierDidService(), mapper));
Expand Down Expand Up @@ -171,6 +177,34 @@ public VcContainer createVcContainer(String issuerDid, String holderDid,
return new VcContainer(result.getContent(), credential, VC1_0_JWT);
}

private Map<String, CredentialObject> buildSupportedCredentials() {
var map = new HashMap<String, CredentialObject>();

Stream.of("vc11-sl2021/jwt", "vc20-bssl/jwt").forEach(profile -> {
var membershipCredential = CredentialObject.Builder.newInstance()
.id(UUID.randomUUID().toString())
.type("CredentialObject")
.credentialType(MEMBERSHIP_CREDENTIAL_TYPE)
.offerReason("issuance")
.bindingMethods(Collections.singletonList("did:web"))
.profile(profile)
.build();
map.put(membershipCredential.getId(), membershipCredential);

var sensitiveDataCredential = CredentialObject.Builder.newInstance()
.id(UUID.randomUUID().toString())
.type("CredentialObject")
.credentialType(SENSITIVE_DATA_CREDENTIAL_TYPE)
.offerReason("issuance")
.bindingMethods(Collections.singletonList("did:web"))
.profile(profile)
.build();
map.put(sensitiveDataCredential.getId(), sensitiveDataCredential);
});

return Collections.unmodifiableMap(map);
}

private CredentialRevocationService createRevocationService(BaseAssembly baseAssembly) {
return switch (baseAssembly.getRevocationListType().toLowerCase()) {
case "bitstringstatuslist" ->
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
/*
* Copyright (c) 2025 Metaform Systems Inc.
*
* This program and the accompanying materials are made available under the
* terms of the Apache License, Version 2.0 which is available at
* https://www.apache.org/licenses/LICENSE-2.0
*
* SPDX-License-Identifier: Apache-2.0
*
* Contributors:
* Metaform Systems Inc. - initial API and implementation
*
*/

package org.eclipse.dataspacetck.dcp.system.cs;

import com.fasterxml.jackson.annotation.JsonProperty;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class CredentialObject {
@JsonProperty(value = "bindingMethods")
private final List<String> bindingMethods = new ArrayList<>();
@JsonProperty(value = "profile")
private String profile;
@JsonProperty(value = "issuancePolicy")
private final Map<String, Object> issuancePolicy = new HashMap<>();
@JsonProperty(value = "id", required = true)
private String id;
@JsonProperty(value = "type")
private String type;
@JsonProperty(value = "credentialType")
private String credentialType;
@JsonProperty(value = "offerReason")
private String offerReason;
@JsonProperty(value = "credentialSchema")
private String credentialSchema;

public List<String> getBindingMethods() {
return bindingMethods;
}

public String getProfile() {
return profile;
}

public Map<String, Object> getIssuancePolicy() {
return issuancePolicy;
}

public String getId() {
return id;
}

public String getType() {
return type;
}

public String getCredentialType() {
return credentialType;
}

public String getOfferReason() {
return offerReason;
}

public String getCredentialSchema() {
return credentialSchema;
}

public boolean validate() {
if (type == null && credentialType == null && id != null) {
return true;
}
return type != null && credentialType != null && id != null;
}

public static class Builder {
private final CredentialObject credentialObject;

private Builder() {
credentialObject = new CredentialObject();
}

public static Builder newInstance() {
return new Builder();
}

public Builder bindingMethods(List<String> bindingMethods) {
credentialObject.bindingMethods.addAll(bindingMethods);
return this;
}

public Builder profile(String profile) {
credentialObject.profile = profile;
return this;
}

public Builder issuancePolicy(Map<String, Object> issuancePolicy) {
credentialObject.issuancePolicy.putAll(issuancePolicy);
return this;
}

public Builder id(String id) {
credentialObject.id = id;
return this;
}

public Builder type(String type) {
credentialObject.type = type;
return this;
}

public Builder credentialType(String credentialType) {
credentialObject.credentialType = credentialType;
return this;
}

public Builder offerReason(String offerReason) {
credentialObject.offerReason = offerReason;
return this;
}

public Builder credentialSchema(String credentialSchema) {
credentialObject.credentialSchema = credentialSchema;
return this;
}

public CredentialObject build() {
return credentialObject;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,24 +14,21 @@

package org.eclipse.dataspacetck.dcp.system.cs;


import com.fasterxml.jackson.annotation.JsonProperty;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class CredentialOfferMessage {

@JsonProperty(value = "type", required = true)
private String type;
@JsonProperty(value = "issuer", required = true)
private String issuer;

@JsonProperty(value = "credentials", required = true)
private Collection<CredentialObject> credentials = new ArrayList<>();


public String getType() {
return type;
}
Expand All @@ -45,55 +42,8 @@ public Collection<CredentialObject> getCredentials() {
}

public boolean validate() {
return type != null && issuer != null && credentials != null && !credentials.isEmpty() && credentials.stream().allMatch(CredentialObject::validate);
return type != null && issuer != null && credentials != null && !credentials.isEmpty() &&
credentials.stream().allMatch(CredentialObject::validate);
}

public static class CredentialObject {
@JsonProperty(value = "bindingMethods")
private final List<String> bindingMethods = new ArrayList<>();
@JsonProperty(value = "profiles")
private final Collection<String> profiles = new ArrayList<>();
@JsonProperty(value = "issuancePolicy")
private final Map<String, Object> issuancePolicy = new HashMap<>();
@JsonProperty(value = "type")
private String type;
@JsonProperty(value = "credentialType")
private String credentialType;
@JsonProperty(value = "offerReason")
private String offerReason;
@JsonProperty(value = "credentialSchema")
private String credentialSchema;

public List<String> getBindingMethods() {
return bindingMethods;
}

public Collection<String> getProfiles() {
return profiles;
}

public Map<String, Object> getIssuancePolicy() {
return issuancePolicy;
}

public String getType() {
return type;
}

public String getCredentialType() {
return credentialType;
}

public String getOfferReason() {
return offerReason;
}

public String getCredentialSchema() {
return credentialSchema;
}

public boolean validate() {
return type != null && credentialType != null;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/*
* Copyright (c) 2025 Metaform Systems Inc.
*
* This program and the accompanying materials are made available under the
* terms of the Apache License, Version 2.0 which is available at
* https://www.apache.org/licenses/LICENSE-2.0
*
* SPDX-License-Identifier: Apache-2.0
*
* Contributors:
* Metaform Systems Inc. - initial API and implementation
*
*/

package org.eclipse.dataspacetck.dcp.system.issuer;

public record CredentialDescriptor(String credentialType, String format) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/*
* Copyright (c) 2025 Metaform Systems Inc.
*
* This program and the accompanying materials are made available under the
* terms of the Apache License, Version 2.0 which is available at
* https://www.apache.org/licenses/LICENSE-2.0
*
* SPDX-License-Identifier: Apache-2.0
*
* Contributors:
* Metaform Systems Inc. - initial API and implementation
*
*/

package org.eclipse.dataspacetck.dcp.system.issuer;

public record CredentialObjectReference(String id) {
public boolean validate() {
return id != null;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public class CredentialRequestMessage {
private String holderPid;

@JsonProperty("credentials")
private Collection<CredentialDescriptor> credentials = new ArrayList<>();
private Collection<CredentialObjectReference> credentials = new ArrayList<>();

public String getType() {
return type;
Expand All @@ -37,14 +37,12 @@ public String getHolderPid() {
return holderPid;
}

public Collection<CredentialDescriptor> getCredentials() {
public Collection<CredentialObjectReference> getCredentials() {
return credentials;
}

public boolean validate() {
return type != null && holderPid != null && credentials != null && !credentials.isEmpty();
return type != null && holderPid != null && credentials != null && !credentials.isEmpty() && credentials.stream().allMatch(CredentialObjectReference::validate);
}

public record CredentialDescriptor(String credentialType, String format) {
}
}
Loading