package org.argeo.jackrabbit;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Executor;
import javax.jcr.Repository;
import javax.jcr.RepositoryException;
import javax.jcr.security.AccessControlList;
import javax.jcr.security.AccessControlPolicy;
import javax.jcr.security.AccessControlPolicyIterator;
import javax.jcr.security.Privilege;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.jackrabbit.api.JackrabbitSession;
import org.apache.jackrabbit.api.security.JackrabbitAccessControlManager;
import org.apache.jackrabbit.api.security.user.Authorizable;
import org.apache.jackrabbit.api.security.user.Group;
import org.apache.jackrabbit.api.security.user.UserManager;
import org.argeo.ArgeoException;
import org.argeo.jcr.JcrUtils;
/** Apply authorizations to a Jackrabbit repository. */
public class JackrabbitAuthorizations {
private final static Log log = LogFactory
.getLog(JackrabbitAuthorizations.class);
private Repository repository;
private Executor systemExecutor;
/**
* key := privilege1,privilege2/path/to/node
* value := group1,group2
*/
private Map groupPrivileges = new HashMap();
public void init() {
Runnable action = new Runnable() {
public void run() {
JackrabbitSession session = null;
try {
session = (JackrabbitSession) repository.login();
initAuthorizations(session);
} catch (Exception e) {
JcrUtils.discardQuietly(session);
} finally {
JcrUtils.logoutQuietly(session);
}
}
};
if (systemExecutor != null)
systemExecutor.execute(action);
else
action.run();
}
protected void initAuthorizations(JackrabbitSession session)
throws RepositoryException {
JackrabbitAccessControlManager acm = (JackrabbitAccessControlManager) session
.getAccessControlManager();
UserManager um = session.getUserManager();
for (String privileges : groupPrivileges.keySet()) {
String path = null;
int slashIndex = privileges.indexOf('/');
if (slashIndex == 0) {
throw new ArgeoException("Privilege " + privileges
+ " badly formatted it starts with /");
} else if (slashIndex > 0) {
path = privileges.substring(slashIndex);
privileges = privileges.substring(0, slashIndex);
}
if (path == null)
path = "/";
List privs = new ArrayList();
for (String priv : privileges.split(",")) {
privs.add(acm.privilegeFromName(priv));
}
String groupNames = groupPrivileges.get(privileges);
for (String groupName : groupNames.split(",")) {
Group group = (Group) um.getAuthorizable(groupName);
if (group == null)
group = um.createGroup(groupName);
addPrivileges(session, group, path, privs);
}
}
session.save();
}
public static void addPrivileges(JackrabbitSession session,
Authorizable authorizable, String path, List privs)
throws RepositoryException {
JackrabbitAccessControlManager acm = (JackrabbitAccessControlManager) session
.getAccessControlManager();
AccessControlPolicy policy = null;
AccessControlPolicyIterator policyIterator = acm
.getApplicablePolicies(path);
if (policyIterator.hasNext()) {
policy = policyIterator.nextAccessControlPolicy();
} else {
AccessControlPolicy[] existingPolicies = acm.getPolicies(path);
policy = existingPolicies[0];
}
if (policy instanceof AccessControlList) {
((AccessControlList) policy).addAccessControlEntry(
authorizable.getPrincipal(),
privs.toArray(new Privilege[privs.size()]));
acm.setPolicy(path, policy);
}
if (log.isDebugEnabled())
log.debug("Added privileges " + privs + " to " + authorizable
+ " on " + path);
}
public void setGroupPrivileges(Map groupPrivileges) {
this.groupPrivileges = groupPrivileges;
}
public void setRepository(Repository repository) {
this.repository = repository;
}
public void setSystemExecutor(Executor systemExecutor) {
this.systemExecutor = systemExecutor;
}
}