package jackrabbit; import static org.apache.commons.lang3.StringUtils.isNotBlank; import java.security.AccessControlException; import java.util.Map; import javax.jcr.Node; import javax.jcr.NodeIterator; import javax.jcr.PathNotFoundException; import javax.jcr.Property; import javax.jcr.RepositoryException; import javax.jcr.Session; import org.apache.commons.lang3.StringUtils; import com.google.common.collect.Maps; public class PermissionStore { private static final String PSTORE = "pstore"; private static final String PSTORE_PATH = "/"+PSTORE; private static final String WORKSPACE = "workspace"; private static final String PRINCIPAL = "principal"; private static final String ITEMID = "itemid"; private static final String PERMISSION = "permission"; private static final String PERMISSIONS = "permissions"; private static PermissionStore INSTANCE; private final Map<PermissionKey, Permission> permissions = Maps.newTreeMap(); private String getProperty(Node n, String property) throws PathNotFoundException, RepositoryException { Property p = n.getProperty(property); if(p != null) { return p.getString(); } else { return null; } } private void writePermissions(Session session) throws RepositoryException { deletePermissions(session); Node pNode = getPermissions(session); for(Map.Entry<PermissionKey, Permission> me : permissions.entrySet()) { Node p = pNode.addNode(PERMISSION); p.setProperty(WORKSPACE, me.getKey().getWorkspace()); p.setProperty(PRINCIPAL, me.getKey().getPrincipal()); p.setProperty(ITEMID, me.getKey().getId()); p.setProperty(PERMISSION, me.getValue().toString()); } } private void deletePermissions(Session session) throws RepositoryException { Node permissions = getPermissions(session); NodeIterator iter = permissions.getNodes(); while(iter.hasNext()) { Node p = iter.nextNode(); p.remove(); } } private Node getPStore(Session session) throws RepositoryException { try { Node pstore = session.getNode(PSTORE_PATH); return pstore; } catch(PathNotFoundException e) { Node root = session.getRootNode(); Node pstore = root.addNode(PSTORE); return pstore; } } private Node getPermissions(Session session) throws RepositoryException { Node pstore = getPStore(session); try { Node permissions = pstore.getNode(PERMISSIONS); return permissions; } catch(PathNotFoundException e) { Node permissions = pstore.addNode(PERMISSIONS); return permissions; } } public static synchronized PermissionStore getInstance() { if(INSTANCE == null) { INSTANCE = new PermissionStore(); } return INSTANCE; } public synchronized Map<PermissionKey, Permission> getPermissions() { return Maps.newHashMap(permissions); } public synchronized void grant(Session session, String workspace, String principal, String id, Permission permission) throws RepositoryException { checkPermission(session); try { PermissionKey key = new PermissionKey((workspace!=null?workspace:"default"), principal, id); permissions.put(key, permission); writePermissions(session); } finally { init(session); } } public synchronized boolean revoke(Session session , String workspace, String principal, String id) throws RepositoryException { checkPermission(session); try { PermissionKey key = new PermissionKey((workspace!=null?workspace:"default"), principal, id); Permission p = permissions.remove(key); writePermissions(session); return p != null; } finally { init(session); } } private void checkPermission(Session session) throws AccessControlException, RepositoryException { session.checkPermission(PSTORE_PATH, Session.ACTION_ADD_NODE); } public synchronized void init(Session session) throws RepositoryException { permissions.clear(); try { Node pNode = getPermissions(session); NodeIterator iter = pNode.getNodes(); while(iter.hasNext()) { Node n = iter.nextNode(); try { String workspace = getProperty(n, WORKSPACE); String principal = getProperty(n, PRINCIPAL); String id = getProperty(n, ITEMID); String permission = getProperty(n, PERMISSION); Permission p = Permission.valueOf(StringUtils.upperCase(permission)); if(isNotBlank(workspace) && isNotBlank(principal) && isNotBlank(id) && p != null) { permissions.put(new PermissionKey(workspace, principal, id), p); } } catch(PathNotFoundException e) { } } } catch(Exception e) { throw new RepositoryException(e); } } public synchronized Permission getPermission(PermissionKey key) { return permissions.get(key); } }