Using the Javascript Console: Permission reporting

I just came across an old question in the german Alfresco forum on how to create a report of permissions on all nodes in the repository. I thought to me this would be really easy to do with the Javascript Console and went ahead creating this script:

The implementation

recurse(companyhome, function(node) {
  for each(permission in node.fullPermissions) {
    if (/;DIRECT$/.test(permission)) {
      logger.log(node.displayPath + "/" + node.name + ";" + permission);
    }
  }
});

There are a few interesting things going on here.

  • It uses a special recurse() function that iterates the repository recursively. This function has been built into the Javascript Console for some time but is still undocumented because I am hesitant to decide if it is ok to change or add to the Javascript API. Scripts can not be used outside/without of the Javascript Console anymore when using those extensions.
  • The iteration starts with companyhome but you could use the space variable as well and select any folder as a starting point.
  • I learned there is a special property called node.fullpermissions which is undocumented in the Alfresco Javascript API but is needed here because it returns information if a permission is inherited or not (the documented node.permissions does not tell this).
  • The script filters out any permissions that are INHERITED and only shows the DIRECT permissions to make the result list not too huge.

The result

The result of the script is a semicolon separated text output that can be imported in Excel for example, for further analysis and reporting.
/Company Home/Data Dictionary;ALLOWED;GROUP_EVERYONE;Consumer;DIRECT
/Company Home/Data Dictionary/RSS Templates;ALLOWED;guest;Consumer;DIRECT
/Company Home/Data Dictionary/Saved Searches;ALLOWED;GROUP_EVERYONE;Contributor;DIRECT
/Company Home/Guest Home;ALLOWED;guest;Consumer;DIRECT
/Company Home/Guest Home;ALLOWED;GROUP_EVERYONE;Consumer;DIRECT
/Company Home/User Homes/abeecher;ALLOWED;abeecher;All;DIRECT
/Company Home/User Homes/abeecher;ALLOWED;ROLE_OWNER;All;DIRECT

Some background on recurse()

The recurse() function is only available within the Javascript Console and can be used to recursively search through the Alfresco Repository. It is very versatile, check out the following examples.

You can generate an array of all nodes under a specific folder:

var allNodes = recurse(space);

This will return an array with ScriptNode objects (folders and documents).

The second way to use the recurse function is using a callback function as we did in the initial script. The callback is called for each node. Internally node.children is used to get the child nodes and recurse deeper. if you return any objects from the processing function they will be added to an array and are returned from the recurse() function as the first example showed it. Using the callback function is probably the most useful way to use it:

recurse(space, function(node) {
   logger.log(node.displayPath + "/" + node.name);
});

The third way allows to pass in options to change to depth of the recursion. Currently there is only the maxLevel option which is used in the following example to only iterate two levels deep:

recurse(space, {
  process : function(node) {
    logger.log(node.displayPath + "/" + node.name);
  },
  maxlevel : 2
});

One thing you should keep in mind when running recursive Javascript code in Alfresco is that the whole script runs in one transaction. When iterating over a large repository and especially if you are updating nodes you might run into trouble with the transaction caches and maybe even database locking.

6 thoughts on “Using the Javascript Console: Permission reporting

  1. Have you considered enhancing the recurse() function to support transactional batching (ideally with optional parameters that allow the caller to configure batch size, if they wish)? This would be a great enhancement, as this function makes it trivial to accidentally get into trouble with long running transactions.

    Basically I’m envisaging something similar to the Java BatchProcessor functionality [1] in the Alfresco API.

    [1] http://dev.alfresco.com/resource/docs/java/repository/org/alfresco/repo/batch/BatchProcessor.html

  2. Hi Peter,

    Thanks for your comment. I actually have thought about this a lot but haven’t started implementing it yet because it is not trivial to put all my requirements together. My current idea would be to write most of it in Java and use Javascript only for the dynamic parts:

    - BatchProcessor is used for multi threading.
    - Recursion through all nodes (written in Java?). If you throw in multi threading you get the interesting problem that in some cases you don’t want to process children before the parent hasn’t been processed by another thread.
    - Branching should be controlled ideally by Javascript evaluators for maximum flexibility (is it fast enough to call those often?).
    - Transaction size should be configurable, so e.g. 100 documents can be updated in one transaction.
    - Failover to single document transactions in case of an error would be great.
    - The processing logic should either run as Javascript or run an arbitrary Action.
    - The whole batch processing should be an Action itself so you can invoke it on the fly.

    In projects I am currently only using recursive processing written in Java (single threaded) using batched transactions for larger updates.

    I’m wondering who would be the best person at DevCon to talk to about this.

  3. Pingback: La consola Javascript de Alfresco Share - Blog - zylk.net

  4. Pingback: Scripting with Alfresco JS API - Some useful Javascript Console scripts - zylk

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>