propertyPermissions for A12 documents in dataservices

Hey :slight_smile:

I’ll start with the question and then give some context:

  • How do propertyPermissions (UAA) work with dataservices’ rpc operations , e.g. “MODIFY_DOCUMENT”?

Context:
We want to make certain fields in documents not editable for some users. More specifically, we have services and users that modify a document, and users shouldn’t be able to change “technical” fields. As a first step I’ve created a authorization definition file with propertyPermissions and propertyRights where no user should have access to a certain field, in this case /Cockpit/AllgemeineDaten/Status.

Authorization.json

A simplified version of the authorization.json that is included with mgmtp.a12.uaa.authorization.child-authorization-definitions

{
  "policies": [
    {
      "name": "Is IDocument",
      "rules": [
        "#resource instanceof T(com.mgmtp.a12.kernel.md.document.api.IDocument)"
      ]
    },
    {
      "name": "Policy for ExampleDocumentModel",
      "rules": [
        "#resource.documentModelId == 'ExampleDocumentModel'"
      ]
    }
  ],
  "propertyPermissions": [
    {
      "name": "propertyPermission for ExampleDocumentModel",
      "policy-refs": [
        "Is IDocument",
        "Policy for ExampleDocumentModel"
      ],
      "rights-refs": [
        "Rights for ExampleDocumentModel"
      ]
    }
  ],
  "propertyRights": [
    {
      "name": "Rights for ExampleDocumentModel",
      "rights": {
        "READ": [
          ...
          "Cockpit.AllgemeineDaten.Eingang",
          "Cockpit.AllgemeineDaten.Status",
          "Cockpit.AllgemeineDaten.Bundesland",
          ...
        ],
        "WRITE": [
          ...
          "Cockpit.AllgemeineDaten.Eingang",
          "Cockpit.AllgemeineDaten.Bundesland",
          ...
        ],
      }
    }
  ]
}

Now what I hoped that would happen is that dataservices evaluates the propertyPermissions just like permissions. But when I send a “MODIFY_DOCUMENT” rpc request with a modified Status dataservices still accepts the modified document. It seems that the propertyPermissions are not evaluated at all :confused:

So is there a way to set up dataservices in a way that propertyPermissions are evaluated on document updates?
I’ve searched the documentation of DS and UAA (including the UAA training) but couldn’t find anything about how to limit the access of document fields when working with dataservices.

gradle.properties

These are the uaa authorization dependencies I’ve included in the bap server

dependencies {
    implementation "com.mgmtp.a12.uaa:uaa-authorization:7.5.1"
    implementation "com.mgmtp.a12.uaa:uaa-authorization-spring-boot-autoconfigure:7.5.1"
    implementation "com.mgmtp.a12.uaa:uaa-authorization-web-spring-boot-autoconfigure:7.5.1"
    implementation 'com.mgmtp.a12.uaa:uaa-authorization-a12-extension:7.5.1'
}

How about modeling separate documents for the different roles that need to be able to edit data?

The documents will initially be set up with relationship instances between them which are not editable by any role. So it’s made sure that the documents will stay connected to each other. Using a CDM one could still access all of the data at once. Only when it comes to modifying operations one would need to use the separate document model to send to the backend.

This avoids fiddling with property right if facing an often changing document model.

Hi @gero-wide-spruce,

In 2023.06, DS does not support hasUAAPropertyPermission.

You could use DocumentBeforeUpdateEvent to trigger propertyPermissions, something like this:

@PreAuthorize("hasUAAPropertyPermission(#event.persistedDocument, #event.updatedDocument)")
    @DataServicesEventListener
    public void beforeUpdateDocument(final DocumentBeforeUpdateEvent event) {}

You can add more logic to the method’s body or leave it empty.

Regards,
Ben

Hey Ben,
Using an Event listener seems to work :ok_hand:
Thank you for the hint :smiley:

Using seperate documents isn’t possible, because there are computations and validation rules accross the whole document. So technical fields influence user fields and vice versa.
What we would need then would be some kind of “Validation Model”, that can validate and maybe even compute fields accross documents.

Those validation models could be represented by CDMs. But I don’t know if there is support for creating a composed data document from a document that is not yet persistend in dataservices or different from what dataservices has persisted.

Hi @andreas-fresh-mesa, if you can somehow construct a cdd without persisting it to Dataservices and want to apply validation and computation on this CDD by using rules from your CDM, you may consider using this Kernel typescript functionality Kernel | GETA12-Docs, this provides a capability to handle these actions on client side, hope this help.