Skip to content

Commit

Permalink
Merge branch 'release/1.6.2'
Browse files Browse the repository at this point in the history
Conflicts:
	accesscontroltool-bundle/pom.xml
	accesscontroltool-oakindex-package/pom.xml
	accesscontroltool-package/pom.xml
	pom.xml
  • Loading branch information
kwin committed Sep 1, 2015
2 parents 216d4e1 + 2a294f4 commit 03e8ee1
Show file tree
Hide file tree
Showing 11 changed files with 196 additions and 103 deletions.
2 changes: 1 addition & 1 deletion accesscontroltool-bundle/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
<parent>
<groupId>biz.netcentric.cq.tools.accesscontroltool</groupId>
<artifactId>accesscontroltool</artifactId>
<version>1.6.1</version>
<version>1.6.2</version>
</parent>

<!-- ====================================================================== -->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -144,18 +144,7 @@ private static void writeAcBeansToRepository(final Session session,
} else {
history.addVerboseMessage("starting installation of bean: \n"
+ bean);
// check if path exists in CRX
if (session.itemExists(bean.getJcrPath())) {
bean.writeToRepository(session, currentPrincipal, history);
} else {
String warningMessage = "path: "
+ bean.getJcrPath()
+ " doesn't exist in repository. Skipped installation of this ACE!";
LOG.warn(warningMessage);
history.addWarning(warningMessage);
continue;
}

bean.install(session, currentPrincipal, history);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.UnsupportedRepositoryOperationException;
import javax.jcr.Value;
import javax.jcr.security.AccessControlEntry;
import javax.jcr.security.AccessControlException;
import javax.jcr.security.AccessControlManager;
Expand All @@ -44,8 +45,8 @@

/**
* This class provides common access control related utilities.
* Mostly a copy of org.apache.jackrabbit.commons.AccessControlUtils.
*/

public class AccessControlUtils {

private AccessControlUtils() {
Expand Down Expand Up @@ -258,45 +259,6 @@ public static boolean addAccessControlEntry(Session session,
return false;
}

public static void addActions(Session session, AceBean aceBean,
Principal principal, AcInstallationHistoryPojo history)
throws RepositoryException {

boolean isAllow = aceBean.isAllow();
String[] actions = aceBean.getActions();
CqActions cqActions = new CqActions(session);
String absPath = aceBean.getJcrPath();
String globString = aceBean.getRepGlob();
String[] privNames = aceBean.getPrivileges();
Map<String, Boolean> actionMap = new HashMap<String, Boolean>();

if (actions != null) {
for (String action : actions) {
if ("create".equals(action) || "modify".equals(action) || "delete".equals(action)) {
actionMap.put(action, isAllow);
}
}

Collection<String> inheritedAllows = new HashSet<String>();
inheritedAllows.add("read");

LOG.info("setting actions for path: {} and principal {}", absPath,
principal.getName());
cqActions.installActions(absPath, principal, actionMap,
inheritedAllows);
} else {
String message = "Could not install Actions for " + aceBean
+ ", no actions defined!";
history.addWarning(message);

}
// if(privNames != null){
// installPermissions(session, absPath, principal, isAllow, globString,
// privNames);
// }

}

private static Principal getEveryonePrincipal(Session session)
throws RepositoryException {
if (session instanceof JackrabbitSession) {
Expand Down Expand Up @@ -399,5 +361,17 @@ static JackrabbitAccessControlList getModifiableAcl(
}
return null;
}


public static void extendExistingAceWithRestrictions(JackrabbitAccessControlList accessControlList, JackrabbitAccessControlEntry accessControlEntry, Map<String, Value> restrictions) throws AccessControlException, UnsupportedRepositoryOperationException, RepositoryException {
// 1. add new entry
if (!accessControlList.addEntry(accessControlEntry.getPrincipal(), accessControlEntry.getPrivileges(), accessControlEntry.isAllow(), restrictions)) {
throw new IllegalStateException("Could not add entry, probably because it was already there!");
}
// we assume the entry being added is the last one
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);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,24 @@

import java.security.Principal;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.UnsupportedRepositoryOperationException;
import javax.jcr.Value;
import javax.jcr.ValueFormatException;
import javax.jcr.security.AccessControlEntry;
import javax.jcr.security.AccessControlManager;
import javax.jcr.security.Privilege;

import org.apache.commons.lang.StringUtils;
import org.apache.jackrabbit.api.security.JackrabbitAccessControlEntry;
import org.apache.jackrabbit.api.security.JackrabbitAccessControlList;

import biz.netcentric.cq.tools.actool.dumpservice.AcDumpElement;
Expand Down Expand Up @@ -49,6 +55,9 @@ public class AceBean implements AcDumpElement {
private String permission;
private String[] actions;
private String assertedExceptionString;


public static final String RESTRICTION_NAME_GLOB = "rep:glob";

public String getAssertedExceptionString() {
return assertedExceptionString;
Expand Down Expand Up @@ -242,61 +251,151 @@ private static Set<String> removeRedundantPrivileges(Session session, String[] p
return cleanedPrivileges;
}
for (String action : actions) {
@SuppressWarnings("deprecation")
Set<Privilege> coveredPrivileges = cqActions.getPrivileges(action);
for (Privilege coveredPrivilege : coveredPrivileges) {
cleanedPrivileges.remove(coveredPrivilege.getName());
}
}
return cleanedPrivileges;
}

/**
* Persists the AccessControlEntry being represented by this bean to the
* repository
* Creates a restriction map being used in {@link JackrabbitAccessControlList#addEntry(Principal, Privilege[], boolean, 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 a map with restriction names as keys and restriction values as values.
* @throws ValueFormatException
* @throws UnsupportedRepositoryOperationException
* @throws RepositoryException
*/
public void writeToRepository(final Session session, Principal principal, AcInstallationHistoryPojo history)
throws RepositoryException {
AccessControlManager acMgr = session.getAccessControlManager();

// Convert actions to permissions, if necessary
if (getActions() != null) {
// install actions
history.addVerboseMessage("adding action for path: "
+ getJcrPath() + ", principal: "
+ principal.getName() + ", actions: "
+ getActionsString() + ", permission: "
+ getPermission());
AccessControlUtils.addActions(session, this, principal,
history);
removeRedundantPrivileges(session);
private Map<String, Value> getSingleValueRestrictions(Session session, JackrabbitAccessControlList acl) throws ValueFormatException, UnsupportedRepositoryOperationException, RepositoryException {
Collection<String> supportedRestrictionNames = Arrays.asList(acl.getRestrictionNames());
if (getRepGlob() != null) {
if (!supportedRestrictionNames.contains(RESTRICTION_NAME_GLOB)) {
throw new IllegalStateException("The AccessControlList at " + acl.getPath() + " does not support setting rep:glob restrictions!");
}
Value v = session.getValueFactory().createValue(getRepGlob(), acl.getRestrictionType(RESTRICTION_NAME_GLOB));
return Collections.singletonMap(RESTRICTION_NAME_GLOB, v);
} else {
return Collections.emptyMap();
}
}

/**
* 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.
*/
private Map<String, Boolean> getActionMap() {
if (actions == null) {
return Collections.emptyMap();
}
Map<String, Boolean> actionMap = new HashMap<String, Boolean>();
for (String action : actions) {
actionMap.put(action, isAllow());
}


JackrabbitAccessControlList acl = AccessControlUtils.getModifiableAcl(
acMgr, getJcrPath());
Set<Privilege> privileges = AccessControlUtils.getPrivilegeSet(
getPrivileges(), acMgr);
return actionMap;
}

/**
* Installs the CQ actions in the repository.
*
* @param principal
* @param acl
* @param session
* @param acMgr
* @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(Principal principal, JackrabbitAccessControlList acl, Session session, AccessControlManager acMgr) throws RepositoryException {
Map<String, Boolean> actionMap = getActionMap();
if (actionMap.isEmpty()) {
return acl;
}
int previousAclSize = acl.size();

if (!privileges.isEmpty()) {
Map<String, Value> restrictions = null;
if (getRepGlob() != null) {
// is rep:glob supported?
for (String rName : acl.getRestrictionNames()) {
if ("rep:glob".equals(rName)) {
Value v = session.getValueFactory().createValue(
getRepGlob(), acl.getRestrictionType(rName));
restrictions = Collections.singletonMap(rName, v);
break;
}
}
CqActions cqActions = new CqActions(session);
Collection<String> inheritedAllows = cqActions.getAllowedActions(
getJcrPath(), Collections.singleton(principal));
// this does always install new entries
cqActions.installActions(getJcrPath(), principal, actionMap,
inheritedAllows);

// since the aclist has been modified, retrieve it again
JackrabbitAccessControlList newAcl = AccessControlUtils.getAccessControlList(session, getJcrPath());
Map<String, Value> restrictions = getSingleValueRestrictions(session, acl);
if (restrictions.isEmpty()) {
return newAcl;
}
// additionally set restrictions on the installed actions (this is not supported by CQ Security API)
int newAclSize = newAcl.size();
if (previousAclSize >= newAclSize) {
throw new IllegalStateException("No new entries have been set for AccessControlList at " + getJcrPath());
}
AccessControlEntry[] aces = newAcl.getAccessControlEntries();
for (int acEntryIndex = previousAclSize; acEntryIndex < newAclSize; acEntryIndex++) {
if (!(aces[acEntryIndex] instanceof JackrabbitAccessControlEntry)) {
throw new IllegalStateException("Can not deal with non JackrabbitAccessControlEntrys, but entry is of type " + aces[acEntryIndex].getClass().getName());
}
JackrabbitAccessControlEntry ace = (JackrabbitAccessControlEntry)aces[acEntryIndex];
// only extend those AccessControlEntries which do not yet have a restriction
if (ace.getRestrictions("rep:glob") == null) {
// modify this AccessControlEntry by adding the restriction
AccessControlUtils.extendExistingAceWithRestrictions(newAcl, ace, restrictions);
}
if (restrictions != null) {
}
return newAcl;
}

private boolean installPrivileges(Principal principal, JackrabbitAccessControlList acl, Session session, AccessControlManager acMgr) throws RepositoryException {
// then install remaining privileges
Set<Privilege> privileges = AccessControlUtils.getPrivilegeSet(getPrivileges(), acMgr);
if (!privileges.isEmpty()) {
Map<String, Value> restrictions = getSingleValueRestrictions(session, acl);
if (!restrictions.isEmpty()) {
acl.addEntry(principal, (Privilege[]) privileges
.toArray(new Privilege[privileges.size()]), isAllow(),
restrictions);
} else {
acl.addEntry(principal, (Privilege[]) privileges
.toArray(new Privilege[privileges.size()]), isAllow());
}
return true;
}
return false;
}

/**
* Installs the AccessControlEntry being represented by this bean in the
* repository
*/
public void install(final Session session, Principal principal,
AcInstallationHistoryPojo history) throws RepositoryException {
AccessControlManager acMgr = session.getAccessControlManager();

JackrabbitAccessControlList acl = AccessControlUtils.getModifiableAcl(
acMgr, getJcrPath());
if (acl == null) {
history.addWarning("Skipped installing privileges/actions for non existing path: " + getJcrPath());
return;
}

// first install actions
JackrabbitAccessControlList newAcl = installActions(principal, acl, session, acMgr);
if (acl != newAcl) {
history.addVerboseMessage("added action(s) for path: " + getJcrPath()
+ ", principal: " + principal.getName() + ", actions: "
+ getActionsString() + ", allow: " + isAllow());
removeRedundantPrivileges(session);
acl = newAcl;
}

// then install (remaining) privileges
if (installPrivileges(principal, acl, session, acMgr)) {
history.addVerboseMessage("added privilege(s) for path: " + getJcrPath()
+ ", principal: " + principal.getName() + ", privileges: "
+ getPrivilegesString() + ", allow: " + isAllow());
}
acMgr.setPolicy(getJcrPath(), acl);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,4 +47,12 @@ public void setIndex(long index) {
this.index = index;
}

@Override
public String toString() {
return "HistoryEntry [timestamp=" + timestamp + ", message=" + message
+ ", index=" + index + "]";
}



}
Loading

0 comments on commit 03e8ee1

Please sign in to comment.