/* * (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.configmodel; import java.security.Principal; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.commons.lang.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.day.cq.security.util.CqActions; import biz.netcentric.cq.tools.actool.dumpservice.AcDumpElement; import biz.netcentric.cq.tools.actool.dumpservice.AcDumpElementVisitor; /** This class is used to store data of an AcessControlEntry. Objects of this class get created during the reading of the configuration file * in order to set the corresponding ACEs in the system on the one hand and to store data during the reading of existing ACEs before writing * the data back to a dump or configuration file again on the other hand. */ public class AceBean implements AcDumpElement { public static final Logger LOG = LoggerFactory.getLogger(AceBean.class); private String jcrPath; private String actionsStringFromConfig; private String privilegesString; private String principal; private String permission; private String[] actions; private List<Restriction> restrictions = new ArrayList<Restriction>(); private boolean keepOrder = false; // default is to reorder denies before allows private String initialContent; public static final String RESTRICTION_NAME_GLOB = "rep:glob"; @Override public AceBean clone() { AceBean clone = new AceBean(); clone.setJcrPath(jcrPath); clone.setActionsStringFromConfig(actionsStringFromConfig); clone.setPrivilegesString(privilegesString); clone.setPrincipal(principal); clone.setPermission(permission); clone.setActions(actions); clone.setRestrictions(new ArrayList<Restriction>(restrictions)); clone.setInitialContent(initialContent); clone.setKeepOrder(keepOrder); return clone; } public String getPermission() { return permission; } public void setPermission(String permissionString) { permission = permissionString; } public void clearActions() { actions = null; actionsStringFromConfig = ""; } public String getPrincipalName() { return principal; } public void setPrincipal(String principal) { this.principal = principal; } public String getJcrPath() { return jcrPath; } public String getJcrPathForPolicyApi() { if (StringUtils.isBlank(jcrPath)) { return null; // repository level permission } else { return jcrPath; } } public void setJcrPath(String jcrPath) { this.jcrPath = jcrPath; } public boolean isAllow() { return "allow".equalsIgnoreCase(permission); } public List<Restriction> getRestrictions() { return restrictions; } public void setRestrictions(Object restrictionsRaw, String oldStyleRepGlob) { restrictions.clear(); if (restrictionsRaw != null) { if (!(restrictionsRaw instanceof Map)) { throw new IllegalArgumentException("If 'restrictions' is provided for an AC entry, it needs to be a map."); } Map<String, ?> restrictionsMap = (Map<String, ?>) restrictionsRaw; for (final String key : restrictionsMap.keySet()) { final String value = (String) restrictionsMap.get(key); if (value == null) { LOG.debug("Could not get value from restriction map using key: {}", key); continue; } final String[] values = value.split(","); restrictions.add(new Restriction(key, values)); } } if (oldStyleRepGlob != null) { if (containsRestriction(RESTRICTION_NAME_GLOB)) { throw new IllegalArgumentException("Usage of restrictions -> rep:glob and repGlob on top level cannot be mixed."); } restrictions.add(new Restriction(RESTRICTION_NAME_GLOB, oldStyleRepGlob)); } } public boolean containsRestriction(String restrictionName) { for (Restriction currentRestriction : restrictions) { if (StringUtils.equals(currentRestriction.getName(), restrictionName)) { return true; } } return false; } public void setRestrictions(List<Restriction> restrictions) { this.restrictions = restrictions; } public String getRepGlob() { for (Restriction currentRestriction : restrictions) { if (StringUtils.equals(currentRestriction.getName(), RESTRICTION_NAME_GLOB)) { return currentRestriction.getValue(); } } return null; } public String getActionsString() { if (actions != null) { final StringBuilder sb = new StringBuilder(); for (final String action : actions) { sb.append(action).append(","); } return StringUtils.chomp(sb.toString(), ","); } return ""; } public String getActionsStringFromConfig() { return actionsStringFromConfig; } public void setActions(String[] actions) { this.actions = actions; } public void setActionsStringFromConfig(String actionsString) { actionsStringFromConfig = actionsString; } public String[] getActions() { return actions; } public String getPrivilegesString() { return privilegesString; } public String[] getPrivileges() { if (StringUtils.isNotBlank(privilegesString)) { return privilegesString.split(","); } return null; } public void setPrivilegesString(String privilegesString) { this.privilegesString = privilegesString; } public String getInitialContent() { return initialContent; } public void setInitialContent(String initialContent) { this.initialContent = initialContent; } public boolean isKeepOrder() { return keepOrder; } public void setKeepOrder(boolean keepOrder) { this.keepOrder = keepOrder; } @Override public String toString() { return "AceBean [jcrPath=" + jcrPath + "\n" + ", actionsStringFromConfig=" + actionsStringFromConfig + "\n" + ", privilegesString=" + privilegesString + "\n" + ", principal=" + principal + "\n" + ", permission=" + permission + "\n, actions=" + Arrays.toString(actions) + "\n" + ", restrictions=" + restrictions + "\n" + ", initialContent=" + initialContent + "]"; } @Override public int hashCode() { final int prime = 31; int result = 1; result = (prime * result) + Arrays.hashCode(actions); result = (prime * result) + ((actionsStringFromConfig == null) ? 0 : actionsStringFromConfig.hashCode()); result = (prime * result) + ((initialContent == null) ? 0 : initialContent.hashCode()); result = (prime * result) + ((jcrPath == null) ? 0 : jcrPath.hashCode()); result = (prime * result) + ((permission == null) ? 0 : permission.hashCode()); result = (prime * result) + ((principal == null) ? 0 : principal.hashCode()); result = (prime * result) + ((privilegesString == null) ? 0 : privilegesString.hashCode()); result = (prime * result) + ((restrictions == null) ? 0 : restrictions.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } final AceBean other = (AceBean) obj; if (!Arrays.equals(actions, other.actions)) { return false; } if (actionsStringFromConfig == null) { if (other.actionsStringFromConfig != null) { return false; } } else if (!actionsStringFromConfig.equals(other.actionsStringFromConfig)) { return false; } if (initialContent == null) { if (other.initialContent != null) { return false; } } else if (!initialContent.equals(other.initialContent)) { return false; } if (jcrPath == null) { if (other.jcrPath != null) { return false; } } else if (!jcrPath.equals(other.jcrPath)) { return false; } if (permission == null) { if (other.permission != null) { return false; } } else if (!permission.equals(other.permission)) { return false; } if (principal == null) { if (other.principal != null) { return false; } } else if (!principal.equals(other.principal)) { return false; } if (privilegesString == null) { if (other.privilegesString != null) { return false; } } else if (!privilegesString.equals(other.privilegesString)) { return false; } if (restrictions == null) { if (other.restrictions != null) { return false; } } else if (!restrictions.equals(other.restrictions)) { return false; } return true; } @Override public void accept(AcDumpElementVisitor acDumpElementVisitor) { acDumpElementVisitor.visit(this); } /** Creates an action map being used in {@link CqActions#installActions(String, Principal, Map, Collection)} out of the set actions on * this bean. * * @return a map containing actions as keys and booleans representing {@code true} for allow and {@code false} for deny. */ public Map<String, Boolean> getActionMap() { if (actions == null) { return Collections.emptyMap(); } final Map<String, Boolean> actionMap = new HashMap<String, Boolean>(); for (final String action : actions) { actionMap.put(action, isAllow()); } return actionMap; } public boolean isInitialContentOnlyConfig() { return StringUtils.isNotBlank(initialContent) && StringUtils.isBlank(permission) && StringUtils.isBlank(privilegesString) && StringUtils.isBlank(actionsStringFromConfig); } }