diff --git a/core/common/lib/policy-engine-lib/src/main/java/org/eclipse/edc/policy/engine/PolicyEngineImpl.java b/core/common/lib/policy-engine-lib/src/main/java/org/eclipse/edc/policy/engine/PolicyEngineImpl.java index 43d16643517..14a6e2993c5 100644 --- a/core/common/lib/policy-engine-lib/src/main/java/org/eclipse/edc/policy/engine/PolicyEngineImpl.java +++ b/core/common/lib/policy-engine-lib/src/main/java/org/eclipse/edc/policy/engine/PolicyEngineImpl.java @@ -20,7 +20,6 @@ import org.eclipse.edc.policy.engine.spi.PolicyContext; import org.eclipse.edc.policy.engine.spi.PolicyEngine; import org.eclipse.edc.policy.engine.spi.PolicyRuleFunction; -import org.eclipse.edc.policy.engine.spi.PolicyValidatorFunction; import org.eclipse.edc.policy.engine.spi.PolicyValidatorRule; import org.eclipse.edc.policy.engine.spi.plan.PolicyEvaluationPlan; import org.eclipse.edc.policy.engine.validation.PolicyValidator; @@ -40,7 +39,6 @@ import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.function.BiFunction; import java.util.function.Predicate; import static org.eclipse.edc.spi.result.Result.failure; @@ -51,8 +49,6 @@ */ public class PolicyEngineImpl implements PolicyEngine { - public static final String ALL_SCOPES_DELIMITED = ALL_SCOPES + DELIMITER; - private final Map> scopes = new HashMap<>(); private final List> constraintFunctions = new ArrayList<>(); @@ -70,10 +66,6 @@ public PolicyEngineImpl(ScopeFilter scopeFilter, RuleValidator ruleValidator) { this.ruleValidator = ruleValidator; } - public static boolean scopeFilter(String entry, String scope) { - return ALL_SCOPES_DELIMITED.equals(entry) || scope.startsWith(entry); - } - @Override public Policy filter(Policy policy, String scope) { return scopeFilter.applyScope(policy, scope); @@ -206,34 +198,16 @@ public void registerFunction(Class constraintFunctions.add(new ConstraintFunctionEntry(contextType, type, key, function)); } - @Override - @SuppressWarnings({ "unchecked", "rawtypes" }) - public void registerFunction(String scope, Class type, String key, AtomicConstraintRuleFunction function) { - constraintFunctions.add(new ConstraintFunctionEntry(contextType(scope), type, key, function)); - } - @Override public void registerFunction(Class contextType, Class type, DynamicAtomicConstraintRuleFunction function) { dynamicConstraintFunctions.add(new DynamicConstraintFunctionEntry(contextType, type, function)); } - @Override - @SuppressWarnings({ "unchecked", "rawtypes" }) - public void registerFunction(String scope, Class type, DynamicAtomicConstraintRuleFunction function) { - dynamicConstraintFunctions.add(new DynamicConstraintFunctionEntry(contextType(scope), type, function)); - } - @Override public void registerFunction(Class contextType, Class type, PolicyRuleFunction function) { ruleFunctions.add(new RuleFunctionEntry(contextType, type, function)); } - @Override - @SuppressWarnings({ "unchecked", "rawtypes" }) - public void registerFunction(String scope, Class type, PolicyRuleFunction function) { - ruleFunctions.add(new RuleFunctionEntry(contextType(scope), type, function)); - } - @Override public void registerPreValidator(Class contextType, PolicyValidatorRule validator) { preValidators.add(new ValidatorRuleEntry(contextType, validator)); @@ -244,26 +218,6 @@ public void registerPostValidator(Class contextType postValidators.add(new ValidatorRuleEntry(contextType, validator)); } - @Override - public void registerPreValidator(String scope, BiFunction validator) { - registerPreValidator(PolicyContext.class, new PolicyValidatorFunctionWrapper(validator)); - } - - @Override - public void registerPreValidator(String scope, PolicyValidatorFunction validator) { - registerPreValidator(PolicyContext.class, validator); - } - - @Override - public void registerPostValidator(String scope, BiFunction validator) { - registerPostValidator(PolicyContext.class, new PolicyValidatorFunctionWrapper(validator)); - } - - @Override - public void registerPostValidator(String scope, PolicyValidatorFunction validator) { - registerPostValidator(PolicyContext.class, validator); - } - @NotNull private Result failValidator(String type, PolicyValidatorRule validator, PolicyContext context) { return failure(context.hasProblems() ? context.getProblems() : List.of(type + " failed: " + validator.name())); @@ -305,18 +259,4 @@ private interface FunctionEntry { return contextType; } - private record PolicyValidatorFunctionWrapper( - BiFunction function) implements PolicyValidatorFunction { - - @Override - public Boolean apply(Policy policy, PolicyContext policyContext) { - return function.apply(policy, policyContext); - } - - @Override - public String name() { - return function.getClass().getSimpleName(); - } - } - } diff --git a/core/common/lib/policy-engine-lib/src/main/java/org/eclipse/edc/policy/engine/validation/PolicyValidator.java b/core/common/lib/policy-engine-lib/src/main/java/org/eclipse/edc/policy/engine/validation/PolicyValidator.java index 9cb46eb84ee..02e5e462d87 100644 --- a/core/common/lib/policy-engine-lib/src/main/java/org/eclipse/edc/policy/engine/validation/PolicyValidator.java +++ b/core/common/lib/policy-engine-lib/src/main/java/org/eclipse/edc/policy/engine/validation/PolicyValidator.java @@ -14,9 +14,7 @@ package org.eclipse.edc.policy.engine.validation; -import org.eclipse.edc.policy.engine.spi.AtomicConstraintFunction; import org.eclipse.edc.policy.engine.spi.AtomicConstraintRuleFunction; -import org.eclipse.edc.policy.engine.spi.DynamicAtomicConstraintFunction; import org.eclipse.edc.policy.engine.spi.DynamicAtomicConstraintRuleFunction; import org.eclipse.edc.policy.engine.spi.PolicyContext; import org.eclipse.edc.policy.model.AndConstraint; @@ -46,7 +44,7 @@ /** * Validate a policy. *

- * The policy validator is used to validate policies against a set of configured rule bindings, {@link AtomicConstraintFunction} and {@link DynamicAtomicConstraintFunction} + * The policy validator is used to validate policies against a set of configured rule bindings, {@link AtomicConstraintRuleFunction} and {@link DynamicAtomicConstraintRuleFunction} *

* The validation will fail under the following conditions: * diff --git a/core/common/lib/policy-engine-lib/src/test/java/org/eclipse/edc/policy/engine/PolicyEngineImplTest.java b/core/common/lib/policy-engine-lib/src/test/java/org/eclipse/edc/policy/engine/PolicyEngineImplTest.java index 2d030e94495..ebef99ac1c7 100644 --- a/core/common/lib/policy-engine-lib/src/test/java/org/eclipse/edc/policy/engine/PolicyEngineImplTest.java +++ b/core/common/lib/policy-engine-lib/src/test/java/org/eclipse/edc/policy/engine/PolicyEngineImplTest.java @@ -45,7 +45,6 @@ import java.util.stream.Stream; import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.eclipse.edc.junit.assertions.AbstractResultAssert.assertThat; import static org.eclipse.edc.policy.engine.spi.PolicyEngine.ALL_SCOPES; import static org.eclipse.edc.policy.model.Operator.EQ; @@ -88,13 +87,6 @@ void validateEmptyPolicy() { assertThat(result).isSucceeded(); } - @Deprecated(since = "0.10.0") - @Test - void shouldThrowException_whenRegisterWithScopeNotRegistered() { - assertThatThrownBy(() -> policyEngine.registerFunction(ALL_SCOPES, Rule.class, "key", mock())); - assertThatThrownBy(() -> policyEngine.registerFunction("unregistered.scope", Rule.class, "key", mock())); - } - @Test void validateUnsatisfiedDuty() { var context = new TestContext(); diff --git a/core/common/lib/policy-engine-lib/src/test/java/org/eclipse/edc/policy/engine/PolicyEngineImplValidationTest.java b/core/common/lib/policy-engine-lib/src/test/java/org/eclipse/edc/policy/engine/PolicyEngineImplValidationTest.java index 614cc0fcfd2..2dda8da3401 100644 --- a/core/common/lib/policy-engine-lib/src/test/java/org/eclipse/edc/policy/engine/PolicyEngineImplValidationTest.java +++ b/core/common/lib/policy-engine-lib/src/test/java/org/eclipse/edc/policy/engine/PolicyEngineImplValidationTest.java @@ -14,8 +14,7 @@ package org.eclipse.edc.policy.engine; -import org.eclipse.edc.policy.engine.spi.AtomicConstraintFunction; -import org.eclipse.edc.policy.engine.spi.DynamicAtomicConstraintFunction; +import org.eclipse.edc.policy.engine.spi.AtomicConstraintRuleFunction; import org.eclipse.edc.policy.engine.spi.DynamicAtomicConstraintRuleFunction; import org.eclipse.edc.policy.engine.spi.PolicyContext; import org.eclipse.edc.policy.engine.spi.PolicyEngine; @@ -151,7 +150,7 @@ void validate_shouldFail_withDynamicFunction() { @ArgumentsSource(PolicyProvider.class) void validate_withDynamicFunction(Policy policy, Class ruleClass, String key) { - DynamicAtomicConstraintFunction function = mock(); + DynamicAtomicConstraintRuleFunction function = mock(); when(function.canHandle(key)).thenReturn(true); @@ -170,7 +169,7 @@ void validate_withDynamicFunction(Policy policy, Class ruleClass, String k @ArgumentsSource(PolicyProvider.class) void validate_shouldFail_whenSkippingDynamicFunction(Policy policy, Class ruleClass, String key) { - DynamicAtomicConstraintFunction function = mock(); + DynamicAtomicConstraintRuleFunction function = mock(); when(function.canHandle(key)).thenReturn(false); @@ -189,7 +188,7 @@ void validate_shouldFail_whenSkippingDynamicFunction(Policy policy, Class @ArgumentsSource(PolicyProvider.class) void validate_shouldFails_withDynamicFunction(Policy policy, Class ruleClass, String key) { - DynamicAtomicConstraintFunction function = mock(); + DynamicAtomicConstraintRuleFunction function = mock(); when(function.canHandle(key)).thenReturn(true); @@ -209,7 +208,7 @@ void validate_shouldFails_withDynamicFunction(Policy policy, Class ruleCla @ArgumentsSource(PolicyProvider.class) void validate_shouldFail_whenFunctionValidationFails(Policy policy, Class ruleClass, String key) { - AtomicConstraintFunction function = mock(); + AtomicConstraintRuleFunction function = mock(); when(function.validate(any(), any(), any())).thenReturn(Result.failure("Function validation failure")); @@ -232,7 +231,7 @@ void validate_shouldFail_whenActionIsNotBound() { var permission = Permission.Builder.newInstance().constraint(constraint).action(Action.Builder.newInstance().type("use").build()).build(); var policy = Policy.Builder.newInstance().permission(permission).build(); - AtomicConstraintFunction function = mock(); + AtomicConstraintRuleFunction function = mock(); when(function.validate(any(), any(), any())).thenReturn(Result.success()); diff --git a/data-protocols/dsp/dsp-lib/dsp-catalog-lib/dsp-catalog-transform-lib/src/main/java/org/eclipse/edc/protocol/dsp/catalog/transform/from/JsonObjectFromDataServiceTransformer.java b/data-protocols/dsp/dsp-lib/dsp-catalog-lib/dsp-catalog-transform-lib/src/main/java/org/eclipse/edc/protocol/dsp/catalog/transform/from/JsonObjectFromDataServiceTransformer.java index 6f6a041bd60..11d8375fee0 100644 --- a/data-protocols/dsp/dsp-lib/dsp-catalog-lib/dsp-catalog-transform-lib/src/main/java/org/eclipse/edc/protocol/dsp/catalog/transform/from/JsonObjectFromDataServiceTransformer.java +++ b/data-protocols/dsp/dsp-lib/dsp-catalog-lib/dsp-catalog-transform-lib/src/main/java/org/eclipse/edc/protocol/dsp/catalog/transform/from/JsonObjectFromDataServiceTransformer.java @@ -27,7 +27,6 @@ import static org.eclipse.edc.jsonld.spi.PropertyAndTypeNames.DCAT_DATA_SERVICE_TYPE; import static org.eclipse.edc.jsonld.spi.PropertyAndTypeNames.DCAT_ENDPOINT_DESCRIPTION_ATTRIBUTE; import static org.eclipse.edc.jsonld.spi.PropertyAndTypeNames.DCAT_ENDPOINT_URL_ATTRIBUTE; -import static org.eclipse.edc.jsonld.spi.PropertyAndTypeNames.DCAT_ENDPOINT_URL_OLD_ATTRIBUTE; /** * Converts from a {@link DataService} to a DCAT data service as a {@link JsonObject} in JSON-LD expanded form. @@ -48,7 +47,6 @@ public JsonObjectFromDataServiceTransformer(JsonBuilderFactory jsonFactory) { .add(TYPE, DCAT_DATA_SERVICE_TYPE); addIfNotNull(dataService.getEndpointDescription(), DCAT_ENDPOINT_DESCRIPTION_ATTRIBUTE, objectBuilder); - addIfNotNull(dataService.getEndpointUrl(), DCAT_ENDPOINT_URL_OLD_ATTRIBUTE, objectBuilder); addIfNotNull(dataService.getEndpointUrl(), DCAT_ENDPOINT_URL_ATTRIBUTE, objectBuilder); return objectBuilder.build(); diff --git a/data-protocols/dsp/dsp-lib/dsp-catalog-lib/dsp-catalog-transform-lib/src/test/java/org/eclipse/edc/protocol/dsp/catalog/transform/from/JsonObjectFromDataServiceTransformerTest.java b/data-protocols/dsp/dsp-lib/dsp-catalog-lib/dsp-catalog-transform-lib/src/test/java/org/eclipse/edc/protocol/dsp/catalog/transform/from/JsonObjectFromDataServiceTransformerTest.java index e586c42ca47..1d8f31d5505 100644 --- a/data-protocols/dsp/dsp-lib/dsp-catalog-lib/dsp-catalog-transform-lib/src/test/java/org/eclipse/edc/protocol/dsp/catalog/transform/from/JsonObjectFromDataServiceTransformerTest.java +++ b/data-protocols/dsp/dsp-lib/dsp-catalog-lib/dsp-catalog-transform-lib/src/test/java/org/eclipse/edc/protocol/dsp/catalog/transform/from/JsonObjectFromDataServiceTransformerTest.java @@ -29,7 +29,6 @@ import static org.eclipse.edc.jsonld.spi.PropertyAndTypeNames.DCAT_DATA_SERVICE_TYPE; import static org.eclipse.edc.jsonld.spi.PropertyAndTypeNames.DCAT_ENDPOINT_DESCRIPTION_ATTRIBUTE; import static org.eclipse.edc.jsonld.spi.PropertyAndTypeNames.DCAT_ENDPOINT_URL_ATTRIBUTE; -import static org.eclipse.edc.jsonld.spi.PropertyAndTypeNames.DCAT_ENDPOINT_URL_OLD_ATTRIBUTE; import static org.mockito.Mockito.mock; class JsonObjectFromDataServiceTransformerTest { @@ -58,7 +57,6 @@ void transform_returnJsonObject() { assertThat(result.getJsonString(ID).getString()).isEqualTo(dataService.getId()); assertThat(result.getJsonString(TYPE).getString()).isEqualTo(DCAT_DATA_SERVICE_TYPE); assertThat(result.getJsonString(DCAT_ENDPOINT_DESCRIPTION_ATTRIBUTE).getString()).isEqualTo("description"); - assertThat(result.getJsonString(DCAT_ENDPOINT_URL_OLD_ATTRIBUTE).getString()).isEqualTo("url"); assertThat(result.getJsonString(DCAT_ENDPOINT_URL_ATTRIBUTE).getString()).isEqualTo("url"); } diff --git a/dist/bom/controlplane-oauth2-bom/build.gradle.kts b/dist/bom/controlplane-oauth2-bom/build.gradle.kts deleted file mode 100644 index 9c0a935778d..00000000000 --- a/dist/bom/controlplane-oauth2-bom/build.gradle.kts +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (c) 2024 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 - * - */ - -plugins { - `java-library` -} - -dependencies { - // SPI dependencies - api(project(":dist:bom:controlplane-base-bom")) - - // DCP dependencies, JWT and LDP - api(project(":spi:common:jwt-spi")) - - api(project(":extensions:common:iam:oauth2:oauth2-service")) -} \ No newline at end of file diff --git a/extensions/README.md b/extensions/README.md deleted file mode 100644 index fcd202b5e8b..00000000000 --- a/extensions/README.md +++ /dev/null @@ -1,86 +0,0 @@ -# Extensions - -- Common - - API - - [Core](common/api/api-core/) - - [Observability](common/api/api-observability/) - - Auth - - [Basic](common/auth/auth-basic/) - - [Token-based](common/auth/auth-tokenbased/) - - AWS - - [S3 Core](common/aws/aws-s3-core/) - - [Test](common/aws/aws-s3-test/) - - Azure - - [Blob Core](common/azure/azure-blob-core/) - - [Cosmos Common](common/azure/azure-cosmos-core/) - - [Event Grid](common/azure/azure-eventgrid/) - - [Resource Manager](common/azure/azure-resource-manager/) - - [Test](common/azure/azure-test/) - - Configuration - - [Filesystem](common/configuration/configuration-filesystem/) - - Events - - [Cloud HTTP](common/events/events-cloud-http/) - - HTTP - - [Jersey](common/http/jersey-core/) - - [Jersey Micrometer](common/http/jersey-micrometer/) - - [Jetty](common/http/jetty-core/) - - [Jetty Micrometer](common/http/jetty-micrometer/) - - IAM - - [DAPS](common/iam/oauth2/oauth2-daps/) - - [Decentralized Identity](common/iam/decentralized-identity/) - - [OAuth2](common/iam/oauth2/oauth2-core/) - - [JUnit](common/junit/) - - [Micrometer](common/metrics/micrometer-core/) - - Monitor - - [JDK Logger](common/monitor/monitor-jdk-logger/) - - SQL - - [Common](common/sql/sql-core/) - - [Lease](common/sql/sql-lease/) - - [Pool](common/sql/sql-pool/) - - Transaction - - [Atomikos](common/transaction/transaction-atomikos/) - - [Local](common/transaction/transaction-local/) - - Vault - - [Azure](common/vault/vault-azure/) - - [HashiCorp](common/vault/vault-hashicorp/) -- Control Plane - - [Management API](control-plane/api/management-api/) - - [Configuration](control-plane/api/management-api/management-api-configuration/) - - [Asset](control-plane/api/management-api/asset-api/) - - [Catalog](control-plane/api/management-api/catalog-api/) - - [Contract Agreement](control-plane/api/management-api/contract-agreement-api/) - - [Contract Definition](control-plane/api/management-api/contract-definition-api/) - - [Contract Negotiation](control-plane/api/management-api/contract-negotiation-api/) - - [Policy Definition](control-plane/api/management-api/policy-definition-api/) - - [Transfer Process](control-plane/api/management-api/transfer-process-api/) - - [Data Plane Transfer](control-plane/data-plane-transfer/) - - Provision - - [Blob](control-plane/provision/provision-blob/) - - [HTTP](control-plane/provision/provision-http/) - - [S3](control-plane/provision/provision-aws-s3/) - - Store - - Cosmos - - [Asset Index](control-plane/store/cosmos/asset-index-cosmos/) - - [Contract Definition](control-plane/store/cosmos/contract-definition-store-cosmos/) - - [Contract Negotiation](control-plane/store/cosmos/contract-negotiation-store-cosmos/) - - [Control Plane](control-plane/store/cosmos/control-plane-cosmos/) - - [Policy](control-plane/store/cosmos/policy-definition-store-cosmos/) - - [Transfer Process](control-plane/store/cosmos/transfer-process-store-cosmos/) - - SQL - - [Asset Index](control-plane/store/sql/asset-index-sql/) - - [Contract Definition](control-plane/store/sql/contract-definition-store-sql/) - - [Contract Negotiation](control-plane/store/sql/contract-negotiation-store-sql/) - - [Control Plane](control-plane/store/sql/control-plane-sql/) - - [Policy](control-plane/store/sql/policy-definition-store-sql/) - - [Transfer Process](control-plane/store/sql/transfer-process-store-sql/) -- Data Plane - - [API](data-plane/data-plane-api/) - - [Azure Storage](data-plane/data-plane-azure-storage/) - - [Data Factory](data-plane/data-plane-azure-data-factory/) - - [Google Cloud Storage](data-plane/data-plane-google-storage/) - - [HTTP](data-plane/data-plane-http/) - - [S3](data-plane/data-plane-aws-s3/) - - [Tests](data-plane/data-plane-integration-tests/) -- Data Plane Selector - - [API](data-plane-selector/data-plane-selector-api/) - - [Client](data-plane-selector/data-plane-selector-client/) diff --git a/extensions/common/api/management-api-configuration/src/main/resources/management-api-version.json b/extensions/common/api/management-api-configuration/src/main/resources/management-api-version.json index 0509a88ddaf..ba54d3a21dc 100644 --- a/extensions/common/api/management-api-configuration/src/main/resources/management-api-version.json +++ b/extensions/common/api/management-api-configuration/src/main/resources/management-api-version.json @@ -1,8 +1,8 @@ [ { - "version": "3.1.0", + "version": "3.1.1", "urlPath": "/v3", - "lastUpdated": "2025-05-08T16:45:00Z", + "lastUpdated": "2025-06-23T08:30:00Z", "maturity": "stable" }, { diff --git a/extensions/common/iam/oauth2/oauth2-core/README.md b/extensions/common/iam/oauth2/oauth2-core/README.md deleted file mode 100644 index 4a18598e3ef..00000000000 --- a/extensions/common/iam/oauth2/oauth2-core/README.md +++ /dev/null @@ -1,27 +0,0 @@ -# OAuth 2 Identity Service - -**DEPRECATED**: this repo has been deprecated in version 0.10.0 and it will be deleted in the upcoming versions. - -This extension provides an `IdentityService` implementation based on the OAuth2 protocol for authorization. - -## Configuration - -| Parameter name | Description | Mandatory | Default value | -|:-----------------------------------|:---------------------------------------------------------------------------------------------------------------------|:----------|:------------------------------------| -| `edc.oauth.token.url` | URL of the authorization server | true | null | -| `edc.oauth.provider.audience` | Provider audience to be put in the outgoing token as 'aud' claim | false | id of the connector | -| `edc.oauth.endpoint.audience` | Endpoint audience to verify incoming token 'aud' claim | false | `edc.oauth.provider.audience` value | -| `edc.oauth.provider.jwks.url` | URL from which well-known public keys of Authorization server can be fetched | false | http://localhost/empty_jwks_url | -| `edc.oauth.certificate.alias` | Alias of public associated with client certificate | true | null | -| `edc.oauth.private.key.alias` | Alias of private key (used to sign the token) | true | null | -| `edc.oauth.provider.jwks.refresh` | Interval at which public keys are refreshed from Authorization server (in minutes) | false | 5 | -| `edc.oauth.client.id` | Public identifier of the client | true | null | -| `edc.oauth.validation.nbf.leeway` | Leeway in seconds added to current time to remedy clock skew on notBefore claim validation | false | 10 | -| `edc.oauth.token.resource.enabled` | Adds `resource` form parameter in the access token request. Allows to specify an audience as defined in the RFC-8707 | false | false | - -## Extensions - -### CredentialsRequestAdditionalParametersProvider - -An instance of the `CredentialsRequestAdditionalParametersProvider` service interface can be provided to have the -possibility to enrich the form parameters of the client credentials token request diff --git a/extensions/common/iam/oauth2/oauth2-core/build.gradle.kts b/extensions/common/iam/oauth2/oauth2-core/build.gradle.kts deleted file mode 100644 index 5db76b45b7c..00000000000 --- a/extensions/common/iam/oauth2/oauth2-core/build.gradle.kts +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (c) 2020, 2021 Microsoft Corporation - * - * 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: - * Microsoft Corporation - initial API and implementation - * - */ - -plugins { - `java-library` -} - -dependencies { - api(project(":spi:common:http-spi")) - api(project(":spi:common:oauth2-spi")) - implementation(project(":spi:common:keys-spi")) - implementation(project(":spi:common:jwt-signer-spi")) - implementation(project(":extensions:common:iam:oauth2:oauth2-client")) - implementation(project(":core:common:lib:token-lib")) - - implementation(libs.nimbus.jwt) - - testImplementation(project(":core:common:junit")) - testImplementation(testFixtures(project(":core:common:lib:http-lib"))) - - testImplementation(libs.mockserver.netty) - testImplementation(libs.mockserver.client) -} - - diff --git a/extensions/common/iam/oauth2/oauth2-core/src/main/java/org/eclipse/edc/iam/oauth2/Oauth2ServiceConfiguration.java b/extensions/common/iam/oauth2/oauth2-core/src/main/java/org/eclipse/edc/iam/oauth2/Oauth2ServiceConfiguration.java deleted file mode 100644 index 79f97fc05c7..00000000000 --- a/extensions/common/iam/oauth2/oauth2-core/src/main/java/org/eclipse/edc/iam/oauth2/Oauth2ServiceConfiguration.java +++ /dev/null @@ -1,183 +0,0 @@ -/* - * Copyright (c) 2020, 2021 Microsoft Corporation - * - * 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: - * Microsoft Corporation - initial API and implementation - * sovity GmbH - added issuedAt leeway - * - */ - -package org.eclipse.edc.iam.oauth2; - -import org.eclipse.edc.iam.oauth2.identity.Oauth2ServiceImpl; -import org.eclipse.edc.runtime.metamodel.annotation.Setting; -import org.eclipse.edc.runtime.metamodel.annotation.Settings; - -/** - * Configuration values and dependencies for {@link Oauth2ServiceImpl}. - * - * @deprecated please switch to DCP. - */ -@Deprecated(since = "0.10.0") -@Settings -public class Oauth2ServiceConfiguration { - static final String ISSUED_AT_LEEWAY = "edc.oauth.validation.issued.at.leeway"; - private static final int DEFAULT_TOKEN_EXPIRATION = 5; - - @Setting(description = "URL to obtain OAuth2 JSON Web Key Sets", key = "edc.oauth.provider.jwks.url", defaultValue = "http://localhost/empty_jwks_url") - private String jwksUrl; - @Setting(description = "OAuth2 Token URL", key = "edc.oauth.token.url") - private String tokenUrl; - @Setting(description = "OAuth2 client ID", key = "edc.oauth.client.id") - private String clientId; - @Setting(description = "Vault alias for the private key", key = "edc.oauth.private.key.alias") - private String privateKeyAlias; - @Setting(description = "Vault alias for the certificate", key = "edc.oauth.certificate.alias") - private String publicCertificateAlias; - @Setting(description = "outgoing tokens 'aud' claim value, by default it's the connector id", key = "edc.oauth.provider.audience", required = false) - private String providerAudience; - @Setting(description = "Leeway in seconds for validating the not before (nbf) claim in the token.", defaultValue = "10", key = "edc.oauth.validation.nbf.leeway") - private int notBeforeValidationLeeway; - @Setting(description = "Leeway in seconds for validating the issuedAt claim in the token. By default it is 0 seconds.", defaultValue = "0", key = ISSUED_AT_LEEWAY) - private int issuedAtLeeway; - @Setting(description = "incoming tokens 'aud' claim required value, by default it's the provider audience value", key = "edc.oauth.endpoint.audience", required = false) - private String endpointAudience; - - @Setting(description = "Refresh time for the JWKS, in minutes", key = "edc.oauth.provider.jwks.refresh", defaultValue = "5") - private int providerJwksRefresh; // in minutes - - @Setting(description = "Token expiration in minutes. By default is 5 minutes", key = "edc.oauth.token.expiration", defaultValue = DEFAULT_TOKEN_EXPIRATION + "") - private Long tokenExpiration; - - @Setting(description = "Enable the connector to request a token with a specific audience as defined in the RFC-8707.", key = "edc.oauth.token.resource.enabled", defaultValue = "false") - private boolean tokenResourceEnabled; - - private Oauth2ServiceConfiguration() { - - } - - public String getTokenUrl() { - return tokenUrl; - } - - public String getClientId() { - return clientId; - } - - public String getPrivateKeyAlias() { - return privateKeyAlias; - } - - public String getPublicCertificateAlias() { - return publicCertificateAlias; - } - - public String getProviderAudience() { - return providerAudience; - } - - public int getNotBeforeValidationLeeway() { - return notBeforeValidationLeeway; - } - - public int getIssuedAtLeeway() { - return issuedAtLeeway; - } - - public String getEndpointAudience() { - return endpointAudience; - } - - public Long getTokenExpiration() { - return tokenExpiration; - } - - public boolean isTokenResourceEnabled() { - return tokenResourceEnabled; - } - - public int getProviderJwksRefresh() { - return providerJwksRefresh; - } - - public String getJwksUrl() { - return jwksUrl; - } - - public Builder toBuilder() { - return new Builder(this); - } - - public static class Builder { - private final Oauth2ServiceConfiguration configuration; - - private Builder(Oauth2ServiceConfiguration configuration) { - this.configuration = configuration; - } - - public static Builder newInstance() { - return new Builder(new Oauth2ServiceConfiguration()); - } - - public Builder tokenUrl(String url) { - configuration.tokenUrl = url; - return this; - } - - public Builder clientId(String clientId) { - configuration.clientId = clientId; - return this; - } - - - public Builder privateKeyAlias(String privateKeyAlias) { - configuration.privateKeyAlias = privateKeyAlias; - return this; - } - - public Builder publicCertificateAlias(String publicCertificateAlias) { - configuration.publicCertificateAlias = publicCertificateAlias; - return this; - } - - public Builder providerAudience(String providerAudience) { - configuration.providerAudience = providerAudience; - return this; - } - - public Builder notBeforeValidationLeeway(int notBeforeValidationLeeway) { - configuration.notBeforeValidationLeeway = notBeforeValidationLeeway; - return this; - } - - public Builder issuedAtLeeway(int issuedAtLeeway) { - configuration.issuedAtLeeway = issuedAtLeeway; - return this; - } - - public Builder endpointAudience(String endpointAudience) { - configuration.endpointAudience = endpointAudience; - return this; - } - - public Builder tokenExpiration(long tokenExpiration) { - configuration.tokenExpiration = tokenExpiration; - return this; - } - - public Builder tokenResourceEnabled(boolean tokenResourceEnabled) { - configuration.tokenResourceEnabled = tokenResourceEnabled; - return this; - } - - public Oauth2ServiceConfiguration build() { - return configuration; - } - } -} diff --git a/extensions/common/iam/oauth2/oauth2-core/src/main/java/org/eclipse/edc/iam/oauth2/Oauth2ServiceDefaultServicesExtension.java b/extensions/common/iam/oauth2/oauth2-core/src/main/java/org/eclipse/edc/iam/oauth2/Oauth2ServiceDefaultServicesExtension.java deleted file mode 100644 index 782f64ccc3b..00000000000 --- a/extensions/common/iam/oauth2/oauth2-core/src/main/java/org/eclipse/edc/iam/oauth2/Oauth2ServiceDefaultServicesExtension.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (c) 2022 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.oauth2; - -import org.eclipse.edc.runtime.metamodel.annotation.Provider; -import org.eclipse.edc.spi.iam.AudienceResolver; -import org.eclipse.edc.spi.result.Result; -import org.eclipse.edc.spi.system.ServiceExtension; - -/** - * Provides default service implementations for fallback - * Omitted {@link org.eclipse.edc.runtime.metamodel.annotation.Extension} since this module already contains {@link Oauth2ServiceExtension} - * - * @deprecated please switch to DCP. - */ -@Deprecated(since = "0.10.0") -public class Oauth2ServiceDefaultServicesExtension implements ServiceExtension { - - public static final String NAME = "OAuth2 Core Default Services"; - - @Override - public String name() { - return NAME; - } - - - @Provider(isDefault = true) - public AudienceResolver defaultAudienceResolver() { - return (msg) -> Result.success(msg.getCounterPartyAddress()); - } -} diff --git a/extensions/common/iam/oauth2/oauth2-core/src/main/java/org/eclipse/edc/iam/oauth2/Oauth2ServiceExtension.java b/extensions/common/iam/oauth2/oauth2-core/src/main/java/org/eclipse/edc/iam/oauth2/Oauth2ServiceExtension.java deleted file mode 100644 index 48fdd262bbc..00000000000 --- a/extensions/common/iam/oauth2/oauth2-core/src/main/java/org/eclipse/edc/iam/oauth2/Oauth2ServiceExtension.java +++ /dev/null @@ -1,177 +0,0 @@ -/* - * Copyright (c) 2020, 2021 Microsoft Corporation - * - * 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: - * Microsoft Corporation - initial API and implementation - * Fraunhofer Institute for Software and Systems Engineering - Improvements - * sovity GmbH - added issuedAt leeway - * - */ - -package org.eclipse.edc.iam.oauth2; - -import org.eclipse.edc.http.spi.EdcHttpClient; -import org.eclipse.edc.iam.oauth2.identity.IdentityProviderKeyResolver; -import org.eclipse.edc.iam.oauth2.identity.Oauth2ServiceImpl; -import org.eclipse.edc.iam.oauth2.jwt.X509CertificateDecorator; -import org.eclipse.edc.iam.oauth2.spi.Oauth2AssertionDecorator; -import org.eclipse.edc.iam.oauth2.spi.client.Oauth2Client; -import org.eclipse.edc.jwt.signer.spi.JwsSignerProvider; -import org.eclipse.edc.keys.spi.CertificateResolver; -import org.eclipse.edc.keys.spi.PrivateKeyResolver; -import org.eclipse.edc.runtime.metamodel.annotation.Configuration; -import org.eclipse.edc.runtime.metamodel.annotation.Extension; -import org.eclipse.edc.runtime.metamodel.annotation.Inject; -import org.eclipse.edc.runtime.metamodel.annotation.Provides; -import org.eclipse.edc.spi.EdcException; -import org.eclipse.edc.spi.iam.IdentityService; -import org.eclipse.edc.spi.monitor.Monitor; -import org.eclipse.edc.spi.system.ServiceExtension; -import org.eclipse.edc.spi.system.ServiceExtensionContext; -import org.eclipse.edc.spi.types.TypeManager; -import org.eclipse.edc.token.JwtGenerationService; -import org.eclipse.edc.token.rules.AudienceValidationRule; -import org.eclipse.edc.token.rules.ExpirationIssuedAtValidationRule; -import org.eclipse.edc.token.rules.NotBeforeValidationRule; -import org.eclipse.edc.token.spi.TokenDecoratorRegistry; -import org.eclipse.edc.token.spi.TokenValidationRulesRegistry; -import org.eclipse.edc.token.spi.TokenValidationService; -import org.jetbrains.annotations.NotNull; - -import java.time.Clock; -import java.util.function.Supplier; - -import static java.util.Optional.ofNullable; - -/** - * Provides OAuth2 client credentials flow support. - * - * @deprecated please switch to DCP. - */ -@Provides({ IdentityService.class }) -@Extension(value = Oauth2ServiceExtension.NAME) -@Deprecated(since = "0.10.0") -public class Oauth2ServiceExtension implements ServiceExtension { - - public static final String NAME = "OAuth2 Identity Service"; - public static final String OAUTH2_TOKEN_CONTEXT = "oauth2"; - - @Configuration - private Oauth2ServiceConfiguration config; - private IdentityProviderKeyResolver providerKeyResolver; - - @Inject - private EdcHttpClient httpClient; - - @Inject - private PrivateKeyResolver privateKeyResolver; - - @Inject - private CertificateResolver certificateResolver; - - @Inject - private Clock clock; - - @Inject - private Oauth2Client oauth2Client; - - @Inject - private TypeManager typeManager; - - @Inject - private TokenValidationRulesRegistry tokenValidationRulesRegistry; - - @Inject - private TokenValidationService tokenValidationService; - @Inject - private TokenDecoratorRegistry jwtDecoratorRegistry; - @Inject - private JwsSignerProvider jwsSignerProvider; - - @Override - public String name() { - return NAME; - } - - @Override - public void initialize(ServiceExtensionContext context) { - - config = withDefaults(config, context); - warnIfNoLeeway(config, context.getMonitor()); - - var certificate = ofNullable(certificateResolver.resolveCertificate(config.getPublicCertificateAlias())) - .orElseThrow(() -> new EdcException("Public certificate not found: " + config.getPublicCertificateAlias())); - jwtDecoratorRegistry.register(OAUTH2_TOKEN_CONTEXT, Oauth2AssertionDecorator.Builder.newInstance() - .audience(config.getProviderAudience()) - .clientId(config.getClientId()) - .clock(clock) - .validity(config.getTokenExpiration()) - .build()); - jwtDecoratorRegistry.register(OAUTH2_TOKEN_CONTEXT, new X509CertificateDecorator(certificate)); - - providerKeyResolver = identityProviderKeyResolver(context); - - var oauth2Service = createOauth2Service(config, jwtDecoratorRegistry, providerKeyResolver); - context.registerService(IdentityService.class, oauth2Service); - - // add oauth2-specific validation rules - tokenValidationRulesRegistry.addRule(OAUTH2_TOKEN_CONTEXT, new AudienceValidationRule(config.getEndpointAudience())); - tokenValidationRulesRegistry.addRule(OAUTH2_TOKEN_CONTEXT, new NotBeforeValidationRule(clock, config.getNotBeforeValidationLeeway(), false)); - tokenValidationRulesRegistry.addRule(OAUTH2_TOKEN_CONTEXT, new ExpirationIssuedAtValidationRule(clock, config.getIssuedAtLeeway(), false)); - } - - private Oauth2ServiceConfiguration withDefaults(Oauth2ServiceConfiguration config, ServiceExtensionContext context) { - var providerAudience = ofNullable(config.getProviderAudience()).orElseGet(context::getComponentId); - return config.toBuilder() - .providerAudience(providerAudience) - .endpointAudience(ofNullable(config.getEndpointAudience()).orElse(providerAudience)) - .build(); - } - - @Override - public void start() { - providerKeyResolver.start(); - } - - @Override - public void shutdown() { - providerKeyResolver.stop(); - } - - private IdentityProviderKeyResolver identityProviderKeyResolver(ServiceExtensionContext context) { - return new IdentityProviderKeyResolver(context.getMonitor(), httpClient, typeManager, config.getJwksUrl(), config.getProviderJwksRefresh()); - } - - @NotNull - private Oauth2ServiceImpl createOauth2Service(Oauth2ServiceConfiguration configuration, - TokenDecoratorRegistry jwtDecoratorRegistry, - IdentityProviderKeyResolver providerKeyResolver) { - Supplier privateKeySupplier = configuration::getPrivateKeyAlias; - - return new Oauth2ServiceImpl( - configuration.getTokenUrl(), - new JwtGenerationService(jwsSignerProvider), - privateKeySupplier, - oauth2Client, - jwtDecoratorRegistry, - tokenValidationRulesRegistry, - tokenValidationService, - providerKeyResolver, - configuration.isTokenResourceEnabled() - ); - } - - private void warnIfNoLeeway(Oauth2ServiceConfiguration configuration, Monitor monitor) { - if (configuration.getIssuedAtLeeway() == 0) { - var message = "No value was configured for '%s'. Consider setting a leeway of 2-5s in production to avoid problems with clock skew.".formatted(Oauth2ServiceConfiguration.ISSUED_AT_LEEWAY); - monitor.info(message); - } - } - -} diff --git a/extensions/common/iam/oauth2/oauth2-core/src/main/java/org/eclipse/edc/iam/oauth2/identity/IdentityProviderKeyResolver.java b/extensions/common/iam/oauth2/oauth2-core/src/main/java/org/eclipse/edc/iam/oauth2/identity/IdentityProviderKeyResolver.java deleted file mode 100644 index 9c1107a48f5..00000000000 --- a/extensions/common/iam/oauth2/oauth2-core/src/main/java/org/eclipse/edc/iam/oauth2/identity/IdentityProviderKeyResolver.java +++ /dev/null @@ -1,168 +0,0 @@ -/* - * Copyright (c) 2020 - 2022 Microsoft Corporation - * - * 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: - * Microsoft Corporation - initial API and implementation - * Bayerische Motoren Werke Aktiengesellschaft (BMW AG) - improvements - * - */ - -package org.eclipse.edc.iam.oauth2.identity; - -import okhttp3.Request; -import org.eclipse.edc.http.spi.EdcHttpClient; -import org.eclipse.edc.iam.oauth2.jwt.JwkKey; -import org.eclipse.edc.iam.oauth2.jwt.JwkKeys; -import org.eclipse.edc.keys.spi.PublicKeyResolver; -import org.eclipse.edc.spi.EdcException; -import org.eclipse.edc.spi.monitor.Monitor; -import org.eclipse.edc.spi.result.Result; -import org.eclipse.edc.spi.types.TypeManager; - -import java.math.BigInteger; -import java.security.GeneralSecurityException; -import java.security.KeyFactory; -import java.security.PublicKey; -import java.security.interfaces.RSAPublicKey; -import java.security.spec.RSAPublicKeySpec; -import java.util.AbstractMap; -import java.util.Base64; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.atomic.AtomicReference; -import java.util.function.Predicate; -import java.util.stream.Collectors; - -import static java.util.Collections.emptyMap; -import static java.util.concurrent.TimeUnit.MINUTES; - -/** - * Resolves public signing certificates for the identity provider. Used to verify JWTs. - * The keys are cached and the resolver must be started calling the `start` method - */ -public class IdentityProviderKeyResolver implements PublicKeyResolver { - private static final String RSA = "RSA"; - private final Monitor monitor; - private final TypeManager typeManager; - private final ScheduledExecutorService executorService; - private final AtomicReference> cache = new AtomicReference<>(emptyMap()); // the current key cache, atomic for thread-safety - private final EdcHttpClient httpClient; - private final String jwksUrl; - private final int keyRefreshInterval; - private final Predicate isRsa = key -> RSA.equals(key.getKty()); - - public IdentityProviderKeyResolver(Monitor monitor, EdcHttpClient httpClient, TypeManager typeManager, String jwksUrl, int keyRefreshInterval) { - this.monitor = monitor; - this.httpClient = httpClient; - this.typeManager = typeManager; - this.executorService = Executors.newSingleThreadScheduledExecutor(); - this.jwksUrl = jwksUrl; - this.keyRefreshInterval = keyRefreshInterval; - } - - @Override - public Result resolveKey(String id) { - return Result.success(cache.get().get(id)); - } - - /** - * Start the keys cache refreshing job. - * Throws exception if it's not able to load the cache at startup. - */ - public void start() { - var result = refreshKeys(); - if (result.failed()) { - throw new EdcException(String.format("Failed to get keys from %s: %s", jwksUrl, String.join(", " + result.getFailureMessages()))); - } - - executorService.scheduleWithFixedDelay(this::refreshKeys, keyRefreshInterval, keyRefreshInterval, MINUTES); - } - - /** - * Stops the cache refresh job. - */ - public void stop() { - executorService.shutdownNow(); - } - - /** - * Get keys from the JWKS provider. Protected for testing purposes. - * - * @return succeed if keys are retrieved correctly, failure otherwise - */ - protected Result> getKeys() { - var request = new Request.Builder().url(jwksUrl).get().build(); - try (var response = httpClient.execute(request)) { - if (response.code() == 200) { - var body = response.body(); - if (body == null) { - var message = "Unable to refresh identity provider keys. An empty response was returned."; - monitor.severe(message); - return Result.failure(message); - } - - var jwsKeys = typeManager.readValue(body.string(), JwkKeys.class); - var keys = jwsKeys.getKeys(); - if (keys == null || keys.isEmpty()) { - var message = "No keys returned from identity provider."; - monitor.warning(message); - return Result.failure(message); - } - - return Result.success(deserializeKeys(keys)); - - } else { - var message = "Unable to refresh identity provider keys. Response code was: " + response.code(); - monitor.severe(message); - return Result.failure(message); - } - } catch (Exception e) { - var message = "Error resolving identity provider keys: " + jwksUrl; - monitor.severe(message, e); - return Result.failure(message); - } - } - - private Result refreshKeys() { - var result = getKeys(); - if (result.succeeded()) { - cache.set(result.getContent()); - } - return result.mapEmpty(); - } - - private Map deserializeKeys(List jwkKeys) { - return jwkKeys.stream() - .filter(isRsa) - .map(this::deserializeKey) - .filter(Objects::nonNull) - .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); - } - - private Map.Entry deserializeKey(JwkKey key) { - var modulus = unsignedInt(key.getN()); - var exponent = unsignedInt(key.getE()); - var rsaPublicKeySpec = new RSAPublicKeySpec(modulus, exponent); - try { - var keyFactory = KeyFactory.getInstance(RSA); - return new AbstractMap.SimpleEntry<>(key.getKid(), (RSAPublicKey) keyFactory.generatePublic(rsaPublicKeySpec)); - } catch (GeneralSecurityException e) { - monitor.severe("Error parsing identity provider public key, skipping. The kid is: " + key.getKid()); - } - return null; - } - - private BigInteger unsignedInt(String value) { - return new BigInteger(1, Base64.getUrlDecoder().decode(value)); - } - -} diff --git a/extensions/common/iam/oauth2/oauth2-core/src/main/java/org/eclipse/edc/iam/oauth2/identity/Oauth2ServiceImpl.java b/extensions/common/iam/oauth2/oauth2-core/src/main/java/org/eclipse/edc/iam/oauth2/identity/Oauth2ServiceImpl.java deleted file mode 100644 index 28733c6ee2b..00000000000 --- a/extensions/common/iam/oauth2/oauth2-core/src/main/java/org/eclipse/edc/iam/oauth2/identity/Oauth2ServiceImpl.java +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Copyright (c) 2020 - 2022 Microsoft Corporation - * - * 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: - * Microsoft Corporation - initial API and implementation - * Fraunhofer Institute for Software and Systems Engineering - Improvements - * Microsoft Corporation - Use IDS Webhook address for JWT audience claim - * Bayerische Motoren Werke Aktiengesellschaft (BMW AG) - improvements - * - */ - -package org.eclipse.edc.iam.oauth2.identity; - -import org.eclipse.edc.iam.oauth2.spi.client.Oauth2Client; -import org.eclipse.edc.iam.oauth2.spi.client.Oauth2CredentialsRequest; -import org.eclipse.edc.iam.oauth2.spi.client.PrivateKeyOauth2CredentialsRequest.Builder; -import org.eclipse.edc.jwt.spi.JwtRegisteredClaimNames; -import org.eclipse.edc.keys.spi.PublicKeyResolver; -import org.eclipse.edc.spi.iam.ClaimToken; -import org.eclipse.edc.spi.iam.IdentityService; -import org.eclipse.edc.spi.iam.TokenParameters; -import org.eclipse.edc.spi.iam.TokenRepresentation; -import org.eclipse.edc.spi.iam.VerificationContext; -import org.eclipse.edc.spi.result.Result; -import org.eclipse.edc.token.spi.TokenDecorator; -import org.eclipse.edc.token.spi.TokenDecoratorRegistry; -import org.eclipse.edc.token.spi.TokenGenerationService; -import org.eclipse.edc.token.spi.TokenValidationRulesRegistry; -import org.eclipse.edc.token.spi.TokenValidationService; -import org.jetbrains.annotations.NotNull; - -import java.util.function.Supplier; - -import static org.eclipse.edc.iam.oauth2.Oauth2ServiceExtension.OAUTH2_TOKEN_CONTEXT; - -/** - * Implements the OAuth2 client credentials flow and bearer token validation. - */ -public class Oauth2ServiceImpl implements IdentityService { - - private static final String GRANT_TYPE = "client_credentials"; - - private final String tokenUrl; - private final Supplier privateKeySupplier; - private final Oauth2Client client; - private final TokenDecoratorRegistry jwtDecoratorRegistry; - private final TokenGenerationService tokenGenerationService; - private final TokenValidationService tokenValidationService; - private final PublicKeyResolver publicKeyResolver; - private final TokenValidationRulesRegistry tokenValidationRuleRegistry; - private final boolean tokenResourceEnabled; - - /** - * Creates a new instance of the OAuth2 Service - * - * @param tokenUrl Token URL - * @param tokenGenerationService Service used to generate the signed tokens - * @param client client for Oauth2 server - * @param jwtDecoratorRegistry Registry containing the decorator for build the JWT - * @param tokenValidationService Service used for token validation - * @param tokenResourceEnabled Add support for generating access token request with resource parameter - */ - public Oauth2ServiceImpl(String tokenUrl, TokenGenerationService tokenGenerationService, Supplier privateKeyIdSupplier, - Oauth2Client client, TokenDecoratorRegistry jwtDecoratorRegistry, TokenValidationRulesRegistry tokenValidationRuleRegistry, TokenValidationService tokenValidationService, - PublicKeyResolver publicKeyResolver, boolean tokenResourceEnabled) { - this.tokenUrl = tokenUrl; - this.privateKeySupplier = privateKeyIdSupplier; - this.client = client; - this.jwtDecoratorRegistry = jwtDecoratorRegistry; - this.tokenValidationRuleRegistry = tokenValidationRuleRegistry; - this.tokenGenerationService = tokenGenerationService; - this.tokenValidationService = tokenValidationService; - this.publicKeyResolver = publicKeyResolver; - this.tokenResourceEnabled = tokenResourceEnabled; - } - - @Override - public Result obtainClientCredentials(TokenParameters parameters) { - return generateClientAssertion() - .map(assertion -> createRequest(parameters, assertion)) - .compose(client::requestToken); - } - - @Override - public Result verifyJwtToken(TokenRepresentation tokenRepresentation, VerificationContext context) { - return tokenValidationService.validate(tokenRepresentation, publicKeyResolver, tokenValidationRuleRegistry.getRules(OAUTH2_TOKEN_CONTEXT)); - } - - @NotNull - private Result generateClientAssertion() { - var decorators = jwtDecoratorRegistry.getDecoratorsFor(OAUTH2_TOKEN_CONTEXT).toArray(TokenDecorator[]::new); - return tokenGenerationService.generate(privateKeySupplier.get(), decorators) - .map(TokenRepresentation::getToken); - } - - @NotNull - private Oauth2CredentialsRequest createRequest(TokenParameters parameters, String assertion) { - var builder = Builder.newInstance() - .url(tokenUrl) - .clientAssertion(assertion) - .scope(parameters.getStringClaim(JwtRegisteredClaimNames.SCOPE)) - .grantType(GRANT_TYPE); - - if (tokenResourceEnabled) { - builder.resource(parameters.getStringClaim(JwtRegisteredClaimNames.AUDIENCE)); - } - return builder.build(); - } - -} diff --git a/extensions/common/iam/oauth2/oauth2-core/src/main/java/org/eclipse/edc/iam/oauth2/jwt/Fingerprint.java b/extensions/common/iam/oauth2/oauth2-core/src/main/java/org/eclipse/edc/iam/oauth2/jwt/Fingerprint.java deleted file mode 100644 index 00e992097b7..00000000000 --- a/extensions/common/iam/oauth2/oauth2-core/src/main/java/org/eclipse/edc/iam/oauth2/jwt/Fingerprint.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (c) 2020, 2021 Microsoft Corporation - * - * 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: - * Microsoft Corporation - initial API and implementation - * - */ - -package org.eclipse.edc.iam.oauth2.jwt; - -import org.eclipse.edc.spi.EdcException; - -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; -import java.util.Base64; - -/** - * Produces SHA-1 fingerprints. - */ -public class Fingerprint { - private static final char[] HEX_CODES = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}; - - private Fingerprint() { - } - - /** - * Produces a SHA1 fingerprint of the given bytes using HEX encoding. Used for the x5t claim in a JWT. - */ - public static String sha1HexFingerprint(byte[] bytes) { - try { - MessageDigest md = MessageDigest.getInstance("SHA-1"); - byte[] data = md.digest(bytes); - char[] encoded = new char[data.length << 1]; - for (int i = 0, encodedPos = 0; i < data.length; i++) { - encoded[encodedPos++] = HEX_CODES[(0xF0 & data[i]) >>> 4]; - encoded[encodedPos++] = HEX_CODES[0x0F & data[i]]; - } - return new String(encoded); - } catch (NoSuchAlgorithmException e) { - throw new EdcException(e); - } - } - - /** - * Produces a SHA1 fingerprint of the given bytes using Base 64 encoding. Used for the x5t claim in a JWT. - */ - public static String sha1Base64Fingerprint(byte[] bytes) { - try { - MessageDigest md = MessageDigest.getInstance("SHA-1"); - md.update(bytes); - return Base64.getEncoder().encodeToString(md.digest()); - } catch (NoSuchAlgorithmException e) { - throw new EdcException(e); - } - } -} diff --git a/extensions/common/iam/oauth2/oauth2-core/src/main/java/org/eclipse/edc/iam/oauth2/jwt/JwkKey.java b/extensions/common/iam/oauth2/oauth2-core/src/main/java/org/eclipse/edc/iam/oauth2/jwt/JwkKey.java deleted file mode 100644 index 49849fa2252..00000000000 --- a/extensions/common/iam/oauth2/oauth2-core/src/main/java/org/eclipse/edc/iam/oauth2/jwt/JwkKey.java +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright (c) 2020, 2021 Microsoft Corporation - * - * 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: - * Microsoft Corporation - initial API and implementation - * - */ - -package org.eclipse.edc.iam.oauth2.jwt; - -import java.util.List; - -/** - * Models an identity provider JWK key. - */ -public class JwkKey { - private String kty; - private String use; - private String kid; - private String x5t; - private String nn; - private String ee; - private List x5c; - private String issuer; - - public String getKty() { - return kty; - } - - public void setKty(String kty) { - this.kty = kty; - } - - public String getUse() { - return use; - } - - public void setUse(String use) { - this.use = use; - } - - public String getKid() { - return kid; - } - - public void setKid(String kid) { - this.kid = kid; - } - - public String getX5t() { - return x5t; - } - - public void setX5t(String x5t) { - this.x5t = x5t; - } - - public String getN() { - return nn; - } - - public void setN(String n) { - nn = n; - } - - public String getE() { - return ee; - } - - public void setE(String e) { - ee = e; - } - - public List getX5c() { - return x5c; - } - - public void setX5c(List x5c) { - this.x5c = x5c; - } - - public String getIssuer() { - return issuer; - } - - public void setIssuer(String issuer) { - this.issuer = issuer; - } -} diff --git a/extensions/common/iam/oauth2/oauth2-core/src/main/java/org/eclipse/edc/iam/oauth2/jwt/JwkKeys.java b/extensions/common/iam/oauth2/oauth2-core/src/main/java/org/eclipse/edc/iam/oauth2/jwt/JwkKeys.java deleted file mode 100644 index 3c7f5782aaa..00000000000 --- a/extensions/common/iam/oauth2/oauth2-core/src/main/java/org/eclipse/edc/iam/oauth2/jwt/JwkKeys.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (c) 2020, 2021 Microsoft Corporation - * - * 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: - * Microsoft Corporation - initial API and implementation - * - */ - -package org.eclipse.edc.iam.oauth2.jwt; - -import org.jetbrains.annotations.Nullable; - -import java.util.List; - -/** - * Models an identity provider JWK keys response. - */ -public class JwkKeys { - private List keys; - - @Nullable - public List getKeys() { - return keys; - } - - public void setKeys(List keys) { - this.keys = keys; - } -} diff --git a/extensions/common/iam/oauth2/oauth2-core/src/main/java/org/eclipse/edc/iam/oauth2/jwt/X509CertificateDecorator.java b/extensions/common/iam/oauth2/oauth2-core/src/main/java/org/eclipse/edc/iam/oauth2/jwt/X509CertificateDecorator.java deleted file mode 100644 index 9f194e92e41..00000000000 --- a/extensions/common/iam/oauth2/oauth2-core/src/main/java/org/eclipse/edc/iam/oauth2/jwt/X509CertificateDecorator.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (c) 2022 Amadeus - * - * 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: - * Amadeus - Initial implementation - * - */ - -package org.eclipse.edc.iam.oauth2.jwt; - -import org.eclipse.edc.spi.EdcException; -import org.eclipse.edc.spi.iam.TokenParameters; -import org.eclipse.edc.token.spi.TokenDecorator; - -import java.security.cert.CertificateEncodingException; -import java.security.cert.X509Certificate; - -import static org.eclipse.edc.iam.oauth2.jwt.Fingerprint.sha1Base64Fingerprint; - -/** - * Creates the 'x5t' header containing the base64url-encoded SHA-1 thumbprint of the DER encoding of the thumbprint of the - * X.509 certificate corresponding to the key used to sign the JWT. This header is requested by some Oauth2 servers. - */ -public class X509CertificateDecorator implements TokenDecorator { - private final byte[] certificate; - - public X509CertificateDecorator(X509Certificate certificate) { - try { - this.certificate = certificate.getEncoded(); - } catch (CertificateEncodingException e) { - throw new EdcException(e); - } - } - - @Override - public TokenParameters.Builder decorate(TokenParameters.Builder tokenParameters) { - return tokenParameters.header("x5t", sha1Base64Fingerprint(certificate)); - } -} diff --git a/extensions/common/iam/oauth2/oauth2-core/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension b/extensions/common/iam/oauth2/oauth2-core/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension deleted file mode 100644 index b6ef0e6d77a..00000000000 --- a/extensions/common/iam/oauth2/oauth2-core/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension +++ /dev/null @@ -1,16 +0,0 @@ -# -# Copyright (c) 2020 - 2022 Microsoft Corporation -# -# 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: -# Microsoft Corporation - initial API and implementation -# -# - -org.eclipse.edc.iam.oauth2.Oauth2ServiceExtension -org.eclipse.edc.iam.oauth2.Oauth2ServiceDefaultServicesExtension diff --git a/extensions/common/iam/oauth2/oauth2-core/src/test/java/org/eclipse/edc/iam/oauth2/Oauth2DefaultServiceExtensionTest.java b/extensions/common/iam/oauth2/oauth2-core/src/test/java/org/eclipse/edc/iam/oauth2/Oauth2DefaultServiceExtensionTest.java deleted file mode 100644 index f9e52bc09f7..00000000000 --- a/extensions/common/iam/oauth2/oauth2-core/src/test/java/org/eclipse/edc/iam/oauth2/Oauth2DefaultServiceExtensionTest.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2024 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.oauth2; - -import org.eclipse.edc.junit.extensions.DependencyInjectionExtension; -import org.eclipse.edc.spi.result.Result; -import org.eclipse.edc.spi.types.domain.message.RemoteMessage; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -@ExtendWith(DependencyInjectionExtension.class) -class Oauth2DefaultServiceExtensionTest { - - - @Test - void defaultAudienceResolver(Oauth2ServiceDefaultServicesExtension extension) { - var address = "http://address"; - var remoteMessage = mock(RemoteMessage.class); - when(remoteMessage.getCounterPartyAddress()).thenReturn(address); - assertThat(extension.defaultAudienceResolver().resolve(remoteMessage)) - .extracting(Result::getContent) - .isEqualTo(address); - } - -} diff --git a/extensions/common/iam/oauth2/oauth2-core/src/test/java/org/eclipse/edc/iam/oauth2/Oauth2ServiceExtensionTest.java b/extensions/common/iam/oauth2/oauth2-core/src/test/java/org/eclipse/edc/iam/oauth2/Oauth2ServiceExtensionTest.java deleted file mode 100644 index 58d29e79b4a..00000000000 --- a/extensions/common/iam/oauth2/oauth2-core/src/test/java/org/eclipse/edc/iam/oauth2/Oauth2ServiceExtensionTest.java +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Copyright (c) 2022 Microsoft Corporation - * - * 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: - * Microsoft Corporation - initial API and implementation - * sovity GmbH - added issuedAt leeway - * - */ - -package org.eclipse.edc.iam.oauth2; - -import org.eclipse.edc.boot.system.injection.ObjectFactory; -import org.eclipse.edc.junit.extensions.DependencyInjectionExtension; -import org.eclipse.edc.keys.spi.CertificateResolver; -import org.eclipse.edc.keys.spi.PrivateKeyResolver; -import org.eclipse.edc.spi.monitor.Monitor; -import org.eclipse.edc.spi.result.Result; -import org.eclipse.edc.spi.system.ServiceExtensionContext; -import org.eclipse.edc.spi.system.configuration.ConfigFactory; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; - -import java.security.PrivateKey; -import java.security.cert.CertificateEncodingException; -import java.security.cert.X509Certificate; -import java.util.Map; - -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.contains; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -@ExtendWith(DependencyInjectionExtension.class) -class Oauth2ServiceExtensionTest { - - private final CertificateResolver certificateResolver = mock(); - private final PrivateKeyResolver privateKeyResolver = mock(); - - @BeforeEach - void setup(ServiceExtensionContext context) { - context.registerService(CertificateResolver.class, certificateResolver); - context.registerService(PrivateKeyResolver.class, privateKeyResolver); - } - - @Test - void verifyExtensionWithCertificateAlias(ServiceExtensionContext context, ObjectFactory objectFactory) { - var config = spy(ConfigFactory.fromMap(Map.of( - "edc.oauth.client.id", "id", - "edc.oauth.token.url", "url", - "edc.oauth.certificate.alias", "alias", - "edc.oauth.private.key.alias", "p_alias"))); - mockCertificate("alias"); - mockRsaPrivateKey("p_alias"); - - when(context.getConfig(any())).thenReturn(config); - objectFactory.constructInstance(Oauth2ServiceExtension.class).initialize(context); - - verify(config, times(1)).getString("edc.oauth.certificate.alias"); - verify(config, never()).getString("edc.oauth.public.key.alias"); - } - - @Test - void leewayWarningLoggedWhenLeewayUnconfigured(ServiceExtensionContext context, ObjectFactory objectFactory) { - var config = spy(ConfigFactory.fromMap(Map.of( - "edc.oauth.client.id", "id", - "edc.oauth.token.url", "url", - "edc.oauth.certificate.alias", "alias", - "edc.oauth.private.key.alias", "p_alias"))); - mockCertificate("alias"); - mockRsaPrivateKey("p_alias"); - - var monitor = mock(Monitor.class); - when(context.getMonitor()).thenReturn(monitor); - when(context.getConfig()).thenReturn(config); - objectFactory.constructInstance(Oauth2ServiceExtension.class).initialize(context); - - var message = "No value was configured for 'edc.oauth.validation.issued.at.leeway'."; - verify(monitor, times(1)).info(contains(message)); - } - - @Test - void leewayNoWarningWhenLeewayConfigured(ServiceExtensionContext context, ObjectFactory objectFactory) { - var config = spy(ConfigFactory.fromMap(Map.of( - "edc.oauth.client.id", "id", - "edc.oauth.token.url", "url", - "edc.oauth.certificate.alias", "alias", - "edc.oauth.private.key.alias", "p_alias", - "edc.oauth.validation.issued.at.leeway", "5"))); - mockCertificate("alias"); - mockRsaPrivateKey("p_alias"); - - var monitor = mock(Monitor.class); - when(context.getMonitor()).thenReturn(monitor); - when(context.getConfig(any())).thenReturn(config); - objectFactory.constructInstance(Oauth2ServiceExtension.class).initialize(context); - - var message = "No value was configured for 'edc.oauth.validation.issued.at.leeway'."; - verify(monitor, never()).info(contains(message)); - } - - private void mockRsaPrivateKey(String alias) { - var privateKey = mock(PrivateKey.class); - when(privateKey.getAlgorithm()).thenReturn("RSA"); - when(privateKeyResolver.resolvePrivateKey(alias)).thenReturn(Result.success(privateKey)); - } - - private void mockCertificate(String alias) { - try { - var certificate = mock(X509Certificate.class); - when(certificate.getEncoded()).thenReturn(new byte[]{}); - when(certificateResolver.resolveCertificate(alias)).thenReturn(certificate); - } catch (CertificateEncodingException e) { - // Should never happen, it's a checked exception in the way of mocking - throw new RuntimeException(e); - } - } -} diff --git a/extensions/common/iam/oauth2/oauth2-core/src/test/java/org/eclipse/edc/iam/oauth2/identity/IdentityProviderKeyResolverTest.java b/extensions/common/iam/oauth2/oauth2-core/src/test/java/org/eclipse/edc/iam/oauth2/identity/IdentityProviderKeyResolverTest.java deleted file mode 100644 index b52ea618b14..00000000000 --- a/extensions/common/iam/oauth2/oauth2-core/src/test/java/org/eclipse/edc/iam/oauth2/identity/IdentityProviderKeyResolverTest.java +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Copyright (c) 2020 - 2022 Microsoft Corporation - * - * 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: - * Microsoft Corporation - initial API and implementation - * Bayerische Motoren Werke Aktiengesellschaft (BMW AG) - improvements - * - */ - -package org.eclipse.edc.iam.oauth2.identity; - -import com.fasterxml.jackson.databind.ObjectMapper; -import okhttp3.Interceptor; -import okhttp3.MediaType; -import okhttp3.Protocol; -import okhttp3.Request; -import okhttp3.Response; -import okhttp3.ResponseBody; -import org.eclipse.edc.http.spi.EdcHttpClient; -import org.eclipse.edc.iam.oauth2.jwt.JwkKeys; -import org.eclipse.edc.json.JacksonTypeManager; -import org.eclipse.edc.spi.EdcException; -import org.eclipse.edc.spi.monitor.Monitor; -import org.eclipse.edc.spi.types.TypeManager; -import org.jetbrains.annotations.NotNull; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -import java.io.IOException; -import java.util.Map; - -import static java.util.Collections.emptyList; -import static java.util.Collections.emptyMap; -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.eclipse.edc.http.client.testfixtures.HttpTestUtils.testHttpClient; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -class IdentityProviderKeyResolverTest { - - private static final String JWKS_URL = "https://test.jwks.url"; - private static final String JWKS_FILE = "jwks_response.json"; - private final Interceptor interceptor = mock(Interceptor.class); - private final TypeManager typeManager = new JacksonTypeManager(); - private final EdcHttpClient httpClient = testHttpClient(interceptor); - private JwkKeys testKeys; - private IdentityProviderKeyResolver resolver; - - @BeforeEach - void setUp() { - resolver = new IdentityProviderKeyResolver(mock(Monitor.class), httpClient, typeManager, JWKS_URL, 1); - - try (var stream = getClass().getClassLoader().getResourceAsStream(JWKS_FILE)) { - testKeys = new ObjectMapper().readValue(stream, JwkKeys.class); - } catch (IOException e) { - throw new EdcException("Failed to load keys from file"); - } - } - - @Test - void getKeys_shouldGetUpdatedKeys() throws IOException { - when(interceptor.intercept(any())).thenReturn(response(200, testKeys)); - - var result = resolver.getKeys(); - - assertThat(result.succeeded()).isTrue(); - assertThat(result.getContent()).hasSize(5).containsKey("nOo3ZDrODXEK1jKWhXslHR_KXEg"); - } - - @Test - void getKeys_shouldReturnFailureIfServerReturnsError() throws IOException { - when(interceptor.intercept(any())).thenReturn(response(500, emptyMap())); - - var result = resolver.getKeys(); - - assertThat(result.failed()).isTrue(); - } - - @Test - void getKeys_shouldReturnFailureIfBodyCannotBeDeserialized() throws IOException { - when(interceptor.intercept(any())).thenReturn(response(200, null)); - - var result = resolver.getKeys(); - - assertThat(result.failed()).isTrue(); - } - - @Test - void getKeys_shouldReturnFailureIfNoKeysAreContainedInTheResult() throws IOException { - when(interceptor.intercept(any())).thenReturn(response(200, Map.of("keys", emptyList()))); - - var result = resolver.getKeys(); - - assertThat(result.failed()).isTrue(); - } - - @Test - void start_shouldThrowExceptionIfItFailsToLoadKeysTheFirstTime() throws IOException { - when(interceptor.intercept(any())).thenReturn(response(500, emptyMap())); - - assertThatThrownBy(() -> resolver.start()).isInstanceOf(EdcException.class); - } - - @NotNull - private Response response(int code, Object body) { - return new Response.Builder() - .code(code) - .body(ResponseBody.create(typeManager.writeValueAsString(body), MediaType.get("application/json"))) - .message("Test message") - .protocol(Protocol.HTTP_1_1) - .request(new Request.Builder().url("http://test.some.url").build()) - .build(); - } -} diff --git a/extensions/common/iam/oauth2/oauth2-core/src/test/java/org/eclipse/edc/iam/oauth2/identity/Oauth2ServiceImplTest.java b/extensions/common/iam/oauth2/oauth2-core/src/test/java/org/eclipse/edc/iam/oauth2/identity/Oauth2ServiceImplTest.java deleted file mode 100644 index 16cd057ce4c..00000000000 --- a/extensions/common/iam/oauth2/oauth2-core/src/test/java/org/eclipse/edc/iam/oauth2/identity/Oauth2ServiceImplTest.java +++ /dev/null @@ -1,240 +0,0 @@ -/* - * Copyright (c) 2020 - 2022 Microsoft Corporation - * - * 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: - * Microsoft Corporation - initial API and implementation - * Fraunhofer Institute for Software and Systems Engineering - Improvements - * Microsoft Corporation - Use IDS Webhook address for JWT audience claim - * Bayerische Motoren Werke Aktiengesellschaft (BMW AG) - improvements - * - */ - -package org.eclipse.edc.iam.oauth2.identity; - -import com.nimbusds.jose.JOSEException; -import com.nimbusds.jose.JWSAlgorithm; -import com.nimbusds.jose.JWSHeader; -import com.nimbusds.jose.JWSSigner; -import com.nimbusds.jose.crypto.RSASSASigner; -import com.nimbusds.jose.jwk.KeyUse; -import com.nimbusds.jose.jwk.RSAKey; -import com.nimbusds.jose.jwk.gen.RSAKeyGenerator; -import com.nimbusds.jwt.JWTClaimsSet; -import com.nimbusds.jwt.SignedJWT; -import org.eclipse.edc.iam.oauth2.Oauth2ServiceConfiguration; -import org.eclipse.edc.iam.oauth2.spi.client.Oauth2Client; -import org.eclipse.edc.iam.oauth2.spi.client.Oauth2CredentialsRequest; -import org.eclipse.edc.iam.oauth2.spi.client.PrivateKeyOauth2CredentialsRequest; -import org.eclipse.edc.keys.spi.PublicKeyResolver; -import org.eclipse.edc.policy.model.Policy; -import org.eclipse.edc.spi.iam.TokenParameters; -import org.eclipse.edc.spi.iam.TokenRepresentation; -import org.eclipse.edc.spi.iam.VerificationContext; -import org.eclipse.edc.spi.result.Result; -import org.eclipse.edc.token.TokenDecoratorRegistryImpl; -import org.eclipse.edc.token.TokenValidationRulesRegistryImpl; -import org.eclipse.edc.token.TokenValidationServiceImpl; -import org.eclipse.edc.token.rules.AudienceValidationRule; -import org.eclipse.edc.token.rules.ExpirationIssuedAtValidationRule; -import org.eclipse.edc.token.rules.NotBeforeValidationRule; -import org.eclipse.edc.token.spi.TokenDecorator; -import org.eclipse.edc.token.spi.TokenGenerationService; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.mockito.ArgumentCaptor; - -import java.time.Clock; -import java.time.Instant; -import java.util.Date; -import java.util.UUID; - -import static com.nimbusds.jwt.JWTClaimNames.AUDIENCE; -import static com.nimbusds.jwt.JWTClaimNames.EXPIRATION_TIME; -import static com.nimbusds.jwt.JWTClaimNames.NOT_BEFORE; -import static org.assertj.core.api.Assertions.assertThat; -import static org.eclipse.edc.iam.oauth2.Oauth2ServiceExtension.OAUTH2_TOKEN_CONTEXT; -import static org.eclipse.edc.jwt.spi.JwtRegisteredClaimNames.SCOPE; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -class Oauth2ServiceImplTest { - - private static final String CLIENT_ID = "client-test"; - private static final String PRIVATE_KEY_ALIAS = "pk-test"; - private static final String PUBLIC_CERTIFICATE_ALIAS = "cert-test"; - private static final String PROVIDER_AUDIENCE = "audience-test"; - private static final String ENDPOINT_AUDIENCE = "endpoint-audience-test"; - - private static final String TEST_PRIVATE_KEY_ID = "test-private-key-id"; - private static final VerificationContext VERIFICATION_CONTEXT = VerificationContext.Builder.newInstance() - .policy(Policy.Builder.newInstance().build()) - .build(); - private static final String OAUTH2_SERVER_URL = "http://oauth2-server.com"; - - private final Instant now = Instant.now(); - private final Oauth2Client client = mock(Oauth2Client.class); - private final TokenGenerationService tokenGenerationService = mock(TokenGenerationService.class); - private final TokenDecorator jwtDecorator = mock(TokenDecorator.class); - private Oauth2ServiceImpl authService; - private JWSSigner jwsSigner; - - @BeforeEach - void setUp() throws JOSEException { - var testKey = testKey(); - - jwsSigner = new RSASSASigner(testKey.toPrivateKey()); - var publicKeyResolverMock = mock(PublicKeyResolver.class); - when(publicKeyResolverMock.resolveKey(anyString())).thenReturn(Result.success(testKey.toPublicKey())); - var configuration = Oauth2ServiceConfiguration.Builder.newInstance() - .tokenUrl(OAUTH2_SERVER_URL) - .clientId(CLIENT_ID) - .privateKeyAlias(PRIVATE_KEY_ALIAS) - .publicCertificateAlias(PUBLIC_CERTIFICATE_ALIAS) - .providerAudience(PROVIDER_AUDIENCE) - .endpointAudience(ENDPOINT_AUDIENCE) - .tokenResourceEnabled(true) - .build(); - - var tokenValidationService = new TokenValidationServiceImpl(); - - var jwtDecoratorRegistry = new TokenDecoratorRegistryImpl(); - jwtDecoratorRegistry.register(OAUTH2_TOKEN_CONTEXT, jwtDecorator); - - var registry = new TokenValidationRulesRegistryImpl(); - registry.addRule(OAUTH2_TOKEN_CONTEXT, new AudienceValidationRule(configuration.getEndpointAudience())); - registry.addRule(OAUTH2_TOKEN_CONTEXT, new NotBeforeValidationRule(Clock.systemUTC(), configuration.getNotBeforeValidationLeeway(), false)); - registry.addRule(OAUTH2_TOKEN_CONTEXT, new ExpirationIssuedAtValidationRule(Clock.systemUTC(), configuration.getIssuedAtLeeway(), false)); - - authService = new Oauth2ServiceImpl(configuration.getTokenUrl(), tokenGenerationService, () -> TEST_PRIVATE_KEY_ID, client, jwtDecoratorRegistry, registry, - tokenValidationService, publicKeyResolverMock, configuration.isTokenResourceEnabled()); - - } - - @Test - void obtainClientCredentials() { - when(tokenGenerationService.generate(any(), any())).thenReturn(Result.success(TokenRepresentation.Builder.newInstance().token("assertionToken").build())); - - var tokenParameters = TokenParameters.Builder.newInstance() - .claims(AUDIENCE, "audience") - .claims(SCOPE, "scope") - .build(); - - when(client.requestToken(any())).thenReturn(Result.success(TokenRepresentation.Builder.newInstance().token("accessToken").build())); - - var result = authService.obtainClientCredentials(tokenParameters); - - assertThat(result.succeeded()).isTrue(); - assertThat(result.getContent().getToken()).isEqualTo("accessToken"); - var captor = ArgumentCaptor.forClass(Oauth2CredentialsRequest.class); - verify(client).requestToken(captor.capture()); - var captured = captor.getValue(); - assertThat(captured).isNotNull() - .isInstanceOf(PrivateKeyOauth2CredentialsRequest.class); - var capturedRequest = (PrivateKeyOauth2CredentialsRequest) captured; - assertThat(capturedRequest.getGrantType()).isEqualTo("client_credentials"); - assertThat(capturedRequest.getScope()).isEqualTo("scope"); - assertThat(capturedRequest.getClientAssertion()).isEqualTo("assertionToken"); - assertThat(capturedRequest.getClientAssertionType()).isEqualTo("urn:ietf:params:oauth:client-assertion-type:jwt-bearer"); - assertThat(capturedRequest.getResource()).isEqualTo("audience"); - } - - - @Test - void obtainClientCredentials_verifyReturnsFailureIfOauth2ClientFails() { - when(tokenGenerationService.generate(any(), any())).thenReturn(Result.success(TokenRepresentation.Builder.newInstance().token("assertionToken").build())); - - var tokenParameters = TokenParameters.Builder.newInstance() - .claims(AUDIENCE, "audience") - .claims(SCOPE, "scope") - .build(); - - when(client.requestToken(any())).thenReturn(Result.failure("test error")); - - var result = authService.obtainClientCredentials(tokenParameters); - - assertThat(result.failed()).isTrue(); - assertThat(result.getFailureDetail()).contains("test error"); - } - - @Test - void verifyNoAudienceToken() { - var jwt = createJwt(null, Date.from(now.minusSeconds(1000)), Date.from(now.plusSeconds(1000))); - - var result = authService.verifyJwtToken(jwt, VERIFICATION_CONTEXT); - - assertThat(result.succeeded()).isFalse(); - assertThat(result.getFailureMessages()).isNotEmpty(); - } - - @Test - void verifyInvalidAudienceToken() { - var jwt = createJwt("different.audience", Date.from(now.minusSeconds(1000)), Date.from(now.plusSeconds(1000))); - - var result = authService.verifyJwtToken(jwt, VERIFICATION_CONTEXT); - - assertThat(result.succeeded()).isFalse(); - assertThat(result.getFailureMessages()).isNotEmpty(); - } - - @Test - void verifyInvalidAttemptUseNotBeforeToken() { - var jwt = createJwt(PROVIDER_AUDIENCE, Date.from(now.plusSeconds(1000)), Date.from(now.plusSeconds(1000))); - - var result = authService.verifyJwtToken(jwt, VERIFICATION_CONTEXT); - - assertThat(result.succeeded()).isFalse(); - assertThat(result.getFailureMessages()).isNotEmpty(); - } - - @Test - void verifyExpiredToken() { - var jwt = createJwt(PROVIDER_AUDIENCE, Date.from(now.minusSeconds(1000)), Date.from(now.minusSeconds(1000))); - - var result = authService.verifyJwtToken(jwt, VERIFICATION_CONTEXT); - - assertThat(result.succeeded()).isFalse(); - assertThat(result.getFailureMessages()).isNotEmpty(); - } - - @Test - void verifyValidJwt() { - var jwt = createJwt(ENDPOINT_AUDIENCE, Date.from(now.minusSeconds(1000)), new Date(System.currentTimeMillis() + 1000000)); - - var result = authService.verifyJwtToken(jwt, VERIFICATION_CONTEXT); - - assertThat(result.succeeded()).isTrue(); - assertThat(result.getContent().getClaims()).hasSize(3).containsKeys(AUDIENCE, NOT_BEFORE, EXPIRATION_TIME); - } - - private RSAKey testKey() throws JOSEException { - return new RSAKeyGenerator(2048) - .keyUse(KeyUse.SIGNATURE) // indicate the intended use of the key - .keyID(UUID.randomUUID().toString()) // give the key a unique ID - .generate(); - } - - private TokenRepresentation createJwt(String aud, Date nbf, Date exp) { - var claimsSet = new JWTClaimsSet.Builder() - .audience(aud) - .notBeforeTime(nbf) - .expirationTime(exp).build(); - var header = new JWSHeader.Builder(JWSAlgorithm.RS256).keyID("an-id").build(); - - try { - var jwt = new SignedJWT(header, claimsSet); - jwt.sign(jwsSigner); - return TokenRepresentation.Builder.newInstance().token(jwt.serialize()).build(); - } catch (JOSEException e) { - throw new AssertionError(e); - } - } -} diff --git a/extensions/common/iam/oauth2/oauth2-core/src/test/java/org/eclipse/edc/iam/oauth2/jwt/FingerprintTest.java b/extensions/common/iam/oauth2/oauth2-core/src/test/java/org/eclipse/edc/iam/oauth2/jwt/FingerprintTest.java deleted file mode 100644 index 987b6648d2d..00000000000 --- a/extensions/common/iam/oauth2/oauth2-core/src/test/java/org/eclipse/edc/iam/oauth2/jwt/FingerprintTest.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (c) 2020, 2021 Microsoft Corporation - * - * 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: - * Microsoft Corporation - initial API and implementation - * - */ - -package org.eclipse.edc.iam.oauth2.jwt; - -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -import java.io.ByteArrayInputStream; -import java.security.cert.CertificateException; -import java.security.cert.CertificateFactory; -import java.security.cert.X509Certificate; -import java.util.Base64; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -class FingerprintTest { - X509Certificate certificate; - - @Test - void verifySha1HexFingerprint() throws Exception { - String fingerprint = Fingerprint.sha1HexFingerprint(certificate.getEncoded()); - assertEquals("e1b2b8e5ec19d345a4f9afec8694f0d9c0aa25cf", fingerprint); // expected SHA1 fingerprint of the test cert - } - - @Test - void verifySha1Base64Fingerprint() throws Exception { - String fingerprint = Fingerprint.sha1Base64Fingerprint(certificate.getEncoded()); - assertEquals("4bK45ewZ00Wk+a/shpTw2cCqJc8=", fingerprint); // expected SHA1 fingerprint of the test cert - } - - @BeforeEach - void setUp() throws CertificateException { - CertificateFactory factory = CertificateFactory.getInstance("X.509"); - certificate = (X509Certificate) factory.generateCertificate(new ByteArrayInputStream(Base64.getDecoder().decode(X509_CERTIFICATE.getBytes()))); - } - - // X.509 cert with header and footer stripped (required by CertificateFactory) - static final String X509_CERTIFICATE = "MIICVjCCAb8CAg37MA0GCSqGSIb3DQEBBQUAMIGbMQswCQYDVQQGEwJKUDEOMAwG" + - "A1UECBMFVG9reW8xEDAOBgNVBAcTB0NodW8ta3UxETAPBgNVBAoTCEZyYW5rNERE" + - "MRgwFgYDVQQLEw9XZWJDZXJ0IFN1cHBvcnQxGDAWBgNVBAMTD0ZyYW5rNEREIFdl" + - "YiBDQTEjMCEGCSqGSIb3DQEJARYUc3VwcG9ydEBmcmFuazRkZC5jb20wHhcNMTIw" + - "ODIyMDUyNzIzWhcNMTcwODIxMDUyNzIzWjBKMQswCQYDVQQGEwJKUDEOMAwGA1UE" + - "CAwFVG9reW8xETAPBgNVBAoMCEZyYW5rNEREMRgwFgYDVQQDDA93d3cuZXhhbXBs" + - "ZS5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMYBBrx5PlP0WNI/ZdzD" + - "+6Pktmurn+F2kQYbtc7XQh8/LTBvCo+P6iZoLEmUA9e7EXLRxgU1CVqeAi7QcAn9" + - "MwBlc8ksFJHB0rtf9pmf8Oza9E0Bynlq/4/Kb1x+d+AyhL7oK9tQwB24uHOueHi1" + - "C/iVv8CSWKiYe6hzN1txYe8rAgMBAAEwDQYJKoZIhvcNAQEFBQADgYEAASPdjigJ" + - "kXCqKWpnZ/Oc75EUcMi6HztaW8abUMlYXPIgkV2F7YanHOB7K4f7OOLjiz8DTPFf" + - "jC9UeuErhaA/zzWi8ewMTFZW/WshOrm3fNvcMrMLKtH534JKvcdMg6qIdjTFINIr" + - "evnAhf0cwULaebn+lMs8Pdl7y37+sfluVok="; - -} diff --git a/extensions/common/iam/oauth2/oauth2-core/src/test/java/org/eclipse/edc/iam/oauth2/jwt/X509CertificateDecoratorTest.java b/extensions/common/iam/oauth2/oauth2-core/src/test/java/org/eclipse/edc/iam/oauth2/jwt/X509CertificateDecoratorTest.java deleted file mode 100644 index 7fcba868f02..00000000000 --- a/extensions/common/iam/oauth2/oauth2-core/src/test/java/org/eclipse/edc/iam/oauth2/jwt/X509CertificateDecoratorTest.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (c) 2022 Amadeus - * - * 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: - * Amadeus - Initial implementation - * - */ - -package org.eclipse.edc.iam.oauth2.jwt; - -import org.eclipse.edc.spi.iam.TokenParameters; -import org.junit.jupiter.api.Test; - -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.security.cert.CertificateException; -import java.security.cert.CertificateFactory; -import java.security.cert.X509Certificate; -import java.util.Base64; -import java.util.Objects; - -import static org.assertj.core.api.Assertions.assertThat; - -class X509CertificateDecoratorTest { - - private static final String TEST_CERT_FILE = "cert.pem"; - private static final String HEADER = "-----BEGIN CERTIFICATE-----"; - private static final String FOOTER = "-----END CERTIFICATE-----"; - - private static X509Certificate createCertificate() throws CertificateException, IOException { - var classloader = Thread.currentThread().getContextClassLoader(); - var pem = new String(Objects.requireNonNull(classloader.getResourceAsStream(TEST_CERT_FILE)).readAllBytes()); - var encoded = pem.replace(HEADER, "").replaceAll("\\R", "").replace(FOOTER, ""); - CertificateFactory fact = CertificateFactory.getInstance("X.509"); - return (X509Certificate) fact.generateCertificate(new ByteArrayInputStream(Base64.getDecoder().decode(encoded.getBytes()))); - } - - @Test - void verifyDecorator() throws CertificateException, IOException { - var certificate = createCertificate(); - var decorator = new X509CertificateDecorator(certificate); - - var builder = TokenParameters.Builder.newInstance(); - decorator.decorate(builder); - - var tokenParams = builder.build(); - assertThat(tokenParams.getClaims()).isEmpty(); - assertThat(tokenParams.getHeaders()).containsOnlyKeys("x5t"); - } -} \ No newline at end of file diff --git a/extensions/common/iam/oauth2/oauth2-core/src/test/resources/cert.pem b/extensions/common/iam/oauth2/oauth2-core/src/test/resources/cert.pem deleted file mode 100644 index a1a70cc3eb1..00000000000 --- a/extensions/common/iam/oauth2/oauth2-core/src/test/resources/cert.pem +++ /dev/null @@ -1,13 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIB7DCCAVWgAwIBAgIGAYHYExlWMA0GCSqGSIb3DQEBCwUAMA8xDTALBgNVBAMM -BFRlc3QwHhcNMjIwNzA3MDk1MjE5WhcNMzIwNzA0MDk1MjE5WjAPMQ0wCwYDVQQD -DARUZXN0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDHggAW6QF9E2N2y37U -xcacS+LFZwyVIFJkd/Zbe4JF0N+qqPGgRO8kMYiXb12geuJ+lxobLQkOlsnztkfX -htVLkYoruSthMQORC/fZDhP1eV5KpR0LVACoQmLJBTbKE2tOJh5HODxvzhiV+Bi5 -DAWOhmkA1dYo1UFg8ORt/YzOvQIDAQABo1MwUTAdBgNVHQ4EFgQUwxs2XndsvlwH -4JqFpqMXF9mEDVAwHwYDVR0jBBgwFoAUwxs2XndsvlwH4JqFpqMXF9mEDVAwDwYD -VR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOBgQCajJWQ7x7TEZvCRXWr3J43 -WFoOZBjhKwDtNySoeF/mJvxEcWzeCfxvqO/zQ16+vMj/+1kW7+eex8dSYBfRtb83 -MjOtKQYd4PU5uH4QqFFyJ3oH72ZItTAikfuRcrV0Gu7lsLSkLjglUFAREr8aI0QC -0SDLUMXw7nNsSJ/s2yIiVw== ------END CERTIFICATE----- \ No newline at end of file diff --git a/extensions/common/iam/oauth2/oauth2-core/src/test/resources/jwks_response.json b/extensions/common/iam/oauth2/oauth2-core/src/test/resources/jwks_response.json deleted file mode 100644 index 70a222c551c..00000000000 --- a/extensions/common/iam/oauth2/oauth2-core/src/test/resources/jwks_response.json +++ /dev/null @@ -1,64 +0,0 @@ -{ - "keys": [ - { - "kty": "RSA", - "use": "sig", - "kid": "nOo3ZDrODXEK1jKWhXslHR_KXEg", - "x5t": "nOo3ZDrODXEK1jKWhXslHR_KXEg", - "n": "oaLLT9hkcSj2tGfZsjbu7Xz1Krs0qEicXPmEsJKOBQHauZ_kRM1HdEkgOJbUznUspE6xOuOSXjlzErqBxXAu4SCvcvVOCYG2v9G3-uIrLF5dstD0sYHBo1VomtKxzF90Vslrkn6rNQgUGIWgvuQTxm1uRklYFPEcTIRw0LnYknzJ06GC9ljKR617wABVrZNkBuDgQKj37qcyxoaxIGdxEcmVFZXJyrxDgdXh9owRmZn6LIJlGjZ9m59emfuwnBnsIQG7DirJwe9SXrLXnexRQWqyzCdkYaOqkpKrsjuxUj2-MHX31FqsdpJJsOAvYXGOYBKJRjhGrGdONVrZdUdTBQ", - "e": "AQAB", - "x5c": [ - "MIIDBTCCAe2gAwIBAgIQN33ROaIJ6bJBWDCxtmJEbjANBgkqhkiG9w0BAQsFADAtMSswKQYDVQQDEyJhY2NvdW50cy5hY2Nlc3Njb250cm9sLndpbmRvd3MubmV0MB4XDTIwMTIyMTIwNTAxN1oXDTI1MTIyMDIwNTAxN1owLTErMCkGA1UEAxMiYWNjb3VudHMuYWNjZXNzY29udHJvbC53aW5kb3dzLm5ldDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKGiy0/YZHEo9rRn2bI27u189Sq7NKhInFz5hLCSjgUB2rmf5ETNR3RJIDiW1M51LKROsTrjkl45cxK6gcVwLuEgr3L1TgmBtr/Rt/riKyxeXbLQ9LGBwaNVaJrSscxfdFbJa5J+qzUIFBiFoL7kE8ZtbkZJWBTxHEyEcNC52JJ8ydOhgvZYykete8AAVa2TZAbg4ECo9+6nMsaGsSBncRHJlRWVycq8Q4HV4faMEZmZ+iyCZRo2fZufXpn7sJwZ7CEBuw4qycHvUl6y153sUUFqsswnZGGjqpKSq7I7sVI9vjB199RarHaSSbDgL2FxjmASiUY4RqxnTjVa2XVHUwUCAwEAAaMhMB8wHQYDVR0OBBYEFI5mN5ftHloEDVNoIa8sQs7kJAeTMA0GCSqGSIb3DQEBCwUAA4IBAQBnaGnojxNgnV4+TCPZ9br4ox1nRn9tzY8b5pwKTW2McJTe0yEvrHyaItK8KbmeKJOBvASf+QwHkp+F2BAXzRiTl4Z+gNFQULPzsQWpmKlz6fIWhc7ksgpTkMK6AaTbwWYTfmpKnQw/KJm/6rboLDWYyKFpQcStu67RZ+aRvQz68Ev2ga5JsXlcOJ3gP/lE5WC1S0rjfabzdMOGP8qZQhXk4wBOgtFBaisDnbjV5pcIrjRPlhoCxvKgC/290nZ9/DLBH3TbHk8xwHXeBAnAjyAqOZij92uksAv7ZLq4MODcnQshVINXwsYshG1pQqOLwMertNaY5WtrubMRku44Dw7R" - ], - "issuer": "https://login.microsoftonline.com/{tenantid}/v2.0" - }, - { - "kty": "RSA", - "use": "sig", - "kid": "l3sQ-50cCH4xBVZLHTGwnSR7680", - "x5t": "l3sQ-50cCH4xBVZLHTGwnSR7680", - "n": "sfsXMXWuO-dniLaIELa3Pyqz9Y_rWff_AVrCAnFSdPHa8__Pmkbt_yq-6Z3u1o4gjRpKWnrjxIh8zDn1Z1RS26nkKcNg5xfWxR2K8CPbSbY8gMrp_4pZn7tgrEmoLMkwfgYaVC-4MiFEo1P2gd9mCdgIICaNeYkG1bIPTnaqquTM5KfT971MpuOVOdM1ysiejdcNDvEb7v284PYZkw2imwqiBY3FR0sVG7jgKUotFvhd7TR5WsA20GS_6ZIkUUlLUbG_rXWGl0YjZLS_Uf4q8Hbo7u-7MaFn8B69F6YaFdDlXm_A0SpedVFWQFGzMsp43_6vEzjfrFDJVAYkwb6xUQ", - "e": "AQAB", - "x5c": [ - "MIIDBTCCAe2gAwIBAgIQWPB1ofOpA7FFlOBk5iPaNTANBgkqhkiG9w0BAQsFADAtMSswKQYDVQQDEyJhY2NvdW50cy5hY2Nlc3Njb250cm9sLndpbmRvd3MubmV0MB4XDTIxMDIwNzE3MDAzOVoXDTI2MDIwNjE3MDAzOVowLTErMCkGA1UEAxMiYWNjb3VudHMuYWNjZXNzY29udHJvbC53aW5kb3dzLm5ldDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALH7FzF1rjvnZ4i2iBC2tz8qs/WP61n3/wFawgJxUnTx2vP/z5pG7f8qvumd7taOII0aSlp648SIfMw59WdUUtup5CnDYOcX1sUdivAj20m2PIDK6f+KWZ+7YKxJqCzJMH4GGlQvuDIhRKNT9oHfZgnYCCAmjXmJBtWyD052qqrkzOSn0/e9TKbjlTnTNcrIno3XDQ7xG+79vOD2GZMNopsKogWNxUdLFRu44ClKLRb4Xe00eVrANtBkv+mSJFFJS1Gxv611hpdGI2S0v1H+KvB26O7vuzGhZ/AevRemGhXQ5V5vwNEqXnVRVkBRszLKeN/+rxM436xQyVQGJMG+sVECAwEAAaMhMB8wHQYDVR0OBBYEFLlRBSxxgmNPObCFrl+hSsbcvRkcMA0GCSqGSIb3DQEBCwUAA4IBAQB+UQFTNs6BUY3AIGkS2ZRuZgJsNEr/ZEM4aCs2domd2Oqj7+5iWsnPh5CugFnI4nd+ZLgKVHSD6acQ27we+eNY6gxfpQCY1fiN/uKOOsA0If8IbPdBEhtPerRgPJFXLHaYVqD8UYDo5KNCcoB4Kh8nvCWRGPUUHPRqp7AnAcVrcbiXA/bmMCnFWuNNahcaAKiJTxYlKDaDIiPN35yECYbDj0PBWJUxobrvj5I275jbikkp8QSLYnSU/v7dMDUbxSLfZ7zsTuaF2Qx+L62PsYTwLzIFX3M8EMSQ6h68TupFTi5n0M2yIXQgoRoNEDWNJZ/aZMY/gqT02GQGBWrh+/vJ" - ], - "issuer": "https://login.microsoftonline.com/{tenantid}/v2.0" - }, - { - "kty": "RSA", - "use": "sig", - "kid": "DqUu8gf-nAgcyjP3-SuplNAXAnc", - "x5t": "DqUu8gf-nAgcyjP3-SuplNAXAnc", - "n": "1n7-nWSLeuWQzBRlYSbS8RjvWvkQeD7QL9fOWaGXbW73VNGH0YipZisPClFv6GzwfWECTWQp19WFe_lASka5-KEWkQVzCbEMaaafOIs7hC61P5cGgw7dhuW4s7f6ZYGZEzQ4F5rHE-YNRbvD51qirPNzKHk3nji1wrh0YtbPPIf--NbI98bCwLLh9avedOmqESzWOGECEMXv8LSM-B9SKg_4QuBtyBwwIakTuqo84swTBM5w8PdhpWZZDtPgH87Wz-_WjWvk99AjXl7l8pWPQJiKNujt_ck3NDFpzaLEppodhUsID0ptRA008eCU6l8T-ux19wZmb_yBnHcV3pFWhQ", - "e": "AQAB", - "x5c": [ - "MIIC8TCCAdmgAwIBAgIQYVk/tJ1e4phISvVrAALNKTANBgkqhkiG9w0BAQsFADAjMSEwHwYDVQQDExhsb2dpbi5taWNyb3NvZnRvbmxpbmUudXMwHhcNMjAxMjIxMDAwMDAwWhcNMjUxMjIxMDAwMDAwWjAjMSEwHwYDVQQDExhsb2dpbi5taWNyb3NvZnRvbmxpbmUudXMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDWfv6dZIt65ZDMFGVhJtLxGO9a+RB4PtAv185ZoZdtbvdU0YfRiKlmKw8KUW/obPB9YQJNZCnX1YV7+UBKRrn4oRaRBXMJsQxppp84izuELrU/lwaDDt2G5bizt/plgZkTNDgXmscT5g1Fu8PnWqKs83MoeTeeOLXCuHRi1s88h/741sj3xsLAsuH1q9506aoRLNY4YQIQxe/wtIz4H1IqD/hC4G3IHDAhqRO6qjzizBMEznDw92GlZlkO0+AfztbP79aNa+T30CNeXuXylY9AmIo26O39yTc0MWnNosSmmh2FSwgPSm1EDTTx4JTqXxP67HX3BmZv/IGcdxXekVaFAgMBAAGjITAfMB0GA1UdDgQWBBQ2r//lgTPcKughDkzmCtRlw+P9SzANBgkqhkiG9w0BAQsFAAOCAQEAsFdRyczNWh/qpYvcIZbDvWYzlrmFZc6blcUzns9zf7sUWtQZrZPu5DbetV2Gr2r3qtMDKXCUaR+pqoy3I2zxTX3x8bTNhZD9YAgAFlTLNSydTaK5RHyB/5kr6B7ZJeNIk3PRVhRGt6ybCJSjV/VYVkLR5fdLP+5GhvBESobAR/d0ntriTzp7/tLMb/oXx7w5Hu1m3I8rpMocoXfH2SH1GLmMXj6Mx1dtwCDYM6bsb3fhWRz9O9OMR6QNiTnq8q9wn1QzBAnRcswYzT1LKKBPNFSasCvLYOCPOZCL+W8N8jqa9ZRYNYKWXzmiSptgBEM24t3m5FUWzWqoLu9pIcnkPQ==" - ], - "issuer": "https://login.microsoftonline.com/{tenantid}/v2.0" - }, - { - "kty": "RSA", - "use": "sig", - "kid": "1LTMzakihiRla_8z2BEJVXeWMqo", - "x5t": "1LTMzakihiRla_8z2BEJVXeWMqo", - "n": "3sKcJSD4cHwTY5jYm5lNEzqk3wON1CaARO5EoWIQt5u-X-ZnW61CiRZpWpfhKwRYU153td5R8p-AJDWT-NcEJ0MHU3KiuIEPmbgJpS7qkyURuHRucDM2lO4L4XfIlvizQrlyJnJcd09uLErZEO9PcvKiDHoois2B4fGj7CsAe5UZgExJvACDlsQSku2JUyDmZUZP2_u_gCuqNJM5o0hW7FKRI3MFoYCsqSEmHnnumuJ2jF0RHDRWQpodhlAR6uKLoiWHqHO3aG7scxYMj5cMzkpe1Kq_Dm5yyHkMCSJ_JaRhwymFfV_SWkqd3n-WVZT0ADLEq0RNi9tqZ43noUnO_w", - "e": "AQAB", - "x5c": [ - "MIIDYDCCAkigAwIBAgIJAIB4jVVJ3BeuMA0GCSqGSIb3DQEBCwUAMCkxJzAlBgNVBAMTHkxpdmUgSUQgU1RTIFNpZ25pbmcgUHVibGljIEtleTAeFw0xNjA0MDUxNDQzMzVaFw0yMTA0MDQxNDQzMzVaMCkxJzAlBgNVBAMTHkxpdmUgSUQgU1RTIFNpZ25pbmcgUHVibGljIEtleTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAN7CnCUg+HB8E2OY2JuZTRM6pN8DjdQmgETuRKFiELebvl/mZ1utQokWaVqX4SsEWFNed7XeUfKfgCQ1k/jXBCdDB1NyoriBD5m4CaUu6pMlEbh0bnAzNpTuC+F3yJb4s0K5ciZyXHdPbixK2RDvT3Lyogx6KIrNgeHxo+wrAHuVGYBMSbwAg5bEEpLtiVMg5mVGT9v7v4ArqjSTOaNIVuxSkSNzBaGArKkhJh557pridoxdERw0VkKaHYZQEerii6Ilh6hzt2hu7HMWDI+XDM5KXtSqvw5ucsh5DAkifyWkYcMphX1f0lpKnd5/llWU9AAyxKtETYvbameN56FJzv8CAwEAAaOBijCBhzAdBgNVHQ4EFgQU9IdLLpbC2S8Wn1MCXsdtFac9SRYwWQYDVR0jBFIwUIAU9IdLLpbC2S8Wn1MCXsdtFac9SRahLaQrMCkxJzAlBgNVBAMTHkxpdmUgSUQgU1RTIFNpZ25pbmcgUHVibGljIEtleYIJAIB4jVVJ3BeuMAsGA1UdDwQEAwIBxjANBgkqhkiG9w0BAQsFAAOCAQEAXk0sQAib0PGqvwELTlflQEKS++vqpWYPW/2gCVCn5shbyP1J7z1nT8kE/ZDVdl3LvGgTMfdDHaRF5ie5NjkTHmVOKbbHaWpTwUFbYAFBJGnx+s/9XSdmNmW9GlUjdpd6lCZxsI6888r0ptBgKINRRrkwMlq3jD1U0kv4JlsIhafUIOqGi4+hIDXBlY0F/HJPfUU75N885/r4CCxKhmfh3PBM35XOch/NGC67fLjqLN+TIWLoxnvil9m3jRjqOA9u50JUeDGZABIYIMcAdLpI2lcfru4wXcYXuQul22nAR7yOyGKNOKULoOTE4t4AeGRqCogXSxZgaTgKSBhvhE+MGg==" - ], - "issuer": "https://login.microsoftonline.com/9188040d-6c67-4c5b-b112-36a304b66dad/v2.0" - }, - { - "kty": "RSA", - "use": "sig", - "kid": "xP_zn6I1YkXcUUmlBoPuXTGsaxk", - "x5t": "xP_zn6I1YkXcUUmlBoPuXTGsaxk", - "n": "2pWatafeb3mB0A73-Z-URwrubwDldWvivRu19GNC61MBOb3fZ4I4lyhUhNuS7aJRPJIFB6zl-HFx1nHpGg74BHe0z9skODHYZEACd2iKBIet55DdduIe1CXsZ9keyEmNaGv3XS4OW_7IDM0j5wR9OHugUifkH3PQIcFvTYanHmXojTmgjIOWoz7y0okpyN9-FbZRzdfx-ej-njaj5gR8r69muwO5wlTbIG20V40R6zYh-QODMUpayy7jDGFGw5vjFH9Ca0tLZcNQq__JKE_mp-0fODOAQobOrBUoASFkyCd95BVW7KJrndvW7ofRWaCTuZZOy5SnU4asbjMrgxFZFw", - "e": "AQAB", - "x5c": [ - "MIIDYDCCAkigAwIBAgIJAJzCyTLC+DjJMA0GCSqGSIb3DQEBCwUAMCkxJzAlBgNVBAMTHkxpdmUgSUQgU1RTIFNpZ25pbmcgUHVibGljIEtleTAeFw0xNjA3MTMyMDMyMTFaFw0yMTA3MTIyMDMyMTFaMCkxJzAlBgNVBAMTHkxpdmUgSUQgU1RTIFNpZ25pbmcgUHVibGljIEtleTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANqVmrWn3m95gdAO9/mflEcK7m8A5XVr4r0btfRjQutTATm932eCOJcoVITbku2iUTySBQes5fhxcdZx6RoO+AR3tM/bJDgx2GRAAndoigSHreeQ3XbiHtQl7GfZHshJjWhr910uDlv+yAzNI+cEfTh7oFIn5B9z0CHBb02Gpx5l6I05oIyDlqM+8tKJKcjffhW2Uc3X8fno/p42o+YEfK+vZrsDucJU2yBttFeNEes2IfkDgzFKWssu4wxhRsOb4xR/QmtLS2XDUKv/yShP5qftHzgzgEKGzqwVKAEhZMgnfeQVVuyia53b1u6H0Vmgk7mWTsuUp1OGrG4zK4MRWRcCAwEAAaOBijCBhzAdBgNVHQ4EFgQU11z579/IePwuc4WBdN4L0ljG4CUwWQYDVR0jBFIwUIAU11z579/IePwuc4WBdN4L0ljG4CWhLaQrMCkxJzAlBgNVBAMTHkxpdmUgSUQgU1RTIFNpZ25pbmcgUHVibGljIEtleYIJAJzCyTLC+DjJMAsGA1UdDwQEAwIBxjANBgkqhkiG9w0BAQsFAAOCAQEAiASLEpQseGNahE+9f9PQgmX3VgjJerNjXr1zXWXDJfFE31DxgsxddjcIgoBL9lwegOHHvwpzK1ecgH45xcJ0Z/40OgY8NITqXbQRfdgLrEGJCoyOQEbjb5PW5k2aOdn7LBxvDsH6Y8ax26v+EFMPh3G+xheh6bfoIRSK1b+44PfoDZoJ9NfJibOZ4Cq+wt/yOvpMYQDB/9CNo18wmA3RCLYjf2nAc7RO0PDYHSIq5QDWV+1awmXDKgIdRpYPpRtn9KFXQkpCeEc/lDTG+o6n7nC40wyjioyR6QmHGvNkMR4VfSoTKCTnFATyDpI1bqU2K7KNjUEsCYfwybFB8d6mjQ==" - ], - "issuer": "https://login.microsoftonline.com/9188040d-6c67-4c5b-b112-36a304b66dad/v2.0" - } - ] -} \ No newline at end of file diff --git a/extensions/common/iam/oauth2/oauth2-daps/README.md b/extensions/common/iam/oauth2/oauth2-daps/README.md deleted file mode 100644 index 565ab5f145f..00000000000 --- a/extensions/common/iam/oauth2/oauth2-daps/README.md +++ /dev/null @@ -1,8 +0,0 @@ -# Dynamic Attribute Provisioning Service (DAPS) - -## How to run integration tests -Run omejdn server: -``` -export DAPS_RESOURCES=$PWD/extensions/common/iam/oauth2/oauth2-daps/src/test/resources -docker run --rm -p 4567:4567 -v $DAPS_RESOURCES/config:/opt/config -v $DAPS_RESOURCES/keys:/opt/keys ghcr.io/fraunhofer-aisec/omejdn-server:1.4.2 -``` \ No newline at end of file diff --git a/extensions/common/iam/oauth2/oauth2-daps/build.gradle.kts b/extensions/common/iam/oauth2/oauth2-daps/build.gradle.kts deleted file mode 100644 index a77e3d971ab..00000000000 --- a/extensions/common/iam/oauth2/oauth2-daps/build.gradle.kts +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (c) 2020, 2021 Microsoft Corporation - * - * 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: - * Microsoft Corporation - initial API and implementation - * - */ - -plugins { - `java-library` -} - -dependencies { - api(project(":spi:common:core-spi")) - api(project(":spi:common:oauth2-spi")) - - testImplementation(project(":core:common:connector-core")) - testImplementation(project(":core:common:runtime-core")) - testImplementation(project(":core:common:token-core")) - testImplementation(project(":extensions:common:iam:oauth2:oauth2-core")) - testImplementation(project(":core:common:junit")) - testImplementation(libs.testcontainers.junit) -} - - diff --git a/extensions/common/iam/oauth2/oauth2-daps/src/main/java/org/eclipse/edc/iam/oauth2/daps/DapsExtension.java b/extensions/common/iam/oauth2/oauth2-daps/src/main/java/org/eclipse/edc/iam/oauth2/daps/DapsExtension.java deleted file mode 100644 index a908576f56a..00000000000 --- a/extensions/common/iam/oauth2/oauth2-daps/src/main/java/org/eclipse/edc/iam/oauth2/daps/DapsExtension.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (c) 2020, 2021 Microsoft Corporation - * - * 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: - * Amadeus - initial API and implementation - * - */ - -package org.eclipse.edc.iam.oauth2.daps; - -import org.eclipse.edc.runtime.metamodel.annotation.Extension; -import org.eclipse.edc.runtime.metamodel.annotation.Inject; -import org.eclipse.edc.runtime.metamodel.annotation.Provider; -import org.eclipse.edc.runtime.metamodel.annotation.Setting; -import org.eclipse.edc.spi.system.ServiceExtension; -import org.eclipse.edc.spi.system.ServiceExtensionContext; -import org.eclipse.edc.token.spi.TokenDecorator; -import org.eclipse.edc.token.spi.TokenDecoratorRegistry; - -/** - * Provides specialization of Oauth2 extension to interact with DAPS instance - * - * @deprecated will be removed in the next versions. - */ -@Extension(value = DapsExtension.NAME) -@Deprecated(since = "0.10.0") -public class DapsExtension implements ServiceExtension { - - public static final String NAME = "DAPS"; - public static final String DEFAULT_TOKEN_SCOPE = "idsc:IDS_CONNECTOR_ATTRIBUTES_ALL"; - public static final String OAUTH_2_DAPS_TOKEN_CONTEXT = "oauth2-daps"; - - @Setting(description = "The value of the scope claim that is passed to DAPS to obtain a DAT", defaultValue = DEFAULT_TOKEN_SCOPE, key = "edc.iam.token.scope") - private String scope; - - @Inject - private TokenDecoratorRegistry jwtDecoratorRegistry; - - @Override - public String name() { - return NAME; - } - - @Override - public void initialize(ServiceExtensionContext context) { - context.getMonitor().warning("The extension %s has been deprecated, please switch to a decentralized implementation".formatted(NAME)); - jwtDecoratorRegistry.register(OAUTH_2_DAPS_TOKEN_CONTEXT, new DapsJwtDecorator()); - } - - @Provider - public TokenDecorator createDapsTokenDecorator(ServiceExtensionContext context) { - return new DapsTokenDecorator(scope); - } -} diff --git a/extensions/common/iam/oauth2/oauth2-daps/src/main/java/org/eclipse/edc/iam/oauth2/daps/DapsJwtDecorator.java b/extensions/common/iam/oauth2/oauth2-daps/src/main/java/org/eclipse/edc/iam/oauth2/daps/DapsJwtDecorator.java deleted file mode 100644 index f0a73618678..00000000000 --- a/extensions/common/iam/oauth2/oauth2-daps/src/main/java/org/eclipse/edc/iam/oauth2/daps/DapsJwtDecorator.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (c) 2020, 2021 Microsoft Corporation - * - * 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: - * Amadeus - initial API and implementation - * - */ - -package org.eclipse.edc.iam.oauth2.daps; - -import org.eclipse.edc.spi.iam.TokenParameters; -import org.eclipse.edc.token.spi.TokenDecorator; - -@Deprecated(since = "0.10.0") -public class DapsJwtDecorator implements TokenDecorator { - - @Override - public TokenParameters.Builder decorate(TokenParameters.Builder tokenParameters) { - return tokenParameters.claims("@context", "https://w3id.org/idsa/contexts/context.jsonld") - .claims("@type", "ids:DatRequestToken"); - } -} diff --git a/extensions/common/iam/oauth2/oauth2-daps/src/main/java/org/eclipse/edc/iam/oauth2/daps/DapsTokenDecorator.java b/extensions/common/iam/oauth2/oauth2-daps/src/main/java/org/eclipse/edc/iam/oauth2/daps/DapsTokenDecorator.java deleted file mode 100644 index 90ca921581e..00000000000 --- a/extensions/common/iam/oauth2/oauth2-daps/src/main/java/org/eclipse/edc/iam/oauth2/daps/DapsTokenDecorator.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * 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.oauth2.daps; - -import org.eclipse.edc.jwt.spi.JwtRegisteredClaimNames; -import org.eclipse.edc.spi.iam.TokenParameters; -import org.eclipse.edc.token.spi.TokenDecorator; - -/** - * Token decorator that sets the {@code scope} claim on the token that is used on DSP request egress - * - * @deprecated will be removed in the upcoming versions. - */ -@Deprecated(since = "0.10.0") -public class DapsTokenDecorator implements TokenDecorator { - private final String scope; - - public DapsTokenDecorator(String configuredScope) { - this.scope = configuredScope; - } - - @Override - public TokenParameters.Builder decorate(TokenParameters.Builder tokenParametersBuilder) { - return tokenParametersBuilder.claims(JwtRegisteredClaimNames.SCOPE, scope); - } -} diff --git a/extensions/common/iam/oauth2/oauth2-daps/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension b/extensions/common/iam/oauth2/oauth2-daps/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension deleted file mode 100644 index 07e9fb8e76c..00000000000 --- a/extensions/common/iam/oauth2/oauth2-daps/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension +++ /dev/null @@ -1,15 +0,0 @@ -# -# Copyright (c) 2020, 2021 Microsoft Corporation -# -# 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: -# Microsoft Corporation - initial API and implementation -# -# - -org.eclipse.edc.iam.oauth2.daps.DapsExtension diff --git a/extensions/common/iam/oauth2/oauth2-daps/src/test/java/org/eclipse/edc/iam/oauth2/daps/DapsIntegrationTest.java b/extensions/common/iam/oauth2/oauth2-daps/src/test/java/org/eclipse/edc/iam/oauth2/daps/DapsIntegrationTest.java deleted file mode 100644 index b2abb6453bb..00000000000 --- a/extensions/common/iam/oauth2/oauth2-daps/src/test/java/org/eclipse/edc/iam/oauth2/daps/DapsIntegrationTest.java +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright (c) 2022 Microsoft Corporation - * - * 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: - * Amadeus - initial API and implementation - * Microsoft Corporation - Use IDS Webhook address for JWT audience claim - * - */ - -package org.eclipse.edc.iam.oauth2.daps; - -import org.eclipse.edc.junit.annotations.ComponentTest; -import org.eclipse.edc.junit.extensions.RuntimeExtension; -import org.eclipse.edc.junit.extensions.RuntimePerMethodExtension; -import org.eclipse.edc.jwt.spi.JwtRegisteredClaimNames; -import org.eclipse.edc.policy.model.Policy; -import org.eclipse.edc.spi.iam.IdentityService; -import org.eclipse.edc.spi.iam.TokenParameters; -import org.eclipse.edc.spi.iam.VerificationContext; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.testcontainers.containers.GenericContainer; -import org.testcontainers.containers.wait.strategy.Wait; -import org.testcontainers.junit.jupiter.Container; - -import java.nio.file.Path; -import java.util.Map; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.eclipse.edc.junit.testfixtures.TestUtils.findBuildRoot; - -@ExtendWith(RuntimePerMethodExtension.class) -@ComponentTest -class DapsIntegrationTest { - - public static final String CLIENT_CERTIFICATE_ALIAS = "1"; - public static final String CLIENT_PRIVATE_KEY_ALIAS = "2"; - private static final String AUDIENCE_IDS_CONNECTORS_ALL = "idsc:IDS_CONNECTORS_ALL"; - private static final String CLIENT_ID = "68:99:2E:D4:13:2D:FD:3A:66:6B:85:DE:FB:98:2E:2D:FD:E7:83:D7"; - private static final String CLIENT_KEYSTORE_PASSWORD = "1234"; - - private final Path resourceFolder = findBuildRoot().toPath().resolve("extensions/common/iam/oauth2/oauth2-daps/src/test/resources"); - - @Container - private final GenericContainer daps = new GenericContainer<>("ghcr.io/fraunhofer-aisec/omejdn-server:1.4.2") - .withExposedPorts(4567) - .withFileSystemBind(resourceFolder.resolve("config").toString(), "/opt/config") - .withFileSystemBind(resourceFolder.resolve("keys").toString(), "/opt/keys"); - - @Test - void retrieveTokenAndValidate(IdentityService identityService) { - var tokenParameters = TokenParameters.Builder.newInstance() - .claims(JwtRegisteredClaimNames.SCOPE, "idsc:IDS_CONNECTOR_ATTRIBUTES_ALL") - .claims(JwtRegisteredClaimNames.AUDIENCE, "audience") - .build(); - var tokenResult = identityService.obtainClientCredentials(tokenParameters); - - assertThat(tokenResult.succeeded()).withFailMessage(tokenResult::getFailureDetail).isTrue(); - - var verificationContext = VerificationContext.Builder.newInstance() - .policy(Policy.Builder.newInstance().build()) - .build(); - - var verificationResult = identityService.verifyJwtToken(tokenResult.getContent(), verificationContext); - - assertThat(verificationResult.succeeded()).withFailMessage(verificationResult::getFailureDetail).isTrue(); - } - - @BeforeEach - protected void before(RuntimeExtension extension) { - System.setProperty("edc.keystore", "src/test/resources/keystore.p12"); - System.setProperty("edc.keystore.password", CLIENT_KEYSTORE_PASSWORD); - - var jwksPath = "/.well-known/jwks.json"; - daps.waitingFor(Wait.forHttp(jwksPath)).start(); - - var dapsUrl = "http://%s:%s".formatted(daps.getHost(), daps.getFirstMappedPort()); - - extension.setConfiguration(Map.of( - "edc.oauth.token.url", dapsUrl + "/token", - "edc.oauth.client.id", CLIENT_ID, - "edc.oauth.provider.audience", AUDIENCE_IDS_CONNECTORS_ALL, - "edc.oauth.endpoint.audience", AUDIENCE_IDS_CONNECTORS_ALL, - "edc.oauth.provider.jwks.url", dapsUrl + jwksPath, - "edc.oauth.certificate.alias", CLIENT_CERTIFICATE_ALIAS, - "edc.oauth.private.key.alias", CLIENT_PRIVATE_KEY_ALIAS, - "edc.iam.token.scope", "idsc:IDS_CONNECTOR_ATTRIBUTES_ALL" - )); - } - -} diff --git a/extensions/common/iam/oauth2/oauth2-daps/src/test/java/org/eclipse/edc/iam/oauth2/daps/DapsJwtDecoratorTest.java b/extensions/common/iam/oauth2/oauth2-daps/src/test/java/org/eclipse/edc/iam/oauth2/daps/DapsJwtDecoratorTest.java deleted file mode 100644 index 6f0e550e3ad..00000000000 --- a/extensions/common/iam/oauth2/oauth2-daps/src/test/java/org/eclipse/edc/iam/oauth2/daps/DapsJwtDecoratorTest.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (c) 2020, 2021 Microsoft Corporation - * - * 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: - * Amadeus - initial API and implementation - * - */ - -package org.eclipse.edc.iam.oauth2.daps; - -import org.eclipse.edc.spi.iam.TokenParameters; -import org.junit.jupiter.api.Test; - -import static org.assertj.core.api.Assertions.assertThat; - -class DapsJwtDecoratorTest { - - private final DapsJwtDecorator decorator = new DapsJwtDecorator(); - - @Test - void verifyDecorate() { - - var builder = TokenParameters.Builder.newInstance(); - decorator.decorate(builder); - - var tokenParams = builder.build(); - assertThat(tokenParams.getHeaders()).isEmpty(); - assertThat(tokenParams.getClaims()) - .hasFieldOrPropertyWithValue("@context", "https://w3id.org/idsa/contexts/context.jsonld") - .hasFieldOrPropertyWithValue("@type", "ids:DatRequestToken"); - } - -} \ No newline at end of file diff --git a/extensions/common/iam/oauth2/oauth2-daps/src/test/java/org/eclipse/edc/iam/oauth2/daps/DapsTokenDecoratorTest.java b/extensions/common/iam/oauth2/oauth2-daps/src/test/java/org/eclipse/edc/iam/oauth2/daps/DapsTokenDecoratorTest.java deleted file mode 100644 index ba2b9faaa3a..00000000000 --- a/extensions/common/iam/oauth2/oauth2-daps/src/test/java/org/eclipse/edc/iam/oauth2/daps/DapsTokenDecoratorTest.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * 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.oauth2.daps; - -import org.eclipse.edc.spi.iam.TokenParameters; -import org.junit.jupiter.api.Test; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.eclipse.edc.jwt.spi.JwtRegisteredClaimNames.AUDIENCE; -import static org.eclipse.edc.jwt.spi.JwtRegisteredClaimNames.SCOPE; - -class DapsTokenDecoratorTest { - - @Test - void decorate() { - var decorator = new DapsTokenDecorator("test-scope"); - var bldr = TokenParameters.Builder.newInstance() - .claims(AUDIENCE, "test-audience"); - - var result = decorator.decorate(bldr).build(); - - assertThat(result.getStringClaim(AUDIENCE)).isEqualTo("test-audience"); - assertThat(result.getStringClaim(SCOPE)).isEqualTo("test-scope"); - } - -} \ No newline at end of file diff --git a/extensions/common/iam/oauth2/oauth2-daps/src/test/java/org/eclipse/edc/iam/oauth2/daps/VaultSeedExtension.java b/extensions/common/iam/oauth2/oauth2-daps/src/test/java/org/eclipse/edc/iam/oauth2/daps/VaultSeedExtension.java deleted file mode 100644 index d8d80cda3e6..00000000000 --- a/extensions/common/iam/oauth2/oauth2-daps/src/test/java/org/eclipse/edc/iam/oauth2/daps/VaultSeedExtension.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (c) 2024 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.oauth2.daps; - -import org.eclipse.edc.junit.testfixtures.TestUtils; -import org.eclipse.edc.runtime.metamodel.annotation.Inject; -import org.eclipse.edc.spi.security.Vault; -import org.eclipse.edc.spi.system.ServiceExtension; -import org.eclipse.edc.spi.system.ServiceExtensionContext; - -import static org.eclipse.edc.iam.oauth2.daps.DapsIntegrationTest.CLIENT_CERTIFICATE_ALIAS; -import static org.eclipse.edc.iam.oauth2.daps.DapsIntegrationTest.CLIENT_PRIVATE_KEY_ALIAS; - -public class VaultSeedExtension implements ServiceExtension { - - @Inject - private Vault vault; - - @Override - public void initialize(ServiceExtensionContext context) { - var certificate = TestUtils.getResourceFileContentAsString("certificate.pem"); - var privateKey = TestUtils.getResourceFileContentAsString("privatekey.pem"); - vault.storeSecret(CLIENT_CERTIFICATE_ALIAS, certificate); - vault.storeSecret(CLIENT_PRIVATE_KEY_ALIAS, privateKey); - } -} diff --git a/extensions/common/iam/oauth2/oauth2-daps/src/test/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension b/extensions/common/iam/oauth2/oauth2-daps/src/test/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension deleted file mode 100644 index 1d3d2812785..00000000000 --- a/extensions/common/iam/oauth2/oauth2-daps/src/test/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension +++ /dev/null @@ -1 +0,0 @@ -org.eclipse.edc.iam.oauth2.daps.VaultSeedExtension \ No newline at end of file diff --git a/extensions/common/iam/oauth2/oauth2-daps/src/test/resources/certificate.pem b/extensions/common/iam/oauth2/oauth2-daps/src/test/resources/certificate.pem deleted file mode 100644 index 4b9fc86a113..00000000000 --- a/extensions/common/iam/oauth2/oauth2-daps/src/test/resources/certificate.pem +++ /dev/null @@ -1,21 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIDazCCAlOgAwIBAgIUKLpU2zUcd6PlJQ90Jt2WbdG/kxgwDQYJKoZIhvcNAQEL -BQAwRTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoM -GEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDAeFw0yMTExMjIwODA1NTJaFw0zMTEx -MjAwODA1NTJaMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEw -HwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwggEiMA0GCSqGSIb3DQEB -AQUAA4IBDwAwggEKAoIBAQDq4RvLUrLw6tfY5/8Wz6QmG93Gyagbwvr4Y5nXXfMf -lKwAyV6FbxIXp2KnguuXq4wEAss0D3CHbRoSG6Wwur46gigDSaFZIqKKog1dXXaa -2GopTyptAUTedLPD2k5ZeyrU6kRqdOkOj0N1IqrqqrBSSs57zIFz7U86TUEx13+x -FrzpfkiToSPACpvHX4TSs+6bLOnImfqlGghh4lmq22RgRoUFqGa0IrLY1tARsr7g -lcxKWt1VdnudXGA32HL3QIAfTvhitbw4R3068s+wswCpkW98MjHogSR+6x3YvQI/ -gkiyZn5/5jWxrlbOwaFMB5xNkuSd5UnE4PAiaDVUNNprAgMBAAGjUzBRMB0GA1Ud -DgQWBBRomS7UEy39OmZrhd77mC4t/eeD1zAfBgNVHSMEGDAWgBRomS7UEy39OmZr -hd77mC4t/eeD1zAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQBj -KgRXg+6rJih1ENc7y2xKKoGS8GvLCAKp9KmRer3nycaqR/2YmOqAatyFKscW4FCh -s/WIel/L+8SEJSsaAXnfcjk5R18qbxFGY74z25Pbdxskq0WEWrxCVDL4jrPOSFIw -9rY4Ym6rtaPUrelcXpvNuaCSDDVlZt9R7BGncwU0sZCIHtxKnMQklnNhQ2ppRq/e -loVCvuYHS6aTG+QSj5Fejqmazgagf94yRdhQuO0HSCjU/PFyUmthCUGVGGGjcjfT -QookwrHG0TIlXkCCgVcQF+7W6g8MnxJD7JxFDM0LfmKjzx1AstY/Hv6W0JHBaSUm -96sClTHVKuOjc8ox80Oo ------END CERTIFICATE----- diff --git a/extensions/common/iam/oauth2/oauth2-daps/src/test/resources/config/clients.yml b/extensions/common/iam/oauth2/oauth2-daps/src/test/resources/config/clients.yml deleted file mode 100644 index ea39874b0b3..00000000000 --- a/extensions/common/iam/oauth2/oauth2-daps/src/test/resources/config/clients.yml +++ /dev/null @@ -1,11 +0,0 @@ ---- -- client_id: 68:99:2E:D4:13:2D:FD:3A:66:6B:85:DE:FB:98:2E:2D:FD:E7:83:D7 - name: test client - redirect_uri: - allowed_scopes: - - omejdn:write - - openid - - idsc:IDS_CONNECTOR_ATTRIBUTES_ALL - attributes: - - key: omejdn - - value: admin diff --git a/extensions/common/iam/oauth2/oauth2-daps/src/test/resources/config/omejdn.yml b/extensions/common/iam/oauth2/oauth2-daps/src/test/resources/config/omejdn.yml deleted file mode 100644 index 14d91db497d..00000000000 --- a/extensions/common/iam/oauth2/oauth2-daps/src/test/resources/config/omejdn.yml +++ /dev/null @@ -1,18 +0,0 @@ ---- -host: http://localhost:4567 -path_prefix: "/opt" -bind_to: 0.0.0.0 -allow_origin: "*" -app_env: debug -accept_audience: idsc:IDS_CONNECTORS_ALL -token: - expiration: 3600 - signing_key: keys/signing_key.pem - algorithm: RS256 - audience: idsc:IDS_CONNECTORS_ALL - issuer: http://localhost:4567 -id_token: - expiration: 3600 - signing_key: keys/signing_key.pem - algorithm: RS256 - issuer: http://localhost:4567 diff --git a/extensions/common/iam/oauth2/oauth2-daps/src/test/resources/config/scope_mapping.yml b/extensions/common/iam/oauth2/oauth2-daps/src/test/resources/config/scope_mapping.yml deleted file mode 100644 index ea8209b5a63..00000000000 --- a/extensions/common/iam/oauth2/oauth2-daps/src/test/resources/config/scope_mapping.yml +++ /dev/null @@ -1,3 +0,0 @@ ---- -idsc:IDS_CONNECTOR_ATTRIBUTES_ALL: - - omejdn \ No newline at end of file diff --git a/extensions/common/iam/oauth2/oauth2-daps/src/test/resources/keys/Njg6OTk6MkU6RDQ6MTM6MkQ6RkQ6M0E6NjY6NkI6ODU6REU6RkI6OTg6MkU6MkQ6RkQ6RTc6ODM6RDc=.cert b/extensions/common/iam/oauth2/oauth2-daps/src/test/resources/keys/Njg6OTk6MkU6RDQ6MTM6MkQ6RkQ6M0E6NjY6NkI6ODU6REU6RkI6OTg6MkU6MkQ6RkQ6RTc6ODM6RDc=.cert deleted file mode 100644 index 4b9fc86a113..00000000000 --- a/extensions/common/iam/oauth2/oauth2-daps/src/test/resources/keys/Njg6OTk6MkU6RDQ6MTM6MkQ6RkQ6M0E6NjY6NkI6ODU6REU6RkI6OTg6MkU6MkQ6RkQ6RTc6ODM6RDc=.cert +++ /dev/null @@ -1,21 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIDazCCAlOgAwIBAgIUKLpU2zUcd6PlJQ90Jt2WbdG/kxgwDQYJKoZIhvcNAQEL -BQAwRTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoM -GEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDAeFw0yMTExMjIwODA1NTJaFw0zMTEx -MjAwODA1NTJaMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEw -HwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwggEiMA0GCSqGSIb3DQEB -AQUAA4IBDwAwggEKAoIBAQDq4RvLUrLw6tfY5/8Wz6QmG93Gyagbwvr4Y5nXXfMf -lKwAyV6FbxIXp2KnguuXq4wEAss0D3CHbRoSG6Wwur46gigDSaFZIqKKog1dXXaa -2GopTyptAUTedLPD2k5ZeyrU6kRqdOkOj0N1IqrqqrBSSs57zIFz7U86TUEx13+x -FrzpfkiToSPACpvHX4TSs+6bLOnImfqlGghh4lmq22RgRoUFqGa0IrLY1tARsr7g -lcxKWt1VdnudXGA32HL3QIAfTvhitbw4R3068s+wswCpkW98MjHogSR+6x3YvQI/ -gkiyZn5/5jWxrlbOwaFMB5xNkuSd5UnE4PAiaDVUNNprAgMBAAGjUzBRMB0GA1Ud -DgQWBBRomS7UEy39OmZrhd77mC4t/eeD1zAfBgNVHSMEGDAWgBRomS7UEy39OmZr -hd77mC4t/eeD1zAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQBj -KgRXg+6rJih1ENc7y2xKKoGS8GvLCAKp9KmRer3nycaqR/2YmOqAatyFKscW4FCh -s/WIel/L+8SEJSsaAXnfcjk5R18qbxFGY74z25Pbdxskq0WEWrxCVDL4jrPOSFIw -9rY4Ym6rtaPUrelcXpvNuaCSDDVlZt9R7BGncwU0sZCIHtxKnMQklnNhQ2ppRq/e -loVCvuYHS6aTG+QSj5Fejqmazgagf94yRdhQuO0HSCjU/PFyUmthCUGVGGGjcjfT -QookwrHG0TIlXkCCgVcQF+7W6g8MnxJD7JxFDM0LfmKjzx1AstY/Hv6W0JHBaSUm -96sClTHVKuOjc8ox80Oo ------END CERTIFICATE----- diff --git a/extensions/common/iam/oauth2/oauth2-daps/src/test/resources/keys/signing_key.pem b/extensions/common/iam/oauth2/oauth2-daps/src/test/resources/keys/signing_key.pem deleted file mode 100644 index b3235be5006..00000000000 --- a/extensions/common/iam/oauth2/oauth2-daps/src/test/resources/keys/signing_key.pem +++ /dev/null @@ -1,28 +0,0 @@ ------BEGIN PRIVATE KEY----- -MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCS/2Dh4nzop3NC -J1wQpyHrExTHoWJYEmy6nBMsDQ7f2umSICf/KBIqWcsKycwxQPRS66hQXi+aMD1n -fnEFLanFZXlD8UFEXrn5pQwkCMX4hGL8iHpyDK2K/WRWzI8y46mnJ72zDC/eO/+3 -0Ah5O72hccHIAG9E70nekMClNTo29vbJLBNaRpCD2NyYBzIbRdnLpDS91OUzcxE+ -70lwmCIE4ADmIB3DVxOnFXP3bJeCc1KmAL1S4ubi5SaA7GkS6aqHC+Pa/NsCGJTW -foRj2Wc8w3X2Y+MjOeGSAQ8ErwTdEOWens+FtScGUphiFUUhS07ghcfTs/Lz6kVN -Oz1QNWepAgMBAAECggEAVY261l0ac9IZm/QKekq7y/RkELgV48p9a7Kw2d+Tu6fO -b1S10qSAxhNSwCmo5TW3vZcYdAYNUIEpC9Ykc24bNB8WD/wXD3LObMSpp0NP7Y8n -iXDpSv2j95P41SfjZCvqrrXLi6zZI0/qShITDHQ/rvnlXcEbAZT/ekDnToAHLLt4 -IaPiu89JeXOeeaBovOTK54TzKbqPVCTNtks6tHu8wLYcfe/OxVV7q1aJStFNOnbL -V0F1WQlVPRIhHQ8G0iGmwPTNoi80AO9KzSiVxBlWGW3CXZhB89246+Fs2gbJ/70N -lBM9xj2ApuiULFLeh6Ew9wmJetB9B+Ailyi6PADfcQKBgQDCT8F78Tu++IRiyyls -fd3cdQ7Fd3/fjVoYrR79alvarU95XkJjLtyoRWRLJgP0cowwUz2J//HPbPbQeAWR -LlUVpq1DLNlA5H2ES6J41jTcxBoE+7CQ8UM5eIcm3DdWk6RfbXDPWOfwuvLu7xW9 -knPHIYn7rNlz9LKAxfhOS2y07QKBgQDBqkiHE4zJVnZSovJOk38QvUPnirK8TMWs -qTDE8TSBTN+5idZa0XHNQEs2g5PD6rosql7Dpz+FeWlumRDOEqHTA9K9p3t2TTxh -HKqIxgGFma1XlkVVq8LFUw10xrPGszRyXzc1wc90WNQwGrojsWUglmG/68Bh4TBo -njFcLzbCLQKBgFCIca6GyrZZlbTEcwSuHfey5E5fOrZShVbY2ZE6NZuqXNf2gxlM -YNO0/t5OgTEdEJEuzsCVPYk0pg68z8HeLBFvJTxEKD7G9GaSWmIulXYyKH6MOh+4 -fp4hIBKxDpZpVqTeXPTy6h5RvUHeAWqyeh27/s46U13Fuv24DzOT+xf5AoGBALbf -kh8jAdV5NL/xqHc0Zk8rOXziBscyg5L4LNo7nkXejoBIPUaC8kBLzvoKIzVkaCsX -Meb0/lGOhVVvamP9ShvVR2HZTgc3BaX6CLqgpv0+UWYcuxob2A62z0UPAOHHhOXf -LWYwvjHyU2OdSVm9AG5WMrWk64RBvZF8l8Whu8Z9AoGAPbzzGiyUkcVXus6syQV1 -yVSIJdpEQ9hysW6crBoMowe5Jg4XvqBSR3jCOaK565KtJPjHZitOwgt8y+cnaKv1 -IVa9osoClWQ6jMvT5PqGVIDcIvT/9ZsC5UbLLTWPpzxin4FmzGPp8rIbR+Uj7jh8 -OCJAmcrl1M+5fA35/Tihpjw= ------END PRIVATE KEY----- diff --git a/extensions/common/iam/oauth2/oauth2-daps/src/test/resources/privatekey.pem b/extensions/common/iam/oauth2/oauth2-daps/src/test/resources/privatekey.pem deleted file mode 100644 index 7742994cbd7..00000000000 --- a/extensions/common/iam/oauth2/oauth2-daps/src/test/resources/privatekey.pem +++ /dev/null @@ -1,28 +0,0 @@ ------BEGIN PRIVATE KEY----- -MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDq4RvLUrLw6tfY -5/8Wz6QmG93Gyagbwvr4Y5nXXfMflKwAyV6FbxIXp2KnguuXq4wEAss0D3CHbRoS -G6Wwur46gigDSaFZIqKKog1dXXaa2GopTyptAUTedLPD2k5ZeyrU6kRqdOkOj0N1 -IqrqqrBSSs57zIFz7U86TUEx13+xFrzpfkiToSPACpvHX4TSs+6bLOnImfqlGghh -4lmq22RgRoUFqGa0IrLY1tARsr7glcxKWt1VdnudXGA32HL3QIAfTvhitbw4R306 -8s+wswCpkW98MjHogSR+6x3YvQI/gkiyZn5/5jWxrlbOwaFMB5xNkuSd5UnE4PAi -aDVUNNprAgMBAAECggEAek/feXIHXQ3ueTXW0LowcOfyBaLduBdBOjgj1NNH2BpD -t+UlI7dDZK314eV7afAbabtKtkGUB/H4sZVUI0Qb67v7ujqNmy0+F5NsAkK5kMlB -/2EKZtlSU8XSFxuH0XEiTN3x4r4e30YbitQSzUE1sKTkAfPtNcFOkL3KRXpDNKPz -I7KkJM7/Z7f2uzX70p/kTwAYksPNsKJZHyHCHk/l0kBDA37/MRRrM8a8qmBp/l22 -wgmwPjGjTU3KLAjsIxVvQQzV6/EV1H+wHlgHDxj9DcSqmrwJv7MuiIakpxntemfp -Ps5PQqnJbO4Jt9foR8V3ok1+zry9c8DorsbzYd1CgQKBgQD7f5VG1BLh5XHykB8/ -Fr8qrji465PCYllrdIgNR1toPKqc/+IRsVMAZoXyG5NlT+G6Jp1uI6eeKk0aPYnP -83vuaU2xgFPJMKIb2ufF2iLybTckST0KJUH4EaeJ/wTjhXvS6wSNkZZPyhXs2LzU -O2r/oey3cQv1DyMiVTTRGd9BFwKBgQDvFV+lhJpY95XphaXgIj6GXUIlcKyur5vv -IP/LfO3FZPk9zsqDN7ZmpzrHv+VZGCWR9iEnH8qIe+7P7PY93m4jXXXiALHeWEHZ -phKt2a7PLNt9uz/F+rfs+BY7SyXIZpJf4pH2kIJ0jnxHl26JYHDt/CSq+6y2ZsgI -QMgUG/b9zQKBgQDKRlTjgJInSYkaFDxtW3gpdbJ9WEuhHcTZngIG3AtyjMiUOWGz -5TDis5KrpO4pn9PnCkO4X8jidxdIMZJzxFs650rrplC9EfZv/OJIyScuYBTnhFgp -nsmuIVTksk1WSPfMLeWdjyibx+dWdQN6lsd6Dtv6tlttn90cMfem7e4XxQKBgByL -z8TChW9T+HlOdNTDIfYHEovH3UZqP1MY/JG+U+F6weuoUjPCpiuxkeohtm+h23KH -EcRLHnKXYZc/8tLGSR493YJjlNk4bnxfQOGzGRUxhO+JOP8ZhXZs1LK1sUgxPw7l -zYnEDV9/V8Vwhkku060GqxYjQKbytLWPjpQgFqiNAoGAdRZumtaUu1NZ3agKLNdJ -F7CCExrwPWA01U2QT+c/fi1BZppy+tFxBUx8I7dIm/72I3Dxe4wjcyztC71E0ZcJ -6EKRNjNspzJEo2cvhl17HpLfWPfwHMSbyajjXzsiZAmynM+1gDgR/OdvoSm734RK -6qFiMzfjNG4FjMcKmwEoNn8= ------END PRIVATE KEY----- diff --git a/extensions/common/iam/oauth2/oauth2-service/README.md b/extensions/common/iam/oauth2/oauth2-service/README.md deleted file mode 100644 index ac8e1434372..00000000000 --- a/extensions/common/iam/oauth2/oauth2-service/README.md +++ /dev/null @@ -1,9 +0,0 @@ -# OAuth 2 Service - -**DEPRECATED**: this service has been deprecated in version 0.10.0 and it will be deleted in the upcoming versions. - -This BOM provides a ready-to-use version of the [Oauth2 IdentityService](../oauth2-core) including the [Oauth2 Client](../oauth2-client) -provided by the EDC. - -> **_NOTE:_** Unless you are sure of what you are doing, you do not want to implement your own Oauth2 Client in most cases. -> This BOM should thus be considered as the standard and recommended approach of embedding the Oauth2 Identity Service into your runtime. diff --git a/extensions/common/iam/oauth2/oauth2-service/build.gradle.kts b/extensions/common/iam/oauth2/oauth2-service/build.gradle.kts deleted file mode 100644 index e4669f50fb1..00000000000 --- a/extensions/common/iam/oauth2/oauth2-service/build.gradle.kts +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright (c) 2022 Amadeus - * - * 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: - * Amadeus - initial API and implementation - * - */ - -plugins { - `java-library` -} - -dependencies { - implementation(project(":extensions:common:iam:oauth2:oauth2-client")) - implementation(project(":extensions:common:iam:oauth2:oauth2-core")) -} - - diff --git a/extensions/control-plane/api/management-api/catalog-api/src/main/java/org/eclipse/edc/connector/controlplane/api/management/catalog/v3/CatalogApiV3.java b/extensions/control-plane/api/management-api/catalog-api/src/main/java/org/eclipse/edc/connector/controlplane/api/management/catalog/v3/CatalogApiV3.java index ec3b65d8c47..c2216d6301b 100644 --- a/extensions/control-plane/api/management-api/catalog-api/src/main/java/org/eclipse/edc/connector/controlplane/api/management/catalog/v3/CatalogApiV3.java +++ b/extensions/control-plane/api/management-api/catalog-api/src/main/java/org/eclipse/edc/connector/controlplane/api/management/catalog/v3/CatalogApiV3.java @@ -174,7 +174,7 @@ record CatalogSchema( "@id": "5e839777-d93e-4785-8972-1005f51cf367", "@type": "dcat:DataService", "dct:terms": "connector", - "dct:endpointUrl": "http://localhost:16806/protocol" + "dcat:endpointURL": "http://localhost:16806/protocol" }, "dspace:participantId": "urn:connector:provider", "@context": { diff --git a/extensions/control-plane/api/management-api/policy-definition-api/src/test/java/org/eclipse/edc/connector/controlplane/api/management/policy/transform/JsonObjectFromPolicyEvaluationPlanTransformerTest.java b/extensions/control-plane/api/management-api/policy-definition-api/src/test/java/org/eclipse/edc/connector/controlplane/api/management/policy/transform/JsonObjectFromPolicyEvaluationPlanTransformerTest.java index 44009b64c0b..727f77c5afb 100644 --- a/extensions/control-plane/api/management-api/policy-definition-api/src/test/java/org/eclipse/edc/connector/controlplane/api/management/policy/transform/JsonObjectFromPolicyEvaluationPlanTransformerTest.java +++ b/extensions/control-plane/api/management-api/policy-definition-api/src/test/java/org/eclipse/edc/connector/controlplane/api/management/policy/transform/JsonObjectFromPolicyEvaluationPlanTransformerTest.java @@ -16,8 +16,9 @@ import jakarta.json.Json; import jakarta.json.JsonObject; -import org.eclipse.edc.policy.engine.spi.PolicyValidatorFunction; -import org.eclipse.edc.policy.engine.spi.RuleFunction; +import org.eclipse.edc.policy.engine.spi.PolicyContext; +import org.eclipse.edc.policy.engine.spi.PolicyRuleFunction; +import org.eclipse.edc.policy.engine.spi.PolicyValidatorRule; import org.eclipse.edc.policy.engine.spi.plan.PolicyEvaluationPlan; import org.eclipse.edc.policy.engine.spi.plan.step.AndConstraintStep; import org.eclipse.edc.policy.engine.spi.plan.step.AtomicConstraintStep; @@ -115,7 +116,7 @@ void transform_withPermissionStep() { @Test void transform_withValidators() { - var validatorFunction = mock(PolicyValidatorFunction.class); + var validatorFunction = mock(PolicyValidatorRule.class); when(validatorFunction.name()).thenReturn("Name"); var validator = new ValidatorStep(validatorFunction); @@ -184,7 +185,7 @@ private PermissionStep permissionStep() { } private PermissionStep permissionStep(ConstraintStep constraintStep) { - RuleFunction function = mock(); + PolicyRuleFunction function = mock(); when(function.name()).thenReturn("PermissionFunction"); return PermissionStep.Builder.newInstance() .rule(mock()) diff --git a/settings.gradle.kts b/settings.gradle.kts index 8fada1a8915..e5139b40139 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -166,10 +166,7 @@ include(":extensions:common:iam:decentralized-identity") include(":extensions:common:iam:decentralized-identity:identity-did-core") include(":extensions:common:iam:decentralized-identity:identity-did-web") include(":extensions:common:iam:iam-mock") -include(":extensions:common:iam:oauth2:oauth2-daps") -include(":extensions:common:iam:oauth2:oauth2-core") include(":extensions:common:iam:oauth2:oauth2-client") -include(":extensions:common:iam:oauth2:oauth2-service") include(":extensions:common:iam:verifiable-credentials") include(":extensions:common:iam:identity-trust") include(":extensions:common:iam:identity-trust:identity-trust-transform") @@ -333,7 +330,6 @@ include(":system-tests:dcp-tck-tests:presentation") // BOM modules ---------------------------------------------------------------- include(":dist:bom:controlplane-base-bom") include(":dist:bom:controlplane-dcp-bom") -include(":dist:bom:controlplane-oauth2-bom") include(":dist:bom:controlplane-feature-sql-bom") include(":dist:bom:dataplane-base-bom") diff --git a/spi/common/json-ld-spi/src/main/java/org/eclipse/edc/jsonld/spi/PropertyAndTypeNames.java b/spi/common/json-ld-spi/src/main/java/org/eclipse/edc/jsonld/spi/PropertyAndTypeNames.java index cda7feb49ec..7cb8043e52b 100644 --- a/spi/common/json-ld-spi/src/main/java/org/eclipse/edc/jsonld/spi/PropertyAndTypeNames.java +++ b/spi/common/json-ld-spi/src/main/java/org/eclipse/edc/jsonld/spi/PropertyAndTypeNames.java @@ -34,8 +34,6 @@ public interface PropertyAndTypeNames { String DCAT_CATALOG_ATTRIBUTE = DCAT_SCHEMA + "catalog"; String DCAT_DISTRIBUTION_ATTRIBUTE = DCAT_SCHEMA + "distribution"; String DCAT_ACCESS_SERVICE_ATTRIBUTE = DCAT_SCHEMA + "accessService"; - @Deprecated(since = "0.10.0") - String DCAT_ENDPOINT_URL_OLD_ATTRIBUTE = DCAT_SCHEMA + "endpointUrl"; String DCAT_ENDPOINT_URL_ATTRIBUTE = DCAT_SCHEMA + "endpointURL"; String DCAT_ENDPOINT_DESCRIPTION_ATTRIBUTE = DCAT_SCHEMA + "endpointDescription"; diff --git a/spi/common/policy-engine-spi/src/main/java/org/eclipse/edc/policy/engine/spi/AtomicConstraintFunction.java b/spi/common/policy-engine-spi/src/main/java/org/eclipse/edc/policy/engine/spi/AtomicConstraintFunction.java deleted file mode 100644 index 9fad222c2f3..00000000000 --- a/spi/common/policy-engine-spi/src/main/java/org/eclipse/edc/policy/engine/spi/AtomicConstraintFunction.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (c) 2021 Microsoft Corporation - * - * 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: - * Microsoft Corporation - initial API and implementation - * - */ - -package org.eclipse.edc.policy.engine.spi; - -import org.eclipse.edc.policy.model.Rule; - -/** - * Invoked during policy evaluation when the left operand of an atomic constraint evaluates to a key associated with this function. The function is responsible for performing - * policy evaluation on the right operand. - * - * @deprecated use {@link AtomicConstraintRuleFunction}. - */ -@Deprecated(since = "0.10.0") -@FunctionalInterface -public interface AtomicConstraintFunction extends AtomicConstraintRuleFunction { - -} diff --git a/spi/common/policy-engine-spi/src/main/java/org/eclipse/edc/policy/engine/spi/DynamicAtomicConstraintFunction.java b/spi/common/policy-engine-spi/src/main/java/org/eclipse/edc/policy/engine/spi/DynamicAtomicConstraintFunction.java deleted file mode 100644 index 6c95588ac23..00000000000 --- a/spi/common/policy-engine-spi/src/main/java/org/eclipse/edc/policy/engine/spi/DynamicAtomicConstraintFunction.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (c) 2024 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.policy.engine.spi; - -import org.eclipse.edc.policy.model.Rule; - -/** - * Invoked during policy evaluation as when the left operand of an atomic constraint evaluates to a key that is not bound to a {@link AtomicConstraintFunction}. - * The function is responsible for performing policy evaluation on the right operand and the left operand. - * - * @deprecated use {@link DynamicAtomicConstraintRuleFunction} - */ -@Deprecated(since = "0.10.0") -public interface DynamicAtomicConstraintFunction extends DynamicAtomicConstraintRuleFunction { - -} diff --git a/spi/common/policy-engine-spi/src/main/java/org/eclipse/edc/policy/engine/spi/PolicyContext.java b/spi/common/policy-engine-spi/src/main/java/org/eclipse/edc/policy/engine/spi/PolicyContext.java index 02314be97d4..7a55e5cecaa 100644 --- a/spi/common/policy-engine-spi/src/main/java/org/eclipse/edc/policy/engine/spi/PolicyContext.java +++ b/spi/common/policy-engine-spi/src/main/java/org/eclipse/edc/policy/engine/spi/PolicyContext.java @@ -40,28 +40,6 @@ public interface PolicyContext { @NotNull List getProblems(); - /** - * Gets additional data from the context by type. - * - * @param type the type class. - * @param the type of data. - * @return the object associated with the type, or null. - * @deprecated implementations should add specific get methods - */ - @Deprecated(since = "0.10.0") - T getContextData(Class type); - - /** - * Adds additional data to the context. - * - * @param type the type class. - * @param data the data. - * @param the type of data. - * @deprecated implementations should add specific set methods - */ - @Deprecated(since = "0.10.0") - void putContextData(Class type, T data); - /** * The policy scope * diff --git a/spi/common/policy-engine-spi/src/main/java/org/eclipse/edc/policy/engine/spi/PolicyContextImpl.java b/spi/common/policy-engine-spi/src/main/java/org/eclipse/edc/policy/engine/spi/PolicyContextImpl.java index 484f1e2d90f..7b0e8f9bb2a 100644 --- a/spi/common/policy-engine-spi/src/main/java/org/eclipse/edc/policy/engine/spi/PolicyContextImpl.java +++ b/spi/common/policy-engine-spi/src/main/java/org/eclipse/edc/policy/engine/spi/PolicyContextImpl.java @@ -19,16 +19,13 @@ import org.jetbrains.annotations.NotNull; import java.util.ArrayList; -import java.util.HashMap; import java.util.List; -import java.util.Map; /** * Default context implementation. */ public abstract class PolicyContextImpl implements PolicyContext { private final List problems = new ArrayList<>(); - private final Map, Object> additional = new HashMap<>(); protected PolicyContextImpl() { } @@ -48,46 +45,5 @@ public boolean hasProblems() { return problems; } - @Override - @SuppressWarnings("unchecked") - public T getContextData(Class type) { - return (T) additional.get(type); - } - - @Override - public void putContextData(Class type, T data) { - additional.put(type, data); - } - - @Deprecated(since = "0.10.0") - public static class Builder { - - private final PolicyContextImpl context = new PolicyContextImpl() { - @Override - public String scope() { - return ""; - } - }; - - private Builder() { - - } - - @Deprecated(since = "0.10.0") - public static Builder newInstance() { - return new Builder(); - } - - @Deprecated(since = "0.10.0") - public Builder additional(Class clazz, Object object) { - context.additional.put(clazz, object); - return this; - } - - @Deprecated(since = "0.10.0") - public PolicyContext build() { - return context; - } - } } diff --git a/spi/common/policy-engine-spi/src/main/java/org/eclipse/edc/policy/engine/spi/PolicyEngine.java b/spi/common/policy-engine-spi/src/main/java/org/eclipse/edc/policy/engine/spi/PolicyEngine.java index adf152c109e..349dff2c016 100644 --- a/spi/common/policy-engine-spi/src/main/java/org/eclipse/edc/policy/engine/spi/PolicyEngine.java +++ b/spi/common/policy-engine-spi/src/main/java/org/eclipse/edc/policy/engine/spi/PolicyEngine.java @@ -22,8 +22,6 @@ import org.eclipse.edc.runtime.metamodel.annotation.ExtensionPoint; import org.eclipse.edc.spi.result.Result; -import java.util.function.BiFunction; - /** * Evaluates policies. *

@@ -59,16 +57,6 @@ public interface PolicyEngine { */ Result evaluate(Policy policy, C context); - /** - * Evaluates the given policy with a context for the given scope. - * - * @deprecated use {{@link #evaluate(Policy, PolicyContext)}} because scope is determined by {@link PolicyContext} hierarchy. - */ - @Deprecated(since = "0.10.0") - default Result evaluate(String scope, Policy policy, C context) { - return evaluate(policy, context); - } - /** * Validates the given policy. */ @@ -92,18 +80,6 @@ default Result evaluate(String scope, Policy pol */ void registerFunction(Class contextType, Class type, String key, AtomicConstraintRuleFunction function); - /** - * Registers a function that is invoked when a policy contains an atomic constraint whose left operator expression evaluates to the given key for the specified scope. - * - * @param scope the scope the function applies to - * @param type the function type - * @param key the key - * @param function the function - * @deprecated use {{@link #registerFunction(Class, Class, String, AtomicConstraintRuleFunction)}} - */ - @Deprecated(since = "0.10.0") - void registerFunction(String scope, Class type, String key, AtomicConstraintRuleFunction function); - /** * Registers a function that is invoked when a policy contains an atomic constraint whose left operator expression evaluates to the given key that's not bound * to an {@link AtomicConstraintRuleFunction}. @@ -114,18 +90,6 @@ default Result evaluate(String scope, Policy pol */ void registerFunction(Class contextType, Class type, DynamicAtomicConstraintRuleFunction function); - /** - * Registers a function that is invoked when a policy contains an atomic constraint whose left operator expression evaluates to the given key that's not bound - * to an {@link AtomicConstraintFunction}. - * - * @param scope the scope the function applies to - * @param type the function type - * @param function the function - * @deprecated use {{@link #registerFunction(Class, Class, DynamicAtomicConstraintRuleFunction)}} - */ - @Deprecated(since = "0.10.0") - void registerFunction(String scope, Class type, DynamicAtomicConstraintRuleFunction function); - /** * Registers a function that is invoked when a policy contains a rule of the given type for the specified context type. * @@ -135,17 +99,6 @@ default Result evaluate(String scope, Policy pol */ void registerFunction(Class contextType, Class type, PolicyRuleFunction function); - /** - * Registers a function that is invoked when a policy contains a rule of the given type for the specified scope. - * - * @param scope the scope the function applies to - * @param type the {@link Rule} subtype - * @param function the function - * @deprecated use {{@link #registerFunction(Class, Class, PolicyRuleFunction)}} - */ - @Deprecated(since = "0.10.0") - void registerFunction(String scope, Class type, PolicyRuleFunction function); - /** * Registers a function that performs pre-validation on the policy for the given context type. */ @@ -156,35 +109,4 @@ default Result evaluate(String scope, Policy pol */ void registerPostValidator(Class contextType, PolicyValidatorRule validator); - /** - * Registers a function that performs pre-validation on the policy for the given scope. - * - * @deprecated use {@link #registerPreValidator(Class, PolicyValidatorRule)} - */ - @Deprecated(since = "0.10.0") - void registerPreValidator(String scope, BiFunction validator); - - /** - * Registers a function that performs pre-validation on the policy for the given scope. - * - * @deprecated use {@link #registerPreValidator(Class, PolicyValidatorRule)} - */ - @Deprecated(since = "0.10.0") - void registerPreValidator(String scope, PolicyValidatorFunction validator); - - /** - * Registers a function that performs post-validation on the policy for the given scope. - * - * @deprecated use {@link #registerPostValidator(Class, PolicyValidatorRule)} - */ - @Deprecated(since = "0.10.0") - void registerPostValidator(String scope, BiFunction validator); - - /** - * Registers a function that performs post-validation on the policy for the given scope. - * - * @deprecated use {@link #registerPostValidator(Class, PolicyValidatorRule)} - */ - @Deprecated(since = "0.10.0") - void registerPostValidator(String scope, PolicyValidatorFunction validator); } diff --git a/spi/common/policy-engine-spi/src/main/java/org/eclipse/edc/policy/engine/spi/PolicyValidatorFunction.java b/spi/common/policy-engine-spi/src/main/java/org/eclipse/edc/policy/engine/spi/PolicyValidatorFunction.java deleted file mode 100644 index a229afc9d36..00000000000 --- a/spi/common/policy-engine-spi/src/main/java/org/eclipse/edc/policy/engine/spi/PolicyValidatorFunction.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (c) 2024 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.policy.engine.spi; - -import org.eclipse.edc.policy.model.Policy; - -/** - * A {@link Policy} validator that can be registered in the {@link PolicyEngine} in pre- or post-evaluation phase. - * - * @deprecated use {@link PolicyValidatorRule} - */ -@Deprecated(since = "0.10.0") -@FunctionalInterface -public interface PolicyValidatorFunction extends PolicyValidatorRule { - -} diff --git a/spi/common/policy-engine-spi/src/main/java/org/eclipse/edc/policy/engine/spi/RuleFunction.java b/spi/common/policy-engine-spi/src/main/java/org/eclipse/edc/policy/engine/spi/RuleFunction.java deleted file mode 100644 index 814a17d25d7..00000000000 --- a/spi/common/policy-engine-spi/src/main/java/org/eclipse/edc/policy/engine/spi/RuleFunction.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (c) 2021 Microsoft Corporation - * - * 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: - * Microsoft Corporation - initial API and implementation - * - */ - -package org.eclipse.edc.policy.engine.spi; - -import org.eclipse.edc.policy.model.Rule; - -/** - * Invoked during policy evaluation to examine a rule node. - * - * @deprecated use {@link PolicyRuleFunction}. - */ -@Deprecated(since = "0.10.0") -public interface RuleFunction extends PolicyRuleFunction { - -} diff --git a/spi/common/policy-engine-spi/src/main/java/org/eclipse/edc/policy/engine/spi/plan/step/AtomicConstraintStep.java b/spi/common/policy-engine-spi/src/main/java/org/eclipse/edc/policy/engine/spi/plan/step/AtomicConstraintStep.java index 98fbef6662b..29e75270e1c 100644 --- a/spi/common/policy-engine-spi/src/main/java/org/eclipse/edc/policy/engine/spi/plan/step/AtomicConstraintStep.java +++ b/spi/common/policy-engine-spi/src/main/java/org/eclipse/edc/policy/engine/spi/plan/step/AtomicConstraintStep.java @@ -14,7 +14,7 @@ package org.eclipse.edc.policy.engine.spi.plan.step; -import org.eclipse.edc.policy.engine.spi.AtomicConstraintFunction; +import org.eclipse.edc.policy.engine.spi.AtomicConstraintRuleFunction; import org.eclipse.edc.policy.model.AtomicConstraint; import org.eclipse.edc.policy.model.Rule; @@ -26,7 +26,7 @@ * An evaluation step for {@link AtomicConstraint}. *

* The {@link AtomicConstraintStep} should be considered filtered when the left expression is not bound to a - * scope or an evaluation function {@link AtomicConstraintFunction} + * scope or an evaluation function {@link AtomicConstraintRuleFunction} */ public record AtomicConstraintStep(AtomicConstraint constraint, List filteringReasons, diff --git a/spi/common/policy-engine-spi/src/main/java/org/eclipse/edc/policy/engine/spi/plan/step/RuleFunctionStep.java b/spi/common/policy-engine-spi/src/main/java/org/eclipse/edc/policy/engine/spi/plan/step/RuleFunctionStep.java index cf8605a2cd3..52fbdac833f 100644 --- a/spi/common/policy-engine-spi/src/main/java/org/eclipse/edc/policy/engine/spi/plan/step/RuleFunctionStep.java +++ b/spi/common/policy-engine-spi/src/main/java/org/eclipse/edc/policy/engine/spi/plan/step/RuleFunctionStep.java @@ -15,16 +15,15 @@ package org.eclipse.edc.policy.engine.spi.plan.step; import org.eclipse.edc.policy.engine.spi.PolicyRuleFunction; -import org.eclipse.edc.policy.engine.spi.RuleFunction; import org.eclipse.edc.policy.model.Rule; /** - * An evaluation step for {@link RuleFunction} associated to a {@link Rule} + * An evaluation step for {@link PolicyRuleFunction} associated to a {@link Rule} */ public record RuleFunctionStep(PolicyRuleFunction function, R rule) { /** - * Returns the {@link RuleFunction#name()} + * Returns the {@link PolicyRuleFunction#name()} */ public String functionName() { return function.name(); diff --git a/spi/common/verifiable-credentials-spi/src/main/java/org/eclipse/edc/iam/verifiablecredentials/spi/model/revocation/bitstringstatuslist/BitstringStatusListCredential.java b/spi/common/verifiable-credentials-spi/src/main/java/org/eclipse/edc/iam/verifiablecredentials/spi/model/revocation/bitstringstatuslist/BitstringStatusListCredential.java index 1eaf2a5202c..ef39878a9ac 100644 --- a/spi/common/verifiable-credentials-spi/src/main/java/org/eclipse/edc/iam/verifiablecredentials/spi/model/revocation/bitstringstatuslist/BitstringStatusListCredential.java +++ b/spi/common/verifiable-credentials-spi/src/main/java/org/eclipse/edc/iam/verifiablecredentials/spi/model/revocation/bitstringstatuslist/BitstringStatusListCredential.java @@ -51,7 +51,7 @@ public Instant validUntil() { * @see W3C BitStringStatusListCredential * @deprecated the "ttl" field is in conflict with the {@link BitstringStatusListCredential#validUntil()} field and may get removed in the future. */ - @Deprecated(since = "0.9.0") + @Deprecated(since = "0.14.0") public Duration ttl() { var ttl = ofNullable(credentialSubject.get(0).getClaim(BITSTRING_STATUS_LIST_PREFIX, BITSTRING_TTL_LITERAL)) .map(String::valueOf) diff --git a/spi/common/verifiable-credentials-spi/src/test/java/org/eclipse/edc/iam/verifiablecredentials/spi/model/revocation/bitstringstatuslist/BitstringStatusListCredentialTest.java b/spi/common/verifiable-credentials-spi/src/test/java/org/eclipse/edc/iam/verifiablecredentials/spi/model/revocation/bitstringstatuslist/BitstringStatusListCredentialTest.java index dd708ad0d4a..96aaf66b060 100644 --- a/spi/common/verifiable-credentials-spi/src/test/java/org/eclipse/edc/iam/verifiablecredentials/spi/model/revocation/bitstringstatuslist/BitstringStatusListCredentialTest.java +++ b/spi/common/verifiable-credentials-spi/src/test/java/org/eclipse/edc/iam/verifiablecredentials/spi/model/revocation/bitstringstatuslist/BitstringStatusListCredentialTest.java @@ -116,4 +116,4 @@ void parse_noEncodedList_expectException() { assertThatThrownBy(action).isInstanceOf(IllegalArgumentException.class); } -} \ No newline at end of file +} diff --git a/system-tests/bom-tests/src/test/java/org/eclipse/edc/test/bom/BomSmokeTests.java b/system-tests/bom-tests/src/test/java/org/eclipse/edc/test/bom/BomSmokeTests.java index 1e08e4c9629..82619f88929 100644 --- a/system-tests/bom-tests/src/test/java/org/eclipse/edc/test/bom/BomSmokeTests.java +++ b/system-tests/bom-tests/src/test/java/org/eclipse/edc/test/bom/BomSmokeTests.java @@ -14,12 +14,10 @@ package org.eclipse.edc.test.bom; -import org.eclipse.edc.boot.vault.InMemoryVault; import org.eclipse.edc.junit.annotations.EndToEndTest; import org.eclipse.edc.junit.extensions.EmbeddedRuntime; import org.eclipse.edc.junit.extensions.RuntimeExtension; import org.eclipse.edc.junit.extensions.RuntimePerMethodExtension; -import org.eclipse.edc.spi.security.Vault; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Nested; @@ -32,10 +30,8 @@ import static io.restassured.RestAssured.given; import static org.awaitility.Awaitility.await; -import static org.eclipse.edc.junit.testfixtures.TestUtils.getResourceFileContentAsString; import static org.eclipse.edc.util.io.Ports.getFreePort; import static org.hamcrest.Matchers.equalTo; -import static org.mockito.Mockito.mock; import static org.mockserver.model.HttpRequest.request; import static org.mockserver.model.HttpResponse.response; import static org.mockserver.stop.Stop.stopQuietly; @@ -87,57 +83,6 @@ class ControlPlaneDcp extends SmokeTest { )); } - @Nested - @EndToEndTest - class ControlPlaneOauth2 extends SmokeTest { - - @RegisterExtension - protected static RuntimeExtension runtime; - private static ClientAndServer jwksServer; - - static { - var stringStringMap = new java.util.HashMap() { - { - put("edc.oauth.token.url", "https://oauth2.com/token"); - put("edc.oauth.certificate.alias", "test-alias"); - put("edc.oauth.private.key.alias", "private-test-alias"); - put("web.http.management.port", "8081"); - put("web.http.management.path", "/api/management"); - put("web.http.port", DEFAULT_PORT); - put("web.http.path", DEFAULT_PATH); - put("web.http.control.port", String.valueOf(getFreePort())); - put("web.http.control.path", "/api/control"); - put("web.http.version.port", String.valueOf(getFreePort())); - put("web.http.version.path", "/api/version"); - - put("edc.oauth.provider.jwks.url", "http://localhost:9999/jwks"); - put("edc.oauth.client.id", "test-client"); - } - }; - runtime = new RuntimePerMethodExtension(new EmbeddedRuntime("control-plane-oauth2-bom", - stringStringMap, - ":dist:bom:controlplane-oauth2-bom" - )); - } - - @BeforeAll - static void setup() { - var v = new InMemoryVault(mock()); - v.storeSecret("test-alias", getResourceFileContentAsString("cert.pem")); - runtime.registerServiceMock(Vault.class, v); - - // mock the JWKS server, respond with some arbitrary JWKS - jwksServer = ClientAndServer.startClientAndServer(9999); - jwksServer.when(request().withPath("/jwks").withMethod("GET")) - .respond(response().withStatusCode(200).withBody(getResourceFileContentAsString("jwks_response.json"))); - } - - @AfterAll - static void cleanup() { - stopQuietly(jwksServer); - } - } - @Nested @EndToEndTest public class DataPlaneBase extends SmokeTest { diff --git a/system-tests/management-api/management-api-test-runner/src/test/java/org/eclipse/edc/test/e2e/managementapi/CatalogApiEndToEndTest.java b/system-tests/management-api/management-api-test-runner/src/test/java/org/eclipse/edc/test/e2e/managementapi/CatalogApiEndToEndTest.java index a9b431e1887..90f59d03621 100644 --- a/system-tests/management-api/management-api-test-runner/src/test/java/org/eclipse/edc/test/e2e/managementapi/CatalogApiEndToEndTest.java +++ b/system-tests/management-api/management-api-test-runner/src/test/java/org/eclipse/edc/test/e2e/managementapi/CatalogApiEndToEndTest.java @@ -180,7 +180,7 @@ void requestCatalog_whenAssetIsCatalogAsset_shouldReturnCatalogOfCatalogs(Manage .body("'dcat:catalog'.'@type'", equalTo("dcat:Catalog")) .body("'dcat:catalog'.isCatalog", equalTo(true)) .body("'dcat:catalog'.'@id'", equalTo(catalogAssetId)) - .body("'dcat:catalog'.'dcat:service'.'dcat:endpointUrl'", equalTo("http://quizzqua.zz/buzz")) + .body("'dcat:catalog'.'dcat:service'.'dcat:endpointURL'", equalTo("http://quizzqua.zz/buzz")) .body("'dcat:catalog'.'dcat:distribution'.'dcat:accessService'.'@id'", equalTo(Base64.getUrlEncoder().encodeToString(catalogAssetId.getBytes()))); } diff --git a/system-tests/management-api/management-api-test-runner/src/test/java/org/eclipse/edc/test/e2e/managementapi/TestFunctions.java b/system-tests/management-api/management-api-test-runner/src/test/java/org/eclipse/edc/test/e2e/managementapi/TestFunctions.java index a25dfd8cdec..dac53fd908c 100644 --- a/system-tests/management-api/management-api-test-runner/src/test/java/org/eclipse/edc/test/e2e/managementapi/TestFunctions.java +++ b/system-tests/management-api/management-api-test-runner/src/test/java/org/eclipse/edc/test/e2e/managementapi/TestFunctions.java @@ -22,7 +22,7 @@ import org.eclipse.edc.connector.controlplane.contract.spi.types.negotiation.ContractNegotiation; import org.eclipse.edc.connector.controlplane.transfer.spi.types.TransferProcess; import org.eclipse.edc.edr.spi.types.EndpointDataReferenceEntry; -import org.eclipse.edc.policy.engine.spi.PolicyValidatorFunction; +import org.eclipse.edc.policy.engine.spi.PolicyValidatorRule; import org.eclipse.edc.policy.engine.spi.plan.PolicyEvaluationPlan; import org.eclipse.edc.policy.engine.spi.plan.step.AndConstraintStep; import org.eclipse.edc.policy.engine.spi.plan.step.AtomicConstraintStep; @@ -271,7 +271,7 @@ public static PolicyEvaluationPlan createPolicyEvaluationPlan() { var duty = DutyStep.Builder.newInstance().constraint(xoneConstraintStep).rule(mock()).build(); var prohibition = ProhibitionStep.Builder.newInstance().constraint(andConstraintStep).rule(mock()).build(); - var validatorFunction = mock(PolicyValidatorFunction.class); + var validatorFunction = mock(PolicyValidatorRule.class); when(validatorFunction.name()).thenReturn("FunctionName"); return PolicyEvaluationPlan.Builder.newInstance()