/** * Copyright (C) 2010 eXo Platform SAS. * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this software; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. * */ package org.exoplatform.services.jcr.webdav.command.acl; import org.exoplatform.common.util.HierarchicalProperty; import org.exoplatform.services.jcr.access.AccessControlEntry; import org.exoplatform.services.jcr.access.AccessControlList; import org.exoplatform.services.jcr.access.PermissionType; import org.exoplatform.services.jcr.impl.core.NodeImpl; import org.exoplatform.services.jcr.webdav.util.PropertyConstants; import org.exoplatform.services.security.IdentityConstants; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import javax.jcr.RepositoryException; import javax.xml.namespace.QName; /** * Created by The eXo Platform SAS. * Utility class to simplify operations with ACL properties of JCR nodes * for PROPFIND method. * * @author Vitaliy Gulyy - gavrikvetal@gmail.com * @version $ */ public class ACLProperties { /** * Defines the name of the element corresponding to a protected property that specifies * the list of access control entries. * More details can be found <a href="http://www.webdav.org/specs/rfc3744.html#PROPERTY_acl">here</a>. */ public final static QName ACL = new QName("DAV:", "acl"); /** * Defines the name of the element corresponding to a property that the set of privileges * to be either granted or denied to a single principal. * More details can be found <a href="http://www.webdav.org/specs/rfc3744.html#PROPERTY_acl">here</a>. */ public final static QName ACE = new QName("DAV:", "ace"); /** * Defines the name of the element corresponding to a property which identifies the principal * to which this ACE applies. * More details can be found <a href='http://www.webdav.org/specs/rfc3744.html#principals'>here</a> * and <a href="http://www.webdav.org/specs/rfc3744.html#PROPERTY_acl">here</a>. */ public final static QName PRINCIPAL = new QName("DAV:", "principal"); /** * Defines the name of the element corresponding to a property that can be either an aggregate * privilege that contains the entire set of privileges that can be applied to the resource or * an aggregate principal that contains the entire set of principals. * More details can be found <a href="http://www.webdav.org/specs/rfc3744.html#PRIVILEGE_all">here</a>. */ public final static QName ALL = new QName("DAV:", "all"); /** * Defines the name of the element corresponding to a property which is used to uniquely * identify a principal. * More details can be found <a href="http://www.webdav.org/specs/rfc3744.html#PROPERTY_principal-URL">here</a>. */ public final static QName HREF = new QName("DAV:", "href"); /** * Defines the name of the element containing privilege's name. * More details can be found <a href="http://www.webdav.org/specs/rfc3744.html#privileges">here</a>. */ public final static QName PRIVILEGE = new QName("DAV:", "privilege"); /** * Defines the name of the element containing privileges to be granted. * More details can be found <a href="http://www.webdav.org/specs/rfc3744.html#rfc.section.5.5.2">here</a>. */ public final static QName GRANT = new QName("DAV:", "grant"); /** * Defines the name of the element containing privileges to be denied. * More details can be found <a href="http://www.webdav.org/specs/rfc3744.html#rfc.section.5.5.2">here</a>. */ public final static QName DENY = new QName("DAV:", "deny"); /** * Defines the name of the element corresponding to write privilege * which in current implementation aggregate: * ADD_NODE, SET_PROPERTY, REMOVE permissions. * More details can be found <a href="http://www.webdav.org/specs/rfc3744.html#privileges">here</a>. */ public final static QName WRITE = new QName("DAV:", "write"); /** * Defines the name of the element corresponding to read privilege * which in current implementation aggregate: * READ permission. * More details can be found <a href="http://www.webdav.org/specs/rfc3744.html#privileges">here</a>. */ public final static QName READ = new QName("DAV:", "read"); /** * Gets {@link AccessControlList} and transform it to DAV:acl property view * represented by a {@link HierarchicalProperty} instance. * @param node - {@link NodeImpl} from which we are to get an ACL * @return HierarchicalProperty - tree like structure corresponding to an DAV:acl property * @throws RepositoryException */ public static HierarchicalProperty getACL(NodeImpl node) throws RepositoryException { HierarchicalProperty property = new HierarchicalProperty(ACL); AccessControlList acl = node.getACL(); HashMap<String, List<String>> principals = new HashMap<String, List<String>>(); List<AccessControlEntry> entryList = acl.getPermissionEntries(); for (AccessControlEntry entry : entryList) { String principal = entry.getIdentity(); String grant = entry.getPermission(); List<String> grantList = principals.get(principal); if (grantList == null) { grantList = new ArrayList<String>(); principals.put(principal, grantList); } grantList.add(grant); } Iterator<String> principalIter = principals.keySet().iterator(); while (principalIter.hasNext()) { HierarchicalProperty aceProperty = new HierarchicalProperty(ACE); String curPrincipal = principalIter.next(); aceProperty.addChild(getPrincipalProperty(curPrincipal)); aceProperty.addChild(getGrantProperty(principals.get(curPrincipal))); property.addChild(aceProperty); } return property; } /** * Transform owner got from node's {@link AccessControlList} * to tree like {@link HierarchicalProperty} instance to use in PROPFIND response body * @param node * @return {@link HierarchicalProperty} representation of node owner * @throws RepositoryException */ public static HierarchicalProperty getOwner(NodeImpl node) throws RepositoryException { HierarchicalProperty ownerProperty = new HierarchicalProperty(PropertyConstants.OWNER); HierarchicalProperty href = new HierarchicalProperty(new QName("DAV:", "href")); href.setValue(node.getACL().getOwner()); ownerProperty.addChild(href); return ownerProperty; } private static HierarchicalProperty getPrincipalProperty(String principal) { HierarchicalProperty principalProperty = new HierarchicalProperty(PRINCIPAL); if (IdentityConstants.ANY.equals(principal)) { HierarchicalProperty all = new HierarchicalProperty(ALL); principalProperty.addChild(all); } else { HierarchicalProperty href = new HierarchicalProperty(HREF); href.setValue(principal); principalProperty.addChild(href); } return principalProperty; } private static HierarchicalProperty getGrantProperty(List<String> grantList) { HierarchicalProperty grant = new HierarchicalProperty(GRANT); if (grantList.contains(PermissionType.ADD_NODE) || grantList.contains(PermissionType.SET_PROPERTY) || grantList.contains(PermissionType.REMOVE)) { HierarchicalProperty privilege = new HierarchicalProperty(PRIVILEGE); privilege.addChild(new HierarchicalProperty(WRITE)); grant.addChild(privilege); } if (grantList.contains(PermissionType.READ)) { HierarchicalProperty privilege = new HierarchicalProperty(PRIVILEGE); privilege.addChild(new HierarchicalProperty(READ)); grant.addChild(privilege); } return grant; } }