com.cognifide.cq.cqsm.foundation.actions.check.permissions.CheckPermissions Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of apm-bundle Show documentation
Show all versions of apm-bundle Show documentation
AEM Permission Management is an AEM based tool focused on streamlining the permission configuration
/*-
* ========================LICENSE_START=================================
* AEM Permission Management
* %%
* Copyright (C) 2013 Cognifide Limited
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =========================LICENSE_END==================================
*/
package com.cognifide.cq.cqsm.foundation.actions.check.permissions;
import com.google.common.base.Function;
import com.google.common.collect.Lists;
import com.cognifide.cq.cqsm.api.actions.Action;
import com.cognifide.cq.cqsm.api.actions.ActionResult;
import com.cognifide.cq.cqsm.api.exceptions.ActionExecutionException;
import com.cognifide.cq.cqsm.api.executors.Context;
import com.cognifide.cq.cqsm.api.utils.AuthorizablesUtils;
import com.cognifide.cq.cqsm.core.actions.ActionUtils;
import com.cognifide.cq.cqsm.core.utils.MessagingUtils;
import com.day.cq.security.util.CqActions;
import org.apache.commons.lang.StringUtils;
import org.apache.jackrabbit.api.security.principal.PrincipalIterator;
import org.apache.jackrabbit.api.security.user.Authorizable;
import org.apache.sling.api.resource.LoginException;
import java.security.Principal;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.regex.Pattern;
import javax.jcr.Node;
import javax.jcr.NodeIterator;
import javax.jcr.PathNotFoundException;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
public class CheckPermissions implements Action {
private final String path;
private final String glob;
private final List permissions;
private final boolean isAllow;
private final String authorizableId;
public CheckPermissions(final String authorizableId, final String path, final String glob,
final List permissions, boolean isAllow) {
this.authorizableId = authorizableId;
this.path = path;
this.glob = glob;
this.permissions = permissions;
this.isAllow = isAllow;
}
@Override
public ActionResult simulate(Context context) {
return process(context, false);
}
@Override
public ActionResult execute(final Context context) {
return process(context, true);
}
private ActionResult process(final Context context, boolean execute) {
ActionResult actionResult = new ActionResult();
try {
final Authorizable authorizable = AuthorizablesUtils.getAuthorizable(context, authorizableId);
final Set authorizablesToCheck = getAuthorizablesToCheck(authorizable, context);
final CqActions actions = new CqActions(context.getSession());
final List privilegesToCheck = preparePrivilegesToCheck();
if (StringUtils.isBlank(glob)) {
if (checkPermissionsForPath(authorizablesToCheck, actions, privilegesToCheck, path)) {
logFailure(execute, actionResult, authorizable, path);
} else {
actionResult.logMessage(
"All required privileges are set for " + authorizable.getID() + " on " + path);
}
} else {
checkPermissionsForGlob(context.getSession(), execute, actionResult, authorizable, authorizablesToCheck, actions,
privilegesToCheck);
}
} catch (final PathNotFoundException e) {
actionResult.logError("Path " + path + " not found");
} catch (RepositoryException | ActionExecutionException | LoginException e) {
actionResult.logError(MessagingUtils.createMessage(e));
}
return actionResult;
}
private void checkPermissionsForGlob(Session session, final boolean execute, final ActionResult actionResult,
final Authorizable authorizable, final Set authorizablesToCheck,
final CqActions actions, final List privilegesToCheck)
throws RepositoryException, LoginException {
final List subpaths = getAllSubpaths(session, path);
Pattern pattern = Pattern.compile(path + StringUtils.replace(glob, "*", ".*"));
boolean foundMatch = false;
boolean failed = false;
for (String subpath : subpaths) {
if (pattern.matcher(subpath).matches()) {
foundMatch = true;
failed = checkPermissionsForPath(authorizablesToCheck, actions, privilegesToCheck, subpath);
if (failed) {
logFailure(execute, actionResult, authorizable, subpath);
break;
}
}
}
if (!foundMatch) {
actionResult
.logError("No match was found for " + authorizable.getID() + " for given glob " + glob);
if (execute) {
actionResult.logError(ActionUtils.ASSERTION_FAILED_MSG);
}
} else if (!failed) {
actionResult.logMessage(
"All required privileges are set for " + authorizable.getID() + " on " + path);
}
}
private boolean checkPermissionsForPath(final Set authorizablesToCheck,
final CqActions actions, final List privilegesToCheck, String subpath)
throws RepositoryException {
Collection allowedActions = actions.getAllowedActions(subpath, authorizablesToCheck);
final boolean containsAll = allowedActions.containsAll(privilegesToCheck);
return (!containsAll && isAllow) || (containsAll && !isAllow);
}
private void logFailure(boolean execute, ActionResult actionResult, final Authorizable authorizable,
String subpath) throws RepositoryException {
actionResult.logError(
"Not all required privileges are set for " + authorizable.getID() + " on " + subpath);
if (execute) {
actionResult.logError(ActionUtils.ASSERTION_FAILED_MSG);
}
}
private List getAllSubpaths(Session session, final String path) throws RepositoryException, LoginException {
List subPaths = new ArrayList<>();
Node node = session.getNode(path);
subPaths.addAll(crawl(node));
return subPaths;
}
private List crawl(final Node node) throws RepositoryException {
List paths = new ArrayList<>();
paths.add(node.getPath());
for (NodeIterator iter = node.getNodes(); iter.hasNext(); ) {
paths.addAll(crawl(iter.nextNode()));
}
return paths;
}
private Set getAuthorizablesToCheck(Authorizable authorizable, Context context)
throws RepositoryException {
Set principals = new HashSet<>();
Principal principal = authorizable.getPrincipal();
principals.add(principal);
for (PrincipalIterator it = (context.getSession()).getPrincipalManager()
.getGroupMembership(principal); it.hasNext(); ) {
principals.add(it.nextPrincipal());
}
return principals;
}
private List preparePrivilegesToCheck() throws RepositoryException {
return Lists.transform(permissions, new toLowerCase());
}
@Override
public boolean isGeneric() {
return true;
}
private static class toLowerCase implements Function {
@Override
public String apply(String input) {
return input.toLowerCase();
}
}
}