GithubHelp home page GithubHelp logo

netcentric / accesscontroltool Goto Github PK

View Code? Open in Web Editor NEW
146.0 35.0 92.0 4.47 MB

Rights and roles management for AEM made easy

License: Eclipse Public License 1.0

Java 99.97% Less 0.03%
aem oak crx acl-entries acls access-control access-management sling

accesscontroltool's Introduction

Maven Central License Build Status SonarCloud Status SonarCloud Coverage

Access Control Tool for Adobe Experience Manager

The Access Control Tool for Adobe Experience Manager (AC Tool) simplifies the specification and deployment of complex Access Control Lists in AEM as well as users and groups. Instead of existing solutions that build e.g. a content package with actual ACL nodes you can write simple configuration files and deploy them with your content packages. See comparison to other approaches for a comprehensive overview.

Features:

  • easy-to-read Yaml configuration file format
  • run mode support
  • automatic installation with install hook
  • cleans obsolete ACL entries when configuration is changed
  • ACLs can be exported
  • management of user's key stores and the global trust store
  • stores history of changes
  • ensured order of ACLs
  • built-in expression language to reduce rule duplication

See also our talk at adaptTo() 2016

Requirements

The AC Tool requires Java 8 and AEM 6.4 or above (use v2.x for older AEM versions which runs on Java 7 and AEM 6.1 SP1 or above) for on-premise installations. Since v2.5.0 AEM as a Cloud Service is supported, see Startup Hook for details.

It is also possible to run the AC Tool on Apache Sling 11 or above (ensure system user actool-service has jcr:all permissions on root). When using the AC Tool with Sling, actions in ACE definitions and encrypted passwords cannot be used. To use the externalId attribute, ensure bundle oak-auth-external installed (not part of default Sling distribution).

Installation

The content package is available from the Maven Central repository

For quick ad hoc testing and getting to know the AC Tool, the easiest is to

  • Install the latest version via AEM's package manager
  • Create a sample YAML file in CRXDE (e.g. /apps/actool-test/test.yaml)
  • Apply this config using the UI (see User Interface below)

For properly integrating the AC Tool in your own deployment package see Installation.

Configuration of the AC Tool

You need to setup Yaml configuration files to specify your users, groups and ACL entries. See also the best practices for hints on structuring.

There are also some advanced configuration options supported such as loops, conditional statements and permissions for anonymous.

User Interface

There is a Felix Web Console plugin (at /system/console/actool) as well as a Touch UI console (at /mnt/overlay/netcentric/actool/content/overview.html) to apply configurations and to inspect previous executions of the tool. Additionally there is a JMX interface for some advanced use cases.

Applying AC Tool Configurations

Best practice is to apply AC Tool Configurations using the install hook (or startup hook for Cloud Service) during your project's software package installation. See applying the ACL entries for a full list of options.

Migration to AC Tool

You can easily migrate to AC Tool following four simple steps.

Questions

If you have any questions which are still answered after reading the documentation feel free to raise them in the discussion forum.

Contributions

Contributions are highly welcome in the form of issue reports, pull request or providing help in our discussion forum.

Building the packages from source

If needed you can build the AC Tool yourself.

License

The AC Tool is licensed under the Eclipse Public License - v 1.0.

accesscontroltool's People

Contributors

amyrahmady avatar bcsott avatar cpilsworth avatar dependabot[bot] avatar ghenzler avatar jochenkoschorke avatar joestieg avatar josephrignanese avatar kwin avatar luckyluke-nc avatar mtstv avatar nc-andreashaller avatar nc-richard-meier avatar ofarganc avatar oleksandrbarybin avatar oliverlietz avatar otarsko avatar positronic-brain avatar santiagogpnc avatar santiagozky avatar stefanseifert avatar steffenrosi avatar tnebe avatar tomasalmeida avatar ugocei avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

accesscontroltool's Issues

getRepPolicyNodes is not backed by an index

When installing ACLs a large number of the following warning messages appear in the log file, while the whole process takes almost half an hour on a repo of approx 4 million nodes.
It seems to me that the query in QueryHelper.getRepPolicyNodes line 89 is not backed by any index?

10.03.2016 08:16:10.351 WARN [qtp123593292-1375] org.apache.jackrabbit.oak.spi.query.Cursors$TraversingCursor Traversed 4000 nodes with filter Filter(query=SELECT * FROM [rep:ACL] WHERE ISDESCENDANTNODE([/apps]), path=/apps//); consider creating an index or changing the query
10.03.2016 08:16:10.668 *WARN
[qtp123593292-1375] org.apache.jackrabbit.oak.spi.query.Cursors$TraversingCursor Traversed 5000 nodes with filter Filter(query=SELECT * FROM [rep:ACL] WHERE ISDESCENDANTNODE([/apps]), path=/apps//); consider creating an index or changing the query
10.03.2016 08:16:10.845 *WARN
[qtp123593292-1375] org.apache.jackrabbit.oak.spi.query.Cursors$TraversingCursor Traversed 6000 nodes with filter Filter(query=SELECT * FROM [rep:ACL] WHERE ISDESCENDANTNODE([/apps]), path=/apps//); consider creating an index or changing the query
10.03.2016 08:16:10.863 *WARN
[qtp123593292-1375] org.apache.jackrabbit.oak.spi.query.Cursors$TraversingCursor Traversed 7000 nodes with filter Filter(query=SELECT * FROM [rep:ACL] WHERE ISDESCENDANTNODE([/apps]), path=/apps//); consider creating an index or changing the query
10.03.2016 08:16:10.899 *WARN
[qtp123593292-1375] org.apache.jackrabbit.oak.spi.query.Cursors$TraversingCursor Traversed 1000 nodes with filter Filter(query=SELECT * FROM [rep:ACL] WHERE ISDESCENDANTNODE([/content]), path=/content//); consider creating an index or changing the query
10.03.2016 08:16:10.924 *WARN
[qtp123593292-1375] org.apache.jackrabbit.oak.spi.query.Cursors$TraversingCursor Traversed 2000 nodes with filter Filter(query=SELECT * FROM [rep:ACL] WHERE ISDESCENDANTNODE([/content]), path=/content//); consider creating an index or changing the query
10.03.2016 08:16:10.952 *WARN
[qtp123593292-1375] org.apache.jackrabbit.oak.spi.query.Cursors$TraversingCursor Traversed 3000 nodes with filter Filter(query=SELECT * FROM [rep:ACL] WHERE ISDESCENDANTNODE([/content]), path=/content//); consider creating an index or changing the query
10.03.2016 08:16:10.962 *WARN
[qtp123593292-1375] org.apache.jackrabbit.oak.spi.query.Cursors$TraversingCursor Traversed 4000 nodes with filter Filter(query=SELECT * FROM [rep:ACL] WHERE ISDESCENDANTNODE([/content]), path=/content//); consider creating an index or changing the query
10.03.2016 08:16:10.976 *WARN
[qtp123593292-1375] org.apache.jackrabbit.oak.spi.query.Cursors$TraversingCursor Traversed 5000 nodes with filter Filter(query=SELECT * FROM [rep:ACL] WHERE ISDESCENDANTNODE([/content]), path=/content//); consider creating an index or changing the query
10.03.2016 08:16:10.985 *WARN
[qtp123593292-1375] org.apache.jackrabbit.oak.spi.query.Cursors$TraversingCursor Traversed 6000 nodes with filter Filter(query=SELECT * FROM [rep:ACL] WHERE ISDESCENDANTNODE([/content]), path=/content//); consider creating an index or changing the query
10.03.2016 08:16:10.997 *WARN
[qtp123593292-1375] org.apache.jackrabbit.oak.spi.query.Cursors$TraversingCursor Traversed 7000 nodes with filter Filter(query=SELECT * FROM [rep:ACL] WHERE ISDESCENDANTNODE([/content]), path=/content//); consider creating an index or changing the query
10.03.2016 08:16:11.012 *WARN
[qtp123593292-1375] org.apache.jackrabbit.oak.spi.query.Cursors$TraversingCursor Traversed 8000 nodes with filter Filter(query=SELECT * FROM [rep:ACL] WHERE ISDESCENDANTNODE([/content]), path=/content//); consider creating an index or changing the query
10.03.2016 08:16:11.022 *WARN
[qtp123593292-1375] org.apache.jackrabbit.oak.spi.query.Cursors$TraversingCursor Traversed 9000 nodes with filter Filter(query=SELECT * FROM [rep:ACL] WHERE ISDESCENDANTNODE([/content]), path=/content//); consider creating an index or changing the query
10.03.2016 08:16:11.030 *WARN
[qtp123593292-1375] org.apache.jackrabbit.oak.spi.query.Cursors$TraversingCursor Traversed 10000 nodes with filter Filter(query=SELECT * FROM [rep:ACL] WHERE ISDESCENDANTNODE([/content]), path=/content//); consider creating an index or changing the query
10.03.2016 08:16:11.041 *WARN
[qtp123593292-1375] org.apache.jackrabbit.oak.spi.query.Cursors$TraversingCursor Traversed 11000 nodes with filter Filter(query=SELECT * FROM [rep:ACL] WHERE ISDESCENDANTNODE([/content]), path=/content//); consider creating an index or changing the query
10.03.2016 08:16:11.055 *WARN
[qtp123593292-1375] org.apache.jackrabbit.oak.spi.query.Cursors$TraversingCursor Traversed 12000 nodes with filter Filter(query=SELECT * FROM [rep:ACL] WHERE ISDESCENDANTNODE([/content]), path=/content//); consider creating an index or changing the query
10.03.2016 08:16:11.073 *WARN
[qtp123593292-1375] org.apache.jackrabbit.oak.spi.query.Cursors$TraversingCursor Traversed 13000 nodes with filter Filter(query=SELECT * FROM [rep:ACL] WHERE ISDESCENDANTNODE([/content]), path=/content//); consider creating an index or changing the query
10.03.2016 08:16:11.089 *WARN
[qtp123593292-1375] org.apache.jackrabbit.oak.spi.query.Cursors$TraversingCursor Traversed 14000 nodes with filter Filter(query=SELECT * FROM [rep:ACL] WHERE ISDESCENDANTNODE([/content]), path=/content//*); consider creating an index or changing the query

purgeAllAuthorizablesFromConfigurations() method throws Exception

When the number of defined groups in configuration files is very big (>1024), the method purgeAllAuthorizablesFromConfigurations(), which can be triggered from JMX whiteboard, throws an Exception:

20.04.2015 10:30:37.270 ERROR [qtp654152865-153] biz.netcentric.cq.tools.actool.aceservice.impl.AceServiceImpl Exception:
org.apache.lucene.search.BooleanQuery$TooManyClauses: maxClauseCount is set to 1024
at org.apache.lucene.search.BooleanQuery.add(BooleanQuery.java:136)
at org.apache.jackrabbit.core.query.lucene.LuceneQueryBuilder.visit(LuceneQueryBuilder.java:295)
...

Extend functionality with "purges all ACEs of authorizables contained in configuration files from the system"

I would extend functionality of tool with the next:

AceServiceMBean.java
@description("purges all ACEs of authorizables contained in configuration files from the system")
public String purgeACLsOfAuthorizablesFromConfigurations();

We need to delete only old ACEs of our groups without deletetion of groups, because we don't want to lost the membership for users.
The number of groups is very large and it's time expensive to collect a list of groups we want do delete. So we don't want to use other existing methods for purging of ACEs.
After deleting of old ACLs we could just recreate ACEs defined in our new config yaml files.

I extended already the functionality and code is working well already for me.

Groups that are defined in a config file should be usable in ace_config part of other config files

At the moment it causes an exception and defining the same group in multiple files is not possible.

EXCEPTION: biz.netcentric.cq.tools.actool.validators.exceptions.NoGroupDefinedException: Validation error while reading ACE definition nr.1 of authorizable: everyone is not defined in group configuration
2015-01-07 10:24:18.685: saved history in node: /var/statistics/achistory/history_1420622658684

NPE during the installation of a config containing a nested loop

when trying to install the following test config:

  • group_config:
    • for mpc IN [ hq, germany, france ]:
      • for lang IN [ de, en ]:
        • fragment-${mpc}-${lang}-section1-edit:
          • name:
            memberOf:
            path: /dai/groups/f
        • fragment-${mpc}-${lang}-section2-edit:
          • name:
            memberOf:
            path: /dai/groups/f
        • fragment-${mpc}-${lang}-section3-edit:
          • name:
            memberOf:
            path: /dai/groups/f
  • ace_config:
    • for mpc IN [ hq, germany, france ]:
      • for lang IN [ de, en ]:
        • fragment-${mpc}-${lang}-section1-edit:
          • path: /content/${mpc}/${lang}/passengercars
            permission: allow
            actions: acl_read,acl_edit,delete,modify,read,create,replicate
            privileges:
            repGlob:
        • path: /content/${mpc}/${lang}/content-pool/marketing-pool/passengercars
          permission: allow
          actions: acl_read,acl_edit,delete,modify,read,create,replicate
          privileges:
          repGlob:
        • path: /content/dam/hq/passengercars
          permission: allow
          actions: acl_read,acl_edit,delete,modify,read,create,replicate
          privileges:
          repGlob:
        • fragment-${mpc}-${lang}-section2-edit:
          • path: /content/${mpc}/${lang}/transporters
            permission: allow
            actions: acl_read,acl_edit,delete,modify,read,create,replicate
            privileges:
            repGlob:
        • path: /content/${mpc}/${lang}/content-pool/marketing-pool/transporters
          permission: allow
          actions: acl_read,acl_edit,delete,modify,read,create,replicate
          privileges:
          repGlob:
        • path: /content/dam/hq/transporters
          permission: allow
          actions: acl_read,acl_edit,delete,modify,read,create,replicate
          privileges:
          repGlob:
        • fragment-${mpc}-${lang}-section3-edit:
          • path: /content/${mpc}/${lang}/busses
            permission: allow
            actions: acl_read,acl_edit,delete,modify,read,create,replicate
            privileges:
            repGlob:
        • path: /content/${mpc}/${lang}/content-pool/marketing-pool/busses
          permission: allow
          actions: acl_read,acl_edit,delete,modify,read,create,replicate
          privileges:
          repGlob:
        • path: /content/dam/hq/busses
          permission: allow
          actions: acl_read,acl_edit,delete,modify,read,create,replicate
          privileges:
          repGlob:

I get the following NPE:

13.01.2015 17:42:48.272 ERROR [qtp123659800-19062] biz.netcentric.cq.tools.actool.aceservice.impl.AceServiceImpl Exception in AceServiceImpl: {}
java.lang.NullPointerException: null
at biz.netcentric.cq.tools.actool.helper.AccessControlUtils.getPrivilegeSet(AccessControlUtils.java:407)
at biz.netcentric.cq.tools.actool.helper.AccessControlUtils.installPermissions(AccessControlUtils.java:495)
at biz.netcentric.cq.tools.actool.helper.AcHelper.installBean(AcHelper.java:322)
at biz.netcentric.cq.tools.actool.helper.AcHelper.resetAclInRepository(AcHelper.java:208)
at biz.netcentric.cq.tools.actool.helper.AcHelper.installPathBasedACEs(AcHelper.java:147)
...

Combinations of allow/deny rules with actions and repGlob are not fully set

Example:

  • path: /content
    permission: deny
    actions: read,acl_read
    privileges:
    repGlob:
  • path: /content
    permission: allow
    actions: read,acl_read
    privileges:
    repGlob: ""
  • path: /content
    permission: allow
    actions: read,acl_read
    privileges:
    repGlob: /jcr:*

โ€‹I just get the two allow rules. The deny rule is not set.
Probably, this is because when setting the first allow rule without repglob then the deny rule is removed. I saw this kind of effect when I debugged the tool some time ago, OAK seems to remove rules if they are obsoleted by another rule.
Probably, here the second rule with allow removes the first rule since it is added without repglob first (added in a second code step).

Fails to install group and set permissions in one step in AEM 6.1

Example config:

  • group_config:
    • system-tags:
      • name:
        isMemberOf:
        members:
        path: m
  • ace_config:
    • system-tags:
      • path: /etc/tags
        permission: allow
        actions: read
        privileges:

Leads to:

2015-08-06 10:01:14.23: start merging configuration data from: /apps/mwsg-system/acl/serviceuser/config
2015-08-06 10:01:14.232: start installation of merged configurations
2015-08-06 10:01:14.998: finished installation of groups configuration without errors!
2015-08-06 10:01:15.003: EXCEPTION: java.util.NoSuchElementException
2015-08-06 10:01:15.003: performing authorizable installation rollback(s)
2015-08-06 10:01:15.003: WARNING: starting rollback of authorizables...
2015-08-06 10:01:15.003: WARNING: performing Groups rollback!
2015-08-06 10:01:15.036: WARNING: removed authorizable system-tags from the system!
2015-08-06 10:01:15.039: saved history in node: /var/statistics/achistory/history_1438848075038

06.08.2015 10:01:14.995 INFO [qtp1190515388-521] biz.netcentric.cq.tools.actool.authorizableutils.impl.AuthorizableCreatorServiceImpl Successfully created new Group: system-tags
06.08.2015 10:01:14.998 INFO [qtp1190515388-521] biz.netcentric.cq.tools.actool.aceservice.impl.AceServiceImpl finished installation of groups configuration without errors!
06.08.2015 10:01:14.998 INFO [qtp1190515388-521] biz.netcentric.cq.tools.actool.aceservice.impl.AceServiceImpl --- start installation of access control configuration ---
06.08.2015 10:01:14.998 INFO [qtp1190515388-521] biz.netcentric.cq.tools.actool.helper.AcHelper Paths in merged config = [/etc/tags]
06.08.2015 10:01:14.998 INFO [qtp1190515388-521] biz.netcentric.cq.tools.actool.helper.AcHelper authorizablesInAclFromConfig: [system-tags]
06.08.2015 10:01:14.998 INFO [qtp1190515388-521] biz.netcentric.cq.tools.actool.helper.AcHelper Added following ACE to the merged ACL: AceBean [jcrPath=/etc/tags
, permission=allow
, repGlob=null
, actionsString=null
, privilegesString=jcr:read
, principal=mwsg-system-tags
, actions=[read]]
06.08.2015 10:01:14.998 INFO [qtp1190515388-521] biz.netcentric.cq.tools.actool.helper.AcHelper Added following ACE to the merged ACL: AceBean [jcrPath=/etc/tags
, permission=allow
, repGlob=null
, actionsString=null
, privilegesString=crx:replicate,jcr:versionManagement,jcr:read,jcr:modifyAccessControl,jcr:readAccessControl,rep:write,jcr:lockManagement
, principal=tag-administrators
, actions=[modify, replicate, read, create, delete, acl_read, acl_edit]]
06.08.2015 10:01:14.998 INFO [qtp1190515388-521] biz.netcentric.cq.tools.actool.helper.AcHelper Added following ACE to the merged ACL: AceBean [jcrPath=/etc/tags
, permission=allow
, repGlob=
, actionsString=null
, privilegesString=jcr:read
, principal=everyone
, actions=[read]]
06.08.2015 10:01:15.000 INFO [qtp1190515388-521] biz.netcentric.cq.tools.actool.helper.AcHelper Removed all policies from node /etc/tags.

06.08.2015 10:01:15.003 ERROR [qtp1190515388-521] biz.netcentric.cq.tools.actool.aceservice.impl.AceServiceImpl Exception in AceServiceImpl: {}
java.util.NoSuchElementException: null
at java.util.TreeMap$PrivateEntryIterator.nextEntry(TreeMap.java:1205)
at java.util.TreeMap$KeyIterator.next(TreeMap.java:1261)
at biz.netcentric.cq.tools.actool.helper.AcHelper.getPrincipalbyQuery(AcHelper.java:291)
at biz.netcentric.cq.tools.actool.helper.AcHelper.getLdapImportGroupPrincipal(AcHelper.java:266)
at biz.netcentric.cq.tools.actool.helper.AcHelper.resetAclInRepository(AcHelper.java:189)
at biz.netcentric.cq.tools.actool.helper.AcHelper.installPathBasedACEs(AcHelper.java:147)
at biz.netcentric.cq.tools.actool.aceservice.impl.AceServiceImpl.installAces(AceServiceImpl.java:151)
at biz.netcentric.cq.tools.actool.aceservice.impl.AceServiceImpl.installConfigurationFromYamlList(AceServiceImpl.java:129)
at biz.netcentric.cq.tools.actool.aceservice.impl.AceServiceImpl.execute(AceServiceImpl.java:253)
at biz.netcentric.cq.tools.actool.aceservicejmx.impl.AceServiceMBeanImpl.execute(AceServiceMBeanImpl.java:57)

Warnings written to the history are not exposed during Install hook

Currently the warnings written to the AcInstallationHistoryPojo are not evaluated during execution of the install hook. Also the success status is not always reflecting reality (i.e. if the authorizable for one ACE can not be found, ACEs are not installed, but still the status on the history = success)

refactor the biz.netcentric.cq.tools.actool.helper.QueryHelper.java to use SQL2 and optimize Queries to use existing AEM indexes

I just identify, that already existing ACEs of groups which have no more ACE definition inside of yaml files by execute() will be not deleted under the /libs and /etc for example.
I tested Accesscontroltool rel 1.5 with AEM 6.0 and MongoDB.

The queries usually breaks in AEM after 30 seconds. At least this happens if I make a query over CRXDE. I think it was the reason that accesscontroltool by execute() didn't delete old ACEs in the repository and just installed the ACEs configurated in the yaml files.

If I tests with TarMK on the local maschine the old ACEs will be deleted successfully and quickly.

In the log file you can see the next

08.07.2015 12:50:28.419 *WARN* [qtp647970853-284] org.apache.jackrabbit.oak.spi.query.Cursors$TraversingCursor Traversed 1000 nodes with filter Filter(query=select [jcr:path], [jcr:score], * from [nt:base] as a where [jcr:primaryType] = 'rep:ACL' and isdescendantnode(a, '/apps') /* xpath: /jcr:root/apps//*[(@jcr:primaryType = 'rep:ACL') ] */, path=/apps//*, property=[jcr:primaryType=[rep:ACL]]); consider creating an index or changing the query

08.07.2015 12:50:28.531 *WARN* [qtp647970853-284] org.apache.jackrabbit.oak.spi.query.Cursors$TraversingCursor Traversed 21000 nodes with filter Filter(query=select [jcr:path], [jcr:score], * from [nt:base] as a where [jcr:primaryType] = 'rep:ACL' and isdescendantnode(a, '/content') /* xpath: /jcr:root/content//*[(@jcr:primaryType = 'rep:ACL') ] */, path=/content//*, property=[jcr:primaryType=[rep:ACL]]); consider creating an index or changing the query

08.07.2015 12:50:28.672 *WARN* [qtp647970853-284] org.apache.jackrabbit.oak.spi.query.Cursors$TraversingCursor Traversed 23000 nodes with filter Filter(query=select [jcr:path], [jcr:score], * from [nt:base] as a where [jcr:primaryType] = 'rep:ACL' and isdescendantnode(a, '/etc') /* xpath: /jcr:root/etc//*[(@jcr:primaryType = 'rep:ACL') ] */, path=/etc//*, property=[jcr:primaryType=[rep:ACL]]); consider creating an index or changing the query

08.07.2015 12:50:29.467 *WARN* [qtp647970853-284] org.apache.jackrabbit.oak.spi.query.Cursors$TraversingCursor Traversed 182000 nodes with filter Filter(query=select [jcr:path], [jcr:score], * from [nt:base] as a where [jcr:primaryType] = 'rep:ACL' and isdescendantnode(a, '/libs') /* xpath: /jcr:root/libs//*[(@jcr:primaryType = 'rep:ACL') ] */, path=/libs//*, property=[jcr:primaryType=[rep:ACL]]); consider creating an index or changing the query

08.07.2015 12:50:29.559 *WARN* [qtp647970853-284] org.apache.jackrabbit.oak.spi.query.Cursors$TraversingCursor Traversed 16000 nodes with filter Filter(query=select [jcr:path], [jcr:score], * from [nt:base] as a where [jcr:primaryType] = 'rep:ACL' and isdescendantnode(a, '/var') /* xpath: /jcr:root/var//*[(@jcr:primaryType = 'rep:ACL') ] */, path=/var//*, property=[jcr:primaryType=[rep:ACL]]); consider creating an index or changing the query

So the solution is to refactor the biz.netcentric.cq.tools.actool.helper.QueryHelper.java to use SQL2 and optimize the queries to use existing AEM indexes or to provide a set of index configurations.

  1. Instead of using the XPATH
    /jcr:root//*[(@jcr:primaryType = 'rep:GrantACE' or @jcr:primaryType = 'rep:DenyACE' ) and (@rep:principalName = 'fragment-basic')]

it is better use existing indexes "/oak:index/acPrincipalName"
Ex.
SELECT * FROM [rep:ACE] AS s WHERE ISDESCENDANTNODE([/apps]) and [rep:principalName] = 'fragment-basic'

  1. Instead of using the XPATH
    /jcr:root/libs//*[(@jcr:primaryType = 'rep:ACL') ]

prepare a package with own indexes for "rep:ACL" similar to /oak:index/nodetype
In this case such query will be very fast
SELECT * FROM [rep:ACL] AS s WHERE ISDESCENDANTNODE([/libs])

NPE when attempting rollback

The following Exception is thrown when running the ACTool.

java.lang.NullPointerException at biz.netcentric.cq.tools.actool.authorizableutils.impl.AuthorizableCreatorServiceImpl.performRollback(AuthorizableCreatorServiceImpl.java:819) at biz.netcentric.cq.tools.actool.aceservice.impl.AceServiceImpl.execute(AceServiceImpl.java:277) at biz.netcentric.cq.tools.actool.aceservicejmx.impl.AceServiceMBeanImpl.execute(AceServiceMBeanImpl.java:57) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:497) at sun.reflect.misc.Trampoline.invoke(MethodUtil.java:71) at sun.reflect.GeneratedMethodAccessor15.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:497) at sun.reflect.misc.MethodUtil.invoke(MethodUtil.java:275) at com.sun.jmx.mbeanserver.StandardMBeanIntrospector.invokeM2(StandardMBeanIntrospector.java:112) at com.sun.jmx.mbeanserver.StandardMBeanIntrospector.invokeM2(StandardMBeanIntrospector.java:46) at com.sun.jmx.mbeanserver.MBeanIntrospector.invokeM(MBeanIntrospector.java:237) at com.sun.jmx.mbeanserver.PerInterface.invoke(PerInterface.java:138) at com.sun.jmx.mbeanserver.MBeanSupport.invoke(MBeanSupport.java:252) at javax.management.StandardMBean.invoke(StandardMBean.java:405) at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.invoke(DefaultMBeanServerInterceptor.java:819) at com.sun.jmx.mbeanserver.JmxMBeanServer.invoke(JmxMBeanServer.java:801) at com.adobe.granite.jmx.internal.JMXConsolePlugin.invoke(JMXConsolePlugin.java:176) at com.adobe.granite.jmx.internal.JMXConsolePlugin.doPost(JMXConsolePlugin.java:134) at javax.servlet.http.HttpServlet.service(HttpServlet.java:644) at javax.servlet.http.HttpServlet.service(HttpServlet.java:725) at org.apache.felix.webconsole.internal.servlet.OsgiManager.service(OsgiManager.java:555) at org.apache.felix.webconsole.internal.servlet.OsgiManager$3.run(OsgiManager.java:459) at java.security.AccessController.doPrivileged(Native Method) at org.apache.felix.webconsole.internal.servlet.OsgiManager.service(OsgiManager.java:455) at org.apache.felix.http.base.internal.handler.ServletHandler.doHandle(ServletHandler.java:336) at org.apache.felix.http.base.internal.handler.ServletHandler.handle(ServletHandler.java:297) at org.apache.felix.http.base.internal.dispatch.ServletPipeline.handle(ServletPipeline.java:93) at org.apache.felix.http.base.internal.dispatch.InvocationFilterChain.doFilter(InvocationFilterChain.java:50) at org.apache.felix.http.base.internal.dispatch.HttpFilterChain.doFilter(HttpFilterChain.java:31) at org.apache.sling.i18n.impl.I18NFilter.doFilter(I18NFilter.java:129) at org.apache.felix.http.base.internal.handler.FilterHandler.doHandle(FilterHandler.java:108) at org.apache.felix.http.base.internal.handler.FilterHandler.handle(FilterHandler.java:80) at org.apache.felix.http.base.internal.dispatch.InvocationFilterChain.doFilter(InvocationFilterChain.java:46) at org.apache.felix.http.base.internal.dispatch.HttpFilterChain.doFilter(HttpFilterChain.java:31) at org.apache.felix.http.sslfilter.internal.SslFilter.doFilter(SslFilter.java:89) at org.apache.felix.http.base.internal.handler.FilterHandler.doHandle(FilterHandler.java:108) at org.apache.felix.http.base.internal.handler.FilterHandler.handle(FilterHandler.java:80) at org.apache.felix.http.base.internal.dispatch.InvocationFilterChain.doFilter(InvocationFilterChain.java:46) at org.apache.felix.http.base.internal.dispatch.HttpFilterChain.doFilter(HttpFilterChain.java:31) at com.adobe.granite.license.impl.LicenseCheckFilter.doFilter(LicenseCheckFilter.java:308) at org.apache.felix.http.base.internal.handler.FilterHandler.doHandle(FilterHandler.java:108) at org.apache.felix.http.base.internal.handler.FilterHandler.handle(FilterHandler.java:80) at org.apache.felix.http.base.internal.dispatch.InvocationFilterChain.doFilter(InvocationFilterChain.java:46) at org.apache.felix.http.base.internal.dispatch.HttpFilterChain.doFilter(HttpFilterChain.java:31) at org.apache.sling.security.impl.ReferrerFilter.doFilter(ReferrerFilter.java:290) at org.apache.felix.http.base.internal.handler.FilterHandler.doHandle(FilterHandler.java:108) at org.apache.felix.http.base.internal.handler.FilterHandler.handle(FilterHandler.java:80) at org.apache.felix.http.base.internal.dispatch.InvocationFilterChain.doFilter(InvocationFilterChain.java:46) at org.apache.felix.http.base.internal.dispatch.HttpFilterChain.doFilter(HttpFilterChain.java:31) at org.apache.sling.featureflags.impl.FeatureManager.doFilter(FeatureManager.java:115) at org.apache.felix.http.base.internal.handler.FilterHandler.doHandle(FilterHandler.java:108) at org.apache.felix.http.base.internal.handler.FilterHandler.handle(FilterHandler.java:80) at org.apache.felix.http.base.internal.dispatch.InvocationFilterChain.doFilter(InvocationFilterChain.java:46) at org.apache.felix.http.base.internal.dispatch.HttpFilterChain.doFilter(HttpFilterChain.java:31) at org.apache.sling.engine.impl.log.RequestLoggerFilter.doFilter(RequestLoggerFilter.java:75) at org.apache.felix.http.base.internal.handler.FilterHandler.doHandle(FilterHandler.java:108) at org.apache.felix.http.base.internal.handler.FilterHandler.handle(FilterHandler.java:80) at org.apache.felix.http.base.internal.dispatch.InvocationFilterChain.doFilter(InvocationFilterChain.java:46) at org.apache.felix.http.base.internal.dispatch.HttpFilterChain.doFilter(HttpFilterChain.java:31) at org.apache.felix.http.base.internal.dispatch.FilterPipeline.dispatch(FilterPipeline.java:76) at org.apache.felix.http.base.internal.dispatch.Dispatcher.dispatch(Dispatcher.java:49) at org.apache.felix.http.base.internal.DispatcherServlet.service(DispatcherServlet.java:67) at javax.servlet.http.HttpServlet.service(HttpServlet.java:725) at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:808) at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:587) at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:221) at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1127) at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:515) at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:185) at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1061) at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141) at org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:215) at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:97) at org.eclipse.jetty.server.Server.handle(Server.java:497) at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:310) at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:257) at org.eclipse.jetty.io.AbstractConnection$2.run(AbstractConnection.java:540) at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:635) at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:555) at java.lang.Thread.run(Thread.java:745)

Apparently, the rollback is triggered when this exception is detected:
`javax.jcr.nodetype.ConstraintViolationException: OakConstraint0030: Uniqueness constraint violated at path [/] for one of the property in [jcr:uuid] having value 3079a640-921c-32c8-b5ef-a526b7b72a38``

Compiling with Maven 3.3 fails as it requires content-package-maven-plugin version 0.0.24

Error installing version 1.6.2 using Maven 3.3.

It seems only content-package-maven-plugin version 0.0.24 is compatible with Maven 3.3+. Version 1.6.2 uses content-package-maven-plugin version 0.0.23.

[ERROR] Failed to execute goal com.day.jcr.vault:content-package-maven-plugin:0.0.23:package (default-package) on project accesscontroltool-package: Execution default-package of goal com.day.jcr.vault:content-package-maven-plugin:0.0.23:package failed: A required class was missing while executing com.day.jcr.vault:content-package-maven-plugin:0.0.23:package: org/slf4j/helpers/MarkerIgnoringBase
[ERROR] -----------------------------------------------------
[ERROR] realm = extension>com.day.jcr.vault:content-package-maven-plugin:0.0.23
[ERROR] strategy = org.codehaus.plexus.classworlds.strategy.SelfFirstStrategy
[ERROR] urls[0] = file:/Users/antonio/.m2/repository/com/day/jcr/vault/content-package-maven-plugin/0.0.23/content-package-maven-plugin-0.0.23.jar
[ERROR] urls[1] = file:/Users/antonio/.m2/repository/backport-util-concurrent/backport-util-concurrent/3.1/backport-util-concurrent-3.1.jar
[ERROR] urls[2] = file:/Users/antonio/.m2/repository/org/codehaus/plexus/plexus-interpolation/1.11/plexus-interpolation-1.11.jar
[ERROR] urls[3] = file:/Users/antonio/.m2/repository/junit/junit/3.8.1/junit-3.8.1.jar
[ERROR] urls[4] = file:/Users/antonio/.m2/repository/org/apache/maven/maven-archiver/2.3/maven-archiver-2.3.jar
[ERROR] urls[5] = file:/Users/antonio/.m2/repository/org/codehaus/plexus/plexus-archiver/1.0-alpha-9/plexus-archiver-1.0-alpha-9.jar
[ERROR] urls[6] = file:/Users/antonio/.m2/repository/org/codehaus/plexus/plexus-io/1.0-alpha-1/plexus-io-1.0-alpha-1.jar
[ERROR] urls[7] = file:/Users/antonio/.m2/repository/org/codehaus/plexus/plexus-utils/1.4.9/plexus-utils-1.4.9.jar
[ERROR] urls[8] = file:/Users/antonio/.m2/repository/org/sonatype/plexus/plexus-sec-dispatcher/1.3/plexus-sec-dispatcher-1.3.jar
[ERROR] urls[9] = file:/Users/antonio/.m2/repository/org/sonatype/plexus/plexus-cipher/1.4/plexus-cipher-1.4.jar
[ERROR] urls[10] = file:/Users/antonio/.m2/repository/commons-httpclient/commons-httpclient/3.1/commons-httpclient-3.1.jar
[ERROR] urls[11] = file:/Users/antonio/.m2/repository/commons-logging/commons-logging/1.0.4/commons-logging-1.0.4.jar
[ERROR] urls[12] = file:/Users/antonio/.m2/repository/commons-codec/commons-codec/1.2/commons-codec-1.2.jar
[ERROR] urls[13] = file:/Users/antonio/.m2/repository/org/codehaus/mojo/animal-sniffer-maven-plugin/1.8/animal-sniffer-maven-plugin-1.8.jar
[ERROR] urls[14] = file:/Users/antonio/.m2/repository/org/codehaus/mojo/animal-sniffer/1.8/animal-sniffer-1.8.jar
[ERROR] urls[15] = file:/Users/antonio/.m2/repository/org/ow2/asm/asm-all/4.0/asm-all-4.0.jar
[ERROR] urls[16] = file:/Users/antonio/.m2/repository/org/codehaus/mojo/java-boot-classpath-detector/1.8/java-boot-classpath-detector-1.8.jar
[ERROR] urls[17] = file:/Users/antonio/.m2/repository/org/apache/maven/reporting/maven-reporting-api/2.0.1/maven-reporting-api-2.0.1.jar
[ERROR] urls[18] = file:/Users/antonio/.m2/repository/org/apache/maven/doxia/doxia-sink-api/1.0-alpha-6/doxia-sink-api-1.0-alpha-6.jar
[ERROR] urls[19] = file:/Users/antonio/.m2/repository/commons-cli/commons-cli/1.0/commons-cli-1.0.jar
[ERROR] urls[20] = file:/Users/antonio/.m2/repository/org/codehaus/plexus/plexus-interactivity-api/1.0-alpha-4/plexus-interactivity-api-1.0-alpha-4.jar
[ERROR] urls[21] = file:/Users/antonio/.m2/repository/org/apache/maven/shared/maven-common-artifact-filters/1.2/maven-common-artifact-filters-1.2.jar
[ERROR] urls[22] = file:/Users/antonio/.m2/repository/org/apache/maven/shared/maven-plugin-testing-harness/1.1/maven-plugin-testing-harness-1.1.jar
[ERROR] urls[23] = file:/Users/antonio/.m2/repository/org/apache/sling/org.apache.sling.commons.json/2.0.6/org.apache.sling.commons.json-2.0.6.jar
[ERROR] Number of foreign imports: 1
[ERROR] import: Entry[import from realm ClassRealm[maven.api, parent: null]]
[ERROR]
[ERROR] -----------------------------------------------------: org.slf4j.helpers.MarkerIgnoringBas

Make compatible with JDK8 javadoc (without disabling doclint)

Currently when building with Java 8 (and doing either a release or mvn package javadoc:jar) you get a lot of errors due to the more strict doclint validation of javadoc in Java 8 (http://blog.joda.org/2014/02/turning-off-doclint-in-jdk-8-javadoc.html).

These errors are

[ERROR] Failed to execute goal org.apache.maven.plugins:maven-javadoc-plugin:2.9:jar (default-cli) on project accesscontroltool-bundle: MavenReportException: Error while creating archive:
[ERROR] Exit code: 1 - /Users/konradwindszus/git/accesscontroltool/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/aceservice/AceService.java:30: warning: no description for @param
[ERROR] * @param path
[ERROR] ^
[ERROR] /Users/konradwindszus/git/accesscontroltool/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/aceservice/AceService.java:36: warning: no description for @param
[ERROR] * @param path
[ERROR] ^
[ERROR] /Users/konradwindszus/git/accesscontroltool/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/aceservice/AceService.java:42: error: @param name not found
[ERROR] * @param authorizableId
[ERROR] ^
[ERROR] /Users/konradwindszus/git/accesscontroltool/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/aceservice/AceService.java:42: warning: no description for @param
[ERROR] * @param authorizableId
[ERROR] ^
[ERROR] /Users/konradwindszus/git/accesscontroltool/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/aceservice/AceService.java:44: warning: no @param for authorizableIds
[ERROR] public String purgeAuthorizables(String authorizableIds);
[ERROR] ^
[ERROR] /Users/konradwindszus/git/accesscontroltool/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/aceservice/AcInstallService.java:37: error: @param name not found
[ERROR] * @param rootPath the rootPath for which the ACLs should be removed
[ERROR] ^
[ERROR] /Users/konradwindszus/git/accesscontroltool/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/aceservice/AcInstallService.java:41: warning: no @param for session
[ERROR] void purgeAcls(Session session, String rootNodePath, boolean isRecursive, InstallationListener listener);
[ERROR] ^
[ERROR] /Users/konradwindszus/git/accesscontroltool/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/aceservice/AcInstallService.java:41: warning: no @param for rootNodePath
[ERROR] void purgeAcls(Session session, String rootNodePath, boolean isRecursive, InstallationListener listener);
[ERROR] ^
[ERROR] /Users/konradwindszus/git/accesscontroltool/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/comparators/NodeCreatedComparator.java:56: warning: no description for @throws
[ERROR] * @throws RepositoryException
[ERROR] ^
[ERROR] /Users/konradwindszus/git/accesscontroltool/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/configreader/ConfigFilesRetriever.java:17: error: @param name not found
[ERROR] * @param session the jcr session
[ERROR] ^
[ERROR] /Users/konradwindszus/git/accesscontroltool/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/configreader/ConfigFilesRetriever.java:18: error: @param name not found
[ERROR] * @param jcrRootPath the root path in the JCR to start looking for yaml-files
[ERROR] ^
[ERROR] /Users/konradwindszus/git/accesscontroltool/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/configreader/ConfigFilesRetriever.java:21: warning: no @param for rootNode
[ERROR] Map<String, String> getConfigFileContentFromNode(Node rootNode) throws Exception;
[ERROR] ^
[ERROR] /Users/konradwindszus/git/accesscontroltool/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/configreader/ConfigFilesRetriever.java:10: error: bad use of '>'
[ERROR] * (used by JMX). Both methods return a map with filename->yaml-config-content entries.
[ERROR] ^
[ERROR] /Users/konradwindszus/git/accesscontroltool/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/configreader/ConfigurationMerger.java:27: error: @param name not found
[ERROR] * @param session
[ERROR] ^
[ERROR] /Users/konradwindszus/git/accesscontroltool/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/configreader/ConfigurationMerger.java:27: warning: no description for @param
[ERROR] * @param session
[ERROR] ^
[ERROR] /Users/konradwindszus/git/accesscontroltool/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/configreader/ConfigurationMerger.java:38: warning: no description for @throws
[ERROR] * @throws RepositoryException
[ERROR] ^
[ERROR] /Users/konradwindszus/git/accesscontroltool/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/configreader/ConfigurationMerger.java:39: warning: no description for @throws
[ERROR] * @throws AcConfigBeanValidationException
[ERROR] ^
[ERROR] /Users/konradwindszus/git/accesscontroltool/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/configreader/ConfigurationMerger.java:41: warning: no @param for configReader
[ERROR] public abstract List getMergedConfigurations(
[ERROR] ^
[ERROR] /Users/konradwindszus/git/accesscontroltool/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/dumpservice/Dumpservice.java:42: error: @param name not found
[ERROR] /** @param aceMap
[ERROR] ^
[ERROR] /Users/konradwindszus/git/accesscontroltool/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/dumpservice/Dumpservice.java:42: warning: no description for @param
[ERROR] /** @param aceMap
[ERROR] ^
[ERROR] /Users/konradwindszus/git/accesscontroltool/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/dumpservice/Dumpservice.java:43: error: @param name not found
[ERROR] * @param authorizableSet
[ERROR] ^
[ERROR] /Users/konradwindszus/git/accesscontroltool/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/dumpservice/Dumpservice.java:43: warning: no description for @param
[ERROR] * @param authorizableSet
[ERROR] ^
[ERROR] /Users/konradwindszus/git/accesscontroltool/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/dumpservice/Dumpservice.java:44: warning: no description for @param
[ERROR] * @param mapOrder
[ERROR] ^
[ERROR] /Users/konradwindszus/git/accesscontroltool/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/dumpservice/Dumpservice.java:45: warning: no description for @param
[ERROR] * @param serverUrl
[ERROR] ^
[ERROR] /Users/konradwindszus/git/accesscontroltool/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/dumpservice/Dumpservice.java:46: warning: no description for @return
[ERROR] * @return
[ERROR] ^
[ERROR] /Users/konradwindszus/git/accesscontroltool/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/dumpservice/Dumpservice.java:47: warning: no description for @throws
[ERROR] * @throws IOException */
[ERROR] ^
[ERROR] /Users/konradwindszus/git/accesscontroltool/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/dumpservice/Dumpservice.java:48: warning: no @param for aceDumpData
[ERROR] public String getConfigurationDumpAsString(final AceDumpData aceDumpData,
[ERROR] ^
[ERROR] /Users/konradwindszus/git/accesscontroltool/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/dumpservice/Dumpservice.java:48: warning: no @param for groupSet
[ERROR] public String getConfigurationDumpAsString(final AceDumpData aceDumpData,
[ERROR] ^
[ERROR] /Users/konradwindszus/git/accesscontroltool/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/dumpservice/Dumpservice.java:48: warning: no @param for userSet
[ERROR] public String getConfigurationDumpAsString(final AceDumpData aceDumpData,
[ERROR] ^
[ERROR] /Users/konradwindszus/git/accesscontroltool/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/dumpservice/Dumpservice.java:61: warning: no description for @param
[ERROR] /** @param session
[ERROR] ^
[ERROR] /Users/konradwindszus/git/accesscontroltool/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/dumpservice/Dumpservice.java:62: warning: no description for @return
[ERROR] * @return
[ERROR] ^
[ERROR] /Users/konradwindszus/git/accesscontroltool/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/dumpservice/Dumpservice.java:63: warning: no description for @throws
[ERROR] * @throws RepositoryException */
[ERROR] ^
[ERROR] /Users/konradwindszus/git/accesscontroltool/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/dumpservice/Dumpservice.java:69: error: @param name not found
[ERROR] * @param request
[ERROR] ^
[ERROR] /Users/konradwindszus/git/accesscontroltool/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/dumpservice/Dumpservice.java:69: warning: no description for @param
[ERROR] * @param request
[ERROR] ^
[ERROR] /Users/konradwindszus/git/accesscontroltool/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/dumpservice/Dumpservice.java:73: warning: no description for @return
[ERROR] * @return
[ERROR] ^
[ERROR] /Users/konradwindszus/git/accesscontroltool/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/dumpservice/Dumpservice.java:74: warning: no description for @throws
[ERROR] * @throws ValueFormatException
[ERROR] ^
[ERROR] /Users/konradwindszus/git/accesscontroltool/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/dumpservice/Dumpservice.java:75: warning: no description for @throws
[ERROR] * @throws IllegalStateException
[ERROR] ^
[ERROR] /Users/konradwindszus/git/accesscontroltool/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/dumpservice/Dumpservice.java:76: warning: no description for @throws
[ERROR] * @throws RepositoryException */
[ERROR] ^
[ERROR] /Users/konradwindszus/git/accesscontroltool/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/dumpservice/Dumpservice.java:77: warning: no @param for session
[ERROR] public AceDumpData createAclDumpMap(final Session session,
[ERROR] ^
[ERROR] /Users/konradwindszus/git/accesscontroltool/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/dumpservice/Dumpservice.java:77: warning: no @param for excludePaths
[ERROR] public AceDumpData createAclDumpMap(final Session session,
[ERROR] ^
[ERROR] /Users/konradwindszus/git/accesscontroltool/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/dumpservice/Dumpservice.java:90: warning: no description for @return
[ERROR] * @return */
[ERROR] ^
[ERROR] /Users/konradwindszus/git/accesscontroltool/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/dumpservice/Dumpservice.java:95: warning: no description for @return
[ERROR] * @return */
[ERROR] ^
[ERROR] /Users/konradwindszus/git/accesscontroltool/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/dumpservice/Dumpservice.java:102: warning: no description for @param
[ERROR] * @param mapOrdering
[ERROR] ^
[ERROR] /Users/konradwindszus/git/accesscontroltool/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/dumpservice/Dumpservice.java:103: warning: no description for @param
[ERROR] * @param aceOrdering */
[ERROR] ^
[ERROR] /Users/konradwindszus/git/accesscontroltool/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/dumpservice/Dumpservice.java:110: warning: no description for @param
[ERROR] * @param response
[ERROR] ^
[ERROR] /Users/konradwindszus/git/accesscontroltool/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/dumpservice/Dumpservice.java:111: error: @param name not found
[ERROR] * @param aceMap
[ERROR] ^
[ERROR] /Users/konradwindszus/git/accesscontroltool/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/dumpservice/Dumpservice.java:111: warning: no description for @param
[ERROR] * @param aceMap
[ERROR] ^
[ERROR] /Users/konradwindszus/git/accesscontroltool/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/dumpservice/Dumpservice.java:112: error: @param name not found
[ERROR] * @param authorizableSet
[ERROR] ^
[ERROR] /Users/konradwindszus/git/accesscontroltool/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/dumpservice/Dumpservice.java:112: warning: no description for @param
[ERROR] * @param authorizableSet
[ERROR] ^
[ERROR] /Users/konradwindszus/git/accesscontroltool/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/dumpservice/Dumpservice.java:113: warning: no description for @param
[ERROR] * @param session
[ERROR] ^
[ERROR] /Users/konradwindszus/git/accesscontroltool/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/dumpservice/Dumpservice.java:114: warning: no description for @param
[ERROR] * @param mapOrder
[ERROR] ^
[ERROR] /Users/konradwindszus/git/accesscontroltool/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/dumpservice/Dumpservice.java:115: warning: no description for @param
[ERROR] * @param aceOrder
[ERROR] ^
[ERROR] /Users/konradwindszus/git/accesscontroltool/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/dumpservice/Dumpservice.java:116: error: exception not thrown: java.io.IOException
[ERROR] * @throws IOException */
[ERROR] ^
[ERROR] /Users/konradwindszus/git/accesscontroltool/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/dumpservice/Dumpservice.java:116: warning: no description for @throws
[ERROR] * @throws IOException */
[ERROR] ^
[ERROR] /Users/konradwindszus/git/accesscontroltool/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/dumpservice/Dumpservice.java:118: warning: no @param for request
[ERROR] public void returnAceDumpAsFile(final SlingHttpServletRequest request,
[ERROR] ^
[ERROR] /Users/konradwindszus/git/accesscontroltool/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/dumpservice/Dumpservice.java:122: warning: no description for @param
[ERROR] /** @param response
[ERROR] ^
[ERROR] /Users/konradwindszus/git/accesscontroltool/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/dumpservice/Dumpservice.java:123: warning: no description for @param
[ERROR] * @param aceMap
[ERROR] ^
[ERROR] /Users/konradwindszus/git/accesscontroltool/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/dumpservice/Dumpservice.java:124: warning: no description for @param
[ERROR] * @param authorizableSet
[ERROR] ^
[ERROR] /Users/konradwindszus/git/accesscontroltool/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/dumpservice/Dumpservice.java:125: warning: no description for @param
[ERROR] * @param session
[ERROR] ^
[ERROR] /Users/konradwindszus/git/accesscontroltool/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/dumpservice/Dumpservice.java:126: warning: no description for @param
[ERROR] * @param mapOrder
[ERROR] ^
[ERROR] /Users/konradwindszus/git/accesscontroltool/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/dumpservice/Dumpservice.java:127: warning: no description for @param
[ERROR] * @param aceOrder
[ERROR] ^
[ERROR] /Users/konradwindszus/git/accesscontroltool/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/dumpservice/Dumpservice.java:128: warning: no description for @throws
[ERROR] * @throws IOException */
[ERROR] ^
[ERROR] /Users/konradwindszus/git/accesscontroltool/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/dumpservice/Dumpservice.java:136: warning: no description for @param
[ERROR] /** @param response
[ERROR] ^
[ERROR] /Users/konradwindszus/git/accesscontroltool/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/dumpservice/Dumpservice.java:137: warning: no description for @param
[ERROR] * @param aceMap
[ERROR] ^
[ERROR] /Users/konradwindszus/git/accesscontroltool/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/dumpservice/Dumpservice.java:138: warning: no description for @param
[ERROR] * @param mapOrder
[ERROR] ^
[ERROR] /Users/konradwindszus/git/accesscontroltool/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/dumpservice/Dumpservice.java:139: warning: no description for @throws
[ERROR] * @throws IOException */
[ERROR] ^
[ERROR] /Users/konradwindszus/git/accesscontroltool/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/dumpservice/Dumpservice.java:144: warning: no description for @param
[ERROR] /** @param response
[ERROR] ^
[ERROR] /Users/konradwindszus/git/accesscontroltool/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/dumpservice/Dumpservice.java:145: warning: no description for @param
[ERROR] * @param aceMap
[ERROR] ^
[ERROR] /Users/konradwindszus/git/accesscontroltool/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/dumpservice/Dumpservice.java:146: warning: no description for @param
[ERROR] * @param authorizableSet
[ERROR] ^
[ERROR] /Users/konradwindszus/git/accesscontroltool/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/dumpservice/Dumpservice.java:147: warning: no description for @param
[ERROR] * @param mapOrder
[ERROR] ^
[ERROR] /Users/konradwindszus/git/accesscontroltool/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/dumpservice/Dumpservice.java:148: warning: no description for @throws
[ERROR] * @throws IOException */
[ERROR] ^
[ERROR] /Users/konradwindszus/git/accesscontroltool/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/helper/AccessControlUtils.java:202: error: ')' missing in reference
[ERROR] * Please note, that calling {@link javax.jcr.Session#save()()} is required
[ERROR] ^
[ERROR] /Users/konradwindszus/git/accesscontroltool/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/helper/AccessControlUtils.java:229: error: ')' missing in reference
[ERROR] * call to {@link javax.jcr.Session#save()()} is required in order to
[ERROR] ^
[ERROR] /Users/konradwindszus/git/accesscontroltool/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/helper/AccessControlUtils.java:344: warning: no description for @throws
[ERROR] * @throws UnsupportedRepositoryOperationException
[ERROR] ^
[ERROR] /Users/konradwindszus/git/accesscontroltool/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/helper/AccessControlUtils.java:345: warning: no description for @throws
[ERROR] * @throws RepositoryException
[ERROR] ^
[ERROR] /Users/konradwindszus/git/accesscontroltool/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/helper/AceBean.java:256: warning: no description for @param
[ERROR] * @param session
[ERROR] ^
[ERROR] /Users/konradwindszus/git/accesscontroltool/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/helper/AceBean.java:257: warning: no description for @param
[ERROR] * @param principal
[ERROR] ^
[ERROR] /Users/konradwindszus/git/accesscontroltool/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/helper/AceBean.java:258: warning: no description for @param
[ERROR] * @param history
[ERROR] ^
[ERROR] /Users/konradwindszus/git/accesscontroltool/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/helper/AceBean.java:259: warning: no description for @throws
[ERROR] * @throws RepositoryException
[ERROR] ^
[ERROR] /Users/konradwindszus/git/accesscontroltool/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/helper/AcHelper.java:80: error: @param name not found
[ERROR] * @param authorizablesSet set which contains all group names contained in the configurations
[ERROR] ^
[ERROR] /Users/konradwindszus/git/accesscontroltool/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/helper/AcHelper.java:81: warning: no description for @param
[ERROR] * @param session
[ERROR] ^
[ERROR] /Users/konradwindszus/git/accesscontroltool/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/helper/AcHelper.java:82: error: @param name not found
[ERROR] * @param out
[ERROR] ^
[ERROR] /Users/konradwindszus/git/accesscontroltool/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/helper/AcHelper.java:82: warning: no description for @param
[ERROR] * @param out
[ERROR] ^
[ERROR] /Users/konradwindszus/git/accesscontroltool/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/helper/AcHelper.java:84: warning: no description for @throws
[ERROR] * @throws Exception */
[ERROR] ^
[ERROR] /Users/konradwindszus/git/accesscontroltool/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/helper/AcHelper.java:241: warning: no description for @param
[ERROR] * @param groupBasedAceMap
[ERROR] ^
[ERROR] /Users/konradwindszus/git/accesscontroltool/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/helper/AcHelper.java:243: warning: no description for @return
[ERROR] * @return */
[ERROR] ^
[ERROR] /Users/konradwindszus/git/accesscontroltool/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/helper/QueryHelper.java:42: warning: no description for @param
[ERROR] * @param session
[ERROR] ^
[ERROR] /Users/konradwindszus/git/accesscontroltool/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/helper/QueryHelper.java:101: warning: no description for @param
[ERROR] * @param session
[ERROR] ^
[ERROR] /Users/konradwindszus/git/accesscontroltool/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/helper/QueryHelper.java:102: warning: no description for @param
[ERROR] * @param xpathQuery
[ERROR] ^
[ERROR] /Users/konradwindszus/git/accesscontroltool/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/helper/QueryHelper.java:103: warning: no description for @return
[ERROR] * @return
[ERROR] ^
[ERROR] /Users/konradwindszus/git/accesscontroltool/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/helper/QueryHelper.java:104: warning: no description for @throws
[ERROR] * @throws InvalidQueryException
[ERROR] ^
[ERROR] /Users/konradwindszus/git/accesscontroltool/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/helper/QueryHelper.java:105: warning: no description for @throws
[ERROR] * @throws RepositoryException
[ERROR] ^
[ERROR] /Users/konradwindszus/git/accesscontroltool/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/helper/QueryHelper.java:115: warning: no description for @param
[ERROR] * @param session
[ERROR] ^
[ERROR] /Users/konradwindszus/git/accesscontroltool/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/helper/QueryHelper.java:118: warning: no description for @return
[ERROR] * @return
[ERROR] ^
[ERROR] /Users/konradwindszus/git/accesscontroltool/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/helper/QueryHelper.java:119: warning: no description for @throws
[ERROR] * @throws InvalidQueryException
[ERROR] ^
[ERROR] /Users/konradwindszus/git/accesscontroltool/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/helper/QueryHelper.java:120: warning: no description for @throws
[ERROR] * @throws RepositoryException
[ERROR] ^
[ERROR] /Users/konradwindszus/git/accesscontroltool/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/validators/ConfigurationsValidator.java:29: warning: no description for @throws
[ERROR] * @throws IllegalArgumentException
[ERROR] ^
[ERROR] /Users/konradwindszus/git/accesscontroltool/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/validators/ConfigurationsValidator.java:41: error: @param name not found
[ERROR] * @param yamlList
[ERROR] ^
[ERROR] /Users/konradwindszus/git/accesscontroltool/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/validators/ConfigurationsValidator.java:44: warning: no description for @throws
[ERROR] * @throws IllegalArgumentException
[ERROR] ^
[ERROR] /Users/konradwindszus/git/accesscontroltool/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/validators/ConfigurationsValidator.java:46: warning: no @param for configurations
[ERROR] public abstract void validateSectionContentExistence(String configPath,
[ERROR] ^
[ERROR] /Users/konradwindszus/git/accesscontroltool/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/validators/ConfigurationsValidator.java:53: error: @param name not found
[ERROR] * @param entry
[ERROR] ^
[ERROR] /Users/konradwindszus/git/accesscontroltool/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/validators/ConfigurationsValidator.java:55: warning: no description for @throws
[ERROR] * @throws IllegalArgumentException
[ERROR] ^
[ERROR] /Users/konradwindszus/git/accesscontroltool/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/validators/ConfigurationsValidator.java:57: warning: no @param for configuration
[ERROR] public abstract void validateMandatorySectionIdentifiersExistence(
[ERROR] ^
[ERROR] /Users/konradwindszus/git/accesscontroltool/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/validators/ConfigurationsValidator.java:57: warning: no @param for filePath
[ERROR] public abstract void validateMandatorySectionIdentifiersExistence(
[ERROR] ^
[ERROR] /Users/konradwindszus/git/accesscontroltool/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/validators/ConfigurationsValidator.java:64: warning: no description for @param
[ERROR] * @param sectionIdentifiers
[ERROR] ^
[ERROR] /Users/konradwindszus/git/accesscontroltool/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/validators/ConfigurationsValidator.java:65: warning: no description for @param
[ERROR] * @param filePath
[ERROR] ^
[ERROR] /Users/konradwindszus/git/accesscontroltool/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/validators/ConfigurationsValidator.java:66: warning: no description for @throws
[ERROR] * @throws IllegalArgumentException
[ERROR] ^
[ERROR] 
[ERROR] Command line was: /Library/Java/JavaVirtualMachines/jdk1.8.0_51.jdk/Contents/Home/bin/javadoc @options @packages

AC Tool doesn't install modify action correctly

The modify-cqAction doesn't get installed by the AC Tool. If e.g. a combination of read, modify and create is defined in a YAML configuration file, only read and create get installed in repository but not modify.

Allow to validate some best practices

In our projects, we use fragments that group the actual permissions on the content, the actual groups that user administrators for a tenant add users to (let's call them roles) are non-fragments and are just member of one or multiple fragments. This way the user admins never get to edit a role that already has members. It would be nice to validate that behaviour (if configured) automatically:

  • roles should never be used in isMemberOf and should never use "members"
  • roles and fragments for one project should reside in different directories (so only the actual roles can be changed, the fragments are only adjusted by the AC Tool!)

to distinguish what is a role and what a fragment, the algorithm could check

  • either for a name convention (e.g. name.startsWith("fragment-"))
  • or automatically derived assuming that all groups that are underneath a path that can be changed by user admins in the system are roles and all other groups are fragments

The first ist probably the better (easier to understand) approach

Allow to set ACEs for not yet existing nodes

In some cases ACEs need to be set, before the related content nodes do actually exist. Right now those ACEs are just skipped.

Possible solutions

  1. Principal-based ACLs (http://wiki.apache.org/jackrabbit/AccessControl#Principal-based_ACLs), but they don't seem to be supported with Oak (https://issues.apache.org/jira/browse/OAK-3627)
  2. Create the according content nodes if they don't exist yet (with a predefined template)
    • copying over nodes that exist in the JCR at a "template location" (e.g. creating the structure in /etc/actool/contenttemplate and copying nodes from there to the real structure by cutting out the path /etc/actool/contenttemplate)
    • allow to specify a default content structure in a root element of the yaml config, e.g. initial_content
    • allow to specify a default content structure per path defined in ace_config section (as property "initialContent" of the ACE Entry itself

UnsupportedRepositoryOperationException by calling purgeAllAuthorizablesFromConfigurations() or purgeAuthorizables(java.lang.String authorizableIds) over JMX console

By calling purgeAllAuthorizablesFromConfigurations() or purgeAuthorizables(java.lang.String authorizableIds) over JMX console there is an UnsupportedRepositoryOperationException and purging breaks.
"deletion of ACEs failed! reason: RepositoryException: javax.jcr.UnsupportedRepositoryOperationException: Session#save() is always required."

Output from error.log:

26.06.2015 15:10:55.460 *ERROR* [qtp432131260-335] biz.netcentric.cq.tools.actool.aceservice.impl.AceServiceImpl RepositoryException: 
javax.jcr.UnsupportedRepositoryOperationException: Session#save() is always required.
        at org.apache.jackrabbit.oak.security.user.UserManagerImpl.autoSave(UserManagerImpl.java:221)
        at org.apache.jackrabbit.oak.jcr.delegate.UserManagerDelegator$14.perform(UserManagerDelegator.java:237)
        at org.apache.jackrabbit.oak.jcr.delegate.UserManagerDelegator$14.perform(UserManagerDelegator.java:234)
        at org.apache.jackrabbit.oak.jcr.delegate.SessionDelegate.perform(SessionDelegate.java:294)
        at org.apache.jackrabbit.oak.jcr.delegate.UserManagerDelegator.autoSave(UserManagerDelegator.java:233)
        at biz.netcentric.cq.tools.actool.aceservice.impl.AceServiceImpl.purgeAuthorizables(AceServiceImpl.java:595)
        at biz.netcentric.cq.tools.actool.aceservice.impl.AceServiceImpl.purgeAuthorizables(AceServiceImpl.java:570)
        at biz.netcentric.cq.tools.actool.aceservicejmx.impl.AceServiceMBeanImpl.purgeAuthorizables(AceServiceMBeanImpl.java:152)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
        at java.lang.reflect.Method.invoke(Unknown Source)
        at sun.reflect.misc.Trampoline.invoke(Unknown Source)
        at sun.reflect.GeneratedMethodAccessor73.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
        at java.lang.reflect.Method.invoke(Unknown Source)
        at sun.reflect.misc.MethodUtil.invoke(Unknown Source)
        at com.sun.jmx.mbeanserver.StandardMBeanIntrospector.invokeM2(Unknown Source)
        at com.sun.jmx.mbeanserver.StandardMBeanIntrospector.invokeM2(Unknown Source)
        at com.sun.jmx.mbeanserver.MBeanIntrospector.invokeM(Unknown Source)
        at com.sun.jmx.mbeanserver.PerInterface.invoke(Unknown Source)
        at com.sun.jmx.mbeanserver.MBeanSupport.invoke(Unknown Source)
        at javax.management.StandardMBean.invoke(Unknown Source)
        at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.invoke(Unknown Source)
        at com.sun.jmx.mbeanserver.JmxMBeanServer.invoke(Unknown Source)
        at com.adobe.granite.jmx.internal.JMXConsolePlugin.invoke(JMXConsolePlugin.java:176)
        at com.adobe.granite.jmx.internal.JMXConsolePlugin.doPost(JMXConsolePlugin.java:134)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:641)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
        at org.apache.felix.webconsole.internal.servlet.OsgiManager.service(OsgiManager.java:526)
        at org.apache.felix.webconsole.internal.servlet.OsgiManager.service(OsgiManager.java:450)
        at org.apache.felix.http.base.internal.handler.ServletHandler.doHandle(ServletHandler.java:339)
        at org.apache.felix.http.base.internal.handler.ServletHandler.handle(ServletHandler.java:300)
        at org.apache.felix.http.base.internal.dispatch.ServletPipeline.handle(ServletPipeline.java:93)
        at org.apache.felix.http.base.internal.dispatch.InvocationFilterChain.doFilter(InvocationFilterChain.java:50)
        at org.apache.felix.http.base.internal.dispatch.HttpFilterChain.doFilter(HttpFilterChain.java:31)
        at org.apache.sling.i18n.impl.I18NFilter.doFilter(I18NFilter.java:128)
        at org.apache.felix.http.base.internal.handler.FilterHandler.doHandle(FilterHandler.java:108)
        at org.apache.felix.http.base.internal.handler.FilterHandler.handle(FilterHandler.java:80)
        at org.apache.felix.http.base.internal.dispatch.InvocationFilterChain.doFilter(InvocationFilterChain.java:46)
        at org.apache.felix.http.base.internal.dispatch.HttpFilterChain.doFilter(HttpFilterChain.java:31)
        at org.apache.felix.http.sslfilter.internal.SslFilter.doFilter(SslFilter.java:55)
        at org.apache.felix.http.base.internal.handler.FilterHandler.doHandle(FilterHandler.java:108)
        at org.apache.felix.http.base.internal.handler.FilterHandler.handle(FilterHandler.java:80)
        at org.apache.felix.http.base.internal.dispatch.InvocationFilterChain.doFilter(InvocationFilterChain.java:46)
        at org.apache.felix.http.base.internal.dispatch.HttpFilterChain.doFilter(HttpFilterChain.java:31)
        at org.apache.felix.http.sslfilter.internal.SslFilter.doFilter(SslFilter.java:89)
        at org.apache.felix.http.base.internal.handler.FilterHandler.doHandle(FilterHandler.java:108)
        at org.apache.felix.http.base.internal.handler.FilterHandler.handle(FilterHandler.java:80)
        at org.apache.felix.http.base.internal.dispatch.InvocationFilterChain.doFilter(InvocationFilterChain.java:46)
        at org.apache.felix.http.base.internal.dispatch.HttpFilterChain.doFilter(HttpFilterChain.java:31)
        at com.adobe.granite.license.impl.LicenseCheckFilter.doFilter(LicenseCheckFilter.java:300)
        at org.apache.felix.http.base.internal.handler.FilterHandler.doHandle(FilterHandler.java:108)
        at org.apache.felix.http.base.internal.handler.FilterHandler.handle(FilterHandler.java:80)
        at org.apache.felix.http.base.internal.dispatch.InvocationFilterChain.doFilter(InvocationFilterChain.java:46)
        at org.apache.felix.http.base.internal.dispatch.HttpFilterChain.doFilter(HttpFilterChain.java:31)
        at org.apache.sling.security.impl.ReferrerFilter.doFilter(ReferrerFilter.java:290)
        at org.apache.felix.http.base.internal.handler.FilterHandler.doHandle(FilterHandler.java:108)
        at org.apache.felix.http.base.internal.handler.FilterHandler.handle(FilterHandler.java:80)
        at org.apache.felix.http.base.internal.dispatch.InvocationFilterChain.doFilter(InvocationFilterChain.java:46)
        at org.apache.felix.http.base.internal.dispatch.HttpFilterChain.doFilter(HttpFilterChain.java:31)
        at org.apache.sling.featureflags.impl.FeatureManager.doFilter(FeatureManager.java:115)
        at org.apache.felix.http.base.internal.handler.FilterHandler.doHandle(FilterHandler.java:108)
        at org.apache.felix.http.base.internal.handler.FilterHandler.handle(FilterHandler.java:80)
        at org.apache.felix.http.base.internal.dispatch.InvocationFilterChain.doFilter(InvocationFilterChain.java:46)
        at org.apache.felix.http.base.internal.dispatch.HttpFilterChain.doFilter(HttpFilterChain.java:31)
        at org.apache.sling.engine.impl.log.RequestLoggerFilter.doFilter(RequestLoggerFilter.java:75)
        at org.apache.felix.http.base.internal.handler.FilterHandler.doHandle(FilterHandler.java:108)
        at org.apache.felix.http.base.internal.handler.FilterHandler.handle(FilterHandler.java:80)
        at org.apache.felix.http.base.internal.dispatch.InvocationFilterChain.doFilter(InvocationFilterChain.java:46)
        at org.apache.felix.http.base.internal.dispatch.HttpFilterChain.doFilter(HttpFilterChain.java:31)
        at org.apache.felix.http.base.internal.handler.FilterHandler.handle(FilterHandler.java:84)
        at org.apache.felix.http.base.internal.dispatch.InvocationFilterChain.doFilter(InvocationFilterChain.java:46)
        at org.apache.felix.http.base.internal.dispatch.HttpFilterChain.doFilter(HttpFilterChain.java:31)
        at org.apache.felix.http.base.internal.dispatch.FilterPipeline.dispatch(FilterPipeline.java:76)
        at org.apache.felix.http.base.internal.dispatch.Dispatcher.dispatch(Dispatcher.java:49)
        at org.apache.felix.http.base.internal.DispatcherServlet.service(DispatcherServlet.java:67)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
        at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:684)
        at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:501)
        at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:229)
        at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1086)
        at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:428)
        at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:193)
        at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1020)
        at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:135)
        at org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:255)
        at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:116)
        at org.eclipse.jetty.server.Server.handle(Server.java:370)
        at org.eclipse.jetty.server.AbstractHttpConnection.handleRequest(AbstractHttpConnection.java:494)
        at org.eclipse.jetty.server.AbstractHttpConnection.content(AbstractHttpConnection.java:982)
        at org.eclipse.jetty.server.AbstractHttpConnection$RequestHandler.content(AbstractHttpConnection.java:1043)
        at org.eclipse.jetty.http.HttpParser.parseNext(HttpParser.java:865)
        at org.eclipse.jetty.http.HttpParser.parseAvailable(HttpParser.java:240)
        at org.eclipse.jetty.server.AsyncHttpConnection.handle(AsyncHttpConnection.java:82)
        at org.eclipse.jetty.io.nio.SelectChannelEndPoint.handle(SelectChannelEndPoint.java:667)
        at org.eclipse.jetty.io.nio.SelectChannelEndPoint$1.run(SelectChannelEndPoint.java:52)
        at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:608)
        at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:543)
        at java.lang.Thread.run(Unknown Source)

No JCR trigger for updated ACE configurations

The AEM is designed in a way that OSGi configurations, OSGi Bundles and CRX Packages get installed/applied automatically when they are deployed/updated in the JCR repository. The Access Control Tool requires to execute the tool from the JMX console in order to apply the configuration files. This behavior is against the design of AEM and breaks the functionality to setup a whole AEM instance by just using the package installer. Please align the functionality of the Access Control Tool so that the execute task gets triggered automatically.

Import of index package causes SAXParseException

when importing the oak indexing package, the following error pop ups
15.03.2016 10:44:29.135 *INFO* [qtp1538817356-426] org.apache.jackrabbit.vault.packaging.impl.JcrPackageImpl Creating snapshot for Netcentric/.snapshot:accesscontroltool-oakindex-package:1.6.2. 15.03.2016 10:44:29.216 *WARN* [qtp1538817356-426] org.apache.jackrabbit.oak.jcr.session.ItemImpl Item#refresh invokes Session#refresh! 15.03.2016 10:44:29.222 *INFO* [qtp1538817356-426] org.apache.jackrabbit.vault.packaging.impl.JcrPackageImpl Creating snapshot for Netcentric/.snapshot:accesscontroltool-oakindex-package:1.6.2 completed. 15.03.2016 10:44:29.222 *INFO* [qtp1538817356-426] org.apache.jackrabbit.vault.packaging.impl.ZipVaultPackage Extracting Netcentric:accesscontroltool-oakindex-package:1.6.2 15.03.2016 10:44:29.290 *ERROR* [qtp1538817356-426] org.apache.jackrabbit.vault.fs.impl.io.GenericArtifactHandler Error while parsing /jcr_root/_oak_index/repACL.xml: {} org.xml.sax.SAXParseException: The markup in the document following the root element must be well-formed. at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.createSAXParseException(ErrorHandlerWrapper.java:203) at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.fatalError(ErrorHandlerWrapper.java:177) at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(XMLErrorReporter.java:441) at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(XMLErrorReporter.java:368) at com.sun.org.apache.xerces.internal.impl.XMLScanner.reportFatalError(XMLScanner.java:1437) at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$TrailingMiscDriver.next(XMLDocumentScannerImpl.java:1394) at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(XMLDocumentScannerImpl.java:606) at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.next(XMLNSDocumentScannerImpl.java:117) at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragmentScannerImpl.java:510) at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:848) at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:777) at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:141) at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1213) at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(SAXParserImpl.java:649) at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl.parse(SAXParserImpl.java:333) at org.apache.jackrabbit.vault.fs.impl.io.GenericArtifactHandler.accept(GenericArtifactHandler.java:99) at org.apache.jackrabbit.vault.fs.io.Importer.commit(Importer.java:896) at org.apache.jackrabbit.vault.fs.io.Importer.commit(Importer.java:801) at org.apache.jackrabbit.vault.fs.io.Importer.commit(Importer.java:841) at org.apache.jackrabbit.vault.fs.io.Importer.commit(Importer.java:841) at org.apache.jackrabbit.vault.fs.io.Importer.run(Importer.java:415) at org.apache.jackrabbit.vault.packaging.impl.ZipVaultPackage.extract(ZipVaultPackage.java:234) at org.apache.jackrabbit.vault.packaging.impl.JcrPackageImpl.extract(JcrPackageImpl.java:423) at org.apache.jackrabbit.vault.packaging.impl.JcrPackageImpl.install(JcrPackageImpl.java:392) at com.day.jcr.vault.packaging.impl.JrVltJcrPackageAdapter.install(JrVltJcrPackageAdapter.java:107) at com.day.crx.packaging.impl.J2EEPackageManager.consoleInstall(J2EEPackageManager.java:336) at com.day.crx.packaging.impl.J2EEPackageManager.doPost(J2EEPackageManager.java:175) at com.day.crx.packaging.impl.PackageManagerServlet.doPost(PackageManagerServlet.java:148) at javax.servlet.http.HttpServlet.service(HttpServlet.java:644) at javax.servlet.http.HttpServlet.service(HttpServlet.java:725) at org.apache.felix.http.base.internal.handler.ServletHandler.doHandle(ServletHandler.java:336) at org.apache.felix.http.base.internal.handler.ServletHandler.handle(ServletHandler.java:297) at org.apache.felix.http.base.internal.dispatch.ServletPipeline.handle(ServletPipeline.java:93) at org.apache.felix.http.base.internal.dispatch.InvocationFilterChain.doFilter(InvocationFilterChain.java:50) at org.apache.felix.http.base.internal.dispatch.HttpFilterChain.doFilter(HttpFilterChain.java:31) at org.apache.sling.i18n.impl.I18NFilter.doFilter(I18NFilter.java:129) at org.apache.felix.http.base.internal.handler.FilterHandler.doHandle(FilterHandler.java:108) at org.apache.felix.http.base.internal.handler.FilterHandler.handle(FilterHandler.java:80) at org.apache.felix.http.base.internal.dispatch.InvocationFilterChain.doFilter(InvocationFilterChain.java:46) at org.apache.felix.http.base.internal.dispatch.HttpFilterChain.doFilter(HttpFilterChain.java:31) at com.adobe.granite.license.impl.LicenseCheckFilter.doFilter(LicenseCheckFilter.java:308) at org.apache.felix.http.base.internal.handler.FilterHandler.doHandle(FilterHandler.java:108) at org.apache.felix.http.base.internal.handler.FilterHandler.handle(FilterHandler.java:80) at org.apache.felix.http.base.internal.dispatch.InvocationFilterChain.doFilter(InvocationFilterChain.java:46) at org.apache.felix.http.base.internal.dispatch.HttpFilterChain.doFilter(HttpFilterChain.java:31) at org.apache.sling.security.impl.ReferrerFilter.doFilter(ReferrerFilter.java:290) at org.apache.felix.http.base.internal.handler.FilterHandler.doHandle(FilterHandler.java:108) at org.apache.felix.http.base.internal.handler.FilterHandler.handle(FilterHandler.java:80) at org.apache.felix.http.base.internal.dispatch.InvocationFilterChain.doFilter(InvocationFilterChain.java:46) at org.apache.felix.http.base.internal.dispatch.HttpFilterChain.doFilter(HttpFilterChain.java:31) at org.apache.felix.http.sslfilter.internal.SslFilter.doFilter(SslFilter.java:89) at org.apache.felix.http.base.internal.handler.FilterHandler.doHandle(FilterHandler.java:108) at org.apache.felix.http.base.internal.handler.FilterHandler.handle(FilterHandler.java:80) at org.apache.felix.http.base.internal.dispatch.InvocationFilterChain.doFilter(InvocationFilterChain.java:46) at org.apache.felix.http.base.internal.dispatch.HttpFilterChain.doFilter(HttpFilterChain.java:31) at org.apache.sling.featureflags.impl.FeatureManager.doFilter(FeatureManager.java:115) at org.apache.felix.http.base.internal.handler.FilterHandler.doHandle(FilterHandler.java:108) at org.apache.felix.http.base.internal.handler.FilterHandler.handle(FilterHandler.java:80) at org.apache.felix.http.base.internal.dispatch.InvocationFilterChain.doFilter(InvocationFilterChain.java:46) at org.apache.felix.http.base.internal.dispatch.HttpFilterChain.doFilter(HttpFilterChain.java:31) at org.apache.sling.engine.impl.log.RequestLoggerFilter.doFilter(RequestLoggerFilter.java:75) at org.apache.felix.http.base.internal.handler.FilterHandler.doHandle(FilterHandler.java:108) at org.apache.felix.http.base.internal.handler.FilterHandler.handle(FilterHandler.java:80) at org.apache.felix.http.base.internal.dispatch.InvocationFilterChain.doFilter(InvocationFilterChain.java:46) at org.apache.felix.http.base.internal.dispatch.HttpFilterChain.doFilter(HttpFilterChain.java:31) at org.apache.felix.http.base.internal.dispatch.FilterPipeline.dispatch(FilterPipeline.java:76) at org.apache.felix.http.base.internal.dispatch.Dispatcher.dispatch(Dispatcher.java:49) at org.apache.felix.http.base.internal.DispatcherServlet.service(DispatcherServlet.java:67) at javax.servlet.http.HttpServlet.service(HttpServlet.java:725) at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:808) at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:587) at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:221) at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1127) at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:515) at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:185) at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1061) at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141) at org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:215) at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:97) at org.eclipse.jetty.server.Server.handle(Server.java:497) at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:310) at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:257) at org.eclipse.jetty.io.AbstractConnection$2.run(AbstractConnection.java:540) at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:635) at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:555) at java.lang.Thread.run(Thread.java:745) 15.03.2016 10:44:29.292 *ERROR* [qtp1538817356-426] org.apache.jackrabbit.vault.fs.io.Importer E /oak:index/repACL (org.xml.sax.SAXParseException; systemId: file:///jcr_root/_oak_index/repACL.xml; lineNumber: 7; columnNumber: 3; The markup in the document following the root element must be well-formed.)

However, the package seems to be installed and indexing seems also to be working.

Reason is invalid XML in accesscontroltool-oakindex-package/src/main/jcr_root/_oak_index/repACL.xml

The jcr:root opening tag closes implicitly and there's also a closing tag.

System user creation no longer works

Since 1.8.0 the creation of system users no longer works.
I get an IllegalStateException that Boolean is an unexpected class when parsing the "true".

Example:

  • user_config:
    • example-tags:
      • name:
        isMemberOf: example-system-tags
        path: m
        isSystemUser: true

Space in JMX id "ac installation" is an issue on some systems

Some servers are configured to do not allow spaces in URLs.
As AC Tool JMX id contains a space those servers will return a 404 error loading AC Tool JMX console and URLs used to trigger its functionalities.

Either remove the space or replace with a URL compliant separator.

Warning if path is not below /home/groups

- group_config:

   - ac-testgroup-35: 
      - path: /var/ac-test

- ace_config:

   - ac-testgroup-35:
       - path: /content/geometrixx/en/ac-testing/area-01
         permission: allow
         privileges: jcr:all

leeds to
Installation triggered: Wed Apr 23 13:35:40 CEST 2014

2014-04-23 13:35:40.204: start merging configuration data from: /var/ac-tool/project-ac-tool-test-1/confix.txt
2014-04-23 13:35:40.205: start installation of merged configurations
2014-04-23 13:35:40.326: finished installation of groups configuration without errors!
2014-04-23 13:35:40.351: finished (transient) installation of access control configuration without errors!
2014-04-23 13:35:40.367: persisted changes of ACLs
2014-04-23 13:35:40.37: saved history in node: /var/statistics/achistory/history_1398252940368
2014-04-23 13:35:40.386: saved installed configuration files under : /var/statistics/achistory/history_1398252940368/installedConfigs

Execution time: 164 ms

Success: true

but the resulting path is /home/groups/var/ac-test
even worse if group is allready existing:

Installation triggered: Wed Apr 23 13:40:59 CEST 2014

2014-04-23 13:40:59.591: start merging configuration data from: /var/ac-tool/project-ac-tool-test-1/confix.txt
2014-04-23 13:40:59.593: start installation of merged configurations
2014-04-23 13:40:59.725: found change of intermediate path:
existing group: ac-testgroup-35 has intermediate path: /home/groups/var/ac-test
group from config: ac-testgroup-35 has intermediate path: /var/ac-test
recreated group with new intermediate path!
2014-04-23 13:40:59.735: finished installation of groups configuration without errors!
2014-04-23 13:40:59.756: finished (transient) installation of access control configuration without errors!
2014-04-23 13:40:59.772: persisted changes of ACLs
2014-04-23 13:40:59.775: saved history in node: /var/statistics/achistory/history_1398253259773
2014-04-23 13:40:59.792: saved installed configuration files under : /var/statistics/achistory/history_1398253259773/installedConfigs

Execution time: 182 ms

Success: true

Expected behaviour: An explicit Warnig should be rendered

ACTool fails with IllegalStateException "No new entries have been set for AccessControlList at ..." in case an action was redundant

The issue was caused by the fix for #33 because that one does not correctly consider that installing an action does no always lead to new entries.
One example would be:
First the following AceBean would be installed

AceBean [jcrPath=/content/nc_test_hq-approved/en
, permission=deny
, repGlob=null
, actionsString=read
, privilegesString=
, principal=fragment-nc_test_hq-approved-en-passengercars-rmc
, actions=[read]]

then this AceBean would be installed

AceBean [jcrPath=/content/nc_test_hq-approved/en
, permission=allow
, repGlob=
, actionsString=read
, privilegesString=
, principal=fragment-nc_test_hq-approved-en-passengercars-rmc
, actions=[read]]

Since the former is redundant, its ACE is removed when installing the latter. Therefore the number of ACEs is the same before and after the second AceBean has been installed.

Extend runmode mechanism to allow "or" combination of runmodes for certain files

To avoid code duplication (and because it is not always possible to change runmodes for a whole set of existing staging infrastructure) it would be good to allow the following semantic:

config.netcentric.author <- config becomes active only if both runmodes are active (same as for OSGi configs)
config.dev,test <- new 'or' combination, configs becomes active on both dev and test, but not on int/prod

Also a combination should be possible:
config.author.dev,author.test <- config becomes active for authors of dev and test environments

Runmodes are not currently respected by when triggering via JMX

Currently there are two mechanism with inconsistent requirements regarding their content structure:

InstallHook:

  • Any yaml-file within the CRX package containing the hook is respected (extension yaml at any level)
  • the parent of a yaml file (folder name) respects runmodes in the same way as OSGi configuration do

JMX:

  • A configured base path is used
  • Underneath there needs to be a folder on first level
  • in the content of the folder (second level), the newest file (and only the newest) regardless of its extension is used

Proposed solution - use InstallHook approach also for JMX in order to have consistent behaviour between the two mechanisms to trigger installations of the ACE.

Only one path to the ACE configurations can be configured

The current design of the Access Control Tool allows to configure only one JCR path where the ACE configuration files are held.

image

In order to use AEM for multiple tenants it is necessary to define an independent path to the ACE configuration of each tenant. Since it is not possible to configure all possible pathes to all tenants in one OSGi configuration, it should be possible to ship the OSGi configuration per tenant. One example for this principle is the configuration of the Apache Sling Logging Logger Configuration

image

InstallHook fails if service is reconfigured at the same time

The InstallHook is always available as long as the AC Tool Bundle is available, unfortunately the referenced AceServiceImpl is not, because during the time it is reconfigured, it is stopped and afterwards restarted. That may lead to exceptions like

"Could not instanciate AceService. Make sure the ACTool is installed and check the log for errors"

Allow to migrate group names without loosing already assigned members

Introduce a property "migrateFrom" that allows to specify a group name to

  • take over already assigned users
  • delete the group

If the group given in migrateFrom does not exist, it should just log a message (to make sure the same yaml configuration can be run multiple times, but obviously the "migrateFrom" should be taken away at some point again).

Unable to update ace_config for existing group

I've two YAML config files, first file contains the group_config and ace_config of a 'GroupA'.

In second YAML file, I declared only 'ace_config' of 'GroupA', but when it's trying to execute both file, it's setting the permission only from second YAML file, but the first file 'ace_config' is skipped.

This is not the same case for user config, for users the 'ace_config' are working with two separate files.

Please let me know if you need more details, appreciate your help in looking at this issue. Thanks!

Variables in for-loops don't support '-' - character

If a variable name containing a '-' character is used in a for-loop, the Ac-tool doesen't roll out the loop but interprets the whole for-loop expression as group name, which leads to a validation exception.

e.g.

  • for var IN [ name-prefix ]
    ...

doesn't get rolled out, but interpreted as group name: "- for var IN [ name-prefix ]"

Since in general group names in yaml files can contain '-' chars, this should be also the case for variables in for loop, as they become part of group names in the end.

Set target to Java 6

Currently there might be compilation errors because the @Override annotation is used on implemented interface methods (which is only allowed since Java 6). The default for Maven is still Java 5, therefore the target and source should be made explicit in the maven-compiler-plugin.

Absolute path in group config leads to error messages

A path value "/home/groups/f" will create the group in /home/groups/f but the second run prints an error message:

2015-01-21 08:34:16.37: found change of intermediate path:
existing group: content-bmw-common-read has intermediate path: /home/groups/f
group from config: content-bmw-common-read has intermediate path: /home/groups/home/groups/f
recreated group with new intermediate path!

But the group stays in /home/groups/f. So just the error message seems to be wrong.

InstallHook fails if DynamicClassLoaderManager is being restarted due to bundle updates

Especially for packages which nest other packages a lot of bundles might be updated while the package installation is still running.
The CQ Package Manager is relying on the DynamicClassLoader manager to load the hook class. That class loader is unfortunately very often becoming invalid and therefore no longer being able to load any classes (sometimes even during a package installation). That happens if a bundle is updated which provided a package being previously requested through the DynamicClassLoader (compare with https://github.com/apache/sling/blob/trunk/bundles/commons/classloader/src/main/java/org/apache/sling/commons/classloader/impl/Activator.java#L123).

As soon as that is the case you see an error like

11.06.2015 10:42:00.078 *INFO* [qtp456739988-22676] com.day.jcr.vault.packaging.impl.JrVltInstallHookProcessor Loading Hook actool: Main-Class = biz.netcentric.cq.tools.actool.installhook.AcToolInstallHook
11.06.2015 10:42:00.079 *ERROR* [qtp456739988-22676] org.apache.sling.commons.classloader.impl.ClassLoaderFacade Dynamic class loader has already been deactivated.
org.apache.sling.commons.classloader.impl.ClassLoaderFacade$StackTraceProbe: Dynamic class loader has already been deactivated.
    at org.apache.sling.commons.classloader.impl.ClassLoaderFacade.checkManagerActive(ClassLoaderFacade.java:69)
    at org.apache.sling.commons.classloader.impl.ClassLoaderFacade.loadClass(ClassLoaderFacade.java:133)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
    at com.day.jcr.vault.packaging.impl.JrVltInstallHookProcessor$Hook.loadMainClass(JrVltInstallHookProcessor.java:240)
    at com.day.jcr.vault.packaging.impl.JrVltInstallHookProcessor$Hook.init(JrVltInstallHookProcessor.java:231)
    at com.day.jcr.vault.packaging.impl.JrVltInstallHookProcessor$Hook.access$300(JrVltInstallHookProcessor.java:172)
    at com.day.jcr.vault.packaging.impl.JrVltInstallHookProcessor.initHook(JrVltInstallHookProcessor.java:128)
    at com.day.jcr.vault.packaging.impl.JrVltInstallHookProcessor.registerHooks(JrVltInstallHookProcessor.java:97)
    at org.apache.jackrabbit.vault.packaging.impl.ZipVaultPackage.prepareExtract(ZipVaultPackage.java:183)
    at org.apache.jackrabbit.vault.packaging.impl.JcrPackageImpl.extract(JcrPackageImpl.java:393)
    at org.apache.jackrabbit.vault.packaging.impl.JcrPackageImpl.extract(JcrPackageImpl.java:461)
    at org.apache.jackrabbit.vault.packaging.impl.JcrPackageImpl.install(JcrPackageImpl.java:370)
    at com.day.jcr.vault.packaging.impl.JrVltJcrPackageAdapter.install(JrVltJcrPackageAdapter.java:107)
    at com.day.crx.packmgr.impl.servlets.ServiceServlet.doInstall(ServiceServlet.java:324)
    at com.day.crx.packmgr.impl.servlets.ServiceServlet.upload(ServiceServlet.java:394)
    at com.day.crx.packmgr.impl.servlets.ServiceServlet.doService(ServiceServlet.java:151)
    at com.day.crx.packmgr.impl.AbstractServlet.service(AbstractServlet.java:52)
    at com.day.crx.packmgr.impl.MainServlet.doService(MainServlet.java:144)
    at com.day.crx.packmgr.impl.MainServlet.service(MainServlet.java:121)
    at org.apache.felix.http.base.internal.handler.ServletHandler.doHandle(ServletHandler.java:339)
    at org.apache.felix.http.base.internal.handler.ServletHandler.handle(ServletHandler.java:300)
    at org.apache.felix.http.base.internal.dispatch.ServletPipeline.handle(ServletPipeline.java:93)
    at org.apache.felix.http.base.internal.dispatch.InvocationFilterChain.doFilter(InvocationFilterChain.java:50)
    at org.apache.felix.http.base.internal.dispatch.HttpFilterChain.doFilter(HttpFilterChain.java:31)
    at org.apache.sling.i18n.impl.I18NFilter.doFilter(I18NFilter.java:129)
    at org.apache.felix.http.base.internal.handler.FilterHandler.doHandle(FilterHandler.java:108)
    at org.apache.felix.http.base.internal.handler.FilterHandler.handle(FilterHandler.java:80)
    at org.apache.felix.http.base.internal.dispatch.InvocationFilterChain.doFilter(InvocationFilterChain.java:46)
    at org.apache.felix.http.base.internal.dispatch.HttpFilterChain.doFilter(HttpFilterChain.java:31)
    at org.apache.sling.security.impl.ReferrerFilter.doFilter(ReferrerFilter.java:290)
    at org.apache.felix.http.base.internal.handler.FilterHandler.doHandle(FilterHandler.java:108)
    at org.apache.felix.http.base.internal.handler.FilterHandler.handle(FilterHandler.java:80)
    at org.apache.felix.http.base.internal.dispatch.InvocationFilterChain.doFilter(InvocationFilterChain.java:46)
    at org.apache.felix.http.base.internal.dispatch.HttpFilterChain.doFilter(HttpFilterChain.java:31)
    at com.adobe.granite.license.impl.LicenseCheckFilter.doFilter(LicenseCheckFilter.java:300)
    at org.apache.felix.http.base.internal.handler.FilterHandler.doHandle(FilterHandler.java:108)
    at org.apache.felix.http.base.internal.handler.FilterHandler.handle(FilterHandler.java:80)
    at org.apache.felix.http.base.internal.dispatch.InvocationFilterChain.doFilter(InvocationFilterChain.java:46)
    at org.apache.felix.http.base.internal.dispatch.HttpFilterChain.doFilter(HttpFilterChain.java:31)
    at org.apache.felix.http.sslfilter.internal.SslFilter.doFilter(SslFilter.java:55)
    at org.apache.felix.http.base.internal.handler.FilterHandler.doHandle(FilterHandler.java:108)
    at org.apache.felix.http.base.internal.handler.FilterHandler.handle(FilterHandler.java:80)
    at org.apache.felix.http.base.internal.dispatch.InvocationFilterChain.doFilter(InvocationFilterChain.java:46)
    at org.apache.felix.http.base.internal.dispatch.HttpFilterChain.doFilter(HttpFilterChain.java:31)
    at com.daimler.embxp.wholesale.base.core.servletfilter.RenderedByAemResponseHeaderAdderFilter.doFilter(RenderedByAemResponseHeaderAdderFilter.java:46)
    at org.apache.felix.http.base.internal.handler.FilterHandler.doHandle(FilterHandler.java:108)
    at org.apache.felix.http.base.internal.handler.FilterHandler.handle(FilterHandler.java:80)
    at org.apache.felix.http.base.internal.dispatch.InvocationFilterChain.doFilter(InvocationFilterChain.java:46)
    at org.apache.felix.http.base.internal.dispatch.HttpFilterChain.doFilter(HttpFilterChain.java:31)
    at org.apache.felix.http.sslfilter.internal.SslFilter.doFilter(SslFilter.java:89)
    at org.apache.felix.http.base.internal.handler.FilterHandler.doHandle(FilterHandler.java:108)
    at org.apache.felix.http.base.internal.handler.FilterHandler.handle(FilterHandler.java:80)
    at org.apache.felix.http.base.internal.dispatch.InvocationFilterChain.doFilter(InvocationFilterChain.java:46)
    at org.apache.felix.http.base.internal.dispatch.HttpFilterChain.doFilter(HttpFilterChain.java:31)
    at org.apache.sling.featureflags.impl.FeatureManager.doFilter(FeatureManager.java:115)
    at org.apache.felix.http.base.internal.handler.FilterHandler.doHandle(FilterHandler.java:108)
    at org.apache.felix.http.base.internal.handler.FilterHandler.handle(FilterHandler.java:80)
    at org.apache.felix.http.base.internal.dispatch.InvocationFilterChain.doFilter(InvocationFilterChain.java:46)
    at org.apache.felix.http.base.internal.dispatch.HttpFilterChain.doFilter(HttpFilterChain.java:31)
    at org.apache.sling.engine.impl.log.RequestLoggerFilter.doFilter(RequestLoggerFilter.java:75)
    at org.apache.felix.http.base.internal.handler.FilterHandler.doHandle(FilterHandler.java:108)
    at org.apache.felix.http.base.internal.handler.FilterHandler.handle(FilterHandler.java:80)
    at org.apache.felix.http.base.internal.dispatch.InvocationFilterChain.doFilter(InvocationFilterChain.java:46)
    at org.apache.felix.http.base.internal.dispatch.HttpFilterChain.doFilter(HttpFilterChain.java:31)
    at org.apache.felix.http.base.internal.dispatch.FilterPipeline.dispatch(FilterPipeline.java:76)
    at org.apache.felix.http.base.internal.dispatch.Dispatcher.dispatch(Dispatcher.java:49)
    at org.apache.felix.http.base.internal.DispatcherServlet.service(DispatcherServlet.java:67)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
    at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:684)
    at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:501)
    at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:229)
    at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1086)
    at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:428)
    at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:193)
    at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1020)
    at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:135)
    at org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:255)
    at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:116)
    at org.eclipse.jetty.server.Server.handle(Server.java:370)
    at org.eclipse.jetty.server.AbstractHttpConnection.handleRequest(AbstractHttpConnection.java:494)
    at org.eclipse.jetty.server.AbstractHttpConnection.headerComplete(AbstractHttpConnection.java:971)
    at org.eclipse.jetty.server.AbstractHttpConnection$RequestHandler.headerComplete(AbstractHttpConnection.java:1033)
    at org.eclipse.jetty.http.HttpParser.parseNext(HttpParser.java:651)
    at org.eclipse.jetty.http.HttpParser.parseAvailable(HttpParser.java:235)
    at org.eclipse.jetty.server.AsyncHttpConnection.handle(AsyncHttpConnection.java:82)
    at org.eclipse.jetty.io.nio.SelectChannelEndPoint.handle(SelectChannelEndPoint.java:667)
    at org.eclipse.jetty.io.nio.SelectChannelEndPoint$1.run(SelectChannelEndPoint.java:52)
    at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:608)
    at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:543)
    at java.lang.Thread.run(Thread.java:745)
11.06.2015 10:42:00.079 *ERROR* [qtp456739988-22676] com.day.jcr.vault.packaging.impl.JrVltInstallHookProcessor Error while initializing hook: com.day.jcr.vault.packaging.PackageException: hook's main class biz.netcentric.cq.tools.actool.installh
ook.AcToolInstallHook not found: actool

Allow to set profile and preferences data for authorizables

Setting and updating user properties is quite limited ATM (#69 addresses some of the issues). A generic approach to set profile/preferences data would be nice, especially for test users (we should use something like profileContent and preferencesContent rather then direct properties on the authorizable config node because with AEM 6, the user profile has many more properties as in CQ 5.x).

ACTool does not preserve all restrictions

With Oak 1.0 new restrictions are supported, see also http://jackrabbit.apache.org/oak/docs/security/accesscontrol/restriction.html. Those new restrictions are not preserved because currently the logic for writing AccessControlEntrys on a specific node is as follows (https://github.com/Netcentric/accesscontroltool#merging-of-aces)

  1. extract existing entries (and wrap into a bean)
  2. merge all beans (existing ones with yaml ones)
  3. remove all existing entries
  4. serialize all beans
    Both 1. and 4. currently don't support extended restrictions being introduced by Oak, which may lead to corruption of existing entries.

Instead we should do the following

  1. go through all beans coming from the YAML model and delete the existing entries for all authorizables defined in the YAML model
  2. serialize all YAML beans (at the end of the existing list)

Replicating packages which require the ACTool hook are not installed

Although on the author instance you see no error, on the publish instance, the following error is logged when replicating a package which references the ACTool hook

[... POST /bin/receive HTTP/1.1] com.day.jcr.vault.packaging.impl.JrVltInstallHookProcessor Loading Hook actool: Main-Class = biz.netcentric.cq.tools.actool.installhook.AcToolInstallHook
[... POST /bin/receive HTTP/1.1] com.day.jcr.vault.packaging.impl.JrVltInstallHookProcessor Error while initializing hook: com.day.jcr.vault.packaging.PackageException: hook's main class biz.netcentric.cq.tools.actool.installhook.AcToolInstallHook not found: actool

This is due to wrong classloader being used to load the hook class (in contrast to what the package manager does). In fact it is the thread context class loader (which is never working in the OSGi context).

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.