eclipse-tractusx / digital-product-pass

Eclipse Tractus-X Digital Product Pass - An application for visualizing Digital Product Passports, Battery Passports and Transmission Passports, it is the reference implementation of the EcoPass KIT
https://github.com/eclipse-tractusx/digital-product-pass
Apache License 2.0
22 stars 14 forks source link

Provide a solution for policy selection during auto-negotiation from the dDTR asset #272

Closed matbmoser closed 4 months ago

matbmoser commented 5 months ago

Description

When the dDTR is retrived we need to indicate which policies we can "auto sign".

For assets we enable the selection but for the DTRs we need to indicate which policies we are allowed to sign. Not create a policy storage but add in the configuration.

Implement policy check for assets "Membership Active" and "FrameworkSustainability and Propose dpp

1- dDTR (Autosign) -> Check the policy if has the contraints from the configuration

2- DPP Asset (Manual or Autosign) -> User selects or checks contraints from configuration

Follow description from the data souvereignity guidelines

In the configuration we indicate the contraints to be validated and choosen when selecting a contract and a policy from the contract catalog.

For continue with the autosign is necesary to fullfill the constraints from the configuration. In case there is more than one policy fullfilling this constraints, take the one that appears first.

The contraint configuration is flexible for different types

Acceptance Criteria

Additional Information

4 Story points of work have already been done and burned in JIRA

matbmoser commented 5 months ago

Configurations for policies are defined in this structure in (dtr and passport) configurations:

    policyCheck:
      enable: true
      # List of allowed permissions policies
      permission:
        - action: "use"
          logicConstraint: "odrl:and"
          constraints:
          - leftOperand: "cx-policy:UsagePurpose"
            operator: "eq"
            rightOperand: "cx.core.digitalTwinRegistry:1"
          - leftOperand: "Membership"
            operator: "eq"
            rightOperand: "active"
        - action: "use"
          logicConstraint: "odrl:and"
          constraints:
            - leftOperand: "UsagePurpose"
              operator: "eq"
              rightOperand: "cx.core.digitalTwinRegistry:1"
            - leftOperand: "Membership"
              operator: "eq"
              rightOperand: "active"
        - action: "use"
          constraints:
            - leftOperand: "BusinessPartnerNumber"
              operator: "eq"
              rightOperand: "BPNL1TEST12342321"
      prohibition: []
      obligation: []

https://github.com/catenax-ng/tx-digital-product-pass/pull/250/files#diff-288d548e5daecf794ea87e486aca741bd2f1b36da4ce2fba73218d8f3fd4facbR86-R163

matbmoser commented 5 months ago

What is still missing:

What was done:

matbmoser commented 5 months ago

I was not happy enough with the results because it was confusing what to apply when which policy to choose if it was valid.

So I am just including all the policy structure in the configuration and then parsing it in the constructor from the policy class.

I created a test that shows and checks for the parsing from the configuration to a actual policy structure with constraints:

2024-04-17 15:36:37,698 |INFO| [testLogThread] u.LogUtil$LogPrinter: |17724|0,12| [TEST] [INPUT]: [ {
  "permission" : [ {
    "action" : "use",
    "logicalConstraint" : "odrl:and",
    "constraints" : [ {
      "leftOperand" : "cx-policy:UsagePurpose",
      "operator" : "eq",
      "rightOperand" : "cx.core.digitalTwinRegistry:1"
    }, {
      "leftOperand" : "Membership",
      "operator" : "eq",
      "rightOperand" : "active"
    } ]
  } ],
  "obligation" : [ ],
  "prohibition" : [ ]
} ]
2024-04-17 15:36:37,706 |INFO| [testLogThread] u.LogUtil$LogPrinter: |17724|0,12| [TEST] [RESPONSE]: [ {
  "odrl:permission" : [ {
    "odrl:action" : "use",
    "odrl:constraint" : {
      "odrl:and" : [ {
        "odrl:leftOperand" : "cx-policy:UsagePurpose",
        "odrl:operator" : {
          "@id" : "eq"
        },
        "odrl:rightOperand" : "cx.core.digitalTwinRegistry:1"
      }, {
        "odrl:leftOperand" : "Membership",
        "odrl:operator" : {
          "@id" : "eq"
        },
        "odrl:rightOperand" : "active"
      } ]
    }
  } ],
  "odrl:prohibition" : [ ],
  "odrl:obligation" : [ ]
} ]
matbmoser commented 5 months ago

Then the format from the configuration will look something like this:


    policyCheck:
      enabled: true
      # List of allowed permissions policies
      policies:
        - permission:
          - action: "use"
            logicalConstraint: "odrl:and"
            constraints:
            - leftOperand: "cx-policy:UsagePurpose"
              operator: "eq"
              rightOperand: "cx.core.digitalTwinRegistry:1"
            - leftOperand: "Membership"
              operator: "eq"
              rightOperand: "active"
          prohibition: []
          obligation: []

If there is more policies you just do like this:

    policyCheck:
      enabled: true
      # List of allowed permissions policies
      policies:
        - permission:
          - action: "use"
            logicalConstraint: "odrl:and"
            constraints:
            - leftOperand: "cx-policy:UsagePurpose"
              operator: "odrl:eq"
              rightOperand: "cx.core.digitalTwinRegistry:1"
            - leftOperand: "Membership"
              operator: "odrl:eq"
              rightOperand: "active"
          prohibition: []
          obligation: []
        - permission:
          - action: "use"
            constraints:
            - leftOperand: "cx-policy:BusinessPartnerNumber"
              operator: "odrl:eq"
              rightOperand: "BPNL121320AS21320"
          prohibition: []
          obligation: []
        - permission:
          - action: "use"
            logicalConstraint: "odrl:or"
            constraints:
            - leftOperand: "cx-policy:UsagePurpose"
              operator: "odrl:eq"
              rightOperand: "cx.core.digitalTwinRegistry:2"
            - leftOperand: "Membership"
              operator: "odrl:eq"
              rightOperand: "active"
          prohibition: []
          obligation: []
matbmoser commented 5 months ago

Ok thats actually pretty cool what I made here as a solution and now you can indicate "exactly" which policy you want even the order or constraints can be set:

The two objects content hashes will be compared and checked if the same confirming if the policy is inside of the valid policies configuration! image

2024-04-17 17:28:12,094 |INFO| [testLogThread] u.LogUtil$LogPrinter: |14396|0,13| [TEST] [ALL VALID POLICY HASHES]: [ "a760bf47634b1f3e106242d665f19a6e4fe243d4b6521c88e7ae03f94733e08c" ]
2024-04-17 17:28:12,095 |INFO| [testLogThread] u.LogUtil$LogPrinter: |14396|0,13| [TEST] [POLICY HASH]: "a760bf47634b1f3e106242d665f19a6e4fe243d4b6521c88e7ae03f94733e08c"
matbmoser commented 5 months ago

An idea here is to provide two modes for not causing conflicts with policies with the same constraints and different orders.

Maybe as a first solution it's ok but it would be qualified as "strict" mode a more "normal" check would just compare the constraints not considering the order.

But some work needs to be done then. I think I can do it tomorrow

matbmoser commented 5 months ago

For the "normal" check we need to create a method inside "Set" to compare its internal attributes with the ones from the documentation

matbmoser commented 5 months ago

Ok I implemented the "default check": image

Unit Tests: image

Its working as it is expected. I optimized the maximum the logic so that we don't need to do always the O(n^2) processing functionality. By using the "strict" mode you will have complexity O(1).

matbmoser commented 5 months ago

Tested with simple policy and its also working: image

matbmoser commented 5 months ago

Found a bug: image

Showing that the strict cooperation was really more reliable

Ok no bug was there in real, for the debugging I forgot to return false in one condition where I printed

matbmoser commented 5 months ago

Also tested when the operators are different: image

Works!

matbmoser commented 5 months ago

Tested adding prohibitions and with no configuration added for that and also works (the method detects it): image

If you decide then to include the prohibition in the configuration it will work then: image

When the order is changing the strict mode will not work which is expected

matbmoser commented 5 months ago

This is the complete proof that the logic of selecting a policy from a list of policies incoming is working:


2024-04-19 19:42:22,545 |INFO| [testLogThread] u.LogUtil$LogPrinter: |34716|0,06| [TEST] [INPUT]: [ {
  "odrl:permission" : [ {
    "odrl:action" : "USE",
    "odrl:constraint" : {
      "odrl:and" : [ {
        "odrl:leftOperand" : "cx-policy:Membership",
        "odrl:operator" : {
          "@id" : "odrl:eq"
        },
        "odrl:rightOperand" : "active"
      }, {
        "odrl:leftOperand" : "cx-policy:UsagePurpose",
        "odrl:operator" : {
          "@id" : "odrl:eq"
        },
        "odrl:rightOperand" : "cx.core.digitalTwinRegistry:1"
      } ]
    }
  } ],
  "odrl:prohibition" : [ ],
  "odrl:obligation" : [ ]
}, {
  "odrl:permission" : [ {
    "odrl:action" : "USE",
    "odrl:constraint" : {
      "odrl:and" : [ {
        "odrl:leftOperand" : "cx-policy:Membership",
        "odrl:operator" : {
          "@id" : "odrl:eq"
        },
        "odrl:rightOperand" : "active"
      }, {
        "odrl:leftOperand" : "cx-policy:FrameworkAgreement",
        "odrl:operator" : {
          "@id" : "odrl:eq"
        },
        "odrl:rightOperand" : "circulareconomy:1.0"
      } ]
    }
  } ],
  "odrl:prohibition" : [ ],
  "odrl:obligation" : [ ]
} ]
2024-04-19 19:42:22,548 |INFO| [testLogThread] u.LogUtil$LogPrinter: |34716|0,06| [TEST] [POLICY CONFIGURATION]: {
  "enabled" : true,
  "strictMode" : false,
  "policies" : [ {
    "permission" : [ {
      "action" : "USE",
      "logicalConstraint" : "odrl:and",
      "constraints" : [ {
        "leftOperand" : "cx-policy:Membership",
        "operator" : "odrl:eq",
        "rightOperand" : "active"
      }, {
        "leftOperand" : "cx-policy:UsagePurpose",
        "operator" : "odrl:eq",
        "rightOperand" : "cx.core.digitalTwinRegistry:1"
      } ]
    } ],
    "obligation" : [ ],
    "prohibition" : [ ]
  } ]
}
[logic] AND
[currentLogic] AND
[AND LOGIC]
[logic] AND
[currentLogic] AND
[AND LOGIC]
[LEFT CONSTRAINTS ARE NOT THE SAME] [cx-policy:UsagePurpose]&[cx-policy:FrameworkAgreement]
[LEFT CONSTRAINTS ARE NOT THE SAME] [cx-policy:UsagePurpose]&[cx-policy:Membership]
[LEFT CONSTRAINTS ARE NOT THE SAME] [cx-policy:Membership]&[cx-policy:FrameworkAgreement]
[validConstraints]: [true]
[Policy response] false
[VALID POLICIES] []
[LEFT CONSTRAINTS ARE NOT THE SAME] [cx-policy:UsagePurpose]&[cx-policy:Membership]
[LEFT CONSTRAINTS ARE NOT THE SAME] [cx-policy:Membership]&[cx-policy:UsagePurpose]
[validConstraints]: [true, true]
[Policy response] true
[VALID POLICIES] [org.eclipse.tractusx.digitalproductpass.models.negotiation.policy.Set@2dc1d22d]
2024-04-19 19:42:22,555 |INFO| [testLogThread] u.LogUtil$LogPrinter: |34716|0,06| [TEST] [RESPONSE]: {
  "odrl:permission" : [ {
    "odrl:action" : "USE",
    "odrl:constraint" : {
      "odrl:and" : [ {
        "odrl:leftOperand" : "cx-policy:Membership",
        "odrl:operator" : {
          "@id" : "odrl:eq"
        },
        "odrl:rightOperand" : "active"
      }, {
        "odrl:leftOperand" : "cx-policy:UsagePurpose",
        "odrl:operator" : {
          "@id" : "odrl:eq"
        },
        "odrl:rightOperand" : "cx.core.digitalTwinRegistry:1"
      } ]
    }
  } ],
  "odrl:prohibition" : [ ],
  "odrl:obligation" : [ ]
}
matbmoser commented 5 months ago

Ok pushed everything, now just INT testing is missing

matbmoser commented 5 months ago

I am adding some documentation for the functionality

matbmoser commented 5 months ago

I have added a new guide on how to configure the policies and data sovereignty aspects in the Digital Product Pass application: https://github.com/catenax-ng/tx-digital-product-pass/blob/feature/cmp-1147/dtr-policy-check/docs/data-sovereignty/PolicyConfigGuide.md

matbmoser commented 5 months ago

a question here is what happenens when a right operand is an array ? Like having the IN operator