diff --git a/accesscontroltool-apps-package/src/main/META-INF/vault/filter.xml b/accesscontroltool-apps-package/src/main/META-INF/vault/filter.xml
index 835cae651..f17c697fb 100644
--- a/accesscontroltool-apps-package/src/main/META-INF/vault/filter.xml
+++ b/accesscontroltool-apps-package/src/main/META-INF/vault/filter.xml
@@ -1,13 +1,26 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/accesscontroltool-apps-package/src/main/jcr_root/apps/cq/.content.xml b/accesscontroltool-apps-package/src/main/jcr_root/apps/cq/.content.xml
index 160edce61..4decfe490 100644
--- a/accesscontroltool-apps-package/src/main/jcr_root/apps/cq/.content.xml
+++ b/accesscontroltool-apps-package/src/main/jcr_root/apps/cq/.content.xml
@@ -1,3 +1,16 @@
+
+
diff --git a/accesscontroltool-apps-package/src/main/jcr_root/apps/cq/core/content/.content.xml b/accesscontroltool-apps-package/src/main/jcr_root/apps/cq/core/content/.content.xml
index 160edce61..4decfe490 100644
--- a/accesscontroltool-apps-package/src/main/jcr_root/apps/cq/core/content/.content.xml
+++ b/accesscontroltool-apps-package/src/main/jcr_root/apps/cq/core/content/.content.xml
@@ -1,3 +1,16 @@
+
+
diff --git a/accesscontroltool-apps-package/src/main/jcr_root/apps/cq/core/content/nav/.content.xml b/accesscontroltool-apps-package/src/main/jcr_root/apps/cq/core/content/nav/.content.xml
index 160edce61..4decfe490 100644
--- a/accesscontroltool-apps-package/src/main/jcr_root/apps/cq/core/content/nav/.content.xml
+++ b/accesscontroltool-apps-package/src/main/jcr_root/apps/cq/core/content/nav/.content.xml
@@ -1,3 +1,16 @@
+
+
diff --git a/accesscontroltool-apps-package/src/main/jcr_root/apps/cq/core/content/nav/tools/.content.xml b/accesscontroltool-apps-package/src/main/jcr_root/apps/cq/core/content/nav/tools/.content.xml
index 160edce61..4decfe490 100644
--- a/accesscontroltool-apps-package/src/main/jcr_root/apps/cq/core/content/nav/tools/.content.xml
+++ b/accesscontroltool-apps-package/src/main/jcr_root/apps/cq/core/content/nav/tools/.content.xml
@@ -1,3 +1,16 @@
+
+
diff --git a/accesscontroltool-apps-package/src/main/jcr_root/apps/cq/core/content/nav/tools/security/.content.xml b/accesscontroltool-apps-package/src/main/jcr_root/apps/cq/core/content/nav/tools/security/.content.xml
index 22f3a0d46..3f902c0c9 100644
--- a/accesscontroltool-apps-package/src/main/jcr_root/apps/cq/core/content/nav/tools/security/.content.xml
+++ b/accesscontroltool-apps-package/src/main/jcr_root/apps/cq/core/content/nav/tools/security/.content.xml
@@ -1,4 +1,17 @@
+
+
diff --git a/accesscontroltool-apps-package/src/main/jcr_root/apps/cq/core/content/nav/tools/security/actool/.content.xml b/accesscontroltool-apps-package/src/main/jcr_root/apps/cq/core/content/nav/tools/security/actool/.content.xml
index 9e9bc1a1d..b927c352c 100644
--- a/accesscontroltool-apps-package/src/main/jcr_root/apps/cq/core/content/nav/tools/security/actool/.content.xml
+++ b/accesscontroltool-apps-package/src/main/jcr_root/apps/cq/core/content/nav/tools/security/actool/.content.xml
@@ -1,4 +1,17 @@
+
+
+
+
+
+
diff --git a/accesscontroltool-apps-package/src/main/jcr_root/apps/netcentric/actool/content/.content.xml b/accesscontroltool-apps-package/src/main/jcr_root/apps/netcentric/actool/content/.content.xml
index 1727fb27c..8aefd45ed 100644
--- a/accesscontroltool-apps-package/src/main/jcr_root/apps/netcentric/actool/content/.content.xml
+++ b/accesscontroltool-apps-package/src/main/jcr_root/apps/netcentric/actool/content/.content.xml
@@ -1,4 +1,17 @@
+
+
diff --git a/accesscontroltool-apps-package/src/main/jcr_root/apps/netcentric/actool/content/overview/.content.xml b/accesscontroltool-apps-package/src/main/jcr_root/apps/netcentric/actool/content/overview/.content.xml
index ba44ac573..5f52d1c13 100644
--- a/accesscontroltool-apps-package/src/main/jcr_root/apps/netcentric/actool/content/overview/.content.xml
+++ b/accesscontroltool-apps-package/src/main/jcr_root/apps/netcentric/actool/content/overview/.content.xml
@@ -1,4 +1,17 @@
+
+
+
+
> pathBasedAceMapFromConfig, final AcConfiguration acConfiguration, final Session session,
final InstallationLogger installationLog, Set authorizablesToRemoveAcesFor) throws Exception;
-}
\ No newline at end of file
+}
diff --git a/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/aceinstaller/AceBeanInstallerClassic.java b/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/aceinstaller/AceBeanInstallerClassic.java
index 1c7a8d9f8..e52f5b954 100644
--- a/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/aceinstaller/AceBeanInstallerClassic.java
+++ b/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/aceinstaller/AceBeanInstallerClassic.java
@@ -1,248 +1,253 @@
-/*
- * (C) Copyright 2016 Netcentric AG.
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- */
-package biz.netcentric.cq.tools.actool.aceinstaller;
-
-import java.security.Principal;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import javax.jcr.RepositoryException;
-import javax.jcr.Session;
-import javax.jcr.UnsupportedRepositoryOperationException;
-import javax.jcr.security.AccessControlEntry;
-import javax.jcr.security.AccessControlException;
-import javax.jcr.security.AccessControlManager;
-import javax.jcr.security.Privilege;
-
-import org.apache.commons.collections4.CollectionUtils;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.jackrabbit.api.security.JackrabbitAccessControlEntry;
-import org.apache.jackrabbit.api.security.JackrabbitAccessControlList;
-import org.apache.jackrabbit.oak.spi.security.principal.PrincipalImpl;
-import org.osgi.service.component.annotations.Component;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import biz.netcentric.cq.tools.actool.aem.AcToolCqActions;
-import biz.netcentric.cq.tools.actool.configmodel.AceBean;
-import biz.netcentric.cq.tools.actool.helper.AccessControlUtils;
-import biz.netcentric.cq.tools.actool.helper.RestrictionsHolder;
-import biz.netcentric.cq.tools.actool.history.InstallationLogger;
-
-/** The way ACEs were installed in version one is still available and can be configured in "global_config" section by setting
- * "installAclsIncrementally=false". */
-@Component()
-public class AceBeanInstallerClassic extends BaseAceBeanInstaller implements AceBeanInstaller {
-
- private static final Logger LOG = LoggerFactory.getLogger(AceBeanInstallerClassic.class);
-
-
- /** Installs a full set of ACE beans that form an ACL for the path
- *
- * @throws RepositoryException */
- protected void installAcl(Set aceBeanSetFromConfig, String path, Set principalsToRemoveAcesFor, Session session,
- InstallationLogger installLog) throws RepositoryException {
-
- // Remove all config contained authorizables from ACL of this path
- int countRemoved = AccessControlUtils.deleteAllEntriesForPrincipalsFromACL(session,
- path, principalsToRemoveAcesFor.toArray(new String[principalsToRemoveAcesFor.size()]));
-
- installLog.addVerboseMessage(LOG, "Deleted " + countRemoved + " ACEs for configured principals from path " + path);
-
- // Set ACL in repo with permissions from merged config
- for (final AceBean bean : aceBeanSetFromConfig) {
-
- LOG.debug("Writing bean to repository {}", bean);
-
- Principal currentPrincipal = new PrincipalImpl(bean.getPrincipalName());
- installAce(bean, session, currentPrincipal, installLog);
-
- }
-
- installLog.incCountAclsChanged();
-
- }
-
- /** Installs the AccessControlEntry being represented by this bean in the repository
- *
- * @throws NoSuchMethodException */
- private void installAce(AceBean aceBean, final Session session, Principal principal,
- InstallationLogger installLog) throws RepositoryException {
-
- if (aceBean.isInitialContentOnlyConfig()) {
- return;
- }
-
- final AccessControlManager acMgr = session.getAccessControlManager();
-
- JackrabbitAccessControlList acl = AccessControlUtils.getModifiableAcl(acMgr, aceBean.getJcrPathForPolicyApi());
- if (acl == null) {
- installLog.addMessage(LOG, "Skipped installing privileges/actions for non existing path: " + aceBean.getJcrPath());
- return;
- }
-
- // first install actions
- final JackrabbitAccessControlList newAcl = installActions(aceBean, principal, acl, session, acMgr, installLog);
- if (acl != newAcl) {
- installLog.addVerboseMessage(LOG, "Added action(s) for path: " + aceBean.getJcrPath()
- + ", principal: " + principal.getName() + ", actions: "
- + aceBean.getActionsString() + ", allow: " + aceBean.isAllow());
- removeRedundantPrivileges(aceBean, session);
- acl = newAcl;
- }
-
- // then install (remaining) privileges
- if (installPrivileges(aceBean, principal, acl, session, acMgr)) {
- installLog.addVerboseMessage(LOG, "Added privilege(s) for path: " + aceBean.getJcrPath()
- + ", principal: " + principal.getName() + ", privileges: "
- + aceBean.getPrivilegesString() + ", allow: " + aceBean.isAllow());
- }
-
- if (!acl.isEmpty()) {
- acMgr.setPolicy(aceBean.getJcrPathForPolicyApi(), acl);
- } else {
- acMgr.removePolicy(aceBean.getJcrPathForPolicyApi(), acl);
- }
-
- }
-
-
- /** Installs the CQ actions in the repository.
- *
- * @return either the same acl as given in the parameter {@code acl} if no actions have been installed otherwise the new
- * AccessControlList (comprising the entres being installed for the actions).
- * @throws RepositoryException */
- private JackrabbitAccessControlList installActions(AceBean aceBean, Principal principal, JackrabbitAccessControlList acl,
- Session session, AccessControlManager acMgr, InstallationLogger installLog) throws RepositoryException {
- final Map actionMap = aceBean.getActionMap();
- if (actionMap.isEmpty()) {
- return acl;
- }
-
- AcToolCqActions cqActions = new AcToolCqActions(session);
- Collection inheritedAllows = cqActions.getAllowedActions(
- aceBean.getJcrPathForPolicyApi(), Collections.singleton(principal));
- // this does always install new entries
- cqActions.installActions(aceBean.getJcrPathForPolicyApi(), principal, actionMap, inheritedAllows);
-
- // since the aclist has been modified, retrieve it again
- final JackrabbitAccessControlList newAcl = AccessControlUtils.getAccessControlList(session, aceBean.getJcrPath());
- final RestrictionsHolder restrictions = getRestrictions(aceBean, session, acl);
-
- if (!aceBean.getRestrictions().isEmpty()) {
- // additionally set restrictions on the installed actions (this is not supported by CQ Security API)
- addAdditionalRestriction(aceBean, acl, newAcl, restrictions);
- }
- return newAcl;
- }
-
- private void addAdditionalRestriction(AceBean aceBean, JackrabbitAccessControlList oldAcl, JackrabbitAccessControlList newAcl,
- RestrictionsHolder restrictions)
- throws RepositoryException {
- final List changedAces = getModifiedAces(oldAcl, newAcl);
- if (!changedAces.isEmpty()) {
- for (final AccessControlEntry newAce : changedAces) {
- addRestrictionIfNotSet(newAcl, restrictions, newAce);
- }
- } else {
- // check cornercase: yaml file contains 2 ACEs with same action same principal same path but one with additional restriction
- // (e.g. read and repGlob: '')
- // in that case old and new acl contain the same elements (equals == true) and in both lists the last ace contains the action
- // without restriction
- // for that group
- final AccessControlEntry lastOldAce = oldAcl.getAccessControlEntries()[oldAcl.getAccessControlEntries().length - 1];
- final AccessControlEntry lastNewAce = newAcl.getAccessControlEntries()[newAcl.getAccessControlEntries().length - 1];
-
- if (lastOldAce.equals(lastNewAce) && lastNewAce.getPrincipal().getName().equals(aceBean.getPrincipalName())) {
- addRestrictionIfNotSet(newAcl, restrictions, lastNewAce);
-
- } else {
- throw new IllegalStateException("No new entries have been set for AccessControlList at " + aceBean.getJcrPath());
- }
- }
- }
-
- private void addRestrictionIfNotSet(JackrabbitAccessControlList newAcl, RestrictionsHolder restrictions,
- AccessControlEntry newAce)
- throws RepositoryException, AccessControlException, UnsupportedRepositoryOperationException, SecurityException {
- if (!(newAce instanceof JackrabbitAccessControlEntry)) {
- throw new IllegalStateException(
- "Can not deal with non JackrabbitAccessControlEntrys, but entry is of type " + newAce.getClass().getName());
- }
- final JackrabbitAccessControlEntry ace = (JackrabbitAccessControlEntry) newAce;
- // only extend those AccessControlEntries which do not yet have a restriction
-
- if (ace.getRestrictionNames().length == 0) {
- // modify this AccessControlEntry by adding the restriction
- extendExistingAceWithRestrictions(newAcl, ace, restrictions);
- }
- }
-
- private List getModifiedAces(final JackrabbitAccessControlList oldAcl, JackrabbitAccessControlList newAcl)
- throws RepositoryException {
- final List oldAces = Arrays.asList(oldAcl.getAccessControlEntries());
- final List newAces = Arrays.asList(newAcl.getAccessControlEntries());
- return (List) CollectionUtils.subtract(newAces, oldAces);
-
- }
-
-
- private void removeRedundantPrivileges(AceBean aceBean, Session session) throws RepositoryException {
- final Set cleanedPrivileges = removeRedundantPrivileges(session, aceBean.getPrivileges(), aceBean.getActions());
- aceBean.setPrivilegesString(StringUtils.join(cleanedPrivileges, ","));
- }
-
- /** Modifies the privileges so that privileges already covered by actions are removed. This is only a best effort operation as one
- * action can lead to privileges on multiple nodes.
- *
- * @throws RepositoryException */
- private Set removeRedundantPrivileges(Session session, String[] privileges, String[] actions)
- throws RepositoryException {
- AcToolCqActions cqActions = new AcToolCqActions(session);
- Set cleanedPrivileges = new HashSet();
- if (privileges == null) {
- return cleanedPrivileges;
- }
- cleanedPrivileges.addAll(Arrays.asList(privileges));
- if (actions == null) {
- return cleanedPrivileges;
- }
- for (final String action : actions) {
- final Set coveredPrivileges = cqActions.getPrivileges(action);
- for (final Privilege coveredPrivilege : coveredPrivileges) {
- cleanedPrivileges.remove(coveredPrivilege.getName());
- }
- }
- return cleanedPrivileges;
- }
-
-
- private void extendExistingAceWithRestrictions(JackrabbitAccessControlList accessControlList,
- JackrabbitAccessControlEntry accessControlEntry, RestrictionsHolder restrictions)
- throws SecurityException, UnsupportedRepositoryOperationException, RepositoryException {
-
- // 1. add new entry
- if (!accessControlList.addEntry(accessControlEntry.getPrincipal(), accessControlEntry.getPrivileges(), accessControlEntry.isAllow(),
- restrictions.getSingleValuedRestrictionsMap(), restrictions.getMultiValuedRestrictionsMap())) {
- throw new IllegalStateException("Could not add entry, probably because it was already there!");
- }
- // we assume the entry being added is the last one
- final AccessControlEntry newAccessControlEntry = accessControlList.getAccessControlEntries()[accessControlList.size() - 1];
- // 2. put it to the right position now!
- accessControlList.orderBefore(newAccessControlEntry, accessControlEntry);
- // 3. remove old entry
- accessControlList.removeAccessControlEntry(accessControlEntry);
- }
-
-}
+package biz.netcentric.cq.tools.actool.aceinstaller;
+
+/*-
+ * #%L
+ * Access Control Tool Bundle
+ * %%
+ * Copyright (C) 2015 - 2024 Cognizant Netcentric
+ * %%
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * #L%
+ */
+
+import java.security.Principal;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import javax.jcr.UnsupportedRepositoryOperationException;
+import javax.jcr.security.AccessControlEntry;
+import javax.jcr.security.AccessControlException;
+import javax.jcr.security.AccessControlManager;
+import javax.jcr.security.Privilege;
+
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.jackrabbit.api.security.JackrabbitAccessControlEntry;
+import org.apache.jackrabbit.api.security.JackrabbitAccessControlList;
+import org.apache.jackrabbit.oak.spi.security.principal.PrincipalImpl;
+import org.osgi.service.component.annotations.Component;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import biz.netcentric.cq.tools.actool.aem.AcToolCqActions;
+import biz.netcentric.cq.tools.actool.configmodel.AceBean;
+import biz.netcentric.cq.tools.actool.helper.AccessControlUtils;
+import biz.netcentric.cq.tools.actool.helper.RestrictionsHolder;
+import biz.netcentric.cq.tools.actool.history.InstallationLogger;
+
+/** The way ACEs were installed in version one is still available and can be configured in "global_config" section by setting
+ * "installAclsIncrementally=false". */
+@Component()
+public class AceBeanInstallerClassic extends BaseAceBeanInstaller implements AceBeanInstaller {
+
+ private static final Logger LOG = LoggerFactory.getLogger(AceBeanInstallerClassic.class);
+
+
+ /** Installs a full set of ACE beans that form an ACL for the path
+ *
+ * @throws RepositoryException */
+ protected void installAcl(Set aceBeanSetFromConfig, String path, Set principalsToRemoveAcesFor, Session session,
+ InstallationLogger installLog) throws RepositoryException {
+
+ // Remove all config contained authorizables from ACL of this path
+ int countRemoved = AccessControlUtils.deleteAllEntriesForPrincipalsFromACL(session,
+ path, principalsToRemoveAcesFor.toArray(new String[principalsToRemoveAcesFor.size()]));
+
+ installLog.addVerboseMessage(LOG, "Deleted " + countRemoved + " ACEs for configured principals from path " + path);
+
+ // Set ACL in repo with permissions from merged config
+ for (final AceBean bean : aceBeanSetFromConfig) {
+
+ LOG.debug("Writing bean to repository {}", bean);
+
+ Principal currentPrincipal = new PrincipalImpl(bean.getPrincipalName());
+ installAce(bean, session, currentPrincipal, installLog);
+
+ }
+
+ installLog.incCountAclsChanged();
+
+ }
+
+ /** Installs the AccessControlEntry being represented by this bean in the repository
+ *
+ * @throws NoSuchMethodException */
+ private void installAce(AceBean aceBean, final Session session, Principal principal,
+ InstallationLogger installLog) throws RepositoryException {
+
+ if (aceBean.isInitialContentOnlyConfig()) {
+ return;
+ }
+
+ final AccessControlManager acMgr = session.getAccessControlManager();
+
+ JackrabbitAccessControlList acl = AccessControlUtils.getModifiableAcl(acMgr, aceBean.getJcrPathForPolicyApi());
+ if (acl == null) {
+ installLog.addMessage(LOG, "Skipped installing privileges/actions for non existing path: " + aceBean.getJcrPath());
+ return;
+ }
+
+ // first install actions
+ final JackrabbitAccessControlList newAcl = installActions(aceBean, principal, acl, session, acMgr, installLog);
+ if (acl != newAcl) {
+ installLog.addVerboseMessage(LOG, "Added action(s) for path: " + aceBean.getJcrPath()
+ + ", principal: " + principal.getName() + ", actions: "
+ + aceBean.getActionsString() + ", allow: " + aceBean.isAllow());
+ removeRedundantPrivileges(aceBean, session);
+ acl = newAcl;
+ }
+
+ // then install (remaining) privileges
+ if (installPrivileges(aceBean, principal, acl, session, acMgr)) {
+ installLog.addVerboseMessage(LOG, "Added privilege(s) for path: " + aceBean.getJcrPath()
+ + ", principal: " + principal.getName() + ", privileges: "
+ + aceBean.getPrivilegesString() + ", allow: " + aceBean.isAllow());
+ }
+
+ if (!acl.isEmpty()) {
+ acMgr.setPolicy(aceBean.getJcrPathForPolicyApi(), acl);
+ } else {
+ acMgr.removePolicy(aceBean.getJcrPathForPolicyApi(), acl);
+ }
+
+ }
+
+
+ /** Installs the CQ actions in the repository.
+ *
+ * @return either the same acl as given in the parameter {@code acl} if no actions have been installed otherwise the new
+ * AccessControlList (comprising the entres being installed for the actions).
+ * @throws RepositoryException */
+ private JackrabbitAccessControlList installActions(AceBean aceBean, Principal principal, JackrabbitAccessControlList acl,
+ Session session, AccessControlManager acMgr, InstallationLogger installLog) throws RepositoryException {
+ final Map actionMap = aceBean.getActionMap();
+ if (actionMap.isEmpty()) {
+ return acl;
+ }
+
+ AcToolCqActions cqActions = new AcToolCqActions(session);
+ Collection inheritedAllows = cqActions.getAllowedActions(
+ aceBean.getJcrPathForPolicyApi(), Collections.singleton(principal));
+ // this does always install new entries
+ cqActions.installActions(aceBean.getJcrPathForPolicyApi(), principal, actionMap, inheritedAllows);
+
+ // since the aclist has been modified, retrieve it again
+ final JackrabbitAccessControlList newAcl = AccessControlUtils.getAccessControlList(session, aceBean.getJcrPath());
+ final RestrictionsHolder restrictions = getRestrictions(aceBean, session, acl);
+
+ if (!aceBean.getRestrictions().isEmpty()) {
+ // additionally set restrictions on the installed actions (this is not supported by CQ Security API)
+ addAdditionalRestriction(aceBean, acl, newAcl, restrictions);
+ }
+ return newAcl;
+ }
+
+ private void addAdditionalRestriction(AceBean aceBean, JackrabbitAccessControlList oldAcl, JackrabbitAccessControlList newAcl,
+ RestrictionsHolder restrictions)
+ throws RepositoryException {
+ final List changedAces = getModifiedAces(oldAcl, newAcl);
+ if (!changedAces.isEmpty()) {
+ for (final AccessControlEntry newAce : changedAces) {
+ addRestrictionIfNotSet(newAcl, restrictions, newAce);
+ }
+ } else {
+ // check cornercase: yaml file contains 2 ACEs with same action same principal same path but one with additional restriction
+ // (e.g. read and repGlob: '')
+ // in that case old and new acl contain the same elements (equals == true) and in both lists the last ace contains the action
+ // without restriction
+ // for that group
+ final AccessControlEntry lastOldAce = oldAcl.getAccessControlEntries()[oldAcl.getAccessControlEntries().length - 1];
+ final AccessControlEntry lastNewAce = newAcl.getAccessControlEntries()[newAcl.getAccessControlEntries().length - 1];
+
+ if (lastOldAce.equals(lastNewAce) && lastNewAce.getPrincipal().getName().equals(aceBean.getPrincipalName())) {
+ addRestrictionIfNotSet(newAcl, restrictions, lastNewAce);
+
+ } else {
+ throw new IllegalStateException("No new entries have been set for AccessControlList at " + aceBean.getJcrPath());
+ }
+ }
+ }
+
+ private void addRestrictionIfNotSet(JackrabbitAccessControlList newAcl, RestrictionsHolder restrictions,
+ AccessControlEntry newAce)
+ throws RepositoryException, AccessControlException, UnsupportedRepositoryOperationException, SecurityException {
+ if (!(newAce instanceof JackrabbitAccessControlEntry)) {
+ throw new IllegalStateException(
+ "Can not deal with non JackrabbitAccessControlEntrys, but entry is of type " + newAce.getClass().getName());
+ }
+ final JackrabbitAccessControlEntry ace = (JackrabbitAccessControlEntry) newAce;
+ // only extend those AccessControlEntries which do not yet have a restriction
+
+ if (ace.getRestrictionNames().length == 0) {
+ // modify this AccessControlEntry by adding the restriction
+ extendExistingAceWithRestrictions(newAcl, ace, restrictions);
+ }
+ }
+
+ private List getModifiedAces(final JackrabbitAccessControlList oldAcl, JackrabbitAccessControlList newAcl)
+ throws RepositoryException {
+ final List oldAces = Arrays.asList(oldAcl.getAccessControlEntries());
+ final List newAces = Arrays.asList(newAcl.getAccessControlEntries());
+ return (List) CollectionUtils.subtract(newAces, oldAces);
+
+ }
+
+
+ private void removeRedundantPrivileges(AceBean aceBean, Session session) throws RepositoryException {
+ final Set cleanedPrivileges = removeRedundantPrivileges(session, aceBean.getPrivileges(), aceBean.getActions());
+ aceBean.setPrivilegesString(StringUtils.join(cleanedPrivileges, ","));
+ }
+
+ /** Modifies the privileges so that privileges already covered by actions are removed. This is only a best effort operation as one
+ * action can lead to privileges on multiple nodes.
+ *
+ * @throws RepositoryException */
+ private Set removeRedundantPrivileges(Session session, String[] privileges, String[] actions)
+ throws RepositoryException {
+ AcToolCqActions cqActions = new AcToolCqActions(session);
+ Set cleanedPrivileges = new HashSet();
+ if (privileges == null) {
+ return cleanedPrivileges;
+ }
+ cleanedPrivileges.addAll(Arrays.asList(privileges));
+ if (actions == null) {
+ return cleanedPrivileges;
+ }
+ for (final String action : actions) {
+ final Set coveredPrivileges = cqActions.getPrivileges(action);
+ for (final Privilege coveredPrivilege : coveredPrivileges) {
+ cleanedPrivileges.remove(coveredPrivilege.getName());
+ }
+ }
+ return cleanedPrivileges;
+ }
+
+
+ private void extendExistingAceWithRestrictions(JackrabbitAccessControlList accessControlList,
+ JackrabbitAccessControlEntry accessControlEntry, RestrictionsHolder restrictions)
+ throws SecurityException, UnsupportedRepositoryOperationException, RepositoryException {
+
+ // 1. add new entry
+ if (!accessControlList.addEntry(accessControlEntry.getPrincipal(), accessControlEntry.getPrivileges(), accessControlEntry.isAllow(),
+ restrictions.getSingleValuedRestrictionsMap(), restrictions.getMultiValuedRestrictionsMap())) {
+ throw new IllegalStateException("Could not add entry, probably because it was already there!");
+ }
+ // we assume the entry being added is the last one
+ final AccessControlEntry newAccessControlEntry = accessControlList.getAccessControlEntries()[accessControlList.size() - 1];
+ // 2. put it to the right position now!
+ accessControlList.orderBefore(newAccessControlEntry, accessControlEntry);
+ // 3. remove old entry
+ accessControlList.removeAccessControlEntry(accessControlEntry);
+ }
+
+}
diff --git a/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/aceinstaller/AceBeanInstallerIncremental.java b/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/aceinstaller/AceBeanInstallerIncremental.java
index 19d5be9a2..8ace16749 100644
--- a/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/aceinstaller/AceBeanInstallerIncremental.java
+++ b/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/aceinstaller/AceBeanInstallerIncremental.java
@@ -1,439 +1,444 @@
-/*
- * (C) Copyright 2016 Netcentric AG.
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- */
-package biz.netcentric.cq.tools.actool.aceinstaller;
-
-import java.security.Principal;
-import java.text.Collator;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.LinkedHashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.TreeSet;
-import java.util.concurrent.ConcurrentHashMap;
-
-import javax.jcr.PathNotFoundException;
-import javax.jcr.RepositoryException;
-import javax.jcr.Session;
-import javax.jcr.UnsupportedRepositoryOperationException;
-import javax.jcr.security.AccessControlEntry;
-import javax.jcr.security.AccessControlManager;
-import javax.jcr.security.Privilege;
-
-import org.apache.commons.lang3.StringUtils;
-import org.apache.jackrabbit.api.security.JackrabbitAccessControlList;
-import org.apache.jackrabbit.oak.spi.security.principal.PrincipalImpl;
-import org.apache.sling.jcr.api.SlingRepository;
-import org.osgi.service.component.annotations.Component;
-import org.osgi.service.component.annotations.Reference;
-import org.osgi.service.component.annotations.ReferencePolicyOption;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import biz.netcentric.cq.tools.actool.aem.AcToolCqActions;
-import biz.netcentric.cq.tools.actool.configmodel.AceBean;
-import biz.netcentric.cq.tools.actool.configmodel.Restriction;
-import biz.netcentric.cq.tools.actool.helper.AcHelper;
-import biz.netcentric.cq.tools.actool.helper.AccessControlUtils;
-import biz.netcentric.cq.tools.actool.history.InstallationLogger;
-
-@Component
-public class AceBeanInstallerIncremental extends BaseAceBeanInstaller implements AceBeanInstaller {
-
- @Reference(policyOption=ReferencePolicyOption.GREEDY)
- private SlingRepository slingRepository;
-
- private static final Logger LOG = LoggerFactory.getLogger(AceBeanInstallerIncremental.class);
-
- private Map> actionsToPrivilegesMapping = new ConcurrentHashMap>();
-
- /** Installs a full set of ACE beans that form an ACL for the path
- *
- * @throws RepositoryException */
- protected void installAcl(Set aceBeanSetFromConfig, String path, Set principalsInConfiguration, Session session,
- InstallationLogger installLog) throws RepositoryException {
-
- boolean hadPendingChanges = session.hasPendingChanges();
-
- int countDeleted = 0;
- int countAdded = 0;
- int countNoChange = 0;
- int countOutsideConfig = 0;
-
- StringBuilder diffLog = new StringBuilder();
-
- aceBeanSetFromConfig = transformActionsIntoPrivileges(aceBeanSetFromConfig, session, installLog);
- aceBeanSetFromConfig = filterInitialContentOnlyNodes(aceBeanSetFromConfig);
- aceBeanSetFromConfig = filterDuplicates(aceBeanSetFromConfig, session);
-
- List configuredAceEntries = new ArrayList(aceBeanSetFromConfig);
- int currentPositionConfig = 0;
-
- boolean changeHasBeenFound = false;
-
- AccessControlManager acMgr = session.getAccessControlManager();
-
- JackrabbitAccessControlList acl = getAccessControlList(acMgr, path);
- Iterator aceIt = Arrays.asList(acl.getAccessControlEntries()).iterator();
- while (aceIt.hasNext()) {
- AccessControlEntry ace = aceIt.next();
- AceBean actualAceBean = AcHelper.getAceBean(ace, acl);
-
- String acePrincipalName = actualAceBean.getPrincipalName();
- String actualAceBeanCompareStr = toAceCompareString(actualAceBean, acMgr);
-
- if (!principalsInConfiguration.contains(acePrincipalName)) {
- countOutsideConfig++;
- diffLog.append(" OUTSIDE (not in Config) " + actualAceBeanCompareStr + "\n");
- continue;
- }
-
- AceBean configuredAceAtThisLocation;
- if (currentPositionConfig < configuredAceEntries.size()) {
- configuredAceAtThisLocation = configuredAceEntries.get(currentPositionConfig);
- } else {
- // LOG.info("There are now fewer ACEs configured at path " + path + " than there was before");
- changeHasBeenFound = true;
- configuredAceAtThisLocation = null; // setting explicitly to null
- }
-
- String configuredAceAtThisLocationCompareStr = toAceCompareString(configuredAceAtThisLocation, acMgr);
- boolean dumpEqualToConfig = StringUtils.equals(actualAceBeanCompareStr, configuredAceAtThisLocationCompareStr);
-
- if (!changeHasBeenFound && !dumpEqualToConfig) {
- String configBeanStr = configuredAceAtThisLocationCompareStr;
- diffLog.append("<<< CHANGE (Repo Version) " + actualAceBeanCompareStr
- + "\n>>> CHANGE (Config Version) " + configBeanStr + "\n");
- }
-
- if (changeHasBeenFound || !dumpEqualToConfig) {
- changeHasBeenFound = true; // first difference means we delete the rest of the acl and recreate it in the following loop
- acl.removeAccessControlEntry(ace);
- countDeleted++;
-
- diffLog.append(" DELETED (from Repo) " + actualAceBeanCompareStr + "\n");
-
- continue; // we do not touch currentPositionConfig anymore, we'll have to recreate from there
- }
-
- currentPositionConfig++; // found equal ACE, compare next pair
- countNoChange++;
- diffLog.append(" UNCHANGED " + actualAceBeanCompareStr + "\n");
-
- }
-
- // install missing - this can be either because not all configured ACEs were found (append) or because a change was detected and old
- // aces have been deleted
-
- for (int i = currentPositionConfig; i < configuredAceEntries.size(); i++) {
- AceBean aceBeanToAppend = configuredAceEntries.get(i);
-
- installPrivileges(aceBeanToAppend, new PrincipalImpl(aceBeanToAppend.getPrincipalName()), acl, session, acMgr);
- diffLog.append(" APPENDED (from Config) " + toAceCompareString(aceBeanToAppend, acMgr) + "\n");
-
- countAdded++;
- }
-
- if (countAdded > 0 || countDeleted > 0) {
- acMgr.setPolicy(StringUtils.isNotBlank(path) ? path : /* repo level permission */null, acl);
-
- installLog.incCountAclsChanged();
-
- installLog.addVerboseMessage(LOG, "Update result at path " + path + ": O=" + countOutsideConfig + " N="
- + countNoChange + " D=" + countDeleted + " A=" + countAdded
- + (LOG.isDebugEnabled() ? "\nDIFF at " + path + "\n" + diffLog : ""));
-
- } else {
- installLog.incCountAclsNoChange();
- }
-
- if (!hadPendingChanges) {
- if (session.hasPendingChanges()) {
- hadPendingChanges = true;
- installLog.addMessage(LOG, "Path " + path + " introduced pending changes to the session");
- }
- }
-
- }
-
- // When using actions, it often happens that the second entry produced (with the rep:glob '*/jcr:content*') is a duplicate
- // Also without this, a potential effective duplicate in config would be detected as change of incremental run when it is
- // really not since jackrabbit ignores adding a duplicate entry to ACL
- private Set filterDuplicates(Set aceBeanSetFromConfig, Session session)
- throws UnsupportedRepositoryOperationException, RepositoryException {
-
- LinkedHashSet filteredAceBeans = new LinkedHashSet(aceBeanSetFromConfig);
- Iterator aceBeansIt = filteredAceBeans.iterator();
- Set aceCompareKeysToAvoidDuplicates = new HashSet();
- while (aceBeansIt.hasNext()) {
- String aceCompareKey = toAceCompareString(aceBeansIt.next(), session.getAccessControlManager());
- if (aceCompareKeysToAvoidDuplicates.contains(aceCompareKey)) {
- aceBeansIt.remove();
- } else {
- aceCompareKeysToAvoidDuplicates.add(aceCompareKey);
- }
-
- }
- return filteredAceBeans;
- }
-
- private Set filterInitialContentOnlyNodes(Set aceBeanSetFromConfig) {
- Set aceBeanSetNoInitialContentOnlyNodes = new LinkedHashSet();
- for (AceBean aceBean : aceBeanSetFromConfig) {
- if (!aceBean.isInitialContentOnlyConfig()) {
- aceBeanSetNoInitialContentOnlyNodes.add(aceBean);
- }
-
- }
- return aceBeanSetNoInitialContentOnlyNodes;
- }
-
- // to be overwritten in JUnit Test
- protected JackrabbitAccessControlList getAccessControlList(AccessControlManager acMgr, String path) throws RepositoryException {
- JackrabbitAccessControlList acl = AccessControlUtils.getModifiableAcl(acMgr, path);
- return acl;
- }
-
- private Set transformActionsIntoPrivileges(Set aceBeanSetFromConfig, Session session,
- InstallationLogger installLog) throws RepositoryException {
-
-
- Set aceBeanSetWithPrivilegesOnly = new LinkedHashSet();
- for (AceBean origAceBean : aceBeanSetFromConfig) {
- if (origAceBean.getActionMap().isEmpty()) {
- aceBeanSetWithPrivilegesOnly.add(origAceBean);
- continue;
- }
-
- Set aceBeansForActionEntry = getPrincipalAceBeansForActionAceBeanCached(origAceBean, session, installLog);
- for (AceBean aceBeanResolvedFromAction : aceBeansForActionEntry) {
- aceBeanSetWithPrivilegesOnly.add(aceBeanResolvedFromAction);
- }
- }
-
- return aceBeanSetWithPrivilegesOnly;
- }
-
- private Set getPrincipalAceBeansForActionAceBeanCached(AceBean origAceBean, Session session,
- InstallationLogger installLog) throws RepositoryException {
-
- String cacheKey = (definesContent(origAceBean.getJcrPathForPolicyApi(), session) ? "definesContent" : "simple")
- + "-" + origAceBean.getPermission() + "-" + getRestrictionsComparable(origAceBean.getRestrictions()) + "-"
- + Arrays.toString(origAceBean.getActions());
-
- if (actionsToPrivilegesMapping.containsKey(cacheKey)) {
- installLog.incCountActionCacheHit();
- LOG.trace("Cache hit for key " + cacheKey);
- Set cachedAceBeansForActions = actionsToPrivilegesMapping.get(cacheKey);
- Set principalCorrectedAceBeansForActions = new LinkedHashSet();
- for (AceBean aceBean : cachedAceBeansForActions) {
- AceBean clone = aceBean.clone();
- clone.setPrincipalName(origAceBean.getPrincipalName());
- principalCorrectedAceBeansForActions.add(clone);
- }
- return principalCorrectedAceBeansForActions;
- } else {
- installLog.incCountActionCacheMiss();
-
- Set aceBeansForActionEntry = null;
- Session newSession = slingRepository.loginService(null, null);
- try {
- Session relevantSessionToUse;
- if (newSession.nodeExists(origAceBean.getJcrPath())) {
- // a new session is needed to ensure no pending changes are introduced (even if there would not be real pending changes
- // since we add and remove, but session.hasPendingChanges() is true then).
- // The new session is not saved(), its only function is to produce the action->privileges mapping with the ootb class
- // CqActions
- relevantSessionToUse = newSession;
- } else {
- // if the path was just only created in this session via initialContent
- relevantSessionToUse = session;
- LOG.warn("Reusing main session for path {} since the node was only just created in that session via 'initialContent'",
- origAceBean.getJcrPath());
- }
- aceBeansForActionEntry = getPrincipalAceBeansForActionAceBean(origAceBean, relevantSessionToUse);
- } finally {
- newSession.logout();
- }
-
- LOG.debug("Adding to cache: {}={}", cacheKey, aceBeansForActionEntry);
- actionsToPrivilegesMapping.put(cacheKey, aceBeansForActionEntry);
-
-
- return aceBeansForActionEntry;
- }
-
- }
-
- Set getPrincipalAceBeansForActionAceBean(AceBean origAceBean, Session session) throws RepositoryException {
-
- Set aceBeansForActionEntry = new LinkedHashSet();
-
- Principal testActionMapperPrincipal = getTestActionMapperPrincipal();
- applyCqActions(origAceBean, session, testActionMapperPrincipal);
-
- JackrabbitAccessControlList newAcl = getAccessControlList(session.getAccessControlManager(), origAceBean.getJcrPathForPolicyApi());
-
- boolean isFirst = true;
- for (AccessControlEntry newAce : newAcl.getAccessControlEntries()) {
- if (!newAce.getPrincipal().equals(testActionMapperPrincipal)) {
- continue;
- }
-
- AceBean privilegesAceBeanForAction = AcHelper.getAceBean(newAce, newAcl);
- privilegesAceBeanForAction.setPrincipalName(origAceBean.getPrincipalName());
-
- // handle restrictions
- if (isFirst) {
- if (origAceBean.containsRestriction(AceBean.RESTRICTION_NAME_GLOB)
- && privilegesAceBeanForAction.containsRestriction(AceBean.RESTRICTION_NAME_GLOB)) {
- throw new IllegalArgumentException(
- "When using actions that produce rep:glob restrictions (e.g. for page paths), rep:glob cannot be configured (origAceBean="
- + origAceBean.getRestrictions() + ", privilegesAceBeanForAction="
- + privilegesAceBeanForAction.getRestrictions() + "), check configuration for "
- + origAceBean);
- } else {
- // other restrictions are just taken over
- privilegesAceBeanForAction.getRestrictions().addAll(origAceBean.getRestrictions());
- }
- }
-
- aceBeansForActionEntry.add(privilegesAceBeanForAction);
-
- // remove the fake entry again
- newAcl.removeAccessControlEntry(newAce);
- isFirst = false;
- }
- AccessControlManager acMgr = session.getAccessControlManager();
- acMgr.setPolicy(origAceBean.getJcrPath(), newAcl);
-
- // handle privileges
- AceBean firstMappedBean = aceBeansForActionEntry.iterator().next(); // apply additional privileges only to first bean
- Set newPrivilegesFirstMappedBean = new LinkedHashSet();
- // first add regular privileges
- if (firstMappedBean.getPrivileges() != null) {
- newPrivilegesFirstMappedBean.addAll(Arrays.asList(firstMappedBean.getPrivileges()));
- }
- Set flatSetPrincipalsOfFirstMappedBean = flatSetResolvedAggregates(firstMappedBean.getPrivileges(), acMgr, true);
- if (origAceBean.getPrivileges() != null) {
- for (String origBeanPrivString : origAceBean.getPrivileges()) {
- if (!flatSetPrincipalsOfFirstMappedBean.contains(origBeanPrivString)) {
- newPrivilegesFirstMappedBean.add(origBeanPrivString);
- }
- }
- }
- firstMappedBean.setPrivilegesString(StringUtils.join(newPrivilegesFirstMappedBean, ","));
-
- if (LOG.isDebugEnabled()) {
- StringBuilder buf = new StringBuilder();
- buf.append("CqActions at path " + origAceBean.getJcrPath()
- + " with authorizableId=" + origAceBean.getAuthorizableId() + "/" + testActionMapperPrincipal.getName() + " produced \n");
- for (AceBean aceBean : aceBeansForActionEntry) {
- buf.append(" " + toAceCompareString(aceBean, acMgr) + "\n");
- }
- LOG.debug(buf.toString());
- }
-
- return aceBeansForActionEntry;
-
- }
-
- Principal getTestActionMapperPrincipal() {
- String groupPrincipalId = "actool-tester-action-mapper"; // does not have to exist since the ACEs for it are not saved
- Principal principal = new PrincipalImpl(groupPrincipalId);
- return principal;
- }
-
- void applyCqActions(AceBean origAceBean, Session session, Principal principal) throws RepositoryException {
-
- if (origAceBean.getActionMap().isEmpty()) {
- return;
- }
-
- AcToolCqActions cqActions = new AcToolCqActions(session);
- Collection inheritedAllows = cqActions.getAllowedActions(origAceBean.getJcrPathForPolicyApi(),
- Collections.singleton(principal));
- // this does always install new entries
- cqActions.installActions(origAceBean.getJcrPath(), principal, origAceBean.getActionMap(), inheritedAllows);
-
- }
-
- private Set flatSetResolvedAggregates(String[] privNames, AccessControlManager acMgr, boolean includeAggregates)
- throws RepositoryException {
- if (privNames == null) {
- return Collections.emptySet();
- }
- final Set privileges = new HashSet();
- for (final String name : privNames) {
- final Privilege p = acMgr.privilegeFromName(name);
- if (!p.isAggregate() || includeAggregates) {
- privileges.add(p.getName());
- }
- if (p.isAggregate()) { // add "sub privileges" as well
- for (Privilege subPriv : p.getDeclaredAggregatePrivileges()) {
- Set subPrivileges = flatSetResolvedAggregates(new String[] { subPriv.getName() }, acMgr, includeAggregates);
- privileges.addAll(subPrivileges);
- }
- }
- }
- return privileges;
- }
-
- boolean definesContent(String pagePath, Session session) throws RepositoryException {
- if (pagePath == null || pagePath.equals("/")) {
- return false;
- }
- try {
- return AcToolCqActions.definesContent(session.getNode(pagePath));
- } catch (PathNotFoundException e) {
- return false;
- }
-
- }
-
- private String toAceCompareString(AceBean aceBean, AccessControlManager acMgr) throws RepositoryException {
- if (aceBean == null) {
- return "null";
- }
-
- List restrictionsSorted = getRestrictionsComparable(aceBean.getRestrictions());
-
- String nonAggregatePrivsNormalized = privilegesToComparableSet(aceBean.getPrivileges(), acMgr);
-
- String aceCompareStr = aceBean.getPrincipalName() + " " + aceBean.getPermission() + " " + nonAggregatePrivsNormalized
- + Arrays.toString(restrictionsSorted.toArray());
- return aceCompareStr;
- }
-
- private List getRestrictionsComparable(List restrictions) {
- List restrictionsSorted = new ArrayList(restrictions);
- Collections.sort(restrictionsSorted, new Comparator() {
-
- @Override
- public int compare(Restriction r1, Restriction r2) {
- return Collator.getInstance().compare(r1.getName(), r2.getName());
- }
- });
- return restrictionsSorted;
- }
-
- String privilegesToComparableSet(String[] privileges, AccessControlManager acMgr) throws RepositoryException {
- return new TreeSet(flatSetResolvedAggregates(privileges, acMgr, false)).toString();
- }
-
-
-
-
-}
+package biz.netcentric.cq.tools.actool.aceinstaller;
+
+/*-
+ * #%L
+ * Access Control Tool Bundle
+ * %%
+ * Copyright (C) 2015 - 2024 Cognizant Netcentric
+ * %%
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * #L%
+ */
+
+import java.security.Principal;
+import java.text.Collator;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeSet;
+import java.util.concurrent.ConcurrentHashMap;
+
+import javax.jcr.PathNotFoundException;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import javax.jcr.UnsupportedRepositoryOperationException;
+import javax.jcr.security.AccessControlEntry;
+import javax.jcr.security.AccessControlManager;
+import javax.jcr.security.Privilege;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.jackrabbit.api.security.JackrabbitAccessControlList;
+import org.apache.jackrabbit.oak.spi.security.principal.PrincipalImpl;
+import org.apache.sling.jcr.api.SlingRepository;
+import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.Reference;
+import org.osgi.service.component.annotations.ReferencePolicyOption;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import biz.netcentric.cq.tools.actool.aem.AcToolCqActions;
+import biz.netcentric.cq.tools.actool.configmodel.AceBean;
+import biz.netcentric.cq.tools.actool.configmodel.Restriction;
+import biz.netcentric.cq.tools.actool.helper.AcHelper;
+import biz.netcentric.cq.tools.actool.helper.AccessControlUtils;
+import biz.netcentric.cq.tools.actool.history.InstallationLogger;
+
+@Component
+public class AceBeanInstallerIncremental extends BaseAceBeanInstaller implements AceBeanInstaller {
+
+ @Reference(policyOption=ReferencePolicyOption.GREEDY)
+ private SlingRepository slingRepository;
+
+ private static final Logger LOG = LoggerFactory.getLogger(AceBeanInstallerIncremental.class);
+
+ private Map> actionsToPrivilegesMapping = new ConcurrentHashMap>();
+
+ /** Installs a full set of ACE beans that form an ACL for the path
+ *
+ * @throws RepositoryException */
+ protected void installAcl(Set aceBeanSetFromConfig, String path, Set principalsInConfiguration, Session session,
+ InstallationLogger installLog) throws RepositoryException {
+
+ boolean hadPendingChanges = session.hasPendingChanges();
+
+ int countDeleted = 0;
+ int countAdded = 0;
+ int countNoChange = 0;
+ int countOutsideConfig = 0;
+
+ StringBuilder diffLog = new StringBuilder();
+
+ aceBeanSetFromConfig = transformActionsIntoPrivileges(aceBeanSetFromConfig, session, installLog);
+ aceBeanSetFromConfig = filterInitialContentOnlyNodes(aceBeanSetFromConfig);
+ aceBeanSetFromConfig = filterDuplicates(aceBeanSetFromConfig, session);
+
+ List configuredAceEntries = new ArrayList(aceBeanSetFromConfig);
+ int currentPositionConfig = 0;
+
+ boolean changeHasBeenFound = false;
+
+ AccessControlManager acMgr = session.getAccessControlManager();
+
+ JackrabbitAccessControlList acl = getAccessControlList(acMgr, path);
+ Iterator aceIt = Arrays.asList(acl.getAccessControlEntries()).iterator();
+ while (aceIt.hasNext()) {
+ AccessControlEntry ace = aceIt.next();
+ AceBean actualAceBean = AcHelper.getAceBean(ace, acl);
+
+ String acePrincipalName = actualAceBean.getPrincipalName();
+ String actualAceBeanCompareStr = toAceCompareString(actualAceBean, acMgr);
+
+ if (!principalsInConfiguration.contains(acePrincipalName)) {
+ countOutsideConfig++;
+ diffLog.append(" OUTSIDE (not in Config) " + actualAceBeanCompareStr + "\n");
+ continue;
+ }
+
+ AceBean configuredAceAtThisLocation;
+ if (currentPositionConfig < configuredAceEntries.size()) {
+ configuredAceAtThisLocation = configuredAceEntries.get(currentPositionConfig);
+ } else {
+ // LOG.info("There are now fewer ACEs configured at path " + path + " than there was before");
+ changeHasBeenFound = true;
+ configuredAceAtThisLocation = null; // setting explicitly to null
+ }
+
+ String configuredAceAtThisLocationCompareStr = toAceCompareString(configuredAceAtThisLocation, acMgr);
+ boolean dumpEqualToConfig = StringUtils.equals(actualAceBeanCompareStr, configuredAceAtThisLocationCompareStr);
+
+ if (!changeHasBeenFound && !dumpEqualToConfig) {
+ String configBeanStr = configuredAceAtThisLocationCompareStr;
+ diffLog.append("<<< CHANGE (Repo Version) " + actualAceBeanCompareStr
+ + "\n>>> CHANGE (Config Version) " + configBeanStr + "\n");
+ }
+
+ if (changeHasBeenFound || !dumpEqualToConfig) {
+ changeHasBeenFound = true; // first difference means we delete the rest of the acl and recreate it in the following loop
+ acl.removeAccessControlEntry(ace);
+ countDeleted++;
+
+ diffLog.append(" DELETED (from Repo) " + actualAceBeanCompareStr + "\n");
+
+ continue; // we do not touch currentPositionConfig anymore, we'll have to recreate from there
+ }
+
+ currentPositionConfig++; // found equal ACE, compare next pair
+ countNoChange++;
+ diffLog.append(" UNCHANGED " + actualAceBeanCompareStr + "\n");
+
+ }
+
+ // install missing - this can be either because not all configured ACEs were found (append) or because a change was detected and old
+ // aces have been deleted
+
+ for (int i = currentPositionConfig; i < configuredAceEntries.size(); i++) {
+ AceBean aceBeanToAppend = configuredAceEntries.get(i);
+
+ installPrivileges(aceBeanToAppend, new PrincipalImpl(aceBeanToAppend.getPrincipalName()), acl, session, acMgr);
+ diffLog.append(" APPENDED (from Config) " + toAceCompareString(aceBeanToAppend, acMgr) + "\n");
+
+ countAdded++;
+ }
+
+ if (countAdded > 0 || countDeleted > 0) {
+ acMgr.setPolicy(StringUtils.isNotBlank(path) ? path : /* repo level permission */null, acl);
+
+ installLog.incCountAclsChanged();
+
+ installLog.addVerboseMessage(LOG, "Update result at path " + path + ": O=" + countOutsideConfig + " N="
+ + countNoChange + " D=" + countDeleted + " A=" + countAdded
+ + (LOG.isDebugEnabled() ? "\nDIFF at " + path + "\n" + diffLog : ""));
+
+ } else {
+ installLog.incCountAclsNoChange();
+ }
+
+ if (!hadPendingChanges) {
+ if (session.hasPendingChanges()) {
+ hadPendingChanges = true;
+ installLog.addMessage(LOG, "Path " + path + " introduced pending changes to the session");
+ }
+ }
+
+ }
+
+ // When using actions, it often happens that the second entry produced (with the rep:glob '*/jcr:content*') is a duplicate
+ // Also without this, a potential effective duplicate in config would be detected as change of incremental run when it is
+ // really not since jackrabbit ignores adding a duplicate entry to ACL
+ private Set filterDuplicates(Set aceBeanSetFromConfig, Session session)
+ throws UnsupportedRepositoryOperationException, RepositoryException {
+
+ LinkedHashSet filteredAceBeans = new LinkedHashSet(aceBeanSetFromConfig);
+ Iterator aceBeansIt = filteredAceBeans.iterator();
+ Set aceCompareKeysToAvoidDuplicates = new HashSet();
+ while (aceBeansIt.hasNext()) {
+ String aceCompareKey = toAceCompareString(aceBeansIt.next(), session.getAccessControlManager());
+ if (aceCompareKeysToAvoidDuplicates.contains(aceCompareKey)) {
+ aceBeansIt.remove();
+ } else {
+ aceCompareKeysToAvoidDuplicates.add(aceCompareKey);
+ }
+
+ }
+ return filteredAceBeans;
+ }
+
+ private Set filterInitialContentOnlyNodes(Set aceBeanSetFromConfig) {
+ Set aceBeanSetNoInitialContentOnlyNodes = new LinkedHashSet();
+ for (AceBean aceBean : aceBeanSetFromConfig) {
+ if (!aceBean.isInitialContentOnlyConfig()) {
+ aceBeanSetNoInitialContentOnlyNodes.add(aceBean);
+ }
+
+ }
+ return aceBeanSetNoInitialContentOnlyNodes;
+ }
+
+ // to be overwritten in JUnit Test
+ protected JackrabbitAccessControlList getAccessControlList(AccessControlManager acMgr, String path) throws RepositoryException {
+ JackrabbitAccessControlList acl = AccessControlUtils.getModifiableAcl(acMgr, path);
+ return acl;
+ }
+
+ private Set transformActionsIntoPrivileges(Set aceBeanSetFromConfig, Session session,
+ InstallationLogger installLog) throws RepositoryException {
+
+
+ Set aceBeanSetWithPrivilegesOnly = new LinkedHashSet();
+ for (AceBean origAceBean : aceBeanSetFromConfig) {
+ if (origAceBean.getActionMap().isEmpty()) {
+ aceBeanSetWithPrivilegesOnly.add(origAceBean);
+ continue;
+ }
+
+ Set aceBeansForActionEntry = getPrincipalAceBeansForActionAceBeanCached(origAceBean, session, installLog);
+ for (AceBean aceBeanResolvedFromAction : aceBeansForActionEntry) {
+ aceBeanSetWithPrivilegesOnly.add(aceBeanResolvedFromAction);
+ }
+ }
+
+ return aceBeanSetWithPrivilegesOnly;
+ }
+
+ private Set getPrincipalAceBeansForActionAceBeanCached(AceBean origAceBean, Session session,
+ InstallationLogger installLog) throws RepositoryException {
+
+ String cacheKey = (definesContent(origAceBean.getJcrPathForPolicyApi(), session) ? "definesContent" : "simple")
+ + "-" + origAceBean.getPermission() + "-" + getRestrictionsComparable(origAceBean.getRestrictions()) + "-"
+ + Arrays.toString(origAceBean.getActions());
+
+ if (actionsToPrivilegesMapping.containsKey(cacheKey)) {
+ installLog.incCountActionCacheHit();
+ LOG.trace("Cache hit for key " + cacheKey);
+ Set cachedAceBeansForActions = actionsToPrivilegesMapping.get(cacheKey);
+ Set principalCorrectedAceBeansForActions = new LinkedHashSet();
+ for (AceBean aceBean : cachedAceBeansForActions) {
+ AceBean clone = aceBean.clone();
+ clone.setPrincipalName(origAceBean.getPrincipalName());
+ principalCorrectedAceBeansForActions.add(clone);
+ }
+ return principalCorrectedAceBeansForActions;
+ } else {
+ installLog.incCountActionCacheMiss();
+
+ Set aceBeansForActionEntry = null;
+ Session newSession = slingRepository.loginService(null, null);
+ try {
+ Session relevantSessionToUse;
+ if (newSession.nodeExists(origAceBean.getJcrPath())) {
+ // a new session is needed to ensure no pending changes are introduced (even if there would not be real pending changes
+ // since we add and remove, but session.hasPendingChanges() is true then).
+ // The new session is not saved(), its only function is to produce the action->privileges mapping with the ootb class
+ // CqActions
+ relevantSessionToUse = newSession;
+ } else {
+ // if the path was just only created in this session via initialContent
+ relevantSessionToUse = session;
+ LOG.warn("Reusing main session for path {} since the node was only just created in that session via 'initialContent'",
+ origAceBean.getJcrPath());
+ }
+ aceBeansForActionEntry = getPrincipalAceBeansForActionAceBean(origAceBean, relevantSessionToUse);
+ } finally {
+ newSession.logout();
+ }
+
+ LOG.debug("Adding to cache: {}={}", cacheKey, aceBeansForActionEntry);
+ actionsToPrivilegesMapping.put(cacheKey, aceBeansForActionEntry);
+
+
+ return aceBeansForActionEntry;
+ }
+
+ }
+
+ Set getPrincipalAceBeansForActionAceBean(AceBean origAceBean, Session session) throws RepositoryException {
+
+ Set aceBeansForActionEntry = new LinkedHashSet();
+
+ Principal testActionMapperPrincipal = getTestActionMapperPrincipal();
+ applyCqActions(origAceBean, session, testActionMapperPrincipal);
+
+ JackrabbitAccessControlList newAcl = getAccessControlList(session.getAccessControlManager(), origAceBean.getJcrPathForPolicyApi());
+
+ boolean isFirst = true;
+ for (AccessControlEntry newAce : newAcl.getAccessControlEntries()) {
+ if (!newAce.getPrincipal().equals(testActionMapperPrincipal)) {
+ continue;
+ }
+
+ AceBean privilegesAceBeanForAction = AcHelper.getAceBean(newAce, newAcl);
+ privilegesAceBeanForAction.setPrincipalName(origAceBean.getPrincipalName());
+
+ // handle restrictions
+ if (isFirst) {
+ if (origAceBean.containsRestriction(AceBean.RESTRICTION_NAME_GLOB)
+ && privilegesAceBeanForAction.containsRestriction(AceBean.RESTRICTION_NAME_GLOB)) {
+ throw new IllegalArgumentException(
+ "When using actions that produce rep:glob restrictions (e.g. for page paths), rep:glob cannot be configured (origAceBean="
+ + origAceBean.getRestrictions() + ", privilegesAceBeanForAction="
+ + privilegesAceBeanForAction.getRestrictions() + "), check configuration for "
+ + origAceBean);
+ } else {
+ // other restrictions are just taken over
+ privilegesAceBeanForAction.getRestrictions().addAll(origAceBean.getRestrictions());
+ }
+ }
+
+ aceBeansForActionEntry.add(privilegesAceBeanForAction);
+
+ // remove the fake entry again
+ newAcl.removeAccessControlEntry(newAce);
+ isFirst = false;
+ }
+ AccessControlManager acMgr = session.getAccessControlManager();
+ acMgr.setPolicy(origAceBean.getJcrPath(), newAcl);
+
+ // handle privileges
+ AceBean firstMappedBean = aceBeansForActionEntry.iterator().next(); // apply additional privileges only to first bean
+ Set newPrivilegesFirstMappedBean = new LinkedHashSet();
+ // first add regular privileges
+ if (firstMappedBean.getPrivileges() != null) {
+ newPrivilegesFirstMappedBean.addAll(Arrays.asList(firstMappedBean.getPrivileges()));
+ }
+ Set flatSetPrincipalsOfFirstMappedBean = flatSetResolvedAggregates(firstMappedBean.getPrivileges(), acMgr, true);
+ if (origAceBean.getPrivileges() != null) {
+ for (String origBeanPrivString : origAceBean.getPrivileges()) {
+ if (!flatSetPrincipalsOfFirstMappedBean.contains(origBeanPrivString)) {
+ newPrivilegesFirstMappedBean.add(origBeanPrivString);
+ }
+ }
+ }
+ firstMappedBean.setPrivilegesString(StringUtils.join(newPrivilegesFirstMappedBean, ","));
+
+ if (LOG.isDebugEnabled()) {
+ StringBuilder buf = new StringBuilder();
+ buf.append("CqActions at path " + origAceBean.getJcrPath()
+ + " with authorizableId=" + origAceBean.getAuthorizableId() + "/" + testActionMapperPrincipal.getName() + " produced \n");
+ for (AceBean aceBean : aceBeansForActionEntry) {
+ buf.append(" " + toAceCompareString(aceBean, acMgr) + "\n");
+ }
+ LOG.debug(buf.toString());
+ }
+
+ return aceBeansForActionEntry;
+
+ }
+
+ Principal getTestActionMapperPrincipal() {
+ String groupPrincipalId = "actool-tester-action-mapper"; // does not have to exist since the ACEs for it are not saved
+ Principal principal = new PrincipalImpl(groupPrincipalId);
+ return principal;
+ }
+
+ void applyCqActions(AceBean origAceBean, Session session, Principal principal) throws RepositoryException {
+
+ if (origAceBean.getActionMap().isEmpty()) {
+ return;
+ }
+
+ AcToolCqActions cqActions = new AcToolCqActions(session);
+ Collection inheritedAllows = cqActions.getAllowedActions(origAceBean.getJcrPathForPolicyApi(),
+ Collections.singleton(principal));
+ // this does always install new entries
+ cqActions.installActions(origAceBean.getJcrPath(), principal, origAceBean.getActionMap(), inheritedAllows);
+
+ }
+
+ private Set flatSetResolvedAggregates(String[] privNames, AccessControlManager acMgr, boolean includeAggregates)
+ throws RepositoryException {
+ if (privNames == null) {
+ return Collections.emptySet();
+ }
+ final Set privileges = new HashSet();
+ for (final String name : privNames) {
+ final Privilege p = acMgr.privilegeFromName(name);
+ if (!p.isAggregate() || includeAggregates) {
+ privileges.add(p.getName());
+ }
+ if (p.isAggregate()) { // add "sub privileges" as well
+ for (Privilege subPriv : p.getDeclaredAggregatePrivileges()) {
+ Set subPrivileges = flatSetResolvedAggregates(new String[] { subPriv.getName() }, acMgr, includeAggregates);
+ privileges.addAll(subPrivileges);
+ }
+ }
+ }
+ return privileges;
+ }
+
+ boolean definesContent(String pagePath, Session session) throws RepositoryException {
+ if (pagePath == null || pagePath.equals("/")) {
+ return false;
+ }
+ try {
+ return AcToolCqActions.definesContent(session.getNode(pagePath));
+ } catch (PathNotFoundException e) {
+ return false;
+ }
+
+ }
+
+ private String toAceCompareString(AceBean aceBean, AccessControlManager acMgr) throws RepositoryException {
+ if (aceBean == null) {
+ return "null";
+ }
+
+ List restrictionsSorted = getRestrictionsComparable(aceBean.getRestrictions());
+
+ String nonAggregatePrivsNormalized = privilegesToComparableSet(aceBean.getPrivileges(), acMgr);
+
+ String aceCompareStr = aceBean.getPrincipalName() + " " + aceBean.getPermission() + " " + nonAggregatePrivsNormalized
+ + Arrays.toString(restrictionsSorted.toArray());
+ return aceCompareStr;
+ }
+
+ private List getRestrictionsComparable(List restrictions) {
+ List restrictionsSorted = new ArrayList(restrictions);
+ Collections.sort(restrictionsSorted, new Comparator() {
+
+ @Override
+ public int compare(Restriction r1, Restriction r2) {
+ return Collator.getInstance().compare(r1.getName(), r2.getName());
+ }
+ });
+ return restrictionsSorted;
+ }
+
+ String privilegesToComparableSet(String[] privileges, AccessControlManager acMgr) throws RepositoryException {
+ return new TreeSet(flatSetResolvedAggregates(privileges, acMgr, false)).toString();
+ }
+
+
+
+
+}
diff --git a/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/aceinstaller/BaseAceBeanInstaller.java b/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/aceinstaller/BaseAceBeanInstaller.java
index fa230dd87..d39d629d8 100644
--- a/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/aceinstaller/BaseAceBeanInstaller.java
+++ b/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/aceinstaller/BaseAceBeanInstaller.java
@@ -1,208 +1,213 @@
-/*
- * (C) Copyright 2016 Netcentric AG.
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- */
-package biz.netcentric.cq.tools.actool.aceinstaller;
-
-import static biz.netcentric.cq.tools.actool.history.impl.PersistableInstallationLogger.msHumanReadable;
-
-import java.security.Principal;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.TreeSet;
-
-import javax.jcr.RepositoryException;
-import javax.jcr.Session;
-import javax.jcr.UnsupportedRepositoryOperationException;
-import javax.jcr.ValueFormatException;
-import javax.jcr.security.AccessControlManager;
-import javax.jcr.security.Privilege;
-
-import org.apache.commons.lang3.time.StopWatch;
-import org.apache.jackrabbit.api.security.JackrabbitAccessControlList;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import biz.netcentric.cq.tools.actool.comparators.AcePermissionComparator;
-import biz.netcentric.cq.tools.actool.configmodel.AcConfiguration;
-import biz.netcentric.cq.tools.actool.configmodel.AceBean;
-import biz.netcentric.cq.tools.actool.configmodel.Restriction;
-import biz.netcentric.cq.tools.actool.helper.AccessControlUtils;
-import biz.netcentric.cq.tools.actool.helper.ContentHelper;
-import biz.netcentric.cq.tools.actool.helper.RestrictionsHolder;
-import biz.netcentric.cq.tools.actool.helper.runtime.RuntimeHelper;
-import biz.netcentric.cq.tools.actool.history.InstallationLogger;
-
-/** Base Class */
-public abstract class BaseAceBeanInstaller implements AceBeanInstaller {
-
- private static final Logger LOG = LoggerFactory.getLogger(BaseAceBeanInstaller.class);
-
- @Override
- public void installPathBasedACEs(
- final Map> pathBasedAceMapFromConfig,
- final AcConfiguration acConfiguration,
- final Session session,
- final InstallationLogger history, Set principalsToRemoveAcesFor) throws Exception {
-
- StopWatch stopWatch = new StopWatch();
- stopWatch.start();
-
- Set paths = pathBasedAceMapFromConfig.keySet();
-
- history.addVerboseMessage(LOG, "Found " + paths.size() + " paths in config");
- LOG.trace("Paths with ACEs: {}", paths);
-
- paths = filterReadOnlyPaths(paths, history, session);
-
- // loop through all nodes from config
- for (final String path : paths) {
-
- final Set aceBeanSetFromConfig = pathBasedAceMapFromConfig
- .get(path); // Set which holds the AceBeans of the current path in configuration
-
- // check if the path even exists
- final boolean pathExits = AccessControlUtils.getModifiableAcl(session.getAccessControlManager(), path) != null;
- if (!pathExits) {
- if (!ContentHelper.createInitialContent(session, history, path, aceBeanSetFromConfig)) {
- history.addVerboseMessage(LOG, "Skipped installing privileges/actions for non existing path: " + path);
- history.incCountAclsPathDoesNotExist();
- continue;
- }
- }
-
- // order entries (denies in front of allows)
- final Set orderedAceBeanSetFromConfig = new TreeSet(
- new AcePermissionComparator());
- orderedAceBeanSetFromConfig.addAll(aceBeanSetFromConfig);
-
- Set principalsToRemoveAcesForAtThisPath = acConfiguration.getAuthorizablesConfig()
- .removeUnmanagedPrincipalNamesAtPath(path, principalsToRemoveAcesFor,
- acConfiguration.getGlobalConfiguration().getDefaultUnmanagedAcePathsRegex());
- installAcl(orderedAceBeanSetFromConfig, path, principalsToRemoveAcesForAtThisPath, session, history);
-
- }
-
- if (history.getMissingParentPathsForInitialContent() > 0) {
- history.addWarning(LOG, "There were " + history.getMissingParentPathsForInitialContent()
- + " parent paths missing for creation of initial content (those paths were skipped, see verbose log for details)");
- }
-
- history.addMessage(LOG, "ACL Update Statistics: Changed=" + history.getCountAclsChanged() + " Unchanged=" + history.getCountAclsUnchanged()
- + " Path not found=" + history.getCountAclsPathDoesNotExist() + " (action cache hit/miss="
- + history.getCountActionCacheHit() + "/" + history.getCountActionCacheMiss() + ")");
- history.addMessage(LOG, "*** Finished installation of " + paths.size() + " ACLs in "
- + msHumanReadable(stopWatch.getTime()));
- }
-
- private Set filterReadOnlyPaths(Set paths, InstallationLogger history, Session session) {
-
- boolean isCompositeNodeStore = RuntimeHelper.isCompositeNodeStore(session);
- if (isCompositeNodeStore) {
- Set pathsToKeep = new TreeSet();
- Set readOnlyPaths = new TreeSet();
- for (final String path : paths) {
- if (path != null && (path.startsWith("/apps") || path.startsWith("/libs"))) {
- readOnlyPaths.add(path);
- } else {
- pathsToKeep.add(path);
- }
- }
- history.addMessage(LOG, "Ignoring " + readOnlyPaths.size() + " ACLs in /apps and /libs because they are ready-only (Composite NodeStore)");
- return pathsToKeep;
- } else {
- return paths;
- }
- }
-
- /** Installs a full set of ACE beans that form an ACL for the path
- *
- * @throws RepositoryException */
- protected abstract void installAcl(Set aceBeanSetFromConfig, String path, Set authorizablesToRemoveAcesFor,
- Session session, InstallationLogger history) throws RepositoryException;
-
-
- protected boolean installPrivileges(AceBean aceBean, Principal principal, JackrabbitAccessControlList acl, Session session,
- AccessControlManager acMgr)
- throws RepositoryException {
-
- final Set privileges = getPrivilegeSet(aceBean.getPrivileges(), acMgr);
- if (!privileges.isEmpty()) {
- final RestrictionsHolder restrictions = getRestrictions(aceBean, session, acl);
- if (!restrictions.isEmpty()) {
- acl.addEntry(principal, privileges
- .toArray(new Privilege[privileges.size()]), aceBean.isAllow(),
- restrictions.getSingleValuedRestrictionsMap(), restrictions.getMultiValuedRestrictionsMap());
- } else {
- acl.addEntry(principal, privileges
- .toArray(new Privilege[privileges.size()]), aceBean.isAllow());
- }
- return true;
- }
- return false;
- }
-
- /** Creates a RestrictionHolder object containing 2 restriction maps being used in
- * {@link JackrabbitAccessControlList#addEntry(Principal, Privilege[], boolean, Map, Map)} out of the set actions on this bean.
- *
- * @param session the session
- * @param acl the access control list for which this restriction map should be used
- * @return RestrictionMapsHolder containing 2 maps with restriction names as keys and restriction values as values
- * (singleValuedRestrictionsMap) and values[] (multiValuedRestrictionsMap).
- * @throws ValueFormatException
- * @throws UnsupportedRepositoryOperationException
- * @throws RepositoryException */
- protected RestrictionsHolder getRestrictions(AceBean aceBean, Session session, JackrabbitAccessControlList acl)
- throws ValueFormatException, UnsupportedRepositoryOperationException, RepositoryException {
-
- final Collection supportedRestrictionNames = Arrays.asList(acl.getRestrictionNames());
-
- if (aceBean.getRestrictions().isEmpty()) {
- return RestrictionsHolder.empty();
- }
-
- List restrictions = aceBean.getRestrictions();
- for (Restriction restriction : restrictions) {
- if (!supportedRestrictionNames.contains(restriction.getName())) {
- throw new IllegalStateException(
- "The AccessControlList at " + acl.getPath() + " does not support setting " + restriction.getName()
- + " restrictions!");
- }
- }
-
- RestrictionsHolder restrictionsHolder = new RestrictionsHolder(restrictions, session.getValueFactory(), acl);
- return restrictionsHolder;
- }
-
- /** Converts the given privilege names into a set of privilege objects.
- *
- * @param privNames (may be {@code null}
- * @param acMgr
- * @return a set of privileges (never {@code null}, but may be empty set)
- * @throws RepositoryException */
- public Set getPrivilegeSet(String[] privNames, AccessControlManager acMgr) throws RepositoryException {
- if (privNames == null) {
- return Collections.emptySet();
- }
- final Set privileges = new HashSet(privNames.length);
- for (final String name : privNames) {
- final Privilege p = acMgr.privilegeFromName(name);
- if (p.isAggregate()) {
- privileges.addAll(Arrays.asList(p.getAggregatePrivileges()));
- } else {
- privileges.add(p);
- }
- }
- return privileges;
- }
-
-}
+package biz.netcentric.cq.tools.actool.aceinstaller;
+
+/*-
+ * #%L
+ * Access Control Tool Bundle
+ * %%
+ * Copyright (C) 2015 - 2024 Cognizant Netcentric
+ * %%
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * #L%
+ */
+
+import static biz.netcentric.cq.tools.actool.history.impl.PersistableInstallationLogger.msHumanReadable;
+
+import java.security.Principal;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeSet;
+
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import javax.jcr.UnsupportedRepositoryOperationException;
+import javax.jcr.ValueFormatException;
+import javax.jcr.security.AccessControlManager;
+import javax.jcr.security.Privilege;
+
+import org.apache.commons.lang3.time.StopWatch;
+import org.apache.jackrabbit.api.security.JackrabbitAccessControlList;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import biz.netcentric.cq.tools.actool.comparators.AcePermissionComparator;
+import biz.netcentric.cq.tools.actool.configmodel.AcConfiguration;
+import biz.netcentric.cq.tools.actool.configmodel.AceBean;
+import biz.netcentric.cq.tools.actool.configmodel.Restriction;
+import biz.netcentric.cq.tools.actool.helper.AccessControlUtils;
+import biz.netcentric.cq.tools.actool.helper.ContentHelper;
+import biz.netcentric.cq.tools.actool.helper.RestrictionsHolder;
+import biz.netcentric.cq.tools.actool.helper.runtime.RuntimeHelper;
+import biz.netcentric.cq.tools.actool.history.InstallationLogger;
+
+/** Base Class */
+public abstract class BaseAceBeanInstaller implements AceBeanInstaller {
+
+ private static final Logger LOG = LoggerFactory.getLogger(BaseAceBeanInstaller.class);
+
+ @Override
+ public void installPathBasedACEs(
+ final Map> pathBasedAceMapFromConfig,
+ final AcConfiguration acConfiguration,
+ final Session session,
+ final InstallationLogger history, Set principalsToRemoveAcesFor) throws Exception {
+
+ StopWatch stopWatch = new StopWatch();
+ stopWatch.start();
+
+ Set paths = pathBasedAceMapFromConfig.keySet();
+
+ history.addVerboseMessage(LOG, "Found " + paths.size() + " paths in config");
+ LOG.trace("Paths with ACEs: {}", paths);
+
+ paths = filterReadOnlyPaths(paths, history, session);
+
+ // loop through all nodes from config
+ for (final String path : paths) {
+
+ final Set aceBeanSetFromConfig = pathBasedAceMapFromConfig
+ .get(path); // Set which holds the AceBeans of the current path in configuration
+
+ // check if the path even exists
+ final boolean pathExits = AccessControlUtils.getModifiableAcl(session.getAccessControlManager(), path) != null;
+ if (!pathExits) {
+ if (!ContentHelper.createInitialContent(session, history, path, aceBeanSetFromConfig)) {
+ history.addVerboseMessage(LOG, "Skipped installing privileges/actions for non existing path: " + path);
+ history.incCountAclsPathDoesNotExist();
+ continue;
+ }
+ }
+
+ // order entries (denies in front of allows)
+ final Set orderedAceBeanSetFromConfig = new TreeSet(
+ new AcePermissionComparator());
+ orderedAceBeanSetFromConfig.addAll(aceBeanSetFromConfig);
+
+ Set principalsToRemoveAcesForAtThisPath = acConfiguration.getAuthorizablesConfig()
+ .removeUnmanagedPrincipalNamesAtPath(path, principalsToRemoveAcesFor,
+ acConfiguration.getGlobalConfiguration().getDefaultUnmanagedAcePathsRegex());
+ installAcl(orderedAceBeanSetFromConfig, path, principalsToRemoveAcesForAtThisPath, session, history);
+
+ }
+
+ if (history.getMissingParentPathsForInitialContent() > 0) {
+ history.addWarning(LOG, "There were " + history.getMissingParentPathsForInitialContent()
+ + " parent paths missing for creation of initial content (those paths were skipped, see verbose log for details)");
+ }
+
+ history.addMessage(LOG, "ACL Update Statistics: Changed=" + history.getCountAclsChanged() + " Unchanged=" + history.getCountAclsUnchanged()
+ + " Path not found=" + history.getCountAclsPathDoesNotExist() + " (action cache hit/miss="
+ + history.getCountActionCacheHit() + "/" + history.getCountActionCacheMiss() + ")");
+ history.addMessage(LOG, "*** Finished installation of " + paths.size() + " ACLs in "
+ + msHumanReadable(stopWatch.getTime()));
+ }
+
+ private Set filterReadOnlyPaths(Set paths, InstallationLogger history, Session session) {
+
+ boolean isCompositeNodeStore = RuntimeHelper.isCompositeNodeStore(session);
+ if (isCompositeNodeStore) {
+ Set pathsToKeep = new TreeSet();
+ Set readOnlyPaths = new TreeSet();
+ for (final String path : paths) {
+ if (path != null && (path.startsWith("/apps") || path.startsWith("/libs"))) {
+ readOnlyPaths.add(path);
+ } else {
+ pathsToKeep.add(path);
+ }
+ }
+ history.addMessage(LOG, "Ignoring " + readOnlyPaths.size() + " ACLs in /apps and /libs because they are ready-only (Composite NodeStore)");
+ return pathsToKeep;
+ } else {
+ return paths;
+ }
+ }
+
+ /** Installs a full set of ACE beans that form an ACL for the path
+ *
+ * @throws RepositoryException */
+ protected abstract void installAcl(Set aceBeanSetFromConfig, String path, Set authorizablesToRemoveAcesFor,
+ Session session, InstallationLogger history) throws RepositoryException;
+
+
+ protected boolean installPrivileges(AceBean aceBean, Principal principal, JackrabbitAccessControlList acl, Session session,
+ AccessControlManager acMgr)
+ throws RepositoryException {
+
+ final Set privileges = getPrivilegeSet(aceBean.getPrivileges(), acMgr);
+ if (!privileges.isEmpty()) {
+ final RestrictionsHolder restrictions = getRestrictions(aceBean, session, acl);
+ if (!restrictions.isEmpty()) {
+ acl.addEntry(principal, privileges
+ .toArray(new Privilege[privileges.size()]), aceBean.isAllow(),
+ restrictions.getSingleValuedRestrictionsMap(), restrictions.getMultiValuedRestrictionsMap());
+ } else {
+ acl.addEntry(principal, privileges
+ .toArray(new Privilege[privileges.size()]), aceBean.isAllow());
+ }
+ return true;
+ }
+ return false;
+ }
+
+ /** Creates a RestrictionHolder object containing 2 restriction maps being used in
+ * {@link JackrabbitAccessControlList#addEntry(Principal, Privilege[], boolean, Map, Map)} out of the set actions on this bean.
+ *
+ * @param session the session
+ * @param acl the access control list for which this restriction map should be used
+ * @return RestrictionMapsHolder containing 2 maps with restriction names as keys and restriction values as values
+ * (singleValuedRestrictionsMap) and values[] (multiValuedRestrictionsMap).
+ * @throws ValueFormatException
+ * @throws UnsupportedRepositoryOperationException
+ * @throws RepositoryException */
+ protected RestrictionsHolder getRestrictions(AceBean aceBean, Session session, JackrabbitAccessControlList acl)
+ throws ValueFormatException, UnsupportedRepositoryOperationException, RepositoryException {
+
+ final Collection supportedRestrictionNames = Arrays.asList(acl.getRestrictionNames());
+
+ if (aceBean.getRestrictions().isEmpty()) {
+ return RestrictionsHolder.empty();
+ }
+
+ List restrictions = aceBean.getRestrictions();
+ for (Restriction restriction : restrictions) {
+ if (!supportedRestrictionNames.contains(restriction.getName())) {
+ throw new IllegalStateException(
+ "The AccessControlList at " + acl.getPath() + " does not support setting " + restriction.getName()
+ + " restrictions!");
+ }
+ }
+
+ RestrictionsHolder restrictionsHolder = new RestrictionsHolder(restrictions, session.getValueFactory(), acl);
+ return restrictionsHolder;
+ }
+
+ /** Converts the given privilege names into a set of privilege objects.
+ *
+ * @param privNames (may be {@code null}
+ * @param acMgr
+ * @return a set of privileges (never {@code null}, but may be empty set)
+ * @throws RepositoryException */
+ public Set getPrivilegeSet(String[] privNames, AccessControlManager acMgr) throws RepositoryException {
+ if (privNames == null) {
+ return Collections.emptySet();
+ }
+ final Set privileges = new HashSet(privNames.length);
+ for (final String name : privNames) {
+ final Privilege p = acMgr.privilegeFromName(name);
+ if (p.isAggregate()) {
+ privileges.addAll(Arrays.asList(p.getAggregatePrivileges()));
+ } else {
+ privileges.add(p);
+ }
+ }
+ return privileges;
+ }
+
+}
diff --git a/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/aem/AcToolCqActions.java b/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/aem/AcToolCqActions.java
index 31407f777..3491e80d6 100644
--- a/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/aem/AcToolCqActions.java
+++ b/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/aem/AcToolCqActions.java
@@ -1,5 +1,18 @@
package biz.netcentric.cq.tools.actool.aem;
+/*-
+ * #%L
+ * Access Control Tool Bundle
+ * %%
+ * Copyright (C) 2015 - 2024 Cognizant Netcentric
+ * %%
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * #L%
+ */
+
import java.security.AccessControlException;
import java.security.Principal;
import java.util.Arrays;
@@ -239,4 +252,4 @@ private static Set getPrivilegeSet(String[] privNames, AccessControlM
}
return privileges;
}
-}
\ No newline at end of file
+}
diff --git a/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/aem/AemCryptoDecryptionService.java b/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/aem/AemCryptoDecryptionService.java
index 7e5e60253..e0a2730eb 100644
--- a/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/aem/AemCryptoDecryptionService.java
+++ b/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/aem/AemCryptoDecryptionService.java
@@ -1,47 +1,52 @@
-/*
- * (C) Copyright 2019 Netcentric AG.
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- */
-package biz.netcentric.cq.tools.actool.aem;
-
-import org.osgi.framework.Constants;
-import org.osgi.service.component.annotations.Component;
-import org.osgi.service.component.annotations.Reference;
-import org.osgi.service.component.annotations.ReferencePolicyOption;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.adobe.granite.crypto.CryptoException;
-import com.adobe.granite.crypto.CryptoSupport;
-
-import biz.netcentric.cq.tools.actool.crypto.DecryptionService;
-
-@Component(property = Constants.SERVICE_RANKING + ":Integer=1000")
-public class AemCryptoDecryptionService implements DecryptionService {
-
- private static final Logger LOG = LoggerFactory.getLogger(AemCryptoDecryptionService.class);
-
- @Reference(policyOption = ReferencePolicyOption.GREEDY)
- private CryptoSupport cryptoSupport;
-
- @Override
- public String decrypt(String text) {
- if (!cryptoSupport.isProtected(text)) {
- LOG.debug("Given text is not encrypted and therefore doesn't need decryption: {}", text);
- return text;
- }
- String abbreviatedPasswordHint = text.substring(0, 4)+"..";
- try {
- String unprotected = cryptoSupport.unprotect(text);
- LOG.debug("Decrypted {} to text with {} chars", abbreviatedPasswordHint, unprotected.length());
- return unprotected;
- } catch (CryptoException e) {
- throw new IllegalArgumentException("Invalid password string starting with '"+abbreviatedPasswordHint+"' (cannot be decrypted)", e);
- }
- }
-
-}
+package biz.netcentric.cq.tools.actool.aem;
+
+/*-
+ * #%L
+ * Access Control Tool Bundle
+ * %%
+ * Copyright (C) 2015 - 2024 Cognizant Netcentric
+ * %%
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * #L%
+ */
+
+import org.osgi.framework.Constants;
+import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.Reference;
+import org.osgi.service.component.annotations.ReferencePolicyOption;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.adobe.granite.crypto.CryptoException;
+import com.adobe.granite.crypto.CryptoSupport;
+
+import biz.netcentric.cq.tools.actool.crypto.DecryptionService;
+
+@Component(property = Constants.SERVICE_RANKING + ":Integer=1000")
+public class AemCryptoDecryptionService implements DecryptionService {
+
+ private static final Logger LOG = LoggerFactory.getLogger(AemCryptoDecryptionService.class);
+
+ @Reference(policyOption = ReferencePolicyOption.GREEDY)
+ private CryptoSupport cryptoSupport;
+
+ @Override
+ public String decrypt(String text) {
+ if (!cryptoSupport.isProtected(text)) {
+ LOG.debug("Given text is not encrypted and therefore doesn't need decryption: {}", text);
+ return text;
+ }
+ String abbreviatedPasswordHint = text.substring(0, 4)+"..";
+ try {
+ String unprotected = cryptoSupport.unprotect(text);
+ LOG.debug("Decrypted {} to text with {} chars", abbreviatedPasswordHint, unprotected.length());
+ return unprotected;
+ } catch (CryptoException e) {
+ throw new IllegalArgumentException("Invalid password string starting with '"+abbreviatedPasswordHint+"' (cannot be decrypted)", e);
+ }
+ }
+
+}
diff --git a/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/api/AcInstallationService.java b/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/api/AcInstallationService.java
index 6ebb0f0bb..5599d5ea7 100644
--- a/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/api/AcInstallationService.java
+++ b/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/api/AcInstallationService.java
@@ -1,12 +1,17 @@
-/*
- * (C) Copyright 2017 Netcentric AG.
- *
+package biz.netcentric.cq.tools.actool.api;
+
+/*-
+ * #%L
+ * Access Control Tool Bundle
+ * %%
+ * Copyright (C) 2015 - 2024 Cognizant Netcentric
+ * %%
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
+ * #L%
*/
-package biz.netcentric.cq.tools.actool.api;
import org.osgi.annotation.versioning.ProviderType;
diff --git a/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/api/HistoryEntry.java b/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/api/HistoryEntry.java
index cf6c016e2..52b6b4eb7 100644
--- a/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/api/HistoryEntry.java
+++ b/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/api/HistoryEntry.java
@@ -1,12 +1,17 @@
-/*
- * (C) Copyright 2015 Netcentric AG.
- *
+package biz.netcentric.cq.tools.actool.api;
+
+/*-
+ * #%L
+ * Access Control Tool Bundle
+ * %%
+ * Copyright (C) 2015 - 2024 Cognizant Netcentric
+ * %%
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
+ * #L%
*/
-package biz.netcentric.cq.tools.actool.api;
import java.sql.Timestamp;
diff --git a/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/api/InstallationLog.java b/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/api/InstallationLog.java
index 52e5f173e..361bc7303 100644
--- a/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/api/InstallationLog.java
+++ b/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/api/InstallationLog.java
@@ -1,12 +1,17 @@
-/*
- * (C) Copyright 2017 Netcentric AG.
- *
+package biz.netcentric.cq.tools.actool.api;
+
+/*-
+ * #%L
+ * Access Control Tool Bundle
+ * %%
+ * Copyright (C) 2015 - 2024 Cognizant Netcentric
+ * %%
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
+ * #L%
*/
-package biz.netcentric.cq.tools.actool.api;
import java.util.Set;
@@ -30,4 +35,4 @@ public interface InstallationLog {
Set getMessages();
-}
\ No newline at end of file
+}
diff --git a/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/api/InstallationResult.java b/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/api/InstallationResult.java
index 30d7525c7..d2415f55f 100644
--- a/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/api/InstallationResult.java
+++ b/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/api/InstallationResult.java
@@ -1,5 +1,18 @@
package biz.netcentric.cq.tools.actool.api;
+/*-
+ * #%L
+ * Access Control Tool Bundle
+ * %%
+ * Copyright (C) 2015 - 2024 Cognizant Netcentric
+ * %%
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * #L%
+ */
+
import org.osgi.annotation.versioning.ProviderType;
/**
diff --git a/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/api/package-info.java b/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/api/package-info.java
index 6cc5f09a1..663e04cc9 100644
--- a/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/api/package-info.java
+++ b/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/api/package-info.java
@@ -1,12 +1,17 @@
-/*
- * (C) Copyright 2017 Netcentric AG.
- *
+@Version("3.0.0")
+package biz.netcentric.cq.tools.actool.api;
+
+/*-
+ * #%L
+ * Access Control Tool Bundle
+ * %%
+ * Copyright (C) 2015 - 2024 Cognizant Netcentric
+ * %%
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
+ * #L%
*/
-@Version("3.0.0")
-package biz.netcentric.cq.tools.actool.api;
import org.osgi.annotation.versioning.Version;
diff --git a/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/authorizableinstaller/AuthorizableCreatorException.java b/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/authorizableinstaller/AuthorizableCreatorException.java
index 1e004d8d6..f36116206 100644
--- a/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/authorizableinstaller/AuthorizableCreatorException.java
+++ b/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/authorizableinstaller/AuthorizableCreatorException.java
@@ -1,12 +1,17 @@
-/*
- * (C) Copyright 2015 Netcentric AG.
- *
+package biz.netcentric.cq.tools.actool.authorizableinstaller;
+
+/*-
+ * #%L
+ * Access Control Tool Bundle
+ * %%
+ * Copyright (C) 2015 - 2024 Cognizant Netcentric
+ * %%
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
+ * #L%
*/
-package biz.netcentric.cq.tools.actool.authorizableinstaller;
public class AuthorizableCreatorException extends Exception {
public AuthorizableCreatorException(String message) {
diff --git a/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/authorizableinstaller/AuthorizableInstallerService.java b/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/authorizableinstaller/AuthorizableInstallerService.java
index c126c1a73..4ded2431b 100644
--- a/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/authorizableinstaller/AuthorizableInstallerService.java
+++ b/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/authorizableinstaller/AuthorizableInstallerService.java
@@ -1,12 +1,17 @@
-/*
- * (C) Copyright 2015 Netcentric AG.
- *
+package biz.netcentric.cq.tools.actool.authorizableinstaller;
+
+/*-
+ * #%L
+ * Access Control Tool Bundle
+ * %%
+ * Copyright (C) 2015 - 2024 Cognizant Netcentric
+ * %%
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
+ * #L%
*/
-package biz.netcentric.cq.tools.actool.authorizableinstaller;
import java.io.IOException;
import java.security.GeneralSecurityException;
diff --git a/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/authorizableinstaller/impl/AuthInstallerUserManager.java b/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/authorizableinstaller/impl/AuthInstallerUserManager.java
index 1bf86e704..954c5d60f 100644
--- a/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/authorizableinstaller/impl/AuthInstallerUserManager.java
+++ b/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/authorizableinstaller/impl/AuthInstallerUserManager.java
@@ -1,5 +1,18 @@
package biz.netcentric.cq.tools.actool.authorizableinstaller.impl;
+/*-
+ * #%L
+ * Access Control Tool Bundle
+ * %%
+ * Copyright (C) 2015 - 2024 Cognizant Netcentric
+ * %%
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * #L%
+ */
+
import java.security.Principal;
import java.util.Set;
diff --git a/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/authorizableinstaller/impl/AuthInstallerUserManagerPrefetchingImpl.java b/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/authorizableinstaller/impl/AuthInstallerUserManagerPrefetchingImpl.java
index 7dc3a8564..28a5ee760 100644
--- a/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/authorizableinstaller/impl/AuthInstallerUserManagerPrefetchingImpl.java
+++ b/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/authorizableinstaller/impl/AuthInstallerUserManagerPrefetchingImpl.java
@@ -1,5 +1,18 @@
package biz.netcentric.cq.tools.actool.authorizableinstaller.impl;
+/*-
+ * #%L
+ * Access Control Tool Bundle
+ * %%
+ * Copyright (C) 2015 - 2024 Cognizant Netcentric
+ * %%
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * #L%
+ */
+
import static biz.netcentric.cq.tools.actool.history.impl.PersistableInstallationLogger.msHumanReadable;
import java.security.Principal;
diff --git a/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/authorizableinstaller/impl/AuthorizableInstallerServiceImpl.java b/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/authorizableinstaller/impl/AuthorizableInstallerServiceImpl.java
index 729192d1e..65e2d0635 100644
--- a/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/authorizableinstaller/impl/AuthorizableInstallerServiceImpl.java
+++ b/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/authorizableinstaller/impl/AuthorizableInstallerServiceImpl.java
@@ -1,12 +1,17 @@
-/*
- * (C) Copyright 2015 Netcentric AG.
- *
+package biz.netcentric.cq.tools.actool.authorizableinstaller.impl;
+
+/*-
+ * #%L
+ * Access Control Tool Bundle
+ * %%
+ * Copyright (C) 2015 - 2024 Cognizant Netcentric
+ * %%
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
+ * #L%
*/
-package biz.netcentric.cq.tools.actool.authorizableinstaller.impl;
import static biz.netcentric.cq.tools.actool.helper.Constants.PRINCIPAL_EVERYONE;
diff --git a/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/authorizableinstaller/impl/ExternalGroupInstallerServiceImpl.java b/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/authorizableinstaller/impl/ExternalGroupInstallerServiceImpl.java
index 11d9a04d1..7ec9343b2 100644
--- a/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/authorizableinstaller/impl/ExternalGroupInstallerServiceImpl.java
+++ b/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/authorizableinstaller/impl/ExternalGroupInstallerServiceImpl.java
@@ -1,12 +1,18 @@
-/*
- * (C) Copyright 2017 Netcentric AG.
- *
+
+package biz.netcentric.cq.tools.actool.authorizableinstaller.impl;
+
+/*-
+ * #%L
+ * Access Control Tool Bundle
+ * %%
+ * Copyright (C) 2015 - 2024 Cognizant Netcentric
+ * %%
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
+ * #L%
*/
-package biz.netcentric.cq.tools.actool.authorizableinstaller.impl;
import java.util.Collections;
import java.util.Map;
diff --git a/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/authorizableinstaller/impl/ImpersonationInstallerServiceImpl.java b/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/authorizableinstaller/impl/ImpersonationInstallerServiceImpl.java
index 9858ec73f..828bfc639 100644
--- a/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/authorizableinstaller/impl/ImpersonationInstallerServiceImpl.java
+++ b/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/authorizableinstaller/impl/ImpersonationInstallerServiceImpl.java
@@ -1,12 +1,18 @@
-/*
- * (C) Copyright 2017 Netcentric AG.
- *
+
+package biz.netcentric.cq.tools.actool.authorizableinstaller.impl;
+
+/*-
+ * #%L
+ * Access Control Tool Bundle
+ * %%
+ * Copyright (C) 2015 - 2024 Cognizant Netcentric
+ * %%
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
+ * #L%
*/
-package biz.netcentric.cq.tools.actool.authorizableinstaller.impl;
import java.util.ArrayList;
import java.util.Iterator;
diff --git a/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/comparators/AcePathComparator.java b/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/comparators/AcePathComparator.java
index 0d3329dd5..f6995b18b 100644
--- a/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/comparators/AcePathComparator.java
+++ b/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/comparators/AcePathComparator.java
@@ -1,12 +1,17 @@
-/*
- * (C) Copyright 2015 Netcentric AG.
- *
+package biz.netcentric.cq.tools.actool.comparators;
+
+/*-
+ * #%L
+ * Access Control Tool Bundle
+ * %%
+ * Copyright (C) 2015 - 2024 Cognizant Netcentric
+ * %%
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
+ * #L%
*/
-package biz.netcentric.cq.tools.actool.comparators;
import java.util.Comparator;
diff --git a/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/comparators/AcePermissionComparator.java b/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/comparators/AcePermissionComparator.java
index 1ac8acf9c..5d4479e9f 100644
--- a/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/comparators/AcePermissionComparator.java
+++ b/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/comparators/AcePermissionComparator.java
@@ -1,12 +1,17 @@
-/*
- * (C) Copyright 2015 Netcentric AG.
- *
+package biz.netcentric.cq.tools.actool.comparators;
+
+/*-
+ * #%L
+ * Access Control Tool Bundle
+ * %%
+ * Copyright (C) 2015 - 2024 Cognizant Netcentric
+ * %%
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
+ * #L%
*/
-package biz.netcentric.cq.tools.actool.comparators;
import java.util.Comparator;
diff --git a/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/comparators/AuthorizableBeanIDComparator.java b/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/comparators/AuthorizableBeanIDComparator.java
index 1ce4c04e4..30c319ef3 100644
--- a/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/comparators/AuthorizableBeanIDComparator.java
+++ b/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/comparators/AuthorizableBeanIDComparator.java
@@ -1,12 +1,17 @@
-/*
- * (C) Copyright 2015 Netcentric AG.
- *
+package biz.netcentric.cq.tools.actool.comparators;
+
+/*-
+ * #%L
+ * Access Control Tool Bundle
+ * %%
+ * Copyright (C) 2015 - 2024 Cognizant Netcentric
+ * %%
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
+ * #L%
*/
-package biz.netcentric.cq.tools.actool.comparators;
import java.util.Comparator;
diff --git a/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/comparators/HistoryEntryComparator.java b/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/comparators/HistoryEntryComparator.java
index 1144d4d21..851525c38 100644
--- a/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/comparators/HistoryEntryComparator.java
+++ b/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/comparators/HistoryEntryComparator.java
@@ -1,12 +1,17 @@
-/*
- * (C) Copyright 2015 Netcentric AG.
- *
+package biz.netcentric.cq.tools.actool.comparators;
+
+/*-
+ * #%L
+ * Access Control Tool Bundle
+ * %%
+ * Copyright (C) 2015 - 2024 Cognizant Netcentric
+ * %%
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
+ * #L%
*/
-package biz.netcentric.cq.tools.actool.comparators;
import java.util.Comparator;
diff --git a/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/comparators/JcrCreatedComparator.java b/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/comparators/JcrCreatedComparator.java
index e002f7c7e..46fd51d0e 100644
--- a/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/comparators/JcrCreatedComparator.java
+++ b/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/comparators/JcrCreatedComparator.java
@@ -1,12 +1,17 @@
-/*
- * (C) Copyright 2015 Netcentric AG.
- *
+package biz.netcentric.cq.tools.actool.comparators;
+
+/*-
+ * #%L
+ * Access Control Tool Bundle
+ * %%
+ * Copyright (C) 2015 - 2024 Cognizant Netcentric
+ * %%
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
+ * #L%
*/
-package biz.netcentric.cq.tools.actool.comparators;
import java.util.Calendar;
import java.util.Comparator;
diff --git a/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/comparators/NodeCreatedComparator.java b/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/comparators/NodeCreatedComparator.java
index 69166f9a5..337a18244 100644
--- a/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/comparators/NodeCreatedComparator.java
+++ b/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/comparators/NodeCreatedComparator.java
@@ -1,12 +1,17 @@
-/*
- * (C) Copyright 2015 Netcentric AG.
- *
+package biz.netcentric.cq.tools.actool.comparators;
+
+/*-
+ * #%L
+ * Access Control Tool Bundle
+ * %%
+ * Copyright (C) 2015 - 2024 Cognizant Netcentric
+ * %%
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
+ * #L%
*/
-package biz.netcentric.cq.tools.actool.comparators;
import java.util.Calendar;
import java.util.Comparator;
diff --git a/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/comparators/TimestampPropertyComparator.java b/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/comparators/TimestampPropertyComparator.java
index 2f6f3afd6..f690a9ce0 100644
--- a/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/comparators/TimestampPropertyComparator.java
+++ b/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/comparators/TimestampPropertyComparator.java
@@ -1,12 +1,17 @@
-/*
- * (C) Copyright 2015 Netcentric AG.
- *
+package biz.netcentric.cq.tools.actool.comparators;
+
+/*-
+ * #%L
+ * Access Control Tool Bundle
+ * %%
+ * Copyright (C) 2015 - 2024 Cognizant Netcentric
+ * %%
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
+ * #L%
*/
-package biz.netcentric.cq.tools.actool.comparators;
import java.util.Comparator;
diff --git a/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/configmodel/AcConfiguration.java b/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/configmodel/AcConfiguration.java
index 8c8780171..7f11fa4b0 100644
--- a/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/configmodel/AcConfiguration.java
+++ b/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/configmodel/AcConfiguration.java
@@ -1,12 +1,17 @@
-/*
- * (C) Copyright 2016 Netcentric AG.
- *
+package biz.netcentric.cq.tools.actool.configmodel;
+
+/*-
+ * #%L
+ * Access Control Tool Bundle
+ * %%
+ * Copyright (C) 2015 - 2024 Cognizant Netcentric
+ * %%
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
+ * #L%
*/
-package biz.netcentric.cq.tools.actool.configmodel;
import java.util.ArrayList;
import java.util.HashSet;
diff --git a/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/configmodel/AceBean.java b/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/configmodel/AceBean.java
index 1629504e8..00c195e25 100644
--- a/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/configmodel/AceBean.java
+++ b/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/configmodel/AceBean.java
@@ -1,12 +1,17 @@
-/*
- * (C) Copyright 2015 Netcentric AG.
- *
+package biz.netcentric.cq.tools.actool.configmodel;
+
+/*-
+ * #%L
+ * Access Control Tool Bundle
+ * %%
+ * Copyright (C) 2015 - 2024 Cognizant Netcentric
+ * %%
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
+ * #L%
*/
-package biz.netcentric.cq.tools.actool.configmodel;
import java.security.Principal;
import java.util.ArrayList;
diff --git a/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/configmodel/AcesConfig.java b/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/configmodel/AcesConfig.java
index af7cda12e..40c60f28f 100644
--- a/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/configmodel/AcesConfig.java
+++ b/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/configmodel/AcesConfig.java
@@ -1,12 +1,18 @@
-/*
- * (C) Copyright 2017 Netcentric AG.
- *
+
+package biz.netcentric.cq.tools.actool.configmodel;
+
+/*-
+ * #%L
+ * Access Control Tool Bundle
+ * %%
+ * Copyright (C) 2015 - 2024 Cognizant Netcentric
+ * %%
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
+ * #L%
*/
-package biz.netcentric.cq.tools.actool.configmodel;
import java.util.LinkedHashSet;
import java.util.Set;
diff --git a/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/configmodel/AuthorizableConfigBean.java b/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/configmodel/AuthorizableConfigBean.java
index 742a6aa95..67e683598 100644
--- a/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/configmodel/AuthorizableConfigBean.java
+++ b/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/configmodel/AuthorizableConfigBean.java
@@ -1,12 +1,17 @@
-/*
- * (C) Copyright 2015 Netcentric AG.
- *
+package biz.netcentric.cq.tools.actool.configmodel;
+
+/*-
+ * #%L
+ * Access Control Tool Bundle
+ * %%
+ * Copyright (C) 2015 - 2024 Cognizant Netcentric
+ * %%
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
+ * #L%
*/
-package biz.netcentric.cq.tools.actool.configmodel;
import java.util.ArrayList;
import java.util.Arrays;
diff --git a/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/configmodel/AuthorizablesConfig.java b/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/configmodel/AuthorizablesConfig.java
index d1d938c3f..86d4c7dce 100644
--- a/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/configmodel/AuthorizablesConfig.java
+++ b/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/configmodel/AuthorizablesConfig.java
@@ -1,12 +1,18 @@
-/*
- * (C) Copyright 2017 Netcentric AG.
- *
+
+package biz.netcentric.cq.tools.actool.configmodel;
+
+/*-
+ * #%L
+ * Access Control Tool Bundle
+ * %%
+ * Copyright (C) 2015 - 2024 Cognizant Netcentric
+ * %%
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
+ * #L%
*/
-package biz.netcentric.cq.tools.actool.configmodel;
import java.util.HashMap;
import java.util.HashSet;
diff --git a/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/configmodel/AutoCreateTestUsersConfig.java b/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/configmodel/AutoCreateTestUsersConfig.java
index 5a92a53f0..c88ee17da 100644
--- a/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/configmodel/AutoCreateTestUsersConfig.java
+++ b/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/configmodel/AutoCreateTestUsersConfig.java
@@ -1,12 +1,17 @@
-/*
- * (C) Copyright 2018 Netcentric AG.
- *
+package biz.netcentric.cq.tools.actool.configmodel;
+
+/*-
+ * #%L
+ * Access Control Tool Bundle
+ * %%
+ * Copyright (C) 2015 - 2024 Cognizant Netcentric
+ * %%
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
+ * #L%
*/
-package biz.netcentric.cq.tools.actool.configmodel;
import java.util.Arrays;
import java.util.List;
diff --git a/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/configmodel/GlobalConfiguration.java b/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/configmodel/GlobalConfiguration.java
index 555c8ee1f..9015d2be0 100644
--- a/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/configmodel/GlobalConfiguration.java
+++ b/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/configmodel/GlobalConfiguration.java
@@ -1,12 +1,17 @@
-/*
- * (C) Copyright 2016 Netcentric AG.
- *
+package biz.netcentric.cq.tools.actool.configmodel;
+
+/*-
+ * #%L
+ * Access Control Tool Bundle
+ * %%
+ * Copyright (C) 2015 - 2024 Cognizant Netcentric
+ * %%
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
+ * #L%
*/
-package biz.netcentric.cq.tools.actool.configmodel;
import java.util.Map;
import java.util.regex.Pattern;
diff --git a/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/configmodel/Restriction.java b/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/configmodel/Restriction.java
index f7f84382c..61af2691b 100644
--- a/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/configmodel/Restriction.java
+++ b/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/configmodel/Restriction.java
@@ -1,5 +1,18 @@
package biz.netcentric.cq.tools.actool.configmodel;
+/*-
+ * #%L
+ * Access Control Tool Bundle
+ * %%
+ * Copyright (C) 2015 - 2024 Cognizant Netcentric
+ * %%
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * #L%
+ */
+
import java.util.Arrays;
import java.util.List;
diff --git a/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/configmodel/pkcs/BouncycastlePkcs8EncryptedPrivateKeyDecryptor.java b/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/configmodel/pkcs/BouncycastlePkcs8EncryptedPrivateKeyDecryptor.java
index f1216ed6b..2dadb9058 100644
--- a/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/configmodel/pkcs/BouncycastlePkcs8EncryptedPrivateKeyDecryptor.java
+++ b/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/configmodel/pkcs/BouncycastlePkcs8EncryptedPrivateKeyDecryptor.java
@@ -1,5 +1,18 @@
package biz.netcentric.cq.tools.actool.configmodel.pkcs;
+/*-
+ * #%L
+ * Access Control Tool Bundle
+ * %%
+ * Copyright (C) 2015 - 2024 Cognizant Netcentric
+ * %%
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * #L%
+ */
+
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.security.InvalidKeyException;
diff --git a/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/configmodel/pkcs/DerData.java b/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/configmodel/pkcs/DerData.java
index 3f7be8864..5cba0fd59 100644
--- a/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/configmodel/pkcs/DerData.java
+++ b/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/configmodel/pkcs/DerData.java
@@ -1,5 +1,18 @@
package biz.netcentric.cq.tools.actool.configmodel.pkcs;
+/*-
+ * #%L
+ * Access Control Tool Bundle
+ * %%
+ * Copyright (C) 2015 - 2024 Cognizant Netcentric
+ * %%
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * #L%
+ */
+
import java.security.InvalidKeyException;
import java.util.regex.Pattern;
diff --git a/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/configmodel/pkcs/DerType.java b/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/configmodel/pkcs/DerType.java
index 72e7ddeff..aa263c16d 100644
--- a/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/configmodel/pkcs/DerType.java
+++ b/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/configmodel/pkcs/DerType.java
@@ -1,5 +1,18 @@
package biz.netcentric.cq.tools.actool.configmodel.pkcs;
+/*-
+ * #%L
+ * Access Control Tool Bundle
+ * %%
+ * Copyright (C) 2015 - 2024 Cognizant Netcentric
+ * %%
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * #L%
+ */
+
import java.util.regex.Matcher;
import java.util.regex.Pattern;
diff --git a/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/configmodel/pkcs/JcaPkcs8EncryptedPrivateKeyDecryptor.java b/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/configmodel/pkcs/JcaPkcs8EncryptedPrivateKeyDecryptor.java
index cd6aaa7c0..4e197cb50 100644
--- a/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/configmodel/pkcs/JcaPkcs8EncryptedPrivateKeyDecryptor.java
+++ b/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/configmodel/pkcs/JcaPkcs8EncryptedPrivateKeyDecryptor.java
@@ -1,5 +1,18 @@
package biz.netcentric.cq.tools.actool.configmodel.pkcs;
+/*-
+ * #%L
+ * Access Control Tool Bundle
+ * %%
+ * Copyright (C) 2015 - 2024 Cognizant Netcentric
+ * %%
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * #L%
+ */
+
import java.io.IOException;
import java.security.AlgorithmParameters;
import java.security.GeneralSecurityException;
diff --git a/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/configmodel/pkcs/Key.java b/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/configmodel/pkcs/Key.java
index 1f9750d92..4abc016be 100644
--- a/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/configmodel/pkcs/Key.java
+++ b/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/configmodel/pkcs/Key.java
@@ -1,5 +1,18 @@
package biz.netcentric.cq.tools.actool.configmodel.pkcs;
+/*-
+ * #%L
+ * Access Control Tool Bundle
+ * %%
+ * Copyright (C) 2015 - 2024 Cognizant Netcentric
+ * %%
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * #L%
+ */
+
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
diff --git a/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/configmodel/pkcs/PrivateKeyDecryptor.java b/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/configmodel/pkcs/PrivateKeyDecryptor.java
index b850f5a20..f24b6e323 100644
--- a/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/configmodel/pkcs/PrivateKeyDecryptor.java
+++ b/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/configmodel/pkcs/PrivateKeyDecryptor.java
@@ -1,5 +1,18 @@
package biz.netcentric.cq.tools.actool.configmodel.pkcs;
+/*-
+ * #%L
+ * Access Control Tool Bundle
+ * %%
+ * Copyright (C) 2015 - 2024 Cognizant Netcentric
+ * %%
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * #L%
+ */
+
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.security.KeyFactory;
diff --git a/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/configmodel/pkcs/RandomPassword.java b/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/configmodel/pkcs/RandomPassword.java
index 0e20beddf..a559cab0a 100644
--- a/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/configmodel/pkcs/RandomPassword.java
+++ b/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/configmodel/pkcs/RandomPassword.java
@@ -1,5 +1,18 @@
package biz.netcentric.cq.tools.actool.configmodel.pkcs;
+/*-
+ * #%L
+ * Access Control Tool Bundle
+ * %%
+ * Copyright (C) 2015 - 2024 Cognizant Netcentric
+ * %%
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * #L%
+ */
+
import java.security.SecureRandom;
import java.util.Random;
diff --git a/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/configreader/ConfigFilesRetriever.java b/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/configreader/ConfigFilesRetriever.java
index 59102bbda..c3a597dd5 100644
--- a/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/configreader/ConfigFilesRetriever.java
+++ b/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/configreader/ConfigFilesRetriever.java
@@ -1,5 +1,18 @@
package biz.netcentric.cq.tools.actool.configreader;
+/*-
+ * #%L
+ * Access Control Tool Bundle
+ * %%
+ * Copyright (C) 2015 - 2024 Cognizant Netcentric
+ * %%
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * #L%
+ */
+
import java.util.Collection;
import java.util.Map;
diff --git a/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/configreader/ConfigFilesRetrieverImpl.java b/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/configreader/ConfigFilesRetrieverImpl.java
index 5150d2f28..9539d79d2 100644
--- a/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/configreader/ConfigFilesRetrieverImpl.java
+++ b/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/configreader/ConfigFilesRetrieverImpl.java
@@ -1,5 +1,18 @@
package biz.netcentric.cq.tools.actool.configreader;
+/*-
+ * #%L
+ * Access Control Tool Bundle
+ * %%
+ * Copyright (C) 2015 - 2024 Cognizant Netcentric
+ * %%
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * #L%
+ */
+
import java.io.InputStream;
import java.io.StringWriter;
import java.util.Collection;
diff --git a/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/configreader/ConfigReader.java b/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/configreader/ConfigReader.java
index 0c6d235b6..8ef391ed0 100644
--- a/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/configreader/ConfigReader.java
+++ b/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/configreader/ConfigReader.java
@@ -1,44 +1,49 @@
-/*
- * (C) Copyright 2015 Netcentric AG.
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- */
-package biz.netcentric.cq.tools.actool.configreader;
-
-import java.util.Collection;
-import java.util.Set;
-
-import javax.jcr.RepositoryException;
-import javax.jcr.Session;
-
-import biz.netcentric.cq.tools.actool.configmodel.AcesConfig;
-import biz.netcentric.cq.tools.actool.configmodel.AuthorizablesConfig;
-import biz.netcentric.cq.tools.actool.configmodel.GlobalConfiguration;
-import biz.netcentric.cq.tools.actool.validators.AceBeanValidator;
-import biz.netcentric.cq.tools.actool.validators.AuthorizableValidator;
-import biz.netcentric.cq.tools.actool.validators.exceptions.AcConfigBeanValidationException;
-
-public interface ConfigReader {
-
- public AcesConfig getAceConfigurationBeans(
- final Collection> aceConfigData, AceBeanValidator aceBeanValidator, Session session, String sourceFile) throws RepositoryException,
- AcConfigBeanValidationException;
-
- public AuthorizablesConfig getGroupConfigurationBeans(
- final Collection> groupConfigData,
- AuthorizableValidator authorizableValidator)
- throws AcConfigBeanValidationException;
-
- public AuthorizablesConfig getUserConfigurationBeans(
- final Collection> userConfigData,
- AuthorizableValidator authorizableValidator)
- throws AcConfigBeanValidationException;
-
- public GlobalConfiguration getGlobalConfiguration(final Collection yamlList);
-
- public Set getObsoluteAuthorizables(Collection yamlList);
-
-}
\ No newline at end of file
+package biz.netcentric.cq.tools.actool.configreader;
+
+/*-
+ * #%L
+ * Access Control Tool Bundle
+ * %%
+ * Copyright (C) 2015 - 2024 Cognizant Netcentric
+ * %%
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * #L%
+ */
+
+import java.util.Collection;
+import java.util.Set;
+
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+
+import biz.netcentric.cq.tools.actool.configmodel.AcesConfig;
+import biz.netcentric.cq.tools.actool.configmodel.AuthorizablesConfig;
+import biz.netcentric.cq.tools.actool.configmodel.GlobalConfiguration;
+import biz.netcentric.cq.tools.actool.validators.AceBeanValidator;
+import biz.netcentric.cq.tools.actool.validators.AuthorizableValidator;
+import biz.netcentric.cq.tools.actool.validators.exceptions.AcConfigBeanValidationException;
+
+public interface ConfigReader {
+
+ public AcesConfig getAceConfigurationBeans(
+ final Collection> aceConfigData, AceBeanValidator aceBeanValidator, Session session, String sourceFile) throws RepositoryException,
+ AcConfigBeanValidationException;
+
+ public AuthorizablesConfig getGroupConfigurationBeans(
+ final Collection> groupConfigData,
+ AuthorizableValidator authorizableValidator)
+ throws AcConfigBeanValidationException;
+
+ public AuthorizablesConfig getUserConfigurationBeans(
+ final Collection> userConfigData,
+ AuthorizableValidator authorizableValidator)
+ throws AcConfigBeanValidationException;
+
+ public GlobalConfiguration getGlobalConfiguration(final Collection yamlList);
+
+ public Set getObsoluteAuthorizables(Collection yamlList);
+
+}
diff --git a/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/configreader/ConfigurationMerger.java b/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/configreader/ConfigurationMerger.java
index 7f6ec66d7..90bd4479e 100644
--- a/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/configreader/ConfigurationMerger.java
+++ b/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/configreader/ConfigurationMerger.java
@@ -1,38 +1,43 @@
-/*
- * (C) Copyright 2015 Netcentric AG.
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- */
-package biz.netcentric.cq.tools.actool.configreader;
-
-import java.util.Map;
-
-import javax.jcr.RepositoryException;
-import javax.jcr.Session;
-
-import biz.netcentric.cq.tools.actool.configmodel.AcConfiguration;
-import biz.netcentric.cq.tools.actool.history.impl.PersistableInstallationLogger;
-import biz.netcentric.cq.tools.actool.validators.exceptions.AcConfigBeanValidationException;
-
-public interface ConfigurationMerger {
-
- /** Method that merges several textual AccessControlConfigurations written in YAML format, each comprising of a groups and ACE
- * configuration. Validation ensures that no doubled defined groups and only valid section identifiers in configuration files are
- * possible
- *
- * @param newestConfigurations map which contains all paths and configuration in YAML format. key is the node path in CRX under which
- * the respective configuration is stored, entry is the textual configuration
- * @param installationLog
- * @return The AcConfiguration
- * @throws RepositoryException in case some repository error has occurred
- * @throws AcConfigBeanValidationException in case the given configuration is invalid */
- public abstract AcConfiguration getMergedConfigurations(
- final Map newestConfigurations,
- final PersistableInstallationLogger installationLog,
- final ConfigReader configReader, Session session) throws RepositoryException,
- AcConfigBeanValidationException;
-
-}
\ No newline at end of file
+package biz.netcentric.cq.tools.actool.configreader;
+
+/*-
+ * #%L
+ * Access Control Tool Bundle
+ * %%
+ * Copyright (C) 2015 - 2024 Cognizant Netcentric
+ * %%
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * #L%
+ */
+
+import java.util.Map;
+
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+
+import biz.netcentric.cq.tools.actool.configmodel.AcConfiguration;
+import biz.netcentric.cq.tools.actool.history.impl.PersistableInstallationLogger;
+import biz.netcentric.cq.tools.actool.validators.exceptions.AcConfigBeanValidationException;
+
+public interface ConfigurationMerger {
+
+ /** Method that merges several textual AccessControlConfigurations written in YAML format, each comprising of a groups and ACE
+ * configuration. Validation ensures that no doubled defined groups and only valid section identifiers in configuration files are
+ * possible
+ *
+ * @param newestConfigurations map which contains all paths and configuration in YAML format. key is the node path in CRX under which
+ * the respective configuration is stored, entry is the textual configuration
+ * @param installationLog
+ * @return The AcConfiguration
+ * @throws RepositoryException in case some repository error has occurred
+ * @throws AcConfigBeanValidationException in case the given configuration is invalid */
+ public abstract AcConfiguration getMergedConfigurations(
+ final Map newestConfigurations,
+ final PersistableInstallationLogger installationLog,
+ final ConfigReader configReader, Session session) throws RepositoryException,
+ AcConfigBeanValidationException;
+
+}
diff --git a/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/configreader/TestUserConfigsCreator.java b/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/configreader/TestUserConfigsCreator.java
index be623e338..56db10a73 100644
--- a/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/configreader/TestUserConfigsCreator.java
+++ b/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/configreader/TestUserConfigsCreator.java
@@ -1,141 +1,147 @@
-/*
- * (C) Copyright 2017 Netcentric AG.
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- */
-package biz.netcentric.cq.tools.actool.configreader;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.commons.collections4.CollectionUtils;
-import org.apache.commons.lang3.StringUtils;
-import org.osgi.service.component.annotations.Component;
-import org.osgi.service.component.annotations.Reference;
-import org.osgi.service.component.annotations.ReferencePolicyOption;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import biz.netcentric.cq.tools.actool.configmodel.AcConfiguration;
-import biz.netcentric.cq.tools.actool.configmodel.AuthorizableConfigBean;
-import biz.netcentric.cq.tools.actool.configmodel.AuthorizablesConfig;
-import biz.netcentric.cq.tools.actool.configmodel.AutoCreateTestUsersConfig;
-import biz.netcentric.cq.tools.actool.configmodel.GlobalConfiguration;
-import biz.netcentric.cq.tools.actool.crypto.DecryptionService;
-import biz.netcentric.cq.tools.actool.history.InstallationLogger;
-import biz.netcentric.cq.tools.actool.slingsettings.ExtendedSlingSettingsService;
-
-@Component(service=TestUserConfigsCreator.class)
-public class TestUserConfigsCreator {
-
- private static final Logger LOG = LoggerFactory.getLogger(TestUserConfigsCreator.class);
-
- @Reference(policyOption = ReferencePolicyOption.GREEDY)
- ExtendedSlingSettingsService slingSettingsService;
-
- @Reference(policyOption = ReferencePolicyOption.GREEDY)
- DecryptionService decryptionService;
-
- YamlMacroElEvaluator elEvaluator = null;
-
- public boolean isSkippedForRunmode(List skipForRunmodes) {
- return slingSettingsService != null && !CollectionUtils.intersection(slingSettingsService.getRunModes(), skipForRunmodes).isEmpty();
- }
-
- void createTestUserConfigs(AcConfiguration acConfiguration, InstallationLogger logger) {
-
- AutoCreateTestUsersConfig autoCreateTestUsersConf = acConfiguration.getGlobalConfiguration().getAutoCreateTestUsersConfig();
- if (autoCreateTestUsersConf == null) {
- return;
- }
-
- if (isSkippedForRunmode(autoCreateTestUsersConf.getSkipForRunmodes())) {
- return;
- }
-
- List testUserConfigBeansToAdd = new ArrayList<>();
- AuthorizablesConfig authorizablesConfig = acConfiguration.getAuthorizablesConfig();
- for (AuthorizableConfigBean groupAuthConfigBean : authorizablesConfig) {
- if(!groupAuthConfigBean.isGroup()) {
- continue;
- }
- String groupId = groupAuthConfigBean.getAuthorizableId();
- if (groupId.matches(autoCreateTestUsersConf.getCreateForGroupNamesRegEx())) {
-
- Map vars = getVarsForAuthConfigBean(groupAuthConfigBean);
-
- AuthorizableConfigBean testUserConfigBean = new AuthorizableConfigBean();
- testUserConfigBean.setIsGroup(false);
- String testUserAuthId = autoCreateTestUsersConf.getPrefix() + groupId;
- testUserConfigBean.setAuthorizableId(testUserAuthId);
- testUserConfigBean.setPath(autoCreateTestUsersConf.getPath());
- testUserConfigBean.setIsMemberOf(new String[] { groupId });
-
- String name = StringUtils.defaultIfEmpty(autoCreateTestUsersConf.getName(), "Test User %{group.name}");
- testUserConfigBean.setName(processValue(name, vars));
-
- if(StringUtils.isNotBlank(autoCreateTestUsersConf.getEmail())) {
- testUserConfigBean.setEmail(processValue(autoCreateTestUsersConf.getEmail(), vars));
- }
- if(StringUtils.isNotBlank(autoCreateTestUsersConf.getDescription())) {
- testUserConfigBean.setDescription(processValue(autoCreateTestUsersConf.getDescription(), vars));
- }
-
- String password = autoCreateTestUsersConf.getPassword();
- if(StringUtils.isNotBlank(password)) {
- password = processValue(password, vars); // allow for pws ala "pw%{group.id}"
- } else {
- password = testUserAuthId;
- }
-
- try {
- password = decryptionService.decrypt(password);
- } catch (UnsupportedOperationException e) {
- throw new IllegalArgumentException("Could not unprotect password " + password + " as given in "
- + GlobalConfiguration.KEY_AUTOCREATE_TEST_USERS);
- }
- testUserConfigBean.setPassword(password);
-
- testUserConfigBeansToAdd.add(testUserConfigBean);
- }
- }
-
- authorizablesConfig.addAll(testUserConfigBeansToAdd);
-
- logger.addMessage(LOG,
- "Created " + testUserConfigBeansToAdd.size() + " test user configs at path " + autoCreateTestUsersConf.getPath()
- + " (for groups matching " + autoCreateTestUsersConf.getCreateForGroupNamesRegEx() + ")");
-
- }
-
- Map getVarsForAuthConfigBean(AuthorizableConfigBean groupAuthConfigBean) {
- Map vars = new HashMap<>();
- Map groupVar = new HashMap<>();
- String groupId = groupAuthConfigBean.getAuthorizableId();
- groupVar.put("id", groupId);
- groupVar.put("name", StringUtils.defaultIfEmpty(groupAuthConfigBean.getName(), groupId));
- groupVar.put("path", groupAuthConfigBean.getPath());
- vars.put("group", groupVar);
- return vars;
- }
-
- String processValue(String value, Map extends Object, ? extends Object> variables) {
-
- String elWithDollarExpressions = value.replaceAll("%\\{([^\\}]+)\\}", "\\${$1}");
- if(elEvaluator==null) {
- elEvaluator = new YamlMacroElEvaluator();
- }
-
- String interpolatedValue = elEvaluator.evaluateEl(elWithDollarExpressions, String.class, variables);
-
- return interpolatedValue;
- }
-
-
-
-}
+
+package biz.netcentric.cq.tools.actool.configreader;
+
+/*-
+ * #%L
+ * Access Control Tool Bundle
+ * %%
+ * Copyright (C) 2015 - 2024 Cognizant Netcentric
+ * %%
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * #L%
+ */
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.Reference;
+import org.osgi.service.component.annotations.ReferencePolicyOption;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import biz.netcentric.cq.tools.actool.configmodel.AcConfiguration;
+import biz.netcentric.cq.tools.actool.configmodel.AuthorizableConfigBean;
+import biz.netcentric.cq.tools.actool.configmodel.AuthorizablesConfig;
+import biz.netcentric.cq.tools.actool.configmodel.AutoCreateTestUsersConfig;
+import biz.netcentric.cq.tools.actool.configmodel.GlobalConfiguration;
+import biz.netcentric.cq.tools.actool.crypto.DecryptionService;
+import biz.netcentric.cq.tools.actool.history.InstallationLogger;
+import biz.netcentric.cq.tools.actool.slingsettings.ExtendedSlingSettingsService;
+
+@Component(service=TestUserConfigsCreator.class)
+public class TestUserConfigsCreator {
+
+ private static final Logger LOG = LoggerFactory.getLogger(TestUserConfigsCreator.class);
+
+ @Reference(policyOption = ReferencePolicyOption.GREEDY)
+ ExtendedSlingSettingsService slingSettingsService;
+
+ @Reference(policyOption = ReferencePolicyOption.GREEDY)
+ DecryptionService decryptionService;
+
+ YamlMacroElEvaluator elEvaluator = null;
+
+ public boolean isSkippedForRunmode(List skipForRunmodes) {
+ return slingSettingsService != null && !CollectionUtils.intersection(slingSettingsService.getRunModes(), skipForRunmodes).isEmpty();
+ }
+
+ void createTestUserConfigs(AcConfiguration acConfiguration, InstallationLogger logger) {
+
+ AutoCreateTestUsersConfig autoCreateTestUsersConf = acConfiguration.getGlobalConfiguration().getAutoCreateTestUsersConfig();
+ if (autoCreateTestUsersConf == null) {
+ return;
+ }
+
+ if (isSkippedForRunmode(autoCreateTestUsersConf.getSkipForRunmodes())) {
+ return;
+ }
+
+ List testUserConfigBeansToAdd = new ArrayList<>();
+ AuthorizablesConfig authorizablesConfig = acConfiguration.getAuthorizablesConfig();
+ for (AuthorizableConfigBean groupAuthConfigBean : authorizablesConfig) {
+ if(!groupAuthConfigBean.isGroup()) {
+ continue;
+ }
+ String groupId = groupAuthConfigBean.getAuthorizableId();
+ if (groupId.matches(autoCreateTestUsersConf.getCreateForGroupNamesRegEx())) {
+
+ Map vars = getVarsForAuthConfigBean(groupAuthConfigBean);
+
+ AuthorizableConfigBean testUserConfigBean = new AuthorizableConfigBean();
+ testUserConfigBean.setIsGroup(false);
+ String testUserAuthId = autoCreateTestUsersConf.getPrefix() + groupId;
+ testUserConfigBean.setAuthorizableId(testUserAuthId);
+ testUserConfigBean.setPath(autoCreateTestUsersConf.getPath());
+ testUserConfigBean.setIsMemberOf(new String[] { groupId });
+
+ String name = StringUtils.defaultIfEmpty(autoCreateTestUsersConf.getName(), "Test User %{group.name}");
+ testUserConfigBean.setName(processValue(name, vars));
+
+ if(StringUtils.isNotBlank(autoCreateTestUsersConf.getEmail())) {
+ testUserConfigBean.setEmail(processValue(autoCreateTestUsersConf.getEmail(), vars));
+ }
+ if(StringUtils.isNotBlank(autoCreateTestUsersConf.getDescription())) {
+ testUserConfigBean.setDescription(processValue(autoCreateTestUsersConf.getDescription(), vars));
+ }
+
+ String password = autoCreateTestUsersConf.getPassword();
+ if(StringUtils.isNotBlank(password)) {
+ password = processValue(password, vars); // allow for pws ala "pw%{group.id}"
+ } else {
+ password = testUserAuthId;
+ }
+
+ try {
+ password = decryptionService.decrypt(password);
+ } catch (UnsupportedOperationException e) {
+ throw new IllegalArgumentException("Could not unprotect password " + password + " as given in "
+ + GlobalConfiguration.KEY_AUTOCREATE_TEST_USERS);
+ }
+ testUserConfigBean.setPassword(password);
+
+ testUserConfigBeansToAdd.add(testUserConfigBean);
+ }
+ }
+
+ authorizablesConfig.addAll(testUserConfigBeansToAdd);
+
+ logger.addMessage(LOG,
+ "Created " + testUserConfigBeansToAdd.size() + " test user configs at path " + autoCreateTestUsersConf.getPath()
+ + " (for groups matching " + autoCreateTestUsersConf.getCreateForGroupNamesRegEx() + ")");
+
+ }
+
+ Map getVarsForAuthConfigBean(AuthorizableConfigBean groupAuthConfigBean) {
+ Map vars = new HashMap<>();
+ Map groupVar = new HashMap<>();
+ String groupId = groupAuthConfigBean.getAuthorizableId();
+ groupVar.put("id", groupId);
+ groupVar.put("name", StringUtils.defaultIfEmpty(groupAuthConfigBean.getName(), groupId));
+ groupVar.put("path", groupAuthConfigBean.getPath());
+ vars.put("group", groupVar);
+ return vars;
+ }
+
+ String processValue(String value, Map extends Object, ? extends Object> variables) {
+
+ String elWithDollarExpressions = value.replaceAll("%\\{([^\\}]+)\\}", "\\${$1}");
+ if(elEvaluator==null) {
+ elEvaluator = new YamlMacroElEvaluator();
+ }
+
+ String interpolatedValue = elEvaluator.evaluateEl(elWithDollarExpressions, String.class, variables);
+
+ return interpolatedValue;
+ }
+
+
+
+}
diff --git a/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/configreader/VirtualGroupProcessor.java b/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/configreader/VirtualGroupProcessor.java
index 4d7a2a679..69bc629d0 100644
--- a/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/configreader/VirtualGroupProcessor.java
+++ b/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/configreader/VirtualGroupProcessor.java
@@ -1,167 +1,173 @@
-/*
- * (C) Copyright 2017 Netcentric AG.
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- */
-package biz.netcentric.cq.tools.actool.configreader;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Set;
-
-import org.apache.commons.lang3.ArrayUtils;
-import org.apache.commons.lang3.StringUtils;
-import org.osgi.service.component.annotations.Component;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import biz.netcentric.cq.tools.actool.configmodel.AcConfiguration;
-import biz.netcentric.cq.tools.actool.configmodel.AceBean;
-import biz.netcentric.cq.tools.actool.configmodel.AcesConfig;
-import biz.netcentric.cq.tools.actool.configmodel.AuthorizableConfigBean;
-import biz.netcentric.cq.tools.actool.history.InstallationLogger;
-
-@Component(service=VirtualGroupProcessor.class)
-public class VirtualGroupProcessor {
-
- private static final Logger LOG = LoggerFactory.getLogger(VirtualGroupProcessor.class);
-
- void flattenGroupTree(AcConfiguration acConfiguration, InstallationLogger logger) {
-
- List virtualGroups = getVirtualGroups(acConfiguration);
-
- AcesConfig aceConfig = acConfiguration.getAceConfig();
-
- int countAceAdded = 0;
- int countAceRemoved = 0;
-
- for (AuthorizableConfigBean virtualAutBean : virtualGroups) {
-
- logger.addVerboseMessage(LOG, "Authorizable bean " + virtualAutBean.getAuthorizableId() + " is virtual");
-
- if (!ArrayUtils.isEmpty(virtualAutBean.getMembers())) {
- throw new IllegalArgumentException("It is not allowed to define members in virtual groups (offending virtual group: '"
- + virtualAutBean.getAuthorizableId() + "')");
- }
-
- List referencingAuthBeans = getAuthConfigBeansReferencingVirtualGroup(
- virtualAutBean.getAuthorizableId(), acConfiguration);
-
- // fix isMemberOf
- adjustIsMemberOf(logger, virtualAutBean, referencingAuthBeans);
-
- // fix ace beans
- List aceBeansToBeRemoved = new LinkedList();
- List aceBeansToBeAdded = new LinkedList();
- adjustAceBeans(logger, aceConfig, aceBeansToBeRemoved, aceBeansToBeAdded, virtualAutBean,
- referencingAuthBeans);
-
- countAceRemoved += aceBeansToBeRemoved.size();
- aceConfig.removeAll(aceBeansToBeRemoved);
-
- countAceAdded += aceBeansToBeAdded.size();
- aceConfig.addAll(aceBeansToBeAdded);
- }
-
- if (virtualGroups.isEmpty()) {
- return;
- }
-
- acConfiguration.getAuthorizablesConfig().removeAll(virtualGroups);
- acConfiguration.setVirtualGroups(virtualGroups);
- acConfiguration.ensureAceBeansHaveCorrectPrincipalNameSet();
-
- for (AuthorizableConfigBean autBean : acConfiguration.getAuthorizablesConfig()) {
- for (AuthorizableConfigBean virtualGroup : virtualGroups) {
- if (ArrayUtils.contains(autBean.getIsMemberOf(), virtualGroup.getAuthorizableId())) {
- throw new IllegalStateException(
- "Group " + autBean + " in isMemberOf still contains " + virtualGroup.getAuthorizableId());
- }
- }
- }
-
- logger.addMessage(LOG,
- "Processed " + virtualGroups.size() + " virtual groups, replaced " + countAceRemoved
- + " ACEs of virtual groups with " + countAceAdded + " new ACEs in configuration");
-
- }
-
- private List getAuthConfigBeansReferencingVirtualGroup(String virtualGroupAuthId,
- AcConfiguration acConfiguration) {
- List referencingBeans = new ArrayList<>();
- for (AuthorizableConfigBean autBean : acConfiguration.getAuthorizablesConfig()) {
- if (ArrayUtils.contains(autBean.getIsMemberOf(), virtualGroupAuthId)) {
- referencingBeans.add(autBean);
- }
- }
- return referencingBeans;
- }
-
- private void adjustIsMemberOf(InstallationLogger installationLogger,
- AuthorizableConfigBean virtualAutBean, List referencingAuthBeans) {
- String[] isMemberOf = virtualAutBean.getIsMemberOf();
- List isMemberOfOfVirtualGroup = isMemberOf != null ? Arrays.asList(isMemberOf) : Collections. emptyList();
-
- if (referencingAuthBeans == null || referencingAuthBeans.isEmpty()) {
- throw new IllegalArgumentException("Virtual group '" + virtualAutBean.getAuthorizableId()
- + "' is not used in any isMemberOf attribute of other groups, hence it cannot be declared virtual");
- }
-
- for (AuthorizableConfigBean otherAuthBean : referencingAuthBeans) {
- installationLogger.addVerboseMessage(LOG,
- "Virtual Group: " + virtualAutBean.getAuthorizableId() + " - Adding groups " + isMemberOfOfVirtualGroup + " to "
- + otherAuthBean.getAuthorizableId());
- Set adjustedIsMemberOf = new HashSet(Arrays.asList(otherAuthBean.getIsMemberOf()));
- adjustedIsMemberOf.addAll(isMemberOfOfVirtualGroup);
- adjustedIsMemberOf.remove(virtualAutBean.getAuthorizableId());
- otherAuthBean.setIsMemberOf(new ArrayList(adjustedIsMemberOf));
- }
-
- // remove all references as they are moved now
- virtualAutBean.setIsMemberOf(new String[0]);
-
- }
-
- private void adjustAceBeans(InstallationLogger logger, AcesConfig aceConfig, List aceBeansToBeRemoved,
- List aceBeansToBeAdded, AuthorizableConfigBean virtualAutBean, List referencingAuthBeans) {
-
- for (AceBean aceBean : aceConfig) {
-
- if (StringUtils.equals(aceBean.getAuthorizableId(), virtualAutBean.getAuthorizableId())) {
- logger.addVerboseMessage(LOG,
- "ACE at path " + aceBean.getJcrPath() + " for virtual group " + virtualAutBean.getAuthorizableId());
- aceBeansToBeRemoved.add(aceBean);
-
- for (AuthorizableConfigBean newAuthBeanInAcl : referencingAuthBeans) {
- AceBean cloneForAuthConfigBeanUsingIsMemberOf = aceBean.clone();
- cloneForAuthConfigBeanUsingIsMemberOf.setAuthorizableId(newAuthBeanInAcl.getAuthorizableId());
- aceBeansToBeAdded.add(cloneForAuthConfigBeanUsingIsMemberOf);
- logger.addVerboseMessage(LOG, " Adding clone for authorizable id " + newAuthBeanInAcl.getAuthorizableId()
- + " replacing " + aceBean.getAuthorizableId());
-
- }
- }
- }
- }
-
- public List getVirtualGroups(AcConfiguration acConfiguration) {
- List virtualGroups = new ArrayList<>();
- for (AuthorizableConfigBean authBean : acConfiguration.getAuthorizablesConfig()) {
- if (authBean.isVirtual()) {
- if (!authBean.isGroup()) {
- throw new IllegalArgumentException("\"virtual: true\" can only be set on groups, not on users");
- }
- virtualGroups.add(authBean);
- }
- }
- return virtualGroups;
- }
-
-}
+
+package biz.netcentric.cq.tools.actool.configreader;
+
+/*-
+ * #%L
+ * Access Control Tool Bundle
+ * %%
+ * Copyright (C) 2015 - 2024 Cognizant Netcentric
+ * %%
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * #L%
+ */
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.commons.lang3.ArrayUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.osgi.service.component.annotations.Component;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import biz.netcentric.cq.tools.actool.configmodel.AcConfiguration;
+import biz.netcentric.cq.tools.actool.configmodel.AceBean;
+import biz.netcentric.cq.tools.actool.configmodel.AcesConfig;
+import biz.netcentric.cq.tools.actool.configmodel.AuthorizableConfigBean;
+import biz.netcentric.cq.tools.actool.history.InstallationLogger;
+
+@Component(service=VirtualGroupProcessor.class)
+public class VirtualGroupProcessor {
+
+ private static final Logger LOG = LoggerFactory.getLogger(VirtualGroupProcessor.class);
+
+ void flattenGroupTree(AcConfiguration acConfiguration, InstallationLogger logger) {
+
+ List virtualGroups = getVirtualGroups(acConfiguration);
+
+ AcesConfig aceConfig = acConfiguration.getAceConfig();
+
+ int countAceAdded = 0;
+ int countAceRemoved = 0;
+
+ for (AuthorizableConfigBean virtualAutBean : virtualGroups) {
+
+ logger.addVerboseMessage(LOG, "Authorizable bean " + virtualAutBean.getAuthorizableId() + " is virtual");
+
+ if (!ArrayUtils.isEmpty(virtualAutBean.getMembers())) {
+ throw new IllegalArgumentException("It is not allowed to define members in virtual groups (offending virtual group: '"
+ + virtualAutBean.getAuthorizableId() + "')");
+ }
+
+ List referencingAuthBeans = getAuthConfigBeansReferencingVirtualGroup(
+ virtualAutBean.getAuthorizableId(), acConfiguration);
+
+ // fix isMemberOf
+ adjustIsMemberOf(logger, virtualAutBean, referencingAuthBeans);
+
+ // fix ace beans
+ List aceBeansToBeRemoved = new LinkedList();
+ List aceBeansToBeAdded = new LinkedList();
+ adjustAceBeans(logger, aceConfig, aceBeansToBeRemoved, aceBeansToBeAdded, virtualAutBean,
+ referencingAuthBeans);
+
+ countAceRemoved += aceBeansToBeRemoved.size();
+ aceConfig.removeAll(aceBeansToBeRemoved);
+
+ countAceAdded += aceBeansToBeAdded.size();
+ aceConfig.addAll(aceBeansToBeAdded);
+ }
+
+ if (virtualGroups.isEmpty()) {
+ return;
+ }
+
+ acConfiguration.getAuthorizablesConfig().removeAll(virtualGroups);
+ acConfiguration.setVirtualGroups(virtualGroups);
+ acConfiguration.ensureAceBeansHaveCorrectPrincipalNameSet();
+
+ for (AuthorizableConfigBean autBean : acConfiguration.getAuthorizablesConfig()) {
+ for (AuthorizableConfigBean virtualGroup : virtualGroups) {
+ if (ArrayUtils.contains(autBean.getIsMemberOf(), virtualGroup.getAuthorizableId())) {
+ throw new IllegalStateException(
+ "Group " + autBean + " in isMemberOf still contains " + virtualGroup.getAuthorizableId());
+ }
+ }
+ }
+
+ logger.addMessage(LOG,
+ "Processed " + virtualGroups.size() + " virtual groups, replaced " + countAceRemoved
+ + " ACEs of virtual groups with " + countAceAdded + " new ACEs in configuration");
+
+ }
+
+ private List getAuthConfigBeansReferencingVirtualGroup(String virtualGroupAuthId,
+ AcConfiguration acConfiguration) {
+ List referencingBeans = new ArrayList<>();
+ for (AuthorizableConfigBean autBean : acConfiguration.getAuthorizablesConfig()) {
+ if (ArrayUtils.contains(autBean.getIsMemberOf(), virtualGroupAuthId)) {
+ referencingBeans.add(autBean);
+ }
+ }
+ return referencingBeans;
+ }
+
+ private void adjustIsMemberOf(InstallationLogger installationLogger,
+ AuthorizableConfigBean virtualAutBean, List referencingAuthBeans) {
+ String[] isMemberOf = virtualAutBean.getIsMemberOf();
+ List isMemberOfOfVirtualGroup = isMemberOf != null ? Arrays.asList(isMemberOf) : Collections. emptyList();
+
+ if (referencingAuthBeans == null || referencingAuthBeans.isEmpty()) {
+ throw new IllegalArgumentException("Virtual group '" + virtualAutBean.getAuthorizableId()
+ + "' is not used in any isMemberOf attribute of other groups, hence it cannot be declared virtual");
+ }
+
+ for (AuthorizableConfigBean otherAuthBean : referencingAuthBeans) {
+ installationLogger.addVerboseMessage(LOG,
+ "Virtual Group: " + virtualAutBean.getAuthorizableId() + " - Adding groups " + isMemberOfOfVirtualGroup + " to "
+ + otherAuthBean.getAuthorizableId());
+ Set adjustedIsMemberOf = new HashSet(Arrays.asList(otherAuthBean.getIsMemberOf()));
+ adjustedIsMemberOf.addAll(isMemberOfOfVirtualGroup);
+ adjustedIsMemberOf.remove(virtualAutBean.getAuthorizableId());
+ otherAuthBean.setIsMemberOf(new ArrayList(adjustedIsMemberOf));
+ }
+
+ // remove all references as they are moved now
+ virtualAutBean.setIsMemberOf(new String[0]);
+
+ }
+
+ private void adjustAceBeans(InstallationLogger logger, AcesConfig aceConfig, List aceBeansToBeRemoved,
+ List aceBeansToBeAdded, AuthorizableConfigBean virtualAutBean, List referencingAuthBeans) {
+
+ for (AceBean aceBean : aceConfig) {
+
+ if (StringUtils.equals(aceBean.getAuthorizableId(), virtualAutBean.getAuthorizableId())) {
+ logger.addVerboseMessage(LOG,
+ "ACE at path " + aceBean.getJcrPath() + " for virtual group " + virtualAutBean.getAuthorizableId());
+ aceBeansToBeRemoved.add(aceBean);
+
+ for (AuthorizableConfigBean newAuthBeanInAcl : referencingAuthBeans) {
+ AceBean cloneForAuthConfigBeanUsingIsMemberOf = aceBean.clone();
+ cloneForAuthConfigBeanUsingIsMemberOf.setAuthorizableId(newAuthBeanInAcl.getAuthorizableId());
+ aceBeansToBeAdded.add(cloneForAuthConfigBeanUsingIsMemberOf);
+ logger.addVerboseMessage(LOG, " Adding clone for authorizable id " + newAuthBeanInAcl.getAuthorizableId()
+ + " replacing " + aceBean.getAuthorizableId());
+
+ }
+ }
+ }
+ }
+
+ public List getVirtualGroups(AcConfiguration acConfiguration) {
+ List virtualGroups = new ArrayList<>();
+ for (AuthorizableConfigBean authBean : acConfiguration.getAuthorizablesConfig()) {
+ if (authBean.isVirtual()) {
+ if (!authBean.isGroup()) {
+ throw new IllegalArgumentException("\"virtual: true\" can only be set on groups, not on users");
+ }
+ virtualGroups.add(authBean);
+ }
+ }
+ return virtualGroups;
+ }
+
+}
diff --git a/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/configreader/YamlConfigReader.java b/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/configreader/YamlConfigReader.java
index 160d4f9f3..c900a1a7c 100644
--- a/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/configreader/YamlConfigReader.java
+++ b/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/configreader/YamlConfigReader.java
@@ -1,12 +1,17 @@
-/*
- * (C) Copyright 2015 Netcentric AG.
- *
+package biz.netcentric.cq.tools.actool.configreader;
+
+/*-
+ * #%L
+ * Access Control Tool Bundle
+ * %%
+ * Copyright (C) 2015 - 2024 Cognizant Netcentric
+ * %%
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
+ * #L%
*/
-package biz.netcentric.cq.tools.actool.configreader;
import java.io.IOException;
import java.security.GeneralSecurityException;
diff --git a/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/configreader/YamlConfigurationAdminPluginScalarConstructor.java b/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/configreader/YamlConfigurationAdminPluginScalarConstructor.java
index 6e347d370..5704e8afc 100644
--- a/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/configreader/YamlConfigurationAdminPluginScalarConstructor.java
+++ b/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/configreader/YamlConfigurationAdminPluginScalarConstructor.java
@@ -1,5 +1,18 @@
package biz.netcentric.cq.tools.actool.configreader;
+/*-
+ * #%L
+ * Access Control Tool Bundle
+ * %%
+ * Copyright (C) 2015 - 2024 Cognizant Netcentric
+ * %%
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * #L%
+ */
+
import java.util.Dictionary;
import java.util.Hashtable;
diff --git a/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/configreader/YamlConfigurationMerger.java b/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/configreader/YamlConfigurationMerger.java
index 8a293fd74..4935c6632 100644
--- a/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/configreader/YamlConfigurationMerger.java
+++ b/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/configreader/YamlConfigurationMerger.java
@@ -1,291 +1,296 @@
-/*
- * (C) Copyright 2015 Netcentric AG.
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- */
-package biz.netcentric.cq.tools.actool.configreader;
-
-import static biz.netcentric.cq.tools.actool.history.impl.PersistableInstallationLogger.msHumanReadable;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.LinkedHashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.regex.Pattern;
-
-import javax.jcr.RepositoryException;
-import javax.jcr.Session;
-
-import org.osgi.service.cm.ConfigurationPlugin;
-import org.osgi.service.component.annotations.Component;
-import org.osgi.service.component.annotations.Reference;
-import org.osgi.service.component.annotations.ReferenceCardinality;
-import org.osgi.service.component.annotations.ReferencePolicyOption;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.yaml.snakeyaml.Yaml;
-import org.yaml.snakeyaml.error.YAMLException;
-
-import biz.netcentric.cq.tools.actool.configmodel.AcConfiguration;
-import biz.netcentric.cq.tools.actool.configmodel.AceBean;
-import biz.netcentric.cq.tools.actool.configmodel.AcesConfig;
-import biz.netcentric.cq.tools.actool.configmodel.AuthorizableConfigBean;
-import biz.netcentric.cq.tools.actool.configmodel.AuthorizablesConfig;
-import biz.netcentric.cq.tools.actool.configmodel.GlobalConfiguration;
-import biz.netcentric.cq.tools.actool.helper.Constants;
-import biz.netcentric.cq.tools.actool.history.InstallationLogger;
-import biz.netcentric.cq.tools.actool.history.impl.PersistableInstallationLogger;
-import biz.netcentric.cq.tools.actool.slingsettings.ExtendedSlingSettingsService;
-import biz.netcentric.cq.tools.actool.validators.AuthorizableValidator;
-import biz.netcentric.cq.tools.actool.validators.ExternalGroupsInIsMemberOfValidator;
-import biz.netcentric.cq.tools.actool.validators.ConfigurationsValidator;
-import biz.netcentric.cq.tools.actool.validators.GlobalConfigurationValidator;
-import biz.netcentric.cq.tools.actool.validators.ObsoleteAuthorizablesValidator;
-import biz.netcentric.cq.tools.actool.validators.UnmangedExternalMemberRelationshipChecker;
-import biz.netcentric.cq.tools.actool.validators.YamlConfigurationsValidator;
-import biz.netcentric.cq.tools.actool.validators.exceptions.AcConfigBeanValidationException;
-import biz.netcentric.cq.tools.actool.validators.exceptions.NoListOnTopLevelException;
-import biz.netcentric.cq.tools.actool.validators.impl.AceBeanValidatorImpl;
-import biz.netcentric.cq.tools.actool.validators.impl.AuthorizableValidatorImpl;
-
-@Component
-public class YamlConfigurationMerger implements ConfigurationMerger {
-
- private static final Logger LOG = LoggerFactory.getLogger(YamlConfigurationMerger.class);
-
- public static final String GLOBAL_VAR_RUNMODES = "RUNMODES";
-
- @Reference(policyOption = ReferencePolicyOption.GREEDY)
- YamlMacroProcessor yamlMacroProcessor;
-
- @Reference(policyOption = ReferencePolicyOption.GREEDY)
- ObsoleteAuthorizablesValidator obsoleteAuthorizablesValidator;
-
- @Reference(policyOption = ReferencePolicyOption.GREEDY)
- ExternalGroupsInIsMemberOfValidator externalGroupsInIsMemberOfValidator;
-
- @Reference(policyOption = ReferencePolicyOption.GREEDY)
- VirtualGroupProcessor virtualGroupProcessor;
-
- @Reference(policyOption = ReferencePolicyOption.GREEDY)
- TestUserConfigsCreator testUserConfigsCreator;
-
- @Reference(policyOption = ReferencePolicyOption.GREEDY)
- ExtendedSlingSettingsService slingSettingsService;
-
- @Reference(cardinality = ReferenceCardinality.OPTIONAL, policyOption = ReferencePolicyOption.GREEDY, target="(config.plugin.id=org.apache.felix.configadmin.plugin.interpolation)")
- ConfigurationPlugin interpolationPlugin;
-
- /** Regular expression which matches against values which should be interpolated, see https://github.com/apache/felix-dev/blob/master/configadmin-plugins/interpolation/README.md */
- public static final Pattern CONFIG_ADMIN_INTERPOLATOR_FORMAT = Pattern.compile(".*\\$\\[(env|secret|prop):[^\\]]*\\].*");
-
- @Override
- public AcConfiguration getMergedConfigurations(
- final Map configFileContentByFilename,
- final PersistableInstallationLogger installLog,
- final ConfigReader configReader, Session session) throws RepositoryException,
- AcConfigBeanValidationException {
-
- long wholeConfigStart = System.currentTimeMillis();
-
- final GlobalConfiguration globalConfiguration = new GlobalConfiguration();
- final AuthorizablesConfig mergedAuthorizablesBeansfromConfig = new AuthorizablesConfig();
- final AcesConfig mergedAceBeansFromConfig = new AcesConfig();
- final Set authorizableIdsFromAllConfigs = new HashSet(); // needed for detection of doubled defined groups in
- // configurations
- final Set obsoleteAuthorizables = new HashSet();
-
- final Yaml yamlParser;
- if (interpolationPlugin != null) {
- yamlParser = new Yaml(new YamlConfigurationAdminPluginScalarConstructor(installLog, interpolationPlugin));
- // bind constructor to certain scalar formats (compare with https://bitbucket.org/asomov/snakeyaml/src/master/src/test/java/org/yaml/snakeyaml/env/EnvVariableTest.java)
- yamlParser.addImplicitResolver(YamlConfigurationAdminPluginScalarConstructor.TAG, CONFIG_ADMIN_INTERPOLATOR_FORMAT, null);
- installLog.addMessage(LOG, "Using YAML parser with ConfigurationAdmin Plugin placeholder support");
- } else {
- yamlParser = new Yaml();
- }
- final ConfigurationsValidator configurationsValidator = new YamlConfigurationsValidator();
-
- Map globalVariables = getGlobalVariablesForYamlMacroProcessing();
-
- for (final Map.Entry entry : configFileContentByFilename.entrySet()) {
-
- long configFileStart = System.currentTimeMillis();
-
- String sourceFile = entry.getKey();
- installLog.addMessage(LOG, "Using configuration file " + sourceFile);
-
- List