Skip to content

Commit

Permalink
feat: strict policy definition validation
Browse files Browse the repository at this point in the history
  • Loading branch information
wolf4ood committed Nov 27, 2024
1 parent 5765d00 commit e21f946
Show file tree
Hide file tree
Showing 13 changed files with 369 additions and 26 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ private boolean isCacheExpired() {
private Result<Void> updateCache() {
var membershipCredToken = createMembershipPresentation();
if (membershipCredToken.failed()) {
return membershipCredToken.mapTo();
return membershipCredToken.mapEmpty();
}

var request = new Request.Builder()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,11 @@
import org.eclipse.edc.runtime.metamodel.annotation.Inject;
import org.eclipse.edc.spi.system.ServiceExtension;
import org.eclipse.edc.spi.system.ServiceExtensionContext;
import org.eclipse.tractusx.edc.policy.cx.contractreference.ContractReferenceConstraintFunction;
import org.eclipse.tractusx.edc.policy.cx.dismantler.DismantlerCredentialConstraintFunction;
import org.eclipse.tractusx.edc.policy.cx.framework.FrameworkAgreementCredentialConstraintFunction;
import org.eclipse.tractusx.edc.policy.cx.membership.MembershipCredentialConstraintFunction;
import org.eclipse.tractusx.edc.policy.cx.usage.UsagePurposeConstraintFunction;

import java.util.Set;
import java.util.stream.Stream;
Expand All @@ -44,9 +46,11 @@
import static org.eclipse.tractusx.edc.policy.cx.common.PolicyScopes.NEGOTIATION_SCOPE;
import static org.eclipse.tractusx.edc.policy.cx.common.PolicyScopes.TRANSFER_PROCESS_REQUEST_SCOPE;
import static org.eclipse.tractusx.edc.policy.cx.common.PolicyScopes.TRANSFER_PROCESS_SCOPE;
import static org.eclipse.tractusx.edc.policy.cx.contractreference.ContractReferenceConstraintFunction.CONTRACT_REFERENCE;
import static org.eclipse.tractusx.edc.policy.cx.dismantler.DismantlerCredentialConstraintFunction.DISMANTLER_LITERAL;
import static org.eclipse.tractusx.edc.policy.cx.framework.FrameworkAgreementCredentialConstraintFunction.FRAMEWORK_AGREEMENT_LITERAL;
import static org.eclipse.tractusx.edc.policy.cx.membership.MembershipCredentialConstraintFunction.MEMBERSHIP_LITERAL;
import static org.eclipse.tractusx.edc.policy.cx.usage.UsagePurposeConstraintFunction.USAGE_PURPOSE;


/**
Expand All @@ -65,17 +69,6 @@ public class CxPolicyExtension implements ServiceExtension {
@Inject
private RuleBindingRegistry bindingRegistry;

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

@Override
public void initialize(ServiceExtensionContext context) {
registerFunctions(policyEngine);
registerBindings(bindingRegistry);
}

public static void registerFunctions(PolicyEngine engine) {
engine.registerFunction(CatalogPolicyContext.class, Permission.class, new DismantlerCredentialConstraintFunction<>());
engine.registerFunction(ContractNegotiationPolicyContext.class, Permission.class, new DismantlerCredentialConstraintFunction<>());
Expand All @@ -88,6 +81,14 @@ public static void registerFunctions(PolicyEngine engine) {
engine.registerFunction(CatalogPolicyContext.class, Permission.class, new MembershipCredentialConstraintFunction<>());
engine.registerFunction(ContractNegotiationPolicyContext.class, Permission.class, new MembershipCredentialConstraintFunction<>());
engine.registerFunction(TransferProcessPolicyContext.class, Permission.class, new MembershipCredentialConstraintFunction<>());

engine.registerFunction(CatalogPolicyContext.class, Permission.class, CX_POLICY_NS + USAGE_PURPOSE, new UsagePurposeConstraintFunction<>());
engine.registerFunction(ContractNegotiationPolicyContext.class, Permission.class, CX_POLICY_NS + USAGE_PURPOSE, new UsagePurposeConstraintFunction<>());
engine.registerFunction(TransferProcessPolicyContext.class, Permission.class, CX_POLICY_NS + USAGE_PURPOSE, new UsagePurposeConstraintFunction<>());

engine.registerFunction(CatalogPolicyContext.class, Permission.class, CX_POLICY_NS + CONTRACT_REFERENCE, new ContractReferenceConstraintFunction<>());
engine.registerFunction(ContractNegotiationPolicyContext.class, Permission.class, CX_POLICY_NS + CONTRACT_REFERENCE, new ContractReferenceConstraintFunction<>());
engine.registerFunction(TransferProcessPolicyContext.class, Permission.class, CX_POLICY_NS + CONTRACT_REFERENCE, new ContractReferenceConstraintFunction<>());
}

public static void registerBindings(RuleBindingRegistry registry) {
Expand All @@ -101,5 +102,24 @@ public static void registerBindings(RuleBindingRegistry registry) {
registry.bind(ODRL_SCHEMA + "use", CATALOG_SCOPE);
registry.bind(ODRL_SCHEMA + "use", NEGOTIATION_SCOPE);
registry.bind(ODRL_SCHEMA + "use", TRANSFER_PROCESS_SCOPE);

registry.bind(CX_POLICY_NS + USAGE_PURPOSE, CATALOG_SCOPE);
registry.bind(CX_POLICY_NS + USAGE_PURPOSE, NEGOTIATION_SCOPE);
registry.bind(CX_POLICY_NS + USAGE_PURPOSE, TRANSFER_PROCESS_SCOPE);

registry.bind(CX_POLICY_NS + CONTRACT_REFERENCE, CATALOG_SCOPE);
registry.bind(CX_POLICY_NS + CONTRACT_REFERENCE, NEGOTIATION_SCOPE);
registry.bind(CX_POLICY_NS + CONTRACT_REFERENCE, TRANSFER_PROCESS_SCOPE);
}

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

@Override
public void initialize(ServiceExtensionContext context) {
registerFunctions(policyEngine);
registerBindings(bindingRegistry);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*
* Copyright (c) 2024 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
*
* See the NOTICE file(s) distributed with this work for additional
* information regarding copyright ownership.
*
* 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.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* SPDX-License-Identifier: Apache-2.0
*/

package org.eclipse.tractusx.edc.policy.cx.contractreference;

import org.eclipse.edc.iam.verifiablecredentials.spi.model.VerifiableCredential;
import org.eclipse.edc.participant.spi.ParticipantAgent;
import org.eclipse.edc.participant.spi.ParticipantAgentPolicyContext;
import org.eclipse.edc.policy.engine.spi.AtomicConstraintRuleFunction;
import org.eclipse.edc.policy.engine.spi.PolicyContext;
import org.eclipse.edc.policy.model.Operator;
import org.eclipse.edc.policy.model.Permission;


/**
* This constraint function checks that a MembershipCredential is present in a list of {@link VerifiableCredential}
* objects extracted from a {@link ParticipantAgent} which is expected to be present on the {@link PolicyContext}.
*/
public class ContractReferenceConstraintFunction<C extends ParticipantAgentPolicyContext> implements AtomicConstraintRuleFunction<Permission, C> {
public static final String CONTRACT_REFERENCE = "ContractReference";

@Override
public boolean evaluate(Operator operator, Object rightOperand, Permission permission, C c) {
return true;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*
* Copyright (c) 2024 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
*
* See the NOTICE file(s) distributed with this work for additional
* information regarding copyright ownership.
*
* 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.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* SPDX-License-Identifier: Apache-2.0
*/

package org.eclipse.tractusx.edc.policy.cx.usage;

import org.eclipse.edc.iam.verifiablecredentials.spi.model.VerifiableCredential;
import org.eclipse.edc.participant.spi.ParticipantAgent;
import org.eclipse.edc.participant.spi.ParticipantAgentPolicyContext;
import org.eclipse.edc.policy.engine.spi.AtomicConstraintRuleFunction;
import org.eclipse.edc.policy.engine.spi.PolicyContext;
import org.eclipse.edc.policy.model.Operator;
import org.eclipse.edc.policy.model.Permission;


/**
* This constraint function checks that a MembershipCredential is present in a list of {@link VerifiableCredential}
* objects extracted from a {@link ParticipantAgent} which is expected to be present on the {@link PolicyContext}.
*/
public class UsagePurposeConstraintFunction<C extends ParticipantAgentPolicyContext> implements AtomicConstraintRuleFunction<Permission, C> {
public static final String USAGE_PURPOSE = "UsagePurpose";

@Override
public boolean evaluate(Operator operator, Object rightOperand, Permission permission, C c) {
return true;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/********************************************************************************
* Copyright (c) 2024 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
*
* See the NOTICE file(s) distributed with this work for additional
* information regarding copyright ownership.
*
* 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.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* SPDX-License-Identifier: Apache-2.0
********************************************************************************/

package org.eclipse.tractusx.edc.policy.cx.contractreference;

import org.eclipse.edc.participant.spi.ParticipantAgent;
import org.eclipse.edc.participant.spi.ParticipantAgentPolicyContext;
import org.eclipse.edc.policy.model.Operator;
import org.eclipse.tractusx.edc.policy.cx.TestParticipantAgentPolicyContext;
import org.junit.jupiter.api.Test;

import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;

class ContractReferenceConstraintFunctionTest {

private final ParticipantAgent participantAgent = mock();
private final ContractReferenceConstraintFunction<ParticipantAgentPolicyContext> function = new ContractReferenceConstraintFunction<>();
private final ParticipantAgentPolicyContext context = new TestParticipantAgentPolicyContext(participantAgent);

@Test
void evaluate() {
assertThat(function.evaluate(Operator.EQ, "contractRef", null, context)).isTrue();
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/********************************************************************************
* Copyright (c) 2024 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
*
* See the NOTICE file(s) distributed with this work for additional
* information regarding copyright ownership.
*
* 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.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* SPDX-License-Identifier: Apache-2.0
********************************************************************************/

package org.eclipse.tractusx.edc.policy.cx.usage;

import org.eclipse.edc.participant.spi.ParticipantAgent;
import org.eclipse.edc.participant.spi.ParticipantAgentPolicyContext;
import org.eclipse.edc.policy.model.Operator;
import org.eclipse.tractusx.edc.policy.cx.TestParticipantAgentPolicyContext;
import org.junit.jupiter.api.Test;

import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;

class UsagePurposeConstraintFunctionTest {

private final ParticipantAgent participantAgent = mock();
private final UsagePurposeConstraintFunction<ParticipantAgentPolicyContext> function = new UsagePurposeConstraintFunction<>();
private final ParticipantAgentPolicyContext context = new TestParticipantAgentPolicyContext(participantAgent);

@Test
void evaluate() {
assertThat(function.evaluate(Operator.EQ, "usagePurpose", null, context)).isTrue();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,6 @@ private Result<Map<String, Object>> mapClaims(Map<String, String> claims, Map<St
var result = mappings.entrySet().stream()
.map((entry -> mapClaim(claims, entry)))
.peek(inner -> inner.onSuccess(mapped -> payload.put(mapped.getKey(), mapped.getValue())))
.map(Result::mapTo)
.reduce(Result::merge)
.orElseGet(() -> Result.success(null));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ public Map<String, String> getConfiguration() {
put("edc.dataplane.api.public.baseurl", "http://localhost:%d/api/public/v2/data".formatted(dataPlanePublic.getPort()));
put("edc.catalog.cache.execution.delay.seconds", "2");
put("edc.catalog.cache.execution.period.seconds", "2");
put("edc.policy.validation.enabled", "true");
}
};
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
import com.nimbusds.jose.jwk.Curve;
import com.nimbusds.jose.jwk.ECKey;
import com.nimbusds.jose.jwk.gen.ECKeyGenerator;
import org.eclipse.edc.boot.system.injection.InjectionContainer;
import org.eclipse.edc.boot.system.DependencyGraph;
import org.eclipse.edc.iam.did.spi.resolution.DidPublicKeyResolver;
import org.eclipse.edc.iam.identitytrust.spi.SecureTokenService;
import org.eclipse.edc.iam.identitytrust.sts.embedded.EmbeddedSecureTokenService;
Expand All @@ -33,7 +33,6 @@
import org.eclipse.edc.spi.iam.IdentityService;
import org.eclipse.edc.spi.result.Result;
import org.eclipse.edc.spi.security.Vault;
import org.eclipse.edc.spi.system.ServiceExtension;
import org.eclipse.edc.spi.system.ServiceExtensionContext;
import org.eclipse.edc.token.InMemoryJtiValidationStore;
import org.eclipse.edc.token.JwtGenerationService;
Expand All @@ -42,7 +41,6 @@

import java.time.Clock;
import java.time.Duration;
import java.util.List;
import java.util.Map;

/**
Expand Down Expand Up @@ -83,8 +81,8 @@ public DataWiper getWiper() {
}

@Override
protected void bootExtensions(ServiceExtensionContext context, List<InjectionContainer<ServiceExtension>> serviceExtensions) {
super.bootExtensions(context, serviceExtensions);
protected void bootExtensions(ServiceExtensionContext context, DependencyGraph dependencyGraph) {
super.bootExtensions(context, dependencyGraph);
wiper = new DataWiper(context);
registerConsumerPullKeys(runtimeKeyPair);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,6 @@
import static org.awaitility.Awaitility.await;
import static org.awaitility.pollinterval.FibonacciPollInterval.fibonacci;
import static org.eclipse.edc.util.io.Ports.getFreePort;
import static org.eclipse.tractusx.edc.edr.spi.CoreConstants.CX_CREDENTIAL_NS;
import static org.eclipse.tractusx.edc.edr.spi.CoreConstants.CX_POLICY_NS;
import static org.eclipse.tractusx.edc.tests.TestRuntimeConfiguration.CONSUMER_BPN;
import static org.eclipse.tractusx.edc.tests.TestRuntimeConfiguration.CONSUMER_NAME;
Expand Down Expand Up @@ -320,7 +319,7 @@ void catalogRequest_whenCredentialRevoked() {

@Override
protected JsonObject createContractPolicy(String bpn) {
return frameworkPolicy(Map.of(CX_CREDENTIAL_NS + "Membership", "active"));
return frameworkPolicy(Map.of(CX_POLICY_NS + "Membership", "active"));
}

protected abstract RuntimeExtension consumerRuntime();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,17 +20,15 @@
package org.eclipse.tractusx.edc.tests.transfer.iatp.runtime;

import com.nimbusds.jose.jwk.JWK;
import org.eclipse.edc.boot.system.injection.InjectionContainer;
import org.eclipse.edc.boot.system.DependencyGraph;
import org.eclipse.edc.junit.extensions.EmbeddedRuntime;
import org.eclipse.edc.security.token.jwt.CryptoConverter;
import org.eclipse.edc.spi.security.Vault;
import org.eclipse.edc.spi.system.ServiceExtension;
import org.eclipse.edc.spi.system.ServiceExtensionContext;
import org.eclipse.tractusx.edc.spi.identity.mapper.BdrsClient;
import org.eclipse.tractusx.edc.tests.runtimes.DataWiper;

import java.security.KeyPair;
import java.util.List;
import java.util.Map;


Expand All @@ -52,8 +50,8 @@ public DataWiper getWiper() {


@Override
protected void bootExtensions(ServiceExtensionContext context, List<InjectionContainer<ServiceExtension>> serviceExtensions) {
super.bootExtensions(context, serviceExtensions);
protected void bootExtensions(ServiceExtensionContext context, DependencyGraph dependencyGraph) {
super.bootExtensions(context, dependencyGraph);
wiper = new CredentialWiper(getContext());
registerConsumerPullKeys(runtimeKeyPair);
}
Expand Down
Loading

0 comments on commit e21f946

Please sign in to comment.