package org.argeo.jackrabbit.security; import java.security.Principal; import java.util.ArrayList; import java.util.List; import javax.jcr.RepositoryException; import javax.jcr.Session; import javax.jcr.security.Privilege; import org.apache.jackrabbit.api.security.JackrabbitAccessControlList; import org.apache.jackrabbit.api.security.JackrabbitAccessControlManager; import org.argeo.api.cms.CmsLog; import org.argeo.jcr.JcrUtils; /** Utilities around Jackrabbit security extensions. */ public class JackrabbitSecurityUtils { private final static CmsLog log = CmsLog.getLog(JackrabbitSecurityUtils.class); /** * Convenience method for denying a single privilege to a principal (user or * role), typically jcr:all */ public synchronized static void denyPrivilege(Session session, String path, String principal, String privilege) throws RepositoryException { List privileges = new ArrayList(); privileges.add(session.getAccessControlManager().privilegeFromName(privilege)); denyPrivileges(session, path, () -> principal, privileges); } /** * Deny privileges on a path to a {@link Principal}. The path must already * exist. Session is saved. Synchronized to prevent concurrent modifications of * the same node. */ public synchronized static Boolean denyPrivileges(Session session, String path, Principal principal, List privs) throws RepositoryException { // make sure the session is in line with the persisted state session.refresh(false); JackrabbitAccessControlManager acm = (JackrabbitAccessControlManager) session.getAccessControlManager(); JackrabbitAccessControlList acl = (JackrabbitAccessControlList) JcrUtils.getAccessControlList(acm, path); // accessControlEntries: for (AccessControlEntry ace : acl.getAccessControlEntries()) { // Principal currentPrincipal = ace.getPrincipal(); // if (currentPrincipal.getName().equals(principal.getName())) { // Privilege[] currentPrivileges = ace.getPrivileges(); // if (currentPrivileges.length != privs.size()) // break accessControlEntries; // for (int i = 0; i < currentPrivileges.length; i++) { // Privilege currP = currentPrivileges[i]; // Privilege p = privs.get(i); // if (!currP.getName().equals(p.getName())) { // break accessControlEntries; // } // } // return false; // } // } Privilege[] privileges = privs.toArray(new Privilege[privs.size()]); acl.addEntry(principal, privileges, false); acm.setPolicy(path, acl); if (log.isDebugEnabled()) { StringBuffer privBuf = new StringBuffer(); for (Privilege priv : privs) privBuf.append(priv.getName()); log.debug("Denied privileges " + privBuf + " to " + principal.getName() + " on " + path + " in '" + session.getWorkspace().getName() + "'"); } session.refresh(true); session.save(); return true; } /** Singleton. */ private JackrabbitSecurityUtils() { } }