Uploaded image for project: 'OpenIDM'
  1. OpenIDM
  2. OPENIDM-15259

Conditional associations do not fire when object update is triggered by relationship notification



    • Improvement
    • Status: Open
    • Minor
    • Resolution: Unresolved
    • 7.0.0
    • None
    • Module - Relationships


      Use case: Simple role inheritance: when roleA is assigned to a given user, also roleB should be assigned automatically.

      While conditional associations do not accept relationships or other complex properties (such as an array of objects as in effectiveRoles) or in their condition, the new virtual properties calculation feature in IDM 7 allows us to flatten those properties to strings and then use them in the conditional association [or, prior to 7.0, an onUpdate script can be used to achieve the flattening]. This works fine as long as an object satisfying the condition is updated using a direct patch on the object, but it does not work if the update is triggered by a relationship change notification, such as the addition of a role membership via a create operation on the roles collection, as in the above use case.

      To reproduce:
      1. Add a new virtual property to the managed user schema:

      "rolesAsString" : {
                              "title" : "Eff roles flattened",
                              "type" : "array",
                              "viewable" : true,
                              "searchable" : false,
                              "userEditable" : true,
                              "items" : {
                                  "type" : "string"
                              "description" : null,
                              "isVirtual" : true,
                              "returnByDefault" : true,
                              "deleteQueryConfig" : false,
                              "queryConfig" : {
                                  "referencedRelationshipFields" : [
                              "onStore" : {
                                  "type" : "text/javascript",
                                  "globals" : { },
                                  "file" : "onStoreVirtualProperty.js"

      (note: the onStore script should contain logic to convert the calculated virtual properties collection to the desired array of strings, like this:

      if ( !!property ) {
             return Array.isArray(property) ? property.map( function(e) { return e._refResourceId } ) : property._refResourceId ;
           } else {
             return null;

      2. Make sure that "notifySelf":true for the roles property.
      3. Create roles roleA and roleB, with roleB having the following condition:

       "condition": "/rolesAsString co \"roleA\""

      4. Assign roleA to user1 (using httpie in this example):

      http -a openidm-admin:openidm-admin POST :8080/openidm/managed/user/user1/roles _ref=managed/role/roleA

      Expected result: The virtual property contains "roleA", and the user receives roleA and roleB because of roleB's conditional association being satisfied.
      Actual result: The virtual property contains "roleA", but the user receives roleA only.

      If instead the user object is updated via a PATCH on either the roles property, or in fact any other property, the condition is fired and roleB is assigned.
      Similar behaviour is observed when a role is removed, i.e.

      • using a DELETE of roleA on managed/user/user1/roles: roleA is removed, but roleB is still assigned
      • using a PATCH of the roles property on managed/user/user1: both roles are removed.

      So the only way to achieve the desired behaviour in a consistent manner seems to be via additional postUpdate logic, which must trigger an update of the user object as and when appropriate, whilst taking the necessary precautions to prevent an infinite loop of updates.




            dhogan Dirk Hogan
            tim.vogt Tim Vogt
            2 Vote for this issue
            6 Start watching this issue