/*
* (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.helper;
import static biz.netcentric.cq.tools.actool.history.AcInstallationLog.msHumanReadable;
import java.util.Iterator;
import java.util.Set;
import javax.jcr.AccessDeniedException;
import javax.jcr.Node;
import javax.jcr.NodeIterator;
import javax.jcr.PathNotFoundException;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.UnsupportedRepositoryOperationException;
import javax.jcr.lock.LockException;
import javax.jcr.query.Query;
import javax.jcr.query.QueryResult;
import javax.jcr.security.AccessControlEntry;
import javax.jcr.security.AccessControlException;
import javax.jcr.security.AccessControlManager;
import javax.jcr.security.AccessControlPolicy;
import javax.jcr.version.VersionException;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.time.StopWatch;
import org.apache.jackrabbit.api.security.JackrabbitAccessControlList;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceResolver;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class PurgeHelper {
public static final Logger LOG = LoggerFactory.getLogger(PurgeHelper.class);
public static String purgeACLs(final Session session, final String path)
throws Exception {
StringBuilder message = new StringBuilder();
if (StringUtils.isNotBlank(path)) {
String queryString = "/jcr:root" + path.trim() + "//rep:policy";
Query query = session.getWorkspace().getQueryManager()
.createQuery(queryString, Query.XPATH);
QueryResult result = query.execute();
NodeIterator nodeIterator = result.getNodes();
AccessControlManager accessManager = session
.getAccessControlManager();
while (nodeIterator.hasNext()) {
Node res = nodeIterator.nextNode().getParent();
if (res != null) {
AccessControlPolicy[] policies = accessManager
.getPolicies(res.getPath());
for (int j = 0; j < policies.length; j++) {
accessManager.removePolicy(res.getPath(), policies[j]);
}
message.append("Removed all policies from node "
+ res.getPath() + ".\n");
}
}
message.append("\n\nCompleted removing ACLs from path: " + path
+ " and it's subpaths!");
}
session.save();
return message.toString();
}
public static void purgeAcl(final Session session, final String path)
throws Exception {
if (StringUtils.isNotBlank(path)) {
AccessControlManager accessManager = session
.getAccessControlManager();
Node node = session.getNode(path);
AccessControlPolicy[] policies = accessManager.getPolicies(node
.getPath());
for (int i = 0; i < policies.length; i++) {
accessManager.removePolicy(node.getPath(), policies[i]);
AcHelper.LOG.info("Removed all policies from node "
+ node.getPath() + ".\n");
}
}
}
public static void purgeACLs(final ResourceResolver resourceResolver,
final String[] paths) throws Exception {
Session session = resourceResolver.adaptTo(Session.class);
for (int i = 0; i < paths.length; i++) {
if (StringUtils.isNotBlank(paths[i])) {
String query = "/jcr:root" + paths[i].trim() + "//rep:policy";
Iterator<Resource> results = resourceResolver.findResources(
query, Query.XPATH);
AccessControlManager accessManager = session
.getAccessControlManager();
while (results.hasNext()) {
Resource res = results.next().getParent();
if (res != null) {
AccessControlPolicy[] policies = accessManager
.getPolicies(res.getPath());
for (int j = 0; j < policies.length; j++) {
accessManager.removePolicy(res.getPath(),
policies[j]);
}
}
}
}
}
session.save();
}
public static String deleteAcesForPrincipalIds(final Session session,
final Set<String> principalIds, final Set<AclBean> aclBeans)
throws UnsupportedRepositoryOperationException,
RepositoryException, AccessControlException, PathNotFoundException,
AccessDeniedException, LockException, VersionException {
StopWatch sw = new StopWatch();
sw.start();
StringBuilder message = new StringBuilder();
AccessControlManager aMgr = session.getAccessControlManager();
long aceCounter = 0;
for (AclBean aclBean : aclBeans) {
if (aclBean == null) {
continue;
}
JackrabbitAccessControlList acl = aclBean.getAcl();
for (AccessControlEntry ace : acl.getAccessControlEntries()) {
String principalId = ace.getPrincipal().getName();
if (principalIds.contains(principalId)) {
String parentNodePath = aclBean.getParentPath();
acl.removeAccessControlEntry(ace);
boolean aclEmpty = acl.isEmpty();
if (!aclEmpty) {
aMgr.setPolicy(aclBean.getParentPath(), acl);
} else {
aMgr.removePolicy(aclBean.getParentPath(), acl);
}
String msg = "Path " + parentNodePath + ": Removed entry for '" + principalId + "' from ACL "
+ (aclEmpty ? " (and the now emtpy ACL itself)" : "");
LOG.info(msg);
message.append(msg + "\n");
aceCounter++;
}
}
}
sw.stop();
String executionTime = msHumanReadable(sw.getTime());
String resultMsg = (aceCounter > 0)
? "Deleted " + aceCounter + " ACEs for " + principalIds.size() + " principals in " + executionTime
: "Did not delete any ACEs";
message.append(resultMsg + "\n");
LOG.debug(resultMsg);
return message.toString();
}
}