Skip to content

Commit

Permalink
fix: add binding to tx namespace for credential policy
Browse files Browse the repository at this point in the history
  • Loading branch information
wolf4ood committed Aug 17, 2023
1 parent 95ca87a commit f9e0acb
Show file tree
Hide file tree
Showing 12 changed files with 204 additions and 14 deletions.
1 change: 1 addition & 0 deletions core/json-ld-core/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ plugins {
}

dependencies {
implementation(project(":spi:core-spi"))
implementation(libs.edc.spi.core)
implementation(libs.edc.spi.jsonld)
testImplementation(testFixtures(libs.edc.junit))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,15 @@

import static java.lang.String.format;
import static java.nio.file.StandardCopyOption.REPLACE_EXISTING;
import static org.eclipse.tractusx.edc.edr.spi.CoreConstants.EDC_CONTEXT;
import static org.eclipse.tractusx.edc.edr.spi.CoreConstants.TX_CONTEXT;
import static org.eclipse.tractusx.edc.edr.spi.CoreConstants.TX_NAMESPACE;
import static org.eclipse.tractusx.edc.edr.spi.CoreConstants.TX_PREFIX;

public class JsonLdExtension implements ServiceExtension {

public static final String CREDENTIALS_V_1 = "https://www.w3.org/2018/credentials/v1";

public static final String CREDENTIALS_SUMMARY_V_1 = "https://w3id.org/2023/catenax/credentials/summary/v1";
public static final String CREDENTIALS_SUMMARY_V_1_FALLBACK = "https://catenax-ng.github.io/product-core-schemas/SummaryVC.json";
public static final String SECURITY_JWS_V1 = "https://w3id.org/security/suites/jws-2020/v1";
Expand All @@ -43,7 +48,9 @@ public class JsonLdExtension implements ServiceExtension {
CREDENTIALS_SUMMARY_V_1, PREFIX + "summary-vc-context-v1.jsonld",
CREDENTIALS_SUMMARY_V_1_FALLBACK, PREFIX + "summary-vc-context-v1.jsonld",
SECURITY_JWS_V1, PREFIX + "security-jws-2020.jsonld",
SECURITY_ED25519_V1, PREFIX + "security-ed25519-2020.jsonld");
SECURITY_ED25519_V1, PREFIX + "security-ed25519-2020.jsonld",
TX_CONTEXT, PREFIX + "tx-v1.jsonld",
EDC_CONTEXT, PREFIX + "edc-v1.jsonld");
@Inject
private JsonLd jsonLdService;

Expand All @@ -52,6 +59,7 @@ public class JsonLdExtension implements ServiceExtension {

@Override
public void initialize(ServiceExtensionContext context) {
jsonLdService.registerNamespace(TX_PREFIX, TX_NAMESPACE);
FILES.entrySet().stream().map(this::mapToFile)
.forEach(result -> result.onSuccess(entry -> jsonLdService.registerCachedDocument(entry.getKey(), entry.getValue()))
.onFailure(failure -> monitor.warning("Failed to register cached json-ld document: " + failure.getFailureDetail())));
Expand Down
47 changes: 47 additions & 0 deletions core/json-ld-core/src/main/resources/document/edc-v1.jsonld
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
{
"@context": {
"edc": "https://w3id.org/edc/v0.0.1/ns/",
"@vocab": "https://w3id.org/edc/v0.0.1/ns/",
"schema": "http://schema.org/",
"PolicyDefinition": "edc:PolicyDefinition",
"AssetEntryNewDto": "edc:AssetEntryNewDto",
"DataAddress": "edc:DataAddress",
"NegotiationState": "edc:NegotiationState",
"TerminateNegotiation": "edc:TerminateNegotiation",
"ContractRequest": "edc:ContractRequest",
"policy": {
"@id": "edc:policy",
"@type": "@id",
"@context": [
"http://www.w3.org/ns/odrl.jsonld"
]
},
"createdAt": "edc:createdAt",
"properties": "edc:properties",
"privateProperties": "edc:privateProperties",
"dataAddress": "edc:dataAddress",
"type": "edc:type",
"counterPartyAddress": "edc:counterPartyAddress",
"protocol": "edc:protocol",
"querySpec": "edc:querySpec",
"accessPolicyId": "edc:accessPolicyId",
"contractPolicyId": "edc:contractPolicyId",
"assetsSelector": "edc:assetsSelector",
"state": "edc:state",
"reason": "edc:reason",
"connectorAddress": "edc:connectorAddress",
"offer": "edc:offer",
"asset": "edc:asset",
"offerId": "edc:offerId",
"assetId": "edc:assetId",
"contractId": "edc:contractId",
"connectorId": "edc:connectorId",
"callbackAddresses": "edc:callbackAddresses",
"dataDestination": "edc:dataDestination",
"baseUrl": "edc:baseUrl",
"providerId": "edc:providerId",
"uri": "edc:uri",
"events": "edc:events",
"transactional": "edc:transactional"
}
}
21 changes: 21 additions & 0 deletions core/json-ld-core/src/main/resources/document/tx-v1.jsonld
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"@context": {
"@version": 1.1,
"@protected": true,
"tx": "https://w3id.org/tractusx/v0.0.1/ns/",
"BusinessPartnerNumber": "tx:BusinessPartnerNumber",
"NegotiationInitiateRequestDto": "tx:NegotiationInitiateRequestDto",
"BusinessPartnerGroup": "tx:BusinessPartnerGroup",
"EndpointDataReferenceEntry": "tx:EndpointDataReferenceEntry",
"Membership": "tx:Membership",
"Dismantler": "tx:Dismantler",
"FrameworkAgreement.pcf": "tx:FrameworkAgreement.pcf",
"FrameworkAgreement.sustainability": "tx:FrameworkAgreement.sustainability",
"FrameworkAgreement.quality": "tx:FrameworkAgreement.quality",
"FrameworkAgreement.traceability": "tx:FrameworkAgreement.traceability",
"FrameworkAgreement.behavioraltwin": "tx:FrameworkAgreement.behavioraltwin",
"BPN": "tx:BPN",
"expirationDate": "tx:expirationDate",
"edrState": "tx:edrState"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import static org.eclipse.edc.connector.contract.spi.offer.ContractDefinitionResolver.CATALOGING_SCOPE;
import static org.eclipse.edc.connector.contract.spi.validation.ContractValidationService.NEGOTIATION_SCOPE;
import static org.eclipse.edc.connector.contract.spi.validation.ContractValidationService.TRANSFER_SCOPE;
import static org.eclipse.edc.policy.model.OdrlNamespace.ODRL_SCHEMA;

/**
* Registers a {@link org.eclipse.tractusx.edc.validation.businesspartner.functions.BusinessPartnerGroupFunction} for the following scopes:
Expand All @@ -49,7 +50,7 @@
* <p>
* Note that the {@link BusinessPartnerGroupFunction} is an {@link org.eclipse.edc.policy.engine.spi.AtomicConstraintFunction}, thus it is registered with the {@link PolicyEngine} for the {@link Permission} class.
*/
@Extension(value = "Registers a function to evaluate whether a BPN number is covered by a certain policy or not", categories = {"policy", "contract"})
@Extension(value = "Registers a function to evaluate whether a BPN number is covered by a certain policy or not", categories = { "policy", "contract" })
public class BusinessPartnerValidationExtension implements ServiceExtension {

private static final String USE = "USE";
Expand All @@ -71,6 +72,7 @@ public void initialize(ServiceExtensionContext context) {

private void bindToScope(BusinessPartnerGroupFunction function, String scope) {
ruleBindingRegistry.bind(USE, scope);
ruleBindingRegistry.bind(ODRL_SCHEMA + "use", scope);
ruleBindingRegistry.bind(BusinessPartnerGroupFunction.BUSINESS_PARTNER_CONSTRAINT_KEY, scope);

policyEngine.registerFunction(scope, Permission.class, BusinessPartnerGroupFunction.BUSINESS_PARTNER_CONSTRAINT_KEY, function);
Expand Down
1 change: 1 addition & 0 deletions edc-extensions/cx-policy/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ plugins {
}

dependencies {
implementation(project(":spi:core-spi"))
implementation(project(":spi:ssi-spi"))
implementation(libs.edc.spi.policyengine)
implementation(libs.jakartaJson)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,12 @@
import org.eclipse.edc.policy.engine.spi.RuleBindingRegistry;
import org.eclipse.edc.policy.model.Permission;

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

import static java.util.Collections.unmodifiableMap;
import static org.eclipse.edc.policy.model.OdrlNamespace.ODRL_SCHEMA;
import static org.eclipse.tractusx.edc.edr.spi.CoreConstants.TX_NAMESPACE;
import static org.eclipse.tractusx.edc.policy.cx.common.PolicyScopes.CATALOG_REQUEST_SCOPE;
import static org.eclipse.tractusx.edc.policy.cx.common.PolicyScopes.CATALOG_SCOPE;
import static org.eclipse.tractusx.edc.policy.cx.common.PolicyScopes.NEGOTIATION_REQUEST_SCOPE;
Expand All @@ -35,16 +39,26 @@ public class SummaryConstraintFunctionsProvider {
/**
* Mappings from policy constraint left operand values to the corresponding item value in the summary VP.
*/
static final Map<String, String> CREDENTIAL_MAPPINGS = Map.of(
"Membership", "MembershipCredential",
"Dismantler", "DismantlerCredential",
"FrameworkAgreement.pcf", "PcfCredential",
"FrameworkAgreement.sustainability", "SustainabilityCredential",
"FrameworkAgreement.quality", "QualityCredential",
"FrameworkAgreement.traceability", "TraceabilityCredential",
"FrameworkAgreement.behavioraltwin", "BehaviorTwinCredential",
"BPN", "BpnCredential"
);
static final Map<String, String> CREDENTIAL_MAPPINGS;


static {
var initialMappings = Map.of(
"Membership", "MembershipCredential",
"Dismantler", "DismantlerCredential",
"FrameworkAgreement.pcf", "PcfCredential",
"FrameworkAgreement.sustainability", "SustainabilityCredential",
"FrameworkAgreement.quality", "QualityCredential",
"FrameworkAgreement.traceability", "TraceabilityCredential",
"FrameworkAgreement.behavioraltwin", "BehaviorTwinCredential",
"BPN", "BpnCredential"
);
var mappings = new HashMap<>(initialMappings);
initialMappings.forEach((credentialName, summaryType) -> {
mappings.put(TX_NAMESPACE + credentialName, summaryType);
});
CREDENTIAL_MAPPINGS = unmodifiableMap(mappings);
}

/**
* Configures and registers required summary functions with the policy engine.
Expand Down Expand Up @@ -84,6 +98,11 @@ public static void registerBindings(RuleBindingRegistry registry) {
registry.bind(constraintName, NEGOTIATION_SCOPE);
registry.bind(constraintName, TRANSFER_PROCESS_SCOPE);
});

registry.bind(ODRL_SCHEMA + "use", CATALOG_SCOPE);
registry.bind(ODRL_SCHEMA + "use", NEGOTIATION_SCOPE);
registry.bind(ODRL_SCHEMA + "use", TRANSFER_PROCESS_SCOPE);

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@

public class NegotiateEdrRequestDto {

public static final String EDR_REQUEST_DTO_TYPE = TX_NAMESPACE + "NegotiateEdrRequestDto";
public static final String EDR_REQUEST_SIMPLE_DTO_TYPE = "NegotiateEdrRequestDto";
public static final String EDR_REQUEST_DTO_TYPE = TX_NAMESPACE + EDR_REQUEST_SIMPLE_DTO_TYPE;
public static final String EDR_REQUEST_DTO_CONNECTOR_ADDRESS = EDC_NAMESPACE + "connectorAddress";
public static final String EDR_REQUEST_DTO_PROTOCOL = EDC_NAMESPACE + "protocol";
public static final String EDR_REQUEST_DTO_CONNECTOR_ID = EDC_NAMESPACE + "connectorId";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,18 @@
package org.eclipse.tractusx.edc.helpers;


import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.json.Json;
import jakarta.json.JsonArrayBuilder;
import jakarta.json.JsonObject;
import jakarta.json.JsonObjectBuilder;
import org.eclipse.edc.connector.policy.spi.PolicyDefinition;
import org.eclipse.edc.jsonld.util.JacksonJsonLd;
import org.eclipse.edc.policy.model.AtomicConstraint;
import org.eclipse.edc.policy.model.Operator;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.Collection;
import java.util.Map;
Expand All @@ -42,6 +46,8 @@ public class PolicyHelperFunctions {
private static final String BUSINESS_PARTNER_EVALUATION_KEY = "BusinessPartnerNumber";
private static final String BUSINESS_PARTNER_CONSTRAINT_KEY = TX_NAMESPACE + "BusinessPartnerGroup";

private static final ObjectMapper MAPPER = JacksonJsonLd.createObjectMapper();

/**
* Creates a {@link PolicyDefinition} using the given ID, that contains equality constraints for each of the given BusinessPartnerNumbers:
* each BPN is converted into an {@link AtomicConstraint} {@code BusinessPartnerNumber EQ [BPN]}.
Expand Down Expand Up @@ -89,6 +95,30 @@ public static JsonObject frameworkPolicy(String id, Map<String, String> permissi
.build();
}


/**
* Creates a {@link PolicyDefinition} using the given ID, that contains equality constraints for each of the given BusinessPartnerNumbers:
* each BPN is converted into an {@link AtomicConstraint} {@code BusinessPartnerNumber EQ [BPN]}.
*/
public static JsonObject frameworkTemplatePolicy(String id, String frameworkKind) {
var template = fetchFrameworkTemplate().replace("${POLICY_ID}", id).replace("${FRAMEWORK_CREDENTIAL}", frameworkKind);
try {
return MAPPER.readValue(template, JsonObject.class);
} catch (IOException e) {
throw new RuntimeException(e);
}
}


private static String fetchFrameworkTemplate() {
try (var stream = PolicyHelperFunctions.class.getClassLoader().getResourceAsStream("framework-policy.json")) {
return new String(stream.readAllBytes(), StandardCharsets.UTF_8);
} catch (IOException e) {
throw new RuntimeException(e);
}

}

public static JsonObjectBuilder policyDefinitionBuilder() {
return Json.createObjectBuilder()
.add(TYPE, EDC_NAMESPACE + "PolicyDefinitionDto");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import static org.assertj.core.api.Assertions.assertThat;
import static org.eclipse.tractusx.edc.helpers.CatalogHelperFunctions.getDatasetAssetId;
import static org.eclipse.tractusx.edc.helpers.PolicyHelperFunctions.frameworkPolicy;
import static org.eclipse.tractusx.edc.helpers.PolicyHelperFunctions.frameworkTemplatePolicy;
import static org.eclipse.tractusx.edc.helpers.PolicyHelperFunctions.noConstraintPolicyDefinition;
import static org.eclipse.tractusx.edc.lifecycle.TestRuntimeConfiguration.SOKRATES_BPN;
import static org.eclipse.tractusx.edc.lifecycle.TestRuntimeConfiguration.SOKRATES_DSP_CALLBACK;
Expand Down Expand Up @@ -85,6 +86,38 @@ void requestCatalog_fulfillsPolicy_shouldReturnOffer() {
SOKRATES.createContractDefinition("test-asset-1", "test-def-2", "test-ap2", "test-cp1");


// act
var catalog = SOKRATES.getCatalogDatasets(SOKRATES);

// assert
assertThat(catalog).isNotEmpty()
.hasSize(1)
.allSatisfy(co -> {
assertThat(getDatasetAssetId(co)).isEqualTo("test-asset");
});

}


@Test
@DisplayName("Verify that Sokrates receives only the offers he is permitted to using @context")
void requestCatalog_fulfillsPolicy_shouldReturnOffer_withContexts() {
// arrange
SOKRATES.createAsset("test-asset");
SOKRATES.createAsset("test-asset-1");

var bpnAccessPolicy = frameworkTemplatePolicy("test-ap1", "BPN");
var contractPolicy = noConstraintPolicyDefinition("test-cp1");
var dismantlerAccessPolicy = frameworkTemplatePolicy("test-ap2", "Dismantler");

SOKRATES.createPolicy(bpnAccessPolicy);
SOKRATES.createPolicy(contractPolicy);
SOKRATES.createPolicy(dismantlerAccessPolicy);

SOKRATES.createContractDefinition("test-asset", "test-def", "test-ap1", "test-cp1");
SOKRATES.createContractDefinition("test-asset-1", "test-def-2", "test-ap2", "test-cp1");


// act
var catalog = SOKRATES.getCatalogDatasets(SOKRATES);

Expand Down
24 changes: 24 additions & 0 deletions edc-tests/e2e-tests/src/test/resources/framework-policy.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"@context": [
"https://w3id.org/edc/v0.0.1",
"https://w3id.org/tractusx/edc/v0.0.1",
"http://www.w3.org/ns/odrl.jsonld"
],
"@type": "PolicyDefinitionRequest",
"@id": "${POLICY_ID}",
"policy": {
"@type": "Set",
"permission": [
{
"action": "use",
"constraint": [
{
"leftOperand": "${FRAMEWORK_CREDENTIAL}",
"operator": "eq",
"rightOperand": "active"
}
]
}
]
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,10 @@ public final class CoreConstants {

public static final String TX_PREFIX = "tx";
public static final String TX_NAMESPACE = "https://w3id.org/tractusx/v0.0.1/ns/";

public static final String TX_CONTEXT = "https://w3id.org/tractusx/edc/v0.0.1";
public static final String EDC_CONTEXT = "https://w3id.org/edc/v0.0.1";


private CoreConstants() {
}
}

0 comments on commit f9e0acb

Please sign in to comment.