Uploaded image for project: 'Nuxeo Platform'
  1. Nuxeo Platform
  2. NXP-18981

In-memory cache implementation in CacheService should not give direct access to instances of objects stored in cache

    XMLWordPrintable

    Details

    • Type: Bug
    • Status: Resolved
    • Priority: Major
    • Resolution: Duplicate
    • Affects Version/s: 6.0, 7.10, 8.1
    • Fix Version/s: None
    • Component/s: Core

      Description

      When "in-memory" cache is enabled and an object is retrieved from the cache using the get() method, the get() method returns the actual object stored in the cache. This allows the "user" code (i.e. a custom operation, an event listener, ...) to modify the state of the object therefore modify the object in the cache directly.

      An occurence of this behaviour was reported by a customer in ticket SUPNXP-15802: in the case of a LDAP user directory, a cache of NuxeoPrincipal is activated in the User Manager service. By default, it is an "in-memory" cache (can be configured to use redis by activating redis in the platform).

      When the customer retrieved a user's DocumentModel by getting its NuxeoPrincipal using the User Manager service (getPrincipal() method) to change some of the user's properties, the only fact of calling setProperty(propertyName, propertyValue) on the user's DocumentModel would change the object in the cache itself, which makes the changes available to other "client code".

      Normally, a call to method updateUser() on the User Manager service is needed to update the user in the directory (and invalidate its entry in the cache).

      This behaviour does not happen with redis as a new instance of the object is created when calling method getPrincipal().

      This means that the get() on the cache has a different behaviour depending the implementation, this is an inconsistency.

      How to reproduce:

      • activate the "principal" cache in the user manager service (add <userCacheName>default-cache</userCacheName> in the User Manager service's configuration, extension point userManager)
      • create a user action calling an automation chain created with the following code:
        - Context.FetchDocument
        - Context.SetVar:
            name: myFirstName
            value: "@{CurrentUser.firstName}"
        - Context.RunScript:
            script: "import org.nuxeo.ecm.platform.usermanager.UserManager;\n\num = org.nuxeo.runtime.api.Framework.getService(UserManager);\nmodel = um.getPrincipal(CurrentUser.name).getModel();\nmodel.setProperty(um.getUserSchemaName(), 'firstName', 'Kylo');\n\nContext['myFirstName'] = um.getPrincipal(CurrentUser.name).getModel().getProperty(um.getUserSchemaName(), 'firstName');"
        - Seam.AddMessage:
            message: "My first name is @{Context['myFirstName']}"
            severity: INFO
        

      This shows that the current user's first name has been modified in the cache but not in the "user" directory.

        Attachments

          Issue Links

            Activity

              People

              • Votes:
                0 Vote for this issue
                Watchers:
                1 Start watching this issue

                Dates

                • Created:
                  Updated:
                  Resolved: