-
Notifications
You must be signed in to change notification settings - Fork 29
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Add issuance process core services (#546)
* Add issuance process core services * Add modules settings * Add missing annotation * Fix checkstyle
- Loading branch information
Showing
42 changed files
with
2,060 additions
and
0 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
/* | ||
* Copyright (c) 2025 Cofinity-X | ||
* | ||
* 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 | ||
* | ||
*/ | ||
|
||
plugins { | ||
`java-library` | ||
`java-test-fixtures` | ||
`maven-publish` | ||
} | ||
|
||
dependencies { | ||
api(project(":spi:issuance-credentials-spi")) | ||
api(libs.edc.spi.core) | ||
|
||
implementation(libs.edc.spi.validator) | ||
|
||
testImplementation(libs.edc.lib.json) | ||
|
||
testFixturesImplementation(libs.edc.spi.identity.did) | ||
testFixturesImplementation(libs.junit.jupiter.api) | ||
testFixturesImplementation(libs.edc.junit) | ||
testFixturesImplementation(libs.assertj) | ||
} |
73 changes: 73 additions & 0 deletions
73
...org/eclipse/edc/identityhub/issuance/credentials/attestation/AttestationPipelineImpl.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,73 @@ | ||
/* | ||
* Copyright (c) 2025 Cofinity-X | ||
* | ||
* 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: | ||
* Cofinity-X - initial API and implementation | ||
* | ||
*/ | ||
|
||
package org.eclipse.edc.identityhub.issuance.credentials.attestation; | ||
|
||
import org.eclipse.edc.identityhub.spi.issuance.credentials.attestation.AttestationContext; | ||
import org.eclipse.edc.identityhub.spi.issuance.credentials.attestation.AttestationDefinitionStore; | ||
import org.eclipse.edc.identityhub.spi.issuance.credentials.attestation.AttestationPipeline; | ||
import org.eclipse.edc.identityhub.spi.issuance.credentials.attestation.AttestationSourceFactory; | ||
import org.eclipse.edc.identityhub.spi.issuance.credentials.attestation.AttestationSourceFactoryRegistry; | ||
import org.eclipse.edc.identityhub.spi.issuance.credentials.model.AttestationDefinition; | ||
import org.eclipse.edc.spi.result.Result; | ||
|
||
import java.util.HashMap; | ||
import java.util.Map; | ||
import java.util.Set; | ||
|
||
import static java.util.Objects.requireNonNull; | ||
|
||
/** | ||
* Holds registered {@link AttestationSourceFactory}s that performs attestation pipeline evaluations. | ||
*/ | ||
public class AttestationPipelineImpl implements AttestationPipeline, AttestationSourceFactoryRegistry { | ||
private Map<String, AttestationSourceFactory> factories = new HashMap<>(); | ||
private AttestationDefinitionStore store; | ||
|
||
public AttestationPipelineImpl(AttestationDefinitionStore store) { | ||
this.store = store; | ||
} | ||
|
||
@Override | ||
public Set<String> registeredTypes() { | ||
return factories.keySet(); | ||
} | ||
|
||
@Override | ||
public void registerFactory(String type, AttestationSourceFactory factory) { | ||
factories.put(type, factory); | ||
} | ||
|
||
@Override | ||
public Result<Map<String, Object>> evaluate(Set<String> attestations, AttestationContext context) { | ||
var collated = new HashMap<String, Object>(); | ||
for (var attestationId : attestations) { | ||
// if the attestation is not found it is a programming error | ||
var definition = requireNonNull(store.resolveDefinition(attestationId), "Unknown attestation: " + attestationId); | ||
var result = execute(definition, context); | ||
if (result.failed()) { | ||
return result; | ||
} | ||
collated.putAll(result.getContent()); | ||
} | ||
return Result.success(collated); | ||
} | ||
|
||
private Result<Map<String, Object>> execute(AttestationDefinition definition, AttestationContext context) { | ||
var factory = requireNonNull(factories.get(definition.attestationType()), "Unknown attestation type: " + definition.attestationType()); | ||
return requireNonNull(factory.createSource(definition), "Invalid definition for type: " + definition.attestationType()).execute(context); | ||
} | ||
} | ||
|
||
|
50 changes: 50 additions & 0 deletions
50
...g/eclipse/edc/identityhub/issuance/credentials/attestation/DefaultAttestationContext.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,50 @@ | ||
/* | ||
* Copyright (c) 2025 Cofinity-X | ||
* | ||
* 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: | ||
* Cofinity-X - initial API and implementation | ||
* | ||
*/ | ||
|
||
package org.eclipse.edc.identityhub.issuance.credentials.attestation; | ||
|
||
import org.eclipse.edc.identityhub.spi.issuance.credentials.attestation.AttestationContext; | ||
import org.eclipse.edc.spi.iam.ClaimToken; | ||
import org.jetbrains.annotations.Nullable; | ||
|
||
import java.util.Map; | ||
|
||
import static java.util.Objects.requireNonNull; | ||
|
||
/** | ||
* Default context. | ||
*/ | ||
public class DefaultAttestationContext implements AttestationContext { | ||
private Map<String, ClaimToken> claims; | ||
private String participantId; | ||
|
||
@Override | ||
public @Nullable ClaimToken getClaimToken(String type) { | ||
return claims.get(type); | ||
} | ||
|
||
@Override | ||
public String participantId() { | ||
return participantId; | ||
} | ||
|
||
public Map<String, ClaimToken> getClaims() { | ||
return claims; | ||
} | ||
|
||
public DefaultAttestationContext(String participantId, Map<String, ClaimToken> claims) { | ||
this.participantId = requireNonNull(participantId, "participantId"); | ||
this.claims = requireNonNull(claims, "claims"); | ||
} | ||
} |
50 changes: 50 additions & 0 deletions
50
...ntityhub/issuance/credentials/attestation/presentation/PresentationAttestationSource.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,50 @@ | ||
/* | ||
* Copyright (c) 2025 Cofinity-X | ||
* | ||
* 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: | ||
* Cofinity-X - initial API and implementation | ||
* | ||
*/ | ||
|
||
package org.eclipse.edc.identityhub.issuance.credentials.attestation.presentation; | ||
|
||
import org.eclipse.edc.identityhub.spi.issuance.credentials.attestation.AttestationContext; | ||
import org.eclipse.edc.identityhub.spi.issuance.credentials.attestation.AttestationSource; | ||
import org.eclipse.edc.spi.result.Result; | ||
|
||
import java.util.Map; | ||
|
||
import static java.util.Collections.emptyMap; | ||
import static java.util.Objects.requireNonNull; | ||
import static org.eclipse.edc.spi.result.Result.failure; | ||
import static org.eclipse.edc.spi.result.Result.success; | ||
|
||
/** | ||
* Resolves an attestation that is a verifiable presentation. | ||
*/ | ||
public class PresentationAttestationSource implements AttestationSource { | ||
private final String claimType; | ||
private final String outputClaim; | ||
private final boolean required; | ||
|
||
public PresentationAttestationSource(String claimType, String outputClaim, boolean required) { | ||
this.claimType = requireNonNull(claimType, "claimType"); | ||
this.outputClaim = requireNonNull(outputClaim, "outputClaim"); | ||
this.required = required; | ||
} | ||
|
||
@Override | ||
public Result<Map<String, Object>> execute(AttestationContext context) { | ||
var claimToken = context.getClaimToken(claimType); | ||
if (claimToken == null) { | ||
return !required ? success(emptyMap()) : failure("Claim token not found"); | ||
} | ||
return success(Map.of(outputClaim, claimToken.getClaims())); | ||
} | ||
} |
50 changes: 50 additions & 0 deletions
50
...b/issuance/credentials/attestation/presentation/PresentationAttestationSourceFactory.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,50 @@ | ||
/* | ||
* Copyright (c) 2025 Cofinity-X | ||
* | ||
* 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: | ||
* Cofinity-X - initial API and implementation | ||
* | ||
*/ | ||
|
||
package org.eclipse.edc.identityhub.issuance.credentials.attestation.presentation; | ||
|
||
import org.eclipse.edc.identityhub.spi.issuance.credentials.attestation.AttestationSource; | ||
import org.eclipse.edc.identityhub.spi.issuance.credentials.attestation.AttestationSourceFactory; | ||
import org.eclipse.edc.identityhub.spi.issuance.credentials.model.AttestationDefinition; | ||
|
||
/** | ||
* Creates an attestation source that requires a verifiable credential. | ||
* <p> | ||
* Example configuration is: | ||
* <pre> | ||
* { | ||
* "id": "123", | ||
* "attestationType": "presentation", | ||
* "configuration": { | ||
* "credentialType": "https://example.com/ExampleCredential", | ||
* "required": true, | ||
* "outputClaim": "exampleCredential" | ||
* } | ||
* } | ||
* </pre> | ||
*/ | ||
public class PresentationAttestationSourceFactory implements AttestationSourceFactory { | ||
private static final String CREDENTIAL_TYPE = "credentialType"; | ||
private static final String OUTPUT_CLAIM = "outputClaim"; | ||
private static final String REQUIRED = "required"; | ||
|
||
@Override | ||
public AttestationSource createSource(AttestationDefinition definition) { | ||
var configuration = definition.configuration(); | ||
var credentialType = (String) configuration.get(CREDENTIAL_TYPE); | ||
var outputClaim = (String) configuration.get(OUTPUT_CLAIM); | ||
var required = (Boolean) configuration.getOrDefault(REQUIRED, true); | ||
return new PresentationAttestationSource(credentialType, outputClaim, required); | ||
} | ||
} |
48 changes: 48 additions & 0 deletions
48
.../issuance/credentials/attestation/presentation/PresentationAttestatonSourceValidator.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,48 @@ | ||
/* | ||
* Copyright (c) 2025 Cofinity-X | ||
* | ||
* 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: | ||
* Cofinity-X - initial API and implementation | ||
* | ||
*/ | ||
|
||
package org.eclipse.edc.identityhub.issuance.credentials.attestation.presentation; | ||
|
||
|
||
import org.eclipse.edc.identityhub.spi.issuance.credentials.model.AttestationDefinition; | ||
import org.eclipse.edc.validator.spi.ValidationResult; | ||
import org.eclipse.edc.validator.spi.Validator; | ||
|
||
import static java.lang.String.format; | ||
import static org.eclipse.edc.validator.spi.ValidationResult.failure; | ||
import static org.eclipse.edc.validator.spi.ValidationResult.success; | ||
import static org.eclipse.edc.validator.spi.Violation.violation; | ||
|
||
/** | ||
* Validates presentation attestation definitions. | ||
*/ | ||
public class PresentationAttestatonSourceValidator implements Validator<AttestationDefinition> { | ||
private static final String ATTESTATION_TYPE = "presentation"; | ||
private static final String CREDENTIAL_TYPE = "credentialType"; | ||
private static final String OUTPUT_CLAIM = "outputClaim"; | ||
|
||
@Override | ||
public ValidationResult validate(AttestationDefinition definition) { | ||
if (!ATTESTATION_TYPE.equals(definition.attestationType())) { | ||
return failure(violation("Expecting attestation type: " + ATTESTATION_TYPE, ATTESTATION_TYPE)); | ||
} | ||
if (!definition.configuration().containsKey(CREDENTIAL_TYPE)) { | ||
return failure(violation(format("No %s specified", CREDENTIAL_TYPE), CREDENTIAL_TYPE)); | ||
} | ||
if (!definition.configuration().containsKey(OUTPUT_CLAIM)) { | ||
return failure(violation(format("No %s specified", OUTPUT_CLAIM), OUTPUT_CLAIM)); | ||
} | ||
return success(); | ||
} | ||
} |
48 changes: 48 additions & 0 deletions
48
...ls/src/main/java/org/eclipse/edc/identityhub/issuance/credentials/json/JsonNavigator.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,48 @@ | ||
/* | ||
* Copyright (c) 2025 Cofinity-X | ||
* | ||
* 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: | ||
* Cofinity-X - initial API and implementation | ||
* | ||
*/ | ||
|
||
package org.eclipse.edc.identityhub.issuance.credentials.json; | ||
|
||
import org.eclipse.edc.spi.result.Result; | ||
|
||
import java.util.Map; | ||
|
||
import static java.lang.String.format; | ||
import static java.lang.String.join; | ||
import static org.eclipse.edc.spi.result.Result.failure; | ||
import static org.eclipse.edc.spi.result.Result.success; | ||
|
||
/** | ||
* Navigates Json types and resolves property values. | ||
*/ | ||
public class JsonNavigator { | ||
|
||
public static Result<Object> navigateProperty(String[] path, Map<String, Object> input, boolean required) { | ||
Object result = input; | ||
for (var property : path) { | ||
if (!(result instanceof Map)) { | ||
return failure(format("Unexpected type at segment %s for path %s", property, join(".", path))); | ||
} | ||
//noinspection rawtypes | ||
result = ((Map) result).get(property); | ||
if (result == null) { | ||
break; | ||
} | ||
} | ||
return result == null && required ? failure(format("Property not found for path %s", join(".", path))) : success(result); | ||
} | ||
|
||
private JsonNavigator() { | ||
} | ||
} |
38 changes: 38 additions & 0 deletions
38
.../eclipse/edc/identityhub/issuance/credentials/rule/CredentialRuleFactoryRegistryImpl.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,38 @@ | ||
/* | ||
* Copyright (c) 2025 Cofinity-X | ||
* | ||
* 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: | ||
* Cofinity-X - initial API and implementation | ||
* | ||
*/ | ||
|
||
package org.eclipse.edc.identityhub.issuance.credentials.rule; | ||
|
||
import org.eclipse.edc.identityhub.spi.issuance.credentials.rule.CredentialRuleFactory; | ||
import org.eclipse.edc.identityhub.spi.issuance.credentials.rule.CredentialRuleFactoryRegistry; | ||
import org.jetbrains.annotations.Nullable; | ||
|
||
import java.util.HashMap; | ||
import java.util.Map; | ||
|
||
import static java.util.Objects.requireNonNull; | ||
|
||
public class CredentialRuleFactoryRegistryImpl implements CredentialRuleFactoryRegistry { | ||
private Map<String, CredentialRuleFactory> factories = new HashMap<>(); | ||
|
||
@Override | ||
public void registerFactory(String type, CredentialRuleFactory factory) { | ||
factories.put(type, factory); | ||
} | ||
|
||
@Override | ||
public @Nullable CredentialRuleFactory resolveFactory(String type) { | ||
return requireNonNull(factories.get(type), "Unknown rule type: " + type); | ||
} | ||
} |
Oops, something went wrong.