Index: jackrabbit-core/src/main/java/org/apache/jackrabbit/core/NodeImpl.java =================================================================== --- jackrabbit-core/src/main/java/org/apache/jackrabbit/core/NodeImpl.java (revision 828791) +++ jackrabbit-core/src/main/java/org/apache/jackrabbit/core/NodeImpl.java Fri Oct 23 17:42:06 CEST 2009 @@ -77,6 +77,7 @@ import org.apache.jackrabbit.core.nodetype.NodeTypeRegistry; import org.apache.jackrabbit.core.query.QueryManagerImpl; import org.apache.jackrabbit.core.security.authorization.Permission; +import org.apache.jackrabbit.core.security.AccessManager; import org.apache.jackrabbit.core.state.ChildNodeEntry; import org.apache.jackrabbit.core.state.ItemState; import org.apache.jackrabbit.core.state.ItemStateException; @@ -1659,6 +1660,7 @@ throw new ItemNotFoundException( this + " has no child node with name " + name); } + if (dstName != null && !hasNode(dstName.getName(), dstName.getIndex())) { String name; try { @@ -1678,6 +1680,23 @@ | ItemValidator.CHECK_CONSTRAINTS; session.getValidator().checkModify(this, options, Permission.NONE); + /* + make sure the session is allowed to reorder child nodes. + since there is no specific privilege for reordering child nodes, + test if the the node to be reordered can be removed and added, + i.e. treating reorder similar to a move. + TODO: properly deal with sns in which case the index would change upon reorder. + */ + AccessManager acMgr = session.getAccessManager(); + PathBuilder pb = new PathBuilder(getPrimaryPath()); + pb.addLast(srcName.getName(), srcName.getIndex()); + Path childPath = pb.getPath(); + if (!acMgr.isGranted(childPath, Permission.ADD_NODE | Permission.REMOVE_NODE)) { + String msg = "Not allowed to reorder child node " + session.getJCRPath(childPath) + "."; + log.debug(msg); + throw new AccessDeniedException(msg); + } + ArrayList list = new ArrayList(data.getNodeState().getChildNodeEntries()); int srcInd = -1, destInd = -1; for (int i = 0; i < list.size(); i++) { Index: jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authorization/AbstractWriteTest.java =================================================================== --- jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authorization/AbstractWriteTest.java (revision 828791) +++ jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authorization/AbstractWriteTest.java Fri Oct 23 17:45:12 CEST 2009 @@ -992,6 +992,51 @@ assertTrue(acMgr.hasPrivileges(path, remainingprivs.toArray(new Privilege[remainingprivs.size()]))); } + public void testReorder() throws RepositoryException, NotExecutableException { + Session testSession = getTestSession(); + Node n = testSession.getNode(path); + try { + if (!n.getPrimaryNodeType().hasOrderableChildNodes()) { + throw new NotExecutableException("Reordering child nodes is not supported.."); + } + + n.orderBefore(Text.getName(childNPath), Text.getName(childNPath2)); + testSession.save(); + fail("test session must not be allowed to reorder nodes."); + } catch (AccessDeniedException e) { + // success. + } + + // give 'add_child_nodes' and 'nt-management' privilege + // -> not sufficient privileges for a reorder + givePrivileges(path, privilegesFromNames(new String[] {Privilege.JCR_ADD_CHILD_NODES, Privilege.JCR_NODE_TYPE_MANAGEMENT}), getRestrictions(superuser, path)); + try { + n.orderBefore(Text.getName(childNPath), Text.getName(childNPath2)); + testSession.save(); + fail("test session must not be allowed to reorder nodes."); + } catch (AccessDeniedException e) { + // success. + } + + // add 'remove_child_nodes' at 'path + // -> not sufficient for a reorder since 'remove_node' privilege is missing + // on the target + givePrivileges(path, privilegesFromName(Privilege.JCR_REMOVE_CHILD_NODES), getRestrictions(superuser, path)); + try { + n.orderBefore(Text.getName(childNPath), Text.getName(childNPath2)); + testSession.save(); + fail("test session must not be allowed to reorder nodes."); + } catch (AccessDeniedException e) { + // success. + } + + // allow 'remove_node' at childNPath + // -> now reorder must succeed + givePrivileges(childNPath, privilegesFromName(Privilege.JCR_REMOVE_NODE), getRestrictions(superuser, childNPath)); + n.orderBefore(Text.getName(childNPath), Text.getName(childNPath2)); + testSession.save(); + } + private static Node findPolicyNode(Node start) throws RepositoryException { Node policyNode = null; if (start.isNodeType("rep:Policy")) { Index: jackrabbit-core/src/main/java/org/apache/jackrabbit/core/ItemImpl.java =================================================================== --- jackrabbit-core/src/main/java/org/apache/jackrabbit/core/ItemImpl.java (revision 828791) +++ jackrabbit-core/src/main/java/org/apache/jackrabbit/core/ItemImpl.java Fri Oct 23 17:51:30 CEST 2009 @@ -390,6 +390,8 @@ child-item addition or removal or changes of protected properties such as mixin-types which are covered separately note: removed items are checked later on. + note: reordering of child nodes has been covered upfront as + this information isn't available here. */ Path path = stateMgr.getHierarchyMgr().getPath(itemState.getId()); boolean isGranted = true;