Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: adds support for dcp v1.0 in default credential service client #4780

Merged
Show file tree
Hide file tree
Changes from all 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
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import org.eclipse.edc.iam.identitytrust.spi.SecureTokenService;
import org.eclipse.edc.iam.identitytrust.spi.validation.TokenValidationAction;
import org.eclipse.edc.iam.identitytrust.spi.verification.SignatureSuiteRegistry;
import org.eclipse.edc.iam.identitytrust.transform.to.JsonObjectToPresentationResponseMessageTransformer;
import org.eclipse.edc.iam.verifiablecredentials.VerifiableCredentialValidationServiceImpl;
import org.eclipse.edc.iam.verifiablecredentials.revocation.bitstring.BitstringStatusListRevocationService;
import org.eclipse.edc.iam.verifiablecredentials.revocation.statuslist2021.StatusList2021RevocationService;
Expand All @@ -37,6 +38,7 @@
import org.eclipse.edc.iam.verifiablecredentials.spi.validation.PresentationVerifier;
import org.eclipse.edc.iam.verifiablecredentials.spi.validation.TrustedIssuerRegistry;
import org.eclipse.edc.jsonld.spi.JsonLd;
import org.eclipse.edc.jsonld.spi.JsonLdNamespace;
import org.eclipse.edc.jwt.validation.jti.JtiValidationStore;
import org.eclipse.edc.participant.spi.ParticipantAgentService;
import org.eclipse.edc.runtime.metamodel.annotation.Extension;
Expand Down Expand Up @@ -70,6 +72,10 @@
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;

import static org.eclipse.edc.iam.identitytrust.spi.DcpConstants.DCP_CONTEXT_URL;
import static org.eclipse.edc.iam.identitytrust.spi.DcpConstants.DSPACE_DCP_NAMESPACE_V_0_8;
import static org.eclipse.edc.iam.identitytrust.spi.DcpConstants.DSPACE_DCP_NAMESPACE_V_1_0;
import static org.eclipse.edc.iam.identitytrust.spi.DcpConstants.DSPACE_DCP_V_1_0_CONTEXT;
import static org.eclipse.edc.iam.verifiablecredentials.spi.VcConstants.STATUSLIST_2021_URL;
import static org.eclipse.edc.spi.constants.CoreConstants.JSON_LD;
import static org.eclipse.edc.verifiablecredentials.jwt.JwtPresentationVerifier.JWT_VC_TOKEN_CONTEXT;
Expand All @@ -79,6 +85,7 @@ public class IdentityAndTrustExtension implements ServiceExtension {

public static final long DEFAULT_REVOCATION_CACHE_VALIDITY_MILLIS = 15 * 60 * 1000L;
public static final String DCP_SELF_ISSUED_TOKEN_CONTEXT = "dcp-si";
public static final String DCP_CLIENT_CONTEXT = "dcp-client";
public static final String JSON_2020_SIGNATURE_SUITE = "JsonWebSignature2020";
public static final long DEFAULT_CLEANUP_PERIOD_SECONDS = 60;
@Setting(description = "Validity period of cached StatusList2021 credential entries in milliseconds.", defaultValue = DEFAULT_REVOCATION_CACHE_VALIDITY_MILLIS + "", key = "edc.iam.credential.revocation.cache.validity")
Expand All @@ -87,6 +94,10 @@ public class IdentityAndTrustExtension implements ServiceExtension {
private String issuerId;
@Setting(description = "The period of the JTI entry reaper thread in seconds", defaultValue = DEFAULT_CLEANUP_PERIOD_SECONDS + "", key = "edc.sql.store.jti.cleanup.period")
private long reaperCleanupPeriod;

@Setting(description = "If set enable the dcp v0.8 namespace will be used", key = "edc.dcp.v08.forced", required = false, defaultValue = "false")
private boolean enableDcpV08;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

minor nit: i would call that property edc.dcp.v08.forced, since we're "forcing" (rather than "enabling) the v0.8 namespace.


@Inject
private SecureTokenService secureTokenService;

Expand Down Expand Up @@ -201,8 +212,13 @@ public IdentityService createIdentityService(ServiceExtensionContext context) {
@Provider
public CredentialServiceClient getCredentialServiceClient(ServiceExtensionContext context) {
if (credentialServiceClient == null) {

var clientTypeTransformerRegistry = typeTransformerRegistry.forContext(DCP_CLIENT_CONTEXT);
clientTypeTransformerRegistry.register(new JsonObjectToPresentationResponseMessageTransformer(typeManager, JSON_LD, dcpNamespace()));


credentialServiceClient = new DefaultCredentialServiceClient(httpClient, Json.createBuilderFactory(Map.of()),
typeManager, JSON_LD, typeTransformerRegistry, jsonLd, context.getMonitor());
typeManager, JSON_LD, clientTypeTransformerRegistry, jsonLd, context.getMonitor(), dcpContext());
}
return credentialServiceClient;
}
Expand All @@ -225,6 +241,13 @@ public PresentationVerifier createPresentationVerifier(ServiceExtensionContext c
return presentationVerifier;
}

private JsonLdNamespace dcpNamespace() {
return enableDcpV08 ? DSPACE_DCP_NAMESPACE_V_0_8 : DSPACE_DCP_NAMESPACE_V_1_0;
}

private String dcpContext() {
return enableDcpV08 ? DCP_CONTEXT_URL : DSPACE_DCP_V_1_0_CONTEXT;
}

@NotNull
private TokenValidationAction tokenValidationAction() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
import okhttp3.RequestBody;
import org.eclipse.edc.http.spi.EdcHttpClient;
import org.eclipse.edc.iam.identitytrust.spi.CredentialServiceClient;
import org.eclipse.edc.iam.identitytrust.spi.DcpConstants;
import org.eclipse.edc.iam.identitytrust.spi.model.PresentationQueryMessage;
import org.eclipse.edc.iam.identitytrust.spi.model.PresentationResponseMessage;
import org.eclipse.edc.iam.verifiablecredentials.spi.VcConstants;
Expand Down Expand Up @@ -55,15 +54,17 @@ public class DefaultCredentialServiceClient implements CredentialServiceClient {
private final TypeTransformerRegistry transformerRegistry;
private final JsonLd jsonLd;
private final Monitor monitor;
private final String dcpContextUrl;

public DefaultCredentialServiceClient(EdcHttpClient httpClient, JsonBuilderFactory jsonFactory, TypeManager typeManager, String typeContext, TypeTransformerRegistry transformerRegistry, JsonLd jsonLd, Monitor monitor) {
public DefaultCredentialServiceClient(EdcHttpClient httpClient, JsonBuilderFactory jsonFactory, TypeManager typeManager, String typeContext, TypeTransformerRegistry transformerRegistry, JsonLd jsonLd, Monitor monitor, String dcpContextUrl) {
this.httpClient = httpClient;
this.jsonFactory = jsonFactory;
this.typeManager = typeManager;
this.typeContext = typeContext;
this.transformerRegistry = transformerRegistry;
this.jsonLd = jsonLd;
this.monitor = monitor;
this.dcpContextUrl = dcpContextUrl;
}

@Override
Expand Down Expand Up @@ -154,7 +155,7 @@ private JsonObject createPresentationQuery(List<String> scopes) {
return jsonFactory.createObjectBuilder()
.add(JsonLdKeywords.CONTEXT, jsonFactory.createArrayBuilder()
.add(VcConstants.PRESENTATION_EXCHANGE_URL)
.add(DcpConstants.DCP_CONTEXT_URL))
.add(dcpContextUrl))
.add(JsonLdKeywords.TYPE, PresentationQueryMessage.PRESENTATION_QUERY_MESSAGE_TERM)
.add("scope", scopeArray.build())
.build();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import org.eclipse.edc.spi.system.ServiceExtensionContext;
import org.eclipse.edc.spi.system.configuration.ConfigFactory;
import org.eclipse.edc.spi.types.TypeManager;
import org.eclipse.edc.transform.spi.TypeTransformerRegistry;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
Expand All @@ -33,6 +34,7 @@

import static org.assertj.core.api.Assertions.assertThat;
import static org.awaitility.Awaitility.await;
import static org.eclipse.edc.iam.identitytrust.core.IdentityAndTrustExtension.DCP_CLIENT_CONTEXT;
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
Expand All @@ -44,19 +46,22 @@ class IdentityAndTrustExtensionTest {
private static final String CONNECTOR_DID_PROPERTY = "edc.iam.issuer.id";
private static final String CLEANUP_PERIOD = "edc.sql.store.jti.cleanup.period";
private final JtiValidationStore storeMock = mock();
private final TypeTransformerRegistry transformerRegistry = mock();

@BeforeEach
void setUp(ServiceExtensionContext context) {
context.registerService(SecureTokenService.class, mock());
context.registerService(TypeManager.class, new JacksonTypeManager());
context.registerService(JtiValidationStore.class, storeMock);
context.registerService(ExecutorInstrumentation.class, ExecutorInstrumentation.noop());
context.registerService(TypeTransformerRegistry.class, transformerRegistry);

var config = ConfigFactory.fromMap(Map.of(
CONNECTOR_DID_PROPERTY, "did:web:test",
CLEANUP_PERIOD, "1"
));
when(context.getConfig()).thenReturn(config);
when(transformerRegistry.forContext(DCP_CLIENT_CONTEXT)).thenReturn(transformerRegistry);
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@
import java.util.Objects;

import static org.assertj.core.api.Assertions.assertThat;
import static org.eclipse.edc.iam.identitytrust.spi.DcpConstants.DSPACE_DCP_V_1_0_CONTEXT;
import static org.eclipse.edc.junit.testfixtures.TestUtils.getResourceFileContentAsString;
import static org.eclipse.edc.spi.result.Result.success;
import static org.mockito.ArgumentMatchers.any;
Expand Down Expand Up @@ -96,7 +97,7 @@ void setup() {
var jsonLdMock = mock(JsonLd.class);
when(jsonLdMock.expand(any())).thenAnswer(a -> success(a.getArgument(0)));
client = new DefaultCredentialServiceClient(httpClientMock, Json.createBuilderFactory(Map.of()),
typeManager, "test", transformerRegistry, jsonLdMock, mock());
typeManager, "test", transformerRegistry, jsonLdMock, mock(), DSPACE_DCP_V_1_0_CONTEXT);

when(typeManager.getMapper("test")).thenReturn(JacksonJsonLd.createObjectMapper());
}
Expand Down