Skip to content

Commit

Permalink
feat: implement local DidPublisher (#198)
Browse files Browse the repository at this point in the history
  • Loading branch information
paullatzelsperger authored Dec 19, 2023
1 parent 3b92ab0 commit b67982c
Show file tree
Hide file tree
Showing 21 changed files with 992 additions and 35 deletions.
38 changes: 18 additions & 20 deletions DEPENDENCIES
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,9 @@ maven/mavencentral/com.github.stephenc.jcip/jcip-annotations/1.0-1, Apache-2.0,
maven/mavencentral/com.google.code.findbugs/jsr305/2.0.1, BSD-3-Clause AND CC-BY-2.5 AND LGPL-2.1+, approved, CQ13390
maven/mavencentral/com.google.code.findbugs/jsr305/3.0.2, Apache-2.0, approved, #20
maven/mavencentral/com.google.code.gson/gson/2.10.1, Apache-2.0, approved, #6159
maven/mavencentral/com.google.crypto.tink/tink/1.11.0, Apache-2.0, approved, #10719
maven/mavencentral/com.google.crypto.tink/tink/1.12.0, Apache-2.0, approved, #12041
maven/mavencentral/com.google.errorprone/error_prone_annotations/2.11.0, Apache-2.0, approved, clearlydefined
maven/mavencentral/com.google.errorprone/error_prone_annotations/2.18.0, Apache-2.0, approved, clearlydefined
maven/mavencentral/com.google.errorprone/error_prone_annotations/2.22.0, Apache-2.0, approved, #10661
maven/mavencentral/com.google.errorprone/error_prone_annotations/2.7.1, Apache-2.0, approved, clearlydefined
maven/mavencentral/com.google.guava/failureaccess/1.0.1, Apache-2.0, approved, CQ22654
maven/mavencentral/com.google.guava/guava/28.1-android, Apache-2.0, approved, clearlydefined
Expand All @@ -69,14 +69,13 @@ maven/mavencentral/com.google.guava/guava/31.0.1-jre, Apache-2.0, approved, clea
maven/mavencentral/com.google.guava/guava/31.1-jre, Apache-2.0, approved, clearlydefined
maven/mavencentral/com.google.guava/listenablefuture/9999.0-empty-to-avoid-conflict-with-guava, Apache-2.0, approved, CQ22657
maven/mavencentral/com.google.j2objc/j2objc-annotations/1.3, Apache-2.0, approved, CQ21195
maven/mavencentral/com.google.protobuf/protobuf-java/3.19.6, BSD-3-Clause, approved, clearlydefined
maven/mavencentral/com.google.protobuf/protobuf-java/3.24.3, BSD-3-Clause, approved, clearlydefined
maven/mavencentral/com.googlecode.libphonenumber/libphonenumber/8.11.1, Apache-2.0, approved, clearlydefined
maven/mavencentral/com.jayway.jsonpath/json-path/2.7.0, Apache-2.0, approved, clearlydefined
maven/mavencentral/com.jcraft/jzlib/1.1.3, BSD-2-Clause, approved, CQ6218
maven/mavencentral/com.lmax/disruptor/3.4.4, Apache-2.0, approved, clearlydefined
maven/mavencentral/com.networknt/json-schema-validator/1.0.76, Apache-2.0, approved, CQ22638
maven/mavencentral/com.nimbusds/nimbus-jose-jwt/9.28, Apache-2.0, approved, clearlydefined
maven/mavencentral/com.nimbusds/nimbus-jose-jwt/9.37, Apache-2.0, approved, #11701
maven/mavencentral/com.nimbusds/nimbus-jose-jwt/9.37.3, Apache-2.0, approved, #11701
maven/mavencentral/com.puppycrawl.tools/checkstyle/10.0, LGPL-2.1-or-later, approved, #7936
maven/mavencentral/com.samskivert/jmustache/1.15, BSD-2-Clause, approved, clearlydefined
Expand Down Expand Up @@ -124,11 +123,10 @@ maven/mavencentral/io.prometheus/simpleclient_httpserver/0.16.0, Apache-2.0, app
maven/mavencentral/io.prometheus/simpleclient_tracer_common/0.16.0, Apache-2.0, approved, clearlydefined
maven/mavencentral/io.prometheus/simpleclient_tracer_otel/0.16.0, Apache-2.0, approved, clearlydefined
maven/mavencentral/io.prometheus/simpleclient_tracer_otel_agent/0.16.0, Apache-2.0, approved, clearlydefined
maven/mavencentral/io.rest-assured/json-path/5.4.0, , restricted, clearlydefined
maven/mavencentral/io.rest-assured/rest-assured-common/5.4.0, , restricted, clearlydefined
maven/mavencentral/io.rest-assured/rest-assured/5.3.2, Apache-2.0, approved, #9262
maven/mavencentral/io.rest-assured/rest-assured/5.4.0, , restricted, clearlydefined
maven/mavencentral/io.rest-assured/xml-path/5.4.0, , restricted, clearlydefined
maven/mavencentral/io.rest-assured/json-path/5.4.0, Apache-2.0, approved, #12042
maven/mavencentral/io.rest-assured/rest-assured-common/5.4.0, Apache-2.0, approved, #12039
maven/mavencentral/io.rest-assured/rest-assured/5.4.0, Apache-2.0, approved, #12040
maven/mavencentral/io.rest-assured/xml-path/5.4.0, Apache-2.0, approved, #12038
maven/mavencentral/io.setl/rdf-urdna/1.1, Apache-2.0, approved, clearlydefined
maven/mavencentral/io.swagger.core.v3/swagger-annotations-jakarta/2.2.15, Apache-2.0, approved, #5947
maven/mavencentral/io.swagger.core.v3/swagger-annotations-jakarta/2.2.18, Apache-2.0, approved, #5947
Expand Down Expand Up @@ -215,7 +213,7 @@ maven/mavencentral/org.bouncycastle/bcutil-jdk18on/1.72, MIT, approved, #3790
maven/mavencentral/org.bouncycastle/bcutil-jdk18on/1.77, MIT, approved, #11596
maven/mavencentral/org.ccil.cowan.tagsoup/tagsoup/1.2.1, Apache-2.0, approved, clearlydefined
maven/mavencentral/org.checkerframework/checker-qual/3.12.0, MIT, approved, clearlydefined
maven/mavencentral/org.checkerframework/checker-qual/3.31.0, MIT, approved, clearlydefined
maven/mavencentral/org.checkerframework/checker-qual/3.41.0, MIT, approved, #12032
maven/mavencentral/org.eclipse.angus/angus-activation/1.0.0, EPL-2.0 OR GPL-2.0-only with Classpath-exception-2.0, approved, ee4j.angus
maven/mavencentral/org.eclipse.edc/api-observability/0.4.2-SNAPSHOT, Apache-2.0, approved, technology.edc
maven/mavencentral/org.eclipse.edc/autodoc-processor/0.4.2-SNAPSHOT, Apache-2.0, approved, technology.edc
Expand Down Expand Up @@ -290,15 +288,15 @@ maven/mavencentral/org.glassfish.hk2/hk2-api/3.0.5, EPL-2.0 OR GPL-2.0-only with
maven/mavencentral/org.glassfish.hk2/hk2-locator/3.0.5, EPL-2.0 OR GPL-2.0-only with Classpath-exception-2.0, approved, ee4j.glassfish
maven/mavencentral/org.glassfish.hk2/hk2-utils/3.0.5, EPL-2.0 OR GPL-2.0-only with Classpath-exception-2.0, approved, ee4j.glassfish
maven/mavencentral/org.glassfish.hk2/osgi-resource-locator/1.0.3, CDDL-1.0, approved, CQ10889
maven/mavencentral/org.glassfish.jersey.containers/jersey-container-servlet-core/3.1.4, EPL-2.0 OR GPL-2.0-only with Classpath-exception-2.0, approved, ee4j.jersey
maven/mavencentral/org.glassfish.jersey.containers/jersey-container-servlet/3.1.4, EPL-2.0 OR GPL-2.0-only with Classpath-exception-2.0, approved, ee4j.jersey
maven/mavencentral/org.glassfish.jersey.core/jersey-client/3.1.4, EPL-2.0 OR GPL-2.0-only with Classpath-exception-2.0, approved, ee4j.jersey
maven/mavencentral/org.glassfish.jersey.core/jersey-common/3.1.4, EPL-2.0 OR GPL-2.0-only with Classpath-exception-2.0, approved, ee4j.jersey
maven/mavencentral/org.glassfish.jersey.core/jersey-server/3.1.4, EPL-2.0 OR GPL-2.0-only with Classpath-exception-2.0, approved, ee4j.jersey
maven/mavencentral/org.glassfish.jersey.ext/jersey-entity-filtering/3.1.4, EPL-2.0 OR GPL-2.0-only with Classpath-exception-2.0, approved, ee4j.jersey
maven/mavencentral/org.glassfish.jersey.inject/jersey-hk2/3.1.4, EPL-2.0 OR GPL-2.0-only with Classpath-exception-2.0, approved, ee4j.jersey
maven/mavencentral/org.glassfish.jersey.media/jersey-media-json-jackson/3.1.4, EPL-2.0 OR GPL-2.0-only with Classpath-exception-2.0, approved, ee4j.jersey
maven/mavencentral/org.glassfish.jersey.media/jersey-media-multipart/3.1.4, EPL-2.0 OR GPL-2.0-only with Classpath-exception-2.0, approved, ee4j.jersey
maven/mavencentral/org.glassfish.jersey.containers/jersey-container-servlet-core/3.1.5, EPL-2.0 OR GPL-2.0-only with Classpath-exception-2.0, approved, ee4j.jersey
maven/mavencentral/org.glassfish.jersey.containers/jersey-container-servlet/3.1.5, EPL-2.0 OR GPL-2.0-only with Classpath-exception-2.0, approved, ee4j.jersey
maven/mavencentral/org.glassfish.jersey.core/jersey-client/3.1.5, EPL-2.0 OR GPL-2.0-only with Classpath-exception-2.0, approved, ee4j.jersey
maven/mavencentral/org.glassfish.jersey.core/jersey-common/3.1.5, EPL-2.0 OR GPL-2.0-only with Classpath-exception-2.0, approved, ee4j.jersey
maven/mavencentral/org.glassfish.jersey.core/jersey-server/3.1.5, EPL-2.0 OR GPL-2.0-only with Classpath-exception-2.0, approved, ee4j.jersey
maven/mavencentral/org.glassfish.jersey.ext/jersey-entity-filtering/3.1.5, EPL-2.0 OR GPL-2.0-only with Classpath-exception-2.0, approved, ee4j.jersey
maven/mavencentral/org.glassfish.jersey.inject/jersey-hk2/3.1.5, EPL-2.0 OR GPL-2.0-only with Classpath-exception-2.0, approved, ee4j.jersey
maven/mavencentral/org.glassfish.jersey.media/jersey-media-json-jackson/3.1.5, EPL-2.0 OR GPL-2.0-only with Classpath-exception-2.0, approved, ee4j.jersey
maven/mavencentral/org.glassfish.jersey.media/jersey-media-multipart/3.1.5, EPL-2.0 OR GPL-2.0-only with Classpath-exception-2.0, approved, ee4j.jersey
maven/mavencentral/org.glassfish/jakarta.json/2.0.1, EPL-2.0 OR GPL-2.0-only with Classpath-exception-2.0, approved, ee4j.jsonp
maven/mavencentral/org.hamcrest/hamcrest-core/1.3, BSD-2-Clause, approved, CQ11429
maven/mavencentral/org.hamcrest/hamcrest-core/2.2, BSD-3-Clause, approved, clearlydefined
Expand Down Expand Up @@ -344,7 +342,7 @@ maven/mavencentral/org.ow2.asm/asm-tree/9.6, BSD-3-Clause, approved, #10773
maven/mavencentral/org.ow2.asm/asm/9.1, BSD-3-Clause, approved, CQ23029
maven/mavencentral/org.ow2.asm/asm/9.2, BSD-3-Clause, approved, CQ23635
maven/mavencentral/org.ow2.asm/asm/9.6, BSD-3-Clause, approved, #10776
maven/mavencentral/org.postgresql/postgresql/42.7.0, BSD-2-Clause AND Apache-2.0, approved, #11681
maven/mavencentral/org.postgresql/postgresql/42.7.1, BSD-2-Clause AND Apache-2.0, approved, #11681
maven/mavencentral/org.reflections/reflections/0.10.2, Apache-2.0 AND WTFPL, approved, clearlydefined
maven/mavencentral/org.rnorth.duct-tape/duct-tape/1.0.8, MIT, approved, clearlydefined
maven/mavencentral/org.slf4j/slf4j-api/1.7.22, MIT, approved, CQ11943
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,38 +34,37 @@
import org.eclipse.edc.web.jersey.jsonld.ObjectMapperProvider;
import org.eclipse.edc.web.spi.WebService;

import static org.eclipse.edc.identityservice.api.PresentationApiExtension.NAME;
import static org.eclipse.edc.spi.CoreConstants.JSON_LD;

@Extension(value = "Presentation API Extension")
@Extension(value = NAME)
public class PresentationApiExtension implements ServiceExtension {

public static final String NAME = "Presentation API Extension";
public static final String RESOLUTION_SCOPE = "resolution-scope";
public static final String RESOLUTION_CONTEXT = "resolution";

@Inject
private TypeTransformerRegistry typeTransformer;

@Inject
private JsonObjectValidatorRegistry validatorRegistry;

@Inject
private WebService webService;

@Inject
private AccessTokenVerifier accessTokenVerifier;

@Inject
private CredentialQueryResolver credentialResolver;

@Inject
private VerifiablePresentationService verifiablePresentationService;

@Inject
private JsonLd jsonLd;

@Inject
private TypeManager typeManager;

@Override
public String name() {
return NAME;
}

@Override
public void initialize(ServiceExtensionContext context) {
// setup validator
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*
* Copyright (c) 2023 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.edc.identityhub.did;

import org.eclipse.edc.identithub.did.spi.DidDocumentPublisher;
import org.eclipse.edc.identithub.did.spi.DidDocumentPublisherRegistry;

import java.util.HashMap;
import java.util.Map;

/**
* In-mem variant of the publisher registry.
*/
public class DidDocumentPublisherRegistryImpl implements DidDocumentPublisherRegistry {
private final Map<String, DidDocumentPublisher> publishers = new HashMap<>();


@Override
public void addPublisher(String didMethodName, DidDocumentPublisher publisher) {
publishers.put(didMethodName, publisher);
}

@Override
public DidDocumentPublisher getPublisher(String did) {
return publishers.get(did);
}

@Override
public boolean canPublish(String did) {
return publishers.containsKey(did);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,24 @@

package org.eclipse.edc.identityhub.did;

import org.eclipse.edc.identithub.did.spi.DidDocumentPublisherRegistry;
import org.eclipse.edc.runtime.metamodel.annotation.Extension;
import org.eclipse.edc.runtime.metamodel.annotation.Provider;
import org.eclipse.edc.spi.system.ServiceExtension;

import static org.eclipse.edc.identityhub.did.DidServicesExtension.NAME;

@Extension(value = NAME)
public class DidServicesExtension implements ServiceExtension {
public static final String NAME = "DID Service Extension";

@Override
public String name() {
return NAME;
}

@Provider
public DidDocumentPublisherRegistry createRegistry() {
return new DidDocumentPublisherRegistryImpl();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,11 @@
public class DidDefaultServicesExtension implements ServiceExtension {
public static final String NAME = "DID Default Services Extension";

@Override
public String name() {
return NAME;
}

@Provider(isDefault = true)
public DidResourceStore createInMemoryDidResourceStore() {
return new InMemoryDidResourceStore();
Expand Down
32 changes: 32 additions & 0 deletions extensions/did/local-did-publisher/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*
* Copyright (c) 2023 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
*
*/

plugins {
`java-library`
`java-test-fixtures`
`maven-publish`
}

val swagger: String by project

dependencies {

api(project(":spi:identity-hub-did-spi"))
implementation(libs.jakarta.rsApi)
implementation(libs.edc.spi.web)

testImplementation(libs.edc.junit)
testImplementation(libs.restAssured)
testImplementation(testFixtures(libs.edc.core.jersey))
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
/*
* Copyright (c) 2023 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.edc.identityhub.publisher.did.local;

import jakarta.ws.rs.Consumes;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.container.ContainerRequestContext;
import jakarta.ws.rs.core.Context;
import org.eclipse.edc.iam.did.spi.document.DidDocument;
import org.eclipse.edc.identithub.did.spi.DidWebParser;
import org.eclipse.edc.identithub.did.spi.model.DidResource;
import org.eclipse.edc.identithub.did.spi.model.DidState;
import org.eclipse.edc.identithub.did.spi.store.DidResourceStore;
import org.eclipse.edc.spi.monitor.Monitor;
import org.eclipse.edc.spi.query.Criterion;
import org.eclipse.edc.spi.query.QuerySpec;
import org.eclipse.edc.web.spi.exception.InvalidRequestException;

import java.nio.charset.Charset;
import java.util.Optional;
import java.util.regex.Pattern;

import static jakarta.ws.rs.core.HttpHeaders.CONTENT_TYPE;
import static jakarta.ws.rs.core.MediaType.APPLICATION_JSON;

@Consumes(APPLICATION_JSON)
@Produces(APPLICATION_JSON)
@Path("{any:.*}")
public class DidWebController {
private static final Charset DEFAULT_CHARSET = Charset.defaultCharset();
private static final Pattern CHARSET_REGEX_PATTERN = Pattern.compile("(?i)\\bcharset=\\s*\"?([^\\s;\"]*)");
private final Monitor monitor;
private final DidResourceStore didResourceStore;
private final DidWebParser didWebParser;

public DidWebController(Monitor monitor, DidResourceStore didResourceStore, DidWebParser didWebParser) {
this.monitor = monitor;
this.didResourceStore = didResourceStore;
this.didWebParser = didWebParser;
}

@GET
public DidDocument getDidDocument(@Context ContainerRequestContext context) {

var httpUrl = context.getUriInfo().getAbsolutePath();

var charset = extractCharset(context.getHeaderString(CONTENT_TYPE));
String did;
did = didWebParser.parse(httpUrl, charset);


var q = QuerySpec.Builder.newInstance()
.filter(new Criterion("state", "=", DidState.PUBLISHED.code()))
.filter(new Criterion("did", "=", did))
.build();

monitor.debug("Looking up '%s'".formatted(did));
var dids = didResourceStore.query(q)
.stream()
.map(DidResource::getDocument)
.toList();

if (dids.size() > 1) {
throw new InvalidRequestException("DID '%s' resolved more than one document".formatted(did));
}

return dids.stream().findFirst().orElse(null);
}

private Charset extractCharset(String contentType) {
return Optional.ofNullable(contentType)
.map(this::parseCharsetFromContentType)
.orElse(DEFAULT_CHARSET);
}

/**
* Parses the "charset" attribute from the Content-Type header. Returns the value of the charset attribute,
* or {@link Charset#defaultCharset()} if the attribute was not present or represents an invalid charset
*
* @param contentType The Content-Type header
* @return The value of the charset attribute or the default charset
*/
private Charset parseCharsetFromContentType(String contentType) {
var m = CHARSET_REGEX_PATTERN.matcher(contentType);
if (m.find()) {
var cs = m.group(1).trim().toUpperCase();
if (Charset.isSupported(cs)) {
return Charset.forName(cs);
} else {
monitor.warning("Charset '%s' is not supported, defaulting to %s".formatted(cs, DEFAULT_CHARSET));
return DEFAULT_CHARSET;
}
}
return DEFAULT_CHARSET;
}
}
Loading

0 comments on commit b67982c

Please sign in to comment.