-
Notifications
You must be signed in to change notification settings - Fork 244
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: create pluggable CredentialService url resolver (#3654)
* feat: create pluggable CredentialService url resolver * DEPENDENCIES
- Loading branch information
1 parent
906bc17
commit 66ded5e
Showing
7 changed files
with
212 additions
and
19 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
54 changes: 54 additions & 0 deletions
54
...vice/src/main/java/org/eclipse/edc/iam/identitytrust/DidCredentialServiceUrlResolver.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
/* | ||
* Copyright (c) 2023 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) | ||
* | ||
* 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: | ||
* Bayerische Motoren Werke Aktiengesellschaft (BMW AG) - initial API and implementation | ||
* | ||
*/ | ||
|
||
package org.eclipse.edc.iam.identitytrust; | ||
|
||
import org.eclipse.edc.iam.did.spi.resolution.DidResolverRegistry; | ||
import org.eclipse.edc.identitytrust.CredentialServiceUrlResolver; | ||
import org.eclipse.edc.spi.result.Result; | ||
|
||
import static org.eclipse.edc.spi.result.Result.failure; | ||
import static org.eclipse.edc.spi.result.Result.success; | ||
|
||
/** | ||
* Resolves the URL of the credential service based on the issuer's DID document. | ||
*/ | ||
public class DidCredentialServiceUrlResolver implements CredentialServiceUrlResolver { | ||
private static final String CREDENTIAL_SERVICE_TYPE = "CredentialService"; | ||
private final DidResolverRegistry didResolverRegistry; | ||
|
||
public DidCredentialServiceUrlResolver(DidResolverRegistry didResolverRegistry) { | ||
this.didResolverRegistry = didResolverRegistry; | ||
} | ||
|
||
/** | ||
* Resolves the IATP credential service URL from the DID document based on the issuer. The issuer is interpreted as DID | ||
* identifier, and the resolved DID is expected to contain a "CredentialServiceUrl" service endpoint. | ||
* | ||
* @param issuer The issuer of the DID document. | ||
* @return The result containing the service URL if found, or a failure if the DID was not resolvable, or if the required service endpoint wasn't found. | ||
*/ | ||
@Override | ||
public Result<String> resolve(String issuer) { | ||
var didDocument = didResolverRegistry.resolve(issuer); | ||
if (didDocument.failed()) { | ||
return didDocument.mapTo(); | ||
} | ||
return didDocument.getContent().getService().stream() | ||
.filter(s -> s.getType().equals(CREDENTIAL_SERVICE_TYPE)) | ||
.findFirst() | ||
.map(service -> success(service.getServiceEndpoint())) | ||
.orElseGet(() -> failure("No Service endpoint '%s' found on DID Document.".formatted(CREDENTIAL_SERVICE_TYPE))); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
82 changes: 82 additions & 0 deletions
82
.../src/test/java/org/eclipse/edc/iam/identitytrust/DidCredentialServiceUrlResolverTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
/* | ||
* Copyright (c) 2023 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) | ||
* | ||
* 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: | ||
* Bayerische Motoren Werke Aktiengesellschaft (BMW AG) - initial API and implementation | ||
* | ||
*/ | ||
|
||
package org.eclipse.edc.iam.identitytrust; | ||
|
||
import org.eclipse.edc.iam.did.spi.document.DidDocument; | ||
import org.eclipse.edc.iam.did.spi.document.Service; | ||
import org.eclipse.edc.iam.did.spi.resolution.DidResolverRegistry; | ||
import org.junit.jupiter.api.BeforeEach; | ||
import org.junit.jupiter.api.Test; | ||
|
||
import java.util.List; | ||
|
||
import static org.eclipse.edc.junit.assertions.AbstractResultAssert.assertThat; | ||
import static org.eclipse.edc.spi.result.Result.failure; | ||
import static org.eclipse.edc.spi.result.Result.success; | ||
import static org.mockito.ArgumentMatchers.any; | ||
import static org.mockito.Mockito.mock; | ||
import static org.mockito.Mockito.when; | ||
|
||
class DidCredentialServiceUrlResolverTest { | ||
|
||
public static final String CREDENTIAL_SERVICE_URL = "https://foo.bar/credentialservice"; | ||
private final DidResolverRegistry registryMock = mock(); | ||
private final DidCredentialServiceUrlResolver resolver = new DidCredentialServiceUrlResolver(registryMock); | ||
|
||
@BeforeEach | ||
void setup() { | ||
when(registryMock.resolve(any())).thenReturn(success(createDid().build())); | ||
} | ||
|
||
@Test | ||
void resolve() { | ||
assertThat(resolver.resolve("did:web:participant")).isSucceeded().isEqualTo(CREDENTIAL_SERVICE_URL); | ||
} | ||
|
||
@Test | ||
void resolve_didNotSupported() { | ||
when(registryMock.resolve(any())).thenReturn(failure("DID method not supported")); | ||
assertThat(resolver.resolve("did:web:participant")) | ||
.isFailed() | ||
.detail().isEqualTo("DID method not supported"); | ||
} | ||
|
||
@Test | ||
void resolve_didContainsNoServices() { | ||
var did = createDid().build(); | ||
did.getService().clear(); | ||
when(registryMock.resolve(any())).thenReturn(success(did)); | ||
assertThat(resolver.resolve("did:web:participant")) | ||
.isFailed() | ||
.detail().isEqualTo("No Service endpoint 'CredentialService' found on DID Document."); | ||
} | ||
|
||
@Test | ||
void resolve_serviceNotFound() { | ||
var did = createDid().build(); | ||
did.getService().clear(); | ||
did.getService().add(new Service("foo", "bar", "https://foo.bar")); | ||
when(registryMock.resolve(any())).thenReturn(success(did)); | ||
assertThat(resolver.resolve("did:web:participant")) | ||
.isFailed() | ||
.detail().isEqualTo("No Service endpoint 'CredentialService' found on DID Document."); | ||
} | ||
|
||
private DidDocument.Builder createDid() { | ||
return DidDocument.Builder.newInstance() | ||
.id("test-did") | ||
.service(List.of(new Service("test-service", "CredentialService", CREDENTIAL_SERVICE_URL))); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.