package org.argeo.jcr; import java.security.Principal; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.jcr.Repository; import javax.jcr.RepositoryException; import javax.jcr.Session; import javax.jcr.security.AccessControlManager; import javax.jcr.security.Privilege; import javax.naming.InvalidNameException; import javax.naming.ldap.LdapName; /** Apply authorizations to a JCR repository. */ public class JcrAuthorizations implements Runnable { // private final static Log log = // LogFactory.getLog(JcrAuthorizations.class); private Repository repository; private String workspace = null; private String securityWorkspace = "security"; /** * key := privilege1,privilege2/path/to/node
* value := group1,group2,user1 */ private Map principalPrivileges = new HashMap(); public void run() { String currentWorkspace = workspace; Session session = null; try { if (workspace != null && workspace.equals("*")) { session = repository.login(); String[] workspaces = session.getWorkspace().getAccessibleWorkspaceNames(); JcrUtils.logoutQuietly(session); for (String wksp : workspaces) { currentWorkspace = wksp; if (currentWorkspace.equals(securityWorkspace)) continue; session = repository.login(currentWorkspace); initAuthorizations(session); JcrUtils.logoutQuietly(session); } } else { session = repository.login(workspace); initAuthorizations(session); } } catch (RepositoryException e) { JcrUtils.discardQuietly(session); throw new JcrException( "Cannot set authorizations " + principalPrivileges + " on workspace " + currentWorkspace, e); } finally { JcrUtils.logoutQuietly(session); } } protected void processWorkspace(String workspace) { Session session = null; try { session = repository.login(workspace); initAuthorizations(session); } catch (RepositoryException e) { JcrUtils.discardQuietly(session); throw new JcrException( "Cannot set authorizations " + principalPrivileges + " on repository " + repository, e); } finally { JcrUtils.logoutQuietly(session); } } /** @deprecated call {@link #run()} instead. */ @Deprecated public void init() { run(); } protected void initAuthorizations(Session session) throws RepositoryException { AccessControlManager acm = session.getAccessControlManager(); for (String privileges : principalPrivileges.keySet()) { String path = null; int slashIndex = privileges.indexOf('/'); if (slashIndex == 0) { throw new IllegalArgumentException("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 principalNames = principalPrivileges.get(privileges); try { new LdapName(principalNames); // TODO differentiate groups and users ? Principal principal = getOrCreatePrincipal(session, principalNames); JcrUtils.addPrivileges(session, path, principal, privs); } catch (InvalidNameException e) { for (String principalName : principalNames.split(",")) { Principal principal = getOrCreatePrincipal(session, principalName); JcrUtils.addPrivileges(session, path, principal, privs); // if (log.isDebugEnabled()) { // StringBuffer privBuf = new StringBuffer(); // for (Privilege priv : privs) // privBuf.append(priv.getName()); // log.debug("Added privileges " + privBuf + " to " // + principal.getName() + " on " + path + " in '" // + session.getWorkspace().getName() + "'"); // } } } } // if (log.isDebugEnabled()) // log.debug("JCR authorizations applied on '" // + session.getWorkspace().getName() + "'"); } /** * Returns a {@link SimplePrincipal}, does not check whether it exists since * such capabilities is not provided by the standard JCR API. Can be * overridden to provide smarter handling */ protected Principal getOrCreatePrincipal(Session session, String principalName) throws RepositoryException { return new SimplePrincipal(principalName); } // public static void addPrivileges(Session session, Principal principal, // String path, List privs) throws RepositoryException { // AccessControlManager acm = session.getAccessControlManager(); // // search for an access control list // AccessControlList acl = null; // AccessControlPolicyIterator policyIterator = acm // .getApplicablePolicies(path); // if (policyIterator.hasNext()) { // while (policyIterator.hasNext()) { // AccessControlPolicy acp = policyIterator // .nextAccessControlPolicy(); // if (acp instanceof AccessControlList) // acl = ((AccessControlList) acp); // } // } else { // AccessControlPolicy[] existingPolicies = acm.getPolicies(path); // for (AccessControlPolicy acp : existingPolicies) { // if (acp instanceof AccessControlList) // acl = ((AccessControlList) acp); // } // } // // if (acl != null) { // acl.addAccessControlEntry(principal, // privs.toArray(new Privilege[privs.size()])); // acm.setPolicy(path, acl); // session.save(); // if (log.isDebugEnabled()) { // StringBuffer buf = new StringBuffer(""); // for (int i = 0; i < privs.size(); i++) { // if (i != 0) // buf.append(','); // buf.append(privs.get(i).getName()); // } // log.debug("Added privilege(s) '" + buf + "' to '" // + principal.getName() + "' on " + path // + " from workspace '" // + session.getWorkspace().getName() + "'"); // } // } else { // throw new ArgeoJcrException("Don't know how to apply privileges " // + privs + " to " + principal + " on " + path // + " from workspace '" + session.getWorkspace().getName() // + "'"); // } // } @Deprecated public void setGroupPrivileges(Map groupPrivileges) { this.principalPrivileges = groupPrivileges; } public void setPrincipalPrivileges(Map principalPrivileges) { this.principalPrivileges = principalPrivileges; } public void setRepository(Repository repository) { this.repository = repository; } public void setWorkspace(String workspace) { this.workspace = workspace; } public void setSecurityWorkspace(String securityWorkspace) { this.securityWorkspace = securityWorkspace; } }