You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by an...@apache.org on 2009/01/08 12:52:45 UTC

svn commit: r732693 [5/6] - in /jackrabbit/trunk: jackrabbit-api/src/main/java/org/apache/jackrabbit/api/jsr283/security/ jackrabbit-core/src/main/java/org/apache/jackrabbit/core/ jackrabbit-core/src/main/java/org/apache/jackrabbit/core/cluster/ jackra...

Added: jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authorization/AbstractWriteTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authorization/AbstractWriteTest.java?rev=732693&view=auto
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authorization/AbstractWriteTest.java (added)
+++ jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authorization/AbstractWriteTest.java Thu Jan  8 03:52:38 2009
@@ -0,0 +1,965 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.core.security.authorization;
+
+import org.apache.jackrabbit.api.jsr283.security.AccessControlManager;
+import org.apache.jackrabbit.api.jsr283.security.AccessControlPolicy;
+import org.apache.jackrabbit.api.jsr283.security.Privilege;
+import org.apache.jackrabbit.api.security.user.Group;
+import org.apache.jackrabbit.api.security.user.User;
+import org.apache.jackrabbit.core.SessionImpl;
+import org.apache.jackrabbit.core.security.TestPrincipal;
+import org.apache.jackrabbit.test.JUnitTest;
+import org.apache.jackrabbit.test.NotExecutableException;
+import org.apache.jackrabbit.test.api.observation.EventResult;
+import org.apache.jackrabbit.util.Text;
+import org.apache.jackrabbit.uuid.UUID;
+
+import javax.jcr.AccessDeniedException;
+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 javax.jcr.nodetype.ConstraintViolationException;
+import javax.jcr.observation.Event;
+import javax.jcr.observation.ObservationManager;
+import java.security.Principal;
+import java.util.Map;
+
+/**
+ * <code>AbstractEvaluationTest</code>...
+ */
+public abstract class AbstractWriteTest extends AbstractEvaluationTest {
+
+    protected static final long DEFAULT_WAIT_TIMEOUT = 5000;
+
+    private Group testGroup;
+
+    protected String path;
+    protected String childNPath;
+    protected String childNPath2;
+    protected String childPPath;
+    protected String childchildPPath;
+    protected String siblingPath;
+
+    // TODO: test AC for moved node
+    // TODO: test AC for moved AC-controlled node
+    // TODO: test if combination of group and user permissions are properly evaluated
+
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        // create some nodes below the test root in order to apply ac-stuff
+        Node node = testRootNode.addNode(nodeName1, testNodeType);
+        Node cn1 = node.addNode(nodeName2, testNodeType);
+        Property cp1 = node.setProperty(propertyName1, "anyValue");
+        Node cn2 = node.addNode(nodeName3, testNodeType);
+
+        Property ccp1 = cn1.setProperty(propertyName1, "childNodeProperty");
+
+        Node n2 = testRootNode.addNode(nodeName2, testNodeType);
+        superuser.save();
+
+        path = node.getPath();
+        childNPath = cn1.getPath();
+        childNPath2 = cn2.getPath();
+        childPPath = cp1.getPath();
+        childchildPPath = ccp1.getPath();
+        siblingPath = n2.getPath();
+    }
+
+    protected void tearDown() throws Exception {
+        // make sure all ac info is removed
+        clearACInfo();
+        if (testGroup != null && testUser != null) {
+            testGroup.removeMember(testUser);
+            testGroup.remove();
+        }
+        super.tearDown();
+    }
+
+    protected abstract void clearACInfo();
+
+    protected JackrabbitAccessControlList givePrivileges(String nPath, Privilege[] privileges,
+                                                         Map restrictions) throws NotExecutableException, RepositoryException {
+        return givePrivileges(nPath, testUser.getPrincipal(), privileges, restrictions);
+    }
+
+    protected JackrabbitAccessControlList givePrivileges(String nPath, Principal principal,
+                                                         Privilege[] privileges, Map restrictions) throws NotExecutableException, RepositoryException {
+        JackrabbitAccessControlList tmpl = getPolicy(acMgr, nPath, principal);
+        tmpl.addEntry(principal, privileges, true, restrictions);
+        acMgr.setPolicy(tmpl.getPath(), tmpl);
+        superuser.save();
+        return tmpl;
+    }
+
+    protected JackrabbitAccessControlList withdrawPrivileges(String nPath, Privilege[] privileges, Map restrictions) throws NotExecutableException, RepositoryException {
+        return withdrawPrivileges(nPath, testUser.getPrincipal(), privileges, restrictions);
+    }
+
+    protected JackrabbitAccessControlList withdrawPrivileges(String nPath, Principal principal, Privilege[] privileges, Map restrictions) throws NotExecutableException, RepositoryException {
+        JackrabbitAccessControlList tmpl = getPolicy(acMgr, nPath, principal);
+        tmpl.addEntry(principal, privileges, false, restrictions);
+        acMgr.setPolicy(tmpl.getPath(), tmpl);
+        superuser.save();
+        return tmpl;
+    }
+
+    protected User getTestUser() {
+        return testUser;
+    }
+
+    protected Group getTestGroup() throws RepositoryException, NotExecutableException {
+        if (testGroup == null) {
+            // create the testGroup
+            Principal principal = new TestPrincipal("testGroup" + UUID.randomUUID());
+            testGroup = getUserManager(superuser).createGroup(principal);
+            testGroup.addMember(testUser);
+        }
+        return testGroup;
+    }
+
+    public void testGrantedPermissions() throws RepositoryException, AccessDeniedException, NotExecutableException {
+        /* precondition:
+           testuser must have READ-only permission on test-node and below
+         */
+        checkReadOnly(path);
+
+        // give 'testUser' ADD_CHILD_NODES|MODIFY_PROPERTIES privileges at 'path'
+        Privilege[] privileges = privilegesFromNames(new String[] {
+                Privilege.JCR_ADD_CHILD_NODES,
+                Privilege.JCR_MODIFY_PROPERTIES
+        });
+        givePrivileges(path, privileges, getRestrictions(superuser, path));
+        /*
+         testuser must now have
+         - ADD_NODE permission for child node
+         - SET_PROPERTY permission for child props
+         - REMOVE permission for child-props
+         - READ-only permission for the node at 'path'
+
+         testuser must not have
+         - REMOVE permission for child node
+        */
+        SessionImpl testSession = getTestSession();
+        String nonExChildPath = path + "/anyItem";
+        assertTrue(testSession.hasPermission(nonExChildPath, "read,add_node,set_property"));
+        assertFalse(testSession.hasPermission(nonExChildPath, "remove"));
+
+        Node testN = testSession.getNode(path);
+
+        // must be allowed to add child node
+        testN.addNode(nodeName3);
+        testSession.save();
+
+        // must be allowed to remove child-property
+        testSession.getProperty(childPPath).remove();
+        testSession.save();
+
+        // must be allowed to set child property again
+        testN.setProperty(Text.getName(childPPath), "othervalue");
+        testSession.save();
+
+        // must not be allowed to remove child nodes
+        try {
+            testSession.getNode(childNPath).remove();
+            testSession.save();
+            fail("test-user is not allowed to remove a node below " + path);
+        } catch (AccessDeniedException e) {
+            // success
+        }
+
+        // must have read-only access on 'testN' and it's sibling
+        assertTrue(testSession.hasPermission(path, "read"));
+        assertFalse(testSession.hasPermission(path, "add_node,set_property,remove"));
+        checkReadOnly(siblingPath);
+    }
+
+    public void testDeniedPermission() throws RepositoryException, NotExecutableException, InterruptedException {
+        /* precondition:
+           testuser must have READ-only permission on test-node and below
+         */
+        checkReadOnly(path);
+
+        // withdraw READ privilege to 'testUser' at 'path'
+        Privilege[] privileges = privilegesFromName(Privilege.JCR_READ);
+        withdrawPrivileges(childNPath, privileges, getRestrictions(superuser, childNPath));
+        /*
+         testuser must now have
+         - READ-only permission at path
+         - READ-only permission for the child-props of path
+
+         testuser must not have
+         - any permission on child-node and all its subtree
+        */
+
+        // must still have read-access to path, ...
+        SessionImpl testSession = getTestSession();
+        assertTrue(testSession.hasPermission(path, "read"));
+        Node n = testSession.getNode(path);
+        // ... siblings of childN
+        testSession.getNode(childNPath2);
+        // ... and props of path
+        assertTrue(n.getProperties().hasNext());
+
+        //testSession must not have access to 'childNPath'
+        assertFalse(testSession.itemExists(childNPath));
+        try {
+            testSession.getNode(childNPath);
+            fail("Read access has been denied -> cannot retrieve child node.");
+        } catch (PathNotFoundException e) {
+            // ok.
+        }
+        /*
+        -> must not have access to subtree below 'childNPath'
+        */
+        assertFalse(testSession.itemExists(childchildPPath));
+        try {
+            testSession.getItem(childchildPPath);
+            fail("Read access has been denied -> cannot retrieve prop below child node.");
+        } catch (PathNotFoundException e) {
+            // ok.
+        }
+    }
+
+    public void testAccessControlRead() throws NotExecutableException, RepositoryException {
+        AccessControlManager testAcMgr = getTestACManager();
+        checkReadOnly(path);
+
+        // re-grant READ in order to have an ACL-node
+        Privilege[] privileges = privilegesFromName(Privilege.JCR_READ);
+        JackrabbitAccessControlList tmpl = givePrivileges(path, privileges, getRestrictions(superuser, path));
+        // make sure the 'rep:policy' node has been created.
+        assertTrue(superuser.itemExists(tmpl.getPath() + "/rep:policy"));
+
+        SessionImpl testSession = getTestSession();
+        /*
+         Testuser must still have READ-only access only and must not be
+         allowed to view the acl-node that has been created.
+        */
+        assertFalse(testAcMgr.hasPrivileges(path, privilegesFromName(Privilege.JCR_READ_ACCESS_CONTROL)));
+        assertFalse(testSession.itemExists(path + "/rep:policy"));
+
+        Node n = testSession.getNode(tmpl.getPath());
+        assertFalse(n.hasNode("rep:policy"));
+        try {
+            n.getNode("rep:policy");
+            fail("Accessing the rep:policy node must throw PathNotFoundException.");
+        } catch (PathNotFoundException e) {
+            // ok.
+        }
+
+        /* Finally the test user must not be allowed to remove the policy. */
+        try {
+            testAcMgr.removePolicy(path, new AccessControlPolicy() {});
+            fail("Test user must not be allowed to remove the access control policy.");
+        } catch (AccessDeniedException e) {
+            // success
+        }
+    }
+
+    public void testAccessControlModification() throws RepositoryException, NotExecutableException {
+        AccessControlManager testAcMgr = getTestACManager();
+        /* precondition:
+          testuser must have READ-only permission on test-node and below
+        */
+        checkReadOnly(path);
+        SessionImpl testSession = getTestSession();
+
+        // give 'testUser' ADD_CHILD_NODES|MODIFY_PROPERTIES| REMOVE_CHILD_NODES privileges at 'path'
+        Privilege[] privileges = privilegesFromNames(new String[] {
+                Privilege.JCR_ADD_CHILD_NODES,
+                Privilege.JCR_REMOVE_CHILD_NODES,
+                Privilege.JCR_MODIFY_PROPERTIES
+        });
+        JackrabbitAccessControlList tmpl = givePrivileges(path, privileges, getRestrictions(superuser, path));
+        /*
+         testuser must not have
+         - permission to view AC items
+         - permission to modify AC items
+        */
+
+        // make sure the 'rep:policy' node has been created.
+        assertTrue(superuser.itemExists(tmpl.getPath() + "/rep:policy"));
+        // the policy node however must not be visible to the test-user
+        assertFalse(testSession.itemExists(tmpl.getPath() + "/rep:policy"));
+        try {
+            testAcMgr.getPolicies(tmpl.getPath());
+            fail("test user must not have READ_AC privilege.");
+        } catch (AccessDeniedException e) {
+            // success
+        }
+        try {
+            testAcMgr.getEffectivePolicies(tmpl.getPath());
+            fail("test user must not have READ_AC privilege.");
+        } catch (AccessDeniedException e) {
+            // success
+        }
+        try {
+            testAcMgr.getEffectivePolicies(path);
+            fail("test user must not have READ_AC privilege.");
+        } catch (AccessDeniedException e) {
+            // success
+        }
+        try {
+            testAcMgr.removePolicy(tmpl.getPath(), new AccessControlPolicy() {});
+            fail("test user must not have MODIFY_AC privilege.");
+        } catch (AccessDeniedException e) {
+            // success
+        }
+    }
+
+    public void testWithDrawRead() throws RepositoryException, NotExecutableException {
+        /*
+         precondition:
+         testuser must have READ-only permission on test-node and below
+        */
+        checkReadOnly(path);
+
+        // give 'testUser' READ_AC|MODIFY_AC privileges at 'path'
+        Privilege[] grPrivs = privilegesFromName(PrivilegeRegistry.REP_WRITE);
+        givePrivileges(path, grPrivs, getRestrictions(superuser, path));
+        // withdraw the READ privilege
+        Privilege[] dnPrivs = privilegesFromName(Privilege.JCR_READ);
+        withdrawPrivileges(path, dnPrivs, getRestrictions(superuser, path));
+
+        // test if login as testuser -> item at path must not exist.
+        Session s = null;
+        try {
+            s = helper.getRepository().login(creds);
+            assertFalse(s.itemExists(path));
+        } finally {
+            if (s != null) {
+                s.logout();
+            }
+        }
+    }
+
+    public void testEventGeneration() throws RepositoryException, NotExecutableException {
+        /*
+         precondition:
+         testuser must have READ-only permission on test-node and below
+        */
+        checkReadOnly(path);
+        SessionImpl testSession = getTestSession();
+
+        // withdraw the READ privilege
+        Privilege[] dnPrivs = privilegesFromName(Privilege.JCR_READ);
+        withdrawPrivileges(path, dnPrivs, getRestrictions(superuser, path));
+
+        // testUser registers a eventlistener for 'path
+        ObservationManager obsMgr = testSession.getWorkspace().getObservationManager();
+        EventResult listener = new EventResult(((JUnitTest) this).log);
+        try {
+            obsMgr.addEventListener(listener, Event.NODE_REMOVED, path, true, new String[0], new String[0], true);
+
+            // superuser removes the node with childNPath in order to provoke
+            // events being generated
+            superuser.getItem(childNPath).remove();
+            superuser.save();
+
+            obsMgr.removeEventListener(listener);
+            // since the testUser does not have read-permission on the removed
+            // node, no corresponding event must be generated.
+            Event[] evts = listener.getEvents(DEFAULT_WAIT_TIMEOUT);
+            for (int i = 0; i < evts.length; i++) {
+                if (evts[i].getType() == Event.NODE_REMOVED &&
+                        evts[i].getPath().equals(childNPath)) {
+                    fail("TestUser does not have READ permission below " + path + " -> events below must not show up.");
+                }
+            }
+        } finally {
+            obsMgr.removeEventListener(listener);
+        }
+    }
+
+    public void testInheritance() throws RepositoryException, NotExecutableException {
+        SessionImpl testSession = getTestSession();
+        AccessControlManager testAcMgr = getTestACManager();
+        /* precondition:
+          testuser must have READ-only permission on test-node and below
+        */
+        checkReadOnly(path);
+        checkReadOnly(childNPath);
+
+        // give 'modify_properties' and 'remove_node' privilege on 'path'
+        Privilege[] privileges = privilegesFromNames(new String[] {
+                Privilege.JCR_REMOVE_NODE, Privilege.JCR_MODIFY_PROPERTIES});
+        givePrivileges(path, privileges, getRestrictions(superuser, path));
+        // give 'add-child-nodes', remove_child_nodes' on 'childNPath'
+        privileges = privilegesFromNames(new String[] {
+                Privilege.JCR_ADD_CHILD_NODES, Privilege.JCR_REMOVE_CHILD_NODES});
+        givePrivileges(childNPath, privileges, getRestrictions(superuser, childNPath));
+
+        /*
+        since evaluation respects inheritance through the node
+        hierarchy, the following privileges must now be given at 'childNPath':
+        - jcr:read
+        - jcr:modifyProperties
+        - jcr:addChildNodes
+        - jcr:removeChildNodes
+        - jcr:removeNode
+        */
+        Privilege[] expectedPrivileges =  privilegesFromNames(new String[] {
+                Privilege.JCR_READ,
+                Privilege.JCR_ADD_CHILD_NODES,
+                Privilege.JCR_REMOVE_CHILD_NODES,
+                Privilege.JCR_REMOVE_NODE,
+                Privilege.JCR_MODIFY_PROPERTIES
+        });
+        assertTrue(testAcMgr.hasPrivileges(childNPath, expectedPrivileges));
+
+        /*
+         ... permissions granted at childNPath:
+         - read
+         - set-property
+
+         BUT NOT:
+         - add-node
+         - remove.
+         */
+        String aActions = org.apache.jackrabbit.api.jsr283.Session.ACTION_SET_PROPERTY + "," + org.apache.jackrabbit.api.jsr283.Session.ACTION_READ;
+        assertTrue(testSession.hasPermission(childNPath, aActions));
+        String dActions = org.apache.jackrabbit.api.jsr283.Session.ACTION_REMOVE + "," + org.apache.jackrabbit.api.jsr283.Session.ACTION_ADD_NODE;
+        assertFalse(testSession.hasPermission(childNPath, dActions));
+
+        /*
+        ... permissions granted at any child item of child-path:
+        - read
+        - set-property
+        - add-node
+        - remove
+        */
+        String nonExistingItemPath = childNPath + "/anyItem";
+        assertTrue(testSession.hasPermission(nonExistingItemPath, aActions + "," + dActions));
+
+        /* try adding a new child node -> must succeed. */
+        Node childN = testSession.getNode(childNPath);
+        String testPath = childN.addNode(nodeName2).getPath();
+
+        /* test privileges on the 'new' child node */
+        assertTrue(testAcMgr.hasPrivileges(testPath, expectedPrivileges));
+
+        /* repeat test after save. */
+        testSession.save();
+        assertTrue(testAcMgr.hasPrivileges(testPath, expectedPrivileges));
+    }
+
+    public void testRemovePermission() throws NotExecutableException, RepositoryException {
+        /*
+          precondition:
+          testuser must have READ-only permission on test-node and below
+        */
+        checkReadOnly(path);
+        checkReadOnly(childNPath);
+        SessionImpl testSession = getTestSession();
+
+        Privilege[] rmChildNodes = privilegesFromName(Privilege.JCR_REMOVE_CHILD_NODES);
+
+        // add 'remove_child_nodes' privilge at 'path'
+        givePrivileges(path, rmChildNodes, getRestrictions(superuser, path));
+        /*
+         expected result:
+         - neither node at path nor at childNPath can be removed since
+           REMOVE_NODE privilege is missing.
+         */
+        assertFalse(testSession.hasPermission(path, org.apache.jackrabbit.api.jsr283.Session.ACTION_REMOVE));
+        assertFalse(testSession.hasPermission(childNPath, org.apache.jackrabbit.api.jsr283.Session.ACTION_REMOVE));
+    }
+
+    public void testRemovePermission2() throws NotExecutableException, RepositoryException {
+        /*
+          precondition:
+          testuser must have READ-only permission on test-node and below
+        */
+        checkReadOnly(path);
+        checkReadOnly(childNPath);
+        SessionImpl testSession = getTestSession();
+
+        Privilege[] rmChildNodes = privilegesFromName(Privilege.JCR_REMOVE_NODE);
+
+        // add 'remove_node' privilege at 'path'
+        givePrivileges(path, rmChildNodes, getRestrictions(superuser, path));
+        /*
+         expected result:
+         - neither node at path nor at childNPath can be removed permission
+           due to missing remove_child_nodes privilege.
+         */
+        assertFalse(testSession.hasPermission(path, org.apache.jackrabbit.api.jsr283.Session.ACTION_REMOVE));
+        assertFalse(testSession.hasPermission(childNPath, org.apache.jackrabbit.api.jsr283.Session.ACTION_REMOVE));
+    }
+
+    public void testRemovePermission3() throws NotExecutableException, RepositoryException {
+        AccessControlManager testAcMgr = getTestACManager();
+        /*
+          precondition:
+          testuser must have READ-only permission on test-node and below
+        */
+        checkReadOnly(path);
+        checkReadOnly(childNPath);
+        SessionImpl testSession = getTestSession();
+
+        Privilege[] privs = privilegesFromNames(new String[] {
+                Privilege.JCR_REMOVE_CHILD_NODES, Privilege.JCR_REMOVE_NODE
+        });
+        // add 'remove_node' and 'remove_child_nodes' privilge at 'path'
+        givePrivileges(path, privs, getRestrictions(superuser, path));
+        /*
+         expected result:
+         - missing remove permission at path since REMOVE_CHILD_NODES present
+           at path only applies for nodes below. REMOVE_CHILD_NODES must
+           be present at the parent instead (which isn't)
+         - remove permission is however granted at childNPath.
+         - privileges: both at path and at childNPath 'remove_node' and
+           'remove_child_nodes' are present.
+        */
+        assertFalse(testSession.hasPermission(path, org.apache.jackrabbit.api.jsr283.Session.ACTION_REMOVE));
+        assertTrue(testSession.hasPermission(childNPath, org.apache.jackrabbit.api.jsr283.Session.ACTION_REMOVE));
+
+        assertTrue(testAcMgr.hasPrivileges(path, privs));
+        assertTrue(testAcMgr.hasPrivileges(childNPath, privs));
+    }
+
+    public void testRemovePermission4() throws NotExecutableException, RepositoryException {
+        SessionImpl testSession = getTestSession();
+        AccessControlManager testAcMgr = getTestACManager();
+        /*
+          precondition:
+          testuser must have READ-only permission on test-node and below
+        */
+        checkReadOnly(path);
+        checkReadOnly(childNPath);
+
+        Privilege[] rmChildNodes = privilegesFromName(Privilege.JCR_REMOVE_CHILD_NODES);
+        Privilege[] rmNode = privilegesFromName(Privilege.JCR_REMOVE_NODE);
+
+        // add 'remove_child_nodes' privilge at 'path'...
+        givePrivileges(path, rmChildNodes, getRestrictions(superuser, path));
+        // ... and add 'remove_node' privilge at 'childNPath'
+        givePrivileges(childNPath, rmNode, getRestrictions(superuser, childNPath));
+        /*
+         expected result:
+         - remove not allowed for node at path
+         - remove-permission present for node at childNPath
+         - both remove_node and remove_childNodes privilege present at childNPath
+         */
+        assertFalse(testSession.hasPermission(path, org.apache.jackrabbit.api.jsr283.Session.ACTION_REMOVE));
+        assertTrue(testSession.hasPermission(childNPath, org.apache.jackrabbit.api.jsr283.Session.ACTION_REMOVE));
+        assertTrue(testAcMgr.hasPrivileges(childNPath, new Privilege[] {rmChildNodes[0], rmNode[0]}));
+    }
+
+    public void testRemovePermission5() throws NotExecutableException, RepositoryException {
+        /*
+          precondition:
+          testuser must have READ-only permission on test-node and below
+        */
+        checkReadOnly(path);
+        checkReadOnly(childNPath);
+
+        Privilege[] rmNode = privilegesFromName(Privilege.JCR_REMOVE_NODE);
+
+        // add 'remove_node' privilege at 'childNPath'
+        givePrivileges(childNPath, rmNode, getRestrictions(superuser, childNPath));
+        /*
+         expected result:
+         - node at childNPath can't be removed since REMOVE_CHILD_NODES is missing.
+         */
+        assertFalse(getTestSession().hasPermission(childNPath, org.apache.jackrabbit.api.jsr283.Session.ACTION_REMOVE));
+    }
+
+    public void testRemovePermission6() throws NotExecutableException, RepositoryException {
+        SessionImpl testSession = getTestSession();
+        AccessControlManager testAcMgr = getTestACManager();
+        /*
+          precondition:
+          testuser must have READ-only permission on test-node and below
+        */
+        checkReadOnly(path);
+        checkReadOnly(childNPath);
+
+        Privilege[] privs = privilegesFromNames(new String[] {
+                Privilege.JCR_REMOVE_CHILD_NODES, Privilege.JCR_REMOVE_NODE
+        });
+        Privilege[] rmNode = privilegesFromName(Privilege.JCR_REMOVE_NODE);
+
+        // add 'remove_child_nodes' and 'remove_node' privilge at 'path'
+        givePrivileges(path, privs, getRestrictions(superuser, path));
+        // ... but deny 'remove_node' at childNPath
+        withdrawPrivileges(childNPath, rmNode, getRestrictions(superuser, childNPath));
+        /*
+         expected result:
+         - neither node at path nor at childNPath could be removed.
+         - no remove_node privilege at childNPath
+         - read, remove_child_nodes privilege at childNPath
+         */
+        assertFalse(testSession.hasPermission(path, org.apache.jackrabbit.api.jsr283.Session.ACTION_REMOVE));
+        assertFalse(testSession.hasPermission(childNPath, org.apache.jackrabbit.api.jsr283.Session.ACTION_REMOVE));
+        assertTrue(testAcMgr.hasPrivileges(childNPath, privilegesFromNames(new String[] {Privilege.JCR_READ, Privilege.JCR_REMOVE_CHILD_NODES})));
+        assertFalse(testAcMgr.hasPrivileges(childNPath, privilegesFromName(Privilege.JCR_REMOVE_NODE)));
+    }
+
+    public void testRemovePermission7() throws NotExecutableException, RepositoryException {
+        SessionImpl testSession = getTestSession();
+        AccessControlManager testAcMgr = getTestACManager();
+        /*
+          precondition:
+          testuser must have READ-only permission on test-node and below
+        */
+        checkReadOnly(path);
+        checkReadOnly(childNPath);
+
+        Privilege[] rmChildNodes = privilegesFromName(Privilege.JCR_REMOVE_CHILD_NODES);
+        Privilege[] rmNode = privilegesFromName(Privilege.JCR_REMOVE_NODE);
+
+        // deny 'remove_child_nodes' at 'path'
+        withdrawPrivileges(path, rmChildNodes, getRestrictions(superuser, path));
+        // ... but allow 'remove_node' at childNPath
+        givePrivileges(childNPath, rmNode, getRestrictions(superuser, childNPath));
+        /*
+         expected result:
+         - node at childNPath can't be removed.
+         */
+        assertFalse(testSession.hasPermission(childNPath, org.apache.jackrabbit.api.jsr283.Session.ACTION_REMOVE));
+
+        // additionally add remove_child_nodes priv at 'childNPath'
+        givePrivileges(childNPath, rmChildNodes, getRestrictions(superuser, childNPath));
+        /*
+         expected result:
+         - node at childNPath still can't be removed.
+         - but both privileges (remove_node, remove_child_nodes) are present.
+         */
+        assertFalse(testSession.hasPermission(childNPath, org.apache.jackrabbit.api.jsr283.Session.ACTION_REMOVE));
+        assertTrue(testAcMgr.hasPrivileges(childNPath, new Privilege[] {rmChildNodes[0], rmNode[0]}));
+    }
+
+    public void testRemovePermission8() throws NotExecutableException, RepositoryException {
+        AccessControlManager testAcMgr = getTestACManager();
+        /*
+          precondition:
+          testuser must have READ-only permission on test-node and below
+        */
+        checkReadOnly(path);
+        checkReadOnly(childNPath);
+
+        Privilege[] rmChildNodes = privilegesFromName(Privilege.JCR_REMOVE_CHILD_NODES);
+        Privilege[] rmNode = privilegesFromName(Privilege.JCR_REMOVE_NODE);
+
+        // add 'remove_child_nodes' at 'path
+        givePrivileges(path, rmChildNodes, getRestrictions(superuser, path));
+        // deny 'remove_node' at 'path'
+        withdrawPrivileges(path, rmNode, getRestrictions(superuser, path));
+        // and allow 'remove_node' at childNPath
+        givePrivileges(childNPath, rmNode, getRestrictions(superuser, childNPath));
+        /*
+         expected result:
+         - remove permission must be granted at childNPath
+         */
+        assertTrue(getTestSession().hasPermission(childNPath, org.apache.jackrabbit.api.jsr283.Session.ACTION_REMOVE));
+        assertTrue(testAcMgr.hasPrivileges(childNPath, new Privilege[] {rmChildNodes[0], rmNode[0]}));
+    }
+
+    public void testSessionMove() throws RepositoryException, NotExecutableException {
+        /*
+          precondition:
+          testuser must have READ-only permission on test-node and below
+        */
+        checkReadOnly(path);
+        checkReadOnly(childNPath);
+        SessionImpl testSession = getTestSession();
+
+        String destPath = path + "/" + nodeName1;
+
+        // give 'add_child_nodes' and 'nt-management' privilege
+        // -> not sufficient privileges for a move
+        givePrivileges(path, privilegesFromNames(new String[] {Privilege.JCR_ADD_CHILD_NODES, Privilege.JCR_NODE_TYPE_MANAGEMENT}), getRestrictions(superuser, path));
+        try {
+            testSession.move(childNPath, destPath);
+            testSession.save();
+            fail("Move requires add and remove permission.");
+        } catch (AccessDeniedException e) {
+            // success.
+        }
+
+        // add 'remove_child_nodes' at 'path
+        // -> not sufficient for a move since 'remove_node' privilege is missing
+        //    on the move-target
+        givePrivileges(path, privilegesFromName(Privilege.JCR_REMOVE_CHILD_NODES), getRestrictions(superuser, path));
+        try {
+            testSession.move(childNPath, destPath);
+            testSession.save();
+            fail("Move requires add and remove permission.");
+        } catch (AccessDeniedException e) {
+            // success.
+        }
+
+        // allow 'remove_node' at childNPath
+        // -> now move must succeed
+        givePrivileges(childNPath, privilegesFromName(Privilege.JCR_REMOVE_NODE), getRestrictions(superuser, childNPath));
+        testSession.move(childNPath, destPath);
+        testSession.save();
+
+        // withdraw  'add_child_nodes' privilege on former src-parent
+        // -> moving child-node back must fail
+        withdrawPrivileges(path, privilegesFromName(Privilege.JCR_ADD_CHILD_NODES), getRestrictions(superuser, path));
+        try {
+            testSession.move(destPath, childNPath);
+            testSession.save();
+            fail("Move requires add and remove permission.");
+        } catch (AccessDeniedException e) {
+            // success.
+        }
+    }
+
+    public void testWorkspaceMove() throws RepositoryException, NotExecutableException {
+        /*
+          precondition:
+          testuser must have READ-only permission on test-node and below
+        */
+        checkReadOnly(path);
+        checkReadOnly(childNPath);
+        SessionImpl testSession = getTestSession();
+
+        String destPath = path + "/" + nodeName1;
+
+        // give 'add_child_nodes', 'nt-mgmt' privilege
+        // -> not sufficient privileges for a move.
+        givePrivileges(path, privilegesFromNames(new String[] {Privilege.JCR_ADD_CHILD_NODES,
+                Privilege.JCR_NODE_TYPE_MANAGEMENT}), getRestrictions(superuser, path));
+        try {
+            testSession.getWorkspace().move(childNPath, destPath);
+            fail("Move requires add and remove permission.");
+        } catch (AccessDeniedException e) {
+            // success.
+        }
+
+        // add 'remove_child_nodes' at 'path
+        // -> no sufficient for a move since 'remove_node' privilege is missing
+        //    on the move-target
+        givePrivileges(path, privilegesFromName(Privilege.JCR_REMOVE_CHILD_NODES), getRestrictions(superuser, path));
+        try {
+            testSession.getWorkspace().move(childNPath, destPath);
+            fail("Move requires add and remove permission.");
+        } catch (AccessDeniedException e) {
+            // success.
+        }
+
+        // allow 'remove_node' at childNPath
+        // -> now move must succeed
+        givePrivileges(childNPath, privilegesFromName(Privilege.JCR_REMOVE_NODE),
+                getRestrictions(superuser, childNPath));
+        testSession.getWorkspace().move(childNPath, destPath);
+
+        // withdraw  'add_child_nodes' privilege on former src-parent
+        // -> moving child-node back must fail
+        withdrawPrivileges(path, privilegesFromName(Privilege.JCR_ADD_CHILD_NODES), getRestrictions(superuser, path));
+        try {
+            testSession.getWorkspace().move(destPath, childNPath);
+            fail("Move requires add and remove permission.");
+        } catch (AccessDeniedException e) {
+            // success.
+        }
+    }
+
+    public void testGroupPermissions() throws NotExecutableException, RepositoryException {
+        Group testGroup = getTestGroup();
+        AccessControlManager testAcMgr = getTestACManager();
+        /*
+         precondition:
+         testuser must have READ-only permission on test-node and below
+        */
+        checkReadOnly(path);
+
+        /* add privileges for the Group the test-user is member of */
+        Privilege[] privileges = privilegesFromName(Privilege.JCR_MODIFY_PROPERTIES);
+        givePrivileges(path, testGroup.getPrincipal(), privileges, getRestrictions(superuser, path));
+
+        /* testuser must get the permissions/privileges inherited from
+           the group it is member of.
+         */
+        String actions = org.apache.jackrabbit.api.jsr283.Session.ACTION_SET_PROPERTY + "," + org.apache.jackrabbit.api.jsr283.Session.ACTION_READ;
+
+        assertTrue(getTestSession().hasPermission(path, actions));
+        Privilege[] privs = privilegesFromName(Privilege.JCR_MODIFY_PROPERTIES);
+        assertTrue(testAcMgr.hasPrivileges(path, privs));
+    }
+
+    public void testMixedUserGroupPermissions() throws NotExecutableException, RepositoryException {
+        Group testGroup = getTestGroup();
+        AccessControlManager testAcMgr = getTestACManager();
+        /*
+         precondition:
+         testuser must have READ-only permission on test-node and below
+        */
+        checkReadOnly(path);
+
+        /* explicitely withdraw MODIFY_PROPERTIES for the user */
+        Privilege[] privileges = privilegesFromName(Privilege.JCR_MODIFY_PROPERTIES);
+        withdrawPrivileges(path, testUser.getPrincipal(), privileges, getRestrictions(superuser, path));
+        /* give MODIFY_PROPERTIES privilege for a Group the test-user is member of */
+        givePrivileges(path, testGroup.getPrincipal(), privileges, getRestrictions(superuser, path));
+        /*
+         since user-permissions overrule the group permissions, testuser must
+         not have set_property action / modify_properties privilege.
+         */
+        String actions = org.apache.jackrabbit.api.jsr283.Session.ACTION_SET_PROPERTY;
+        assertFalse(getTestSession().hasPermission(path, actions));
+        assertFalse(testAcMgr.hasPrivileges(path, privilegesFromName(Privilege.JCR_MODIFY_PROPERTIES)));
+    }
+
+    public void testNewNodes() throws RepositoryException, NotExecutableException {
+        AccessControlManager testAcMgr = getTestACManager();
+        /*
+         precondition:
+         testuser must have READ-only permission on test-node and below
+        */
+        checkReadOnly(path);
+
+        /* create some new nodes below 'path' */
+        Node n = ((SessionImpl) superuser).getNode(path);
+        for (int i = 0; i < 5; i++) {
+            n = n.addNode(nodeName2, testNodeType);
+        }
+        superuser.save();
+
+        /* make sure the same privileges/permissions are granted as at path. */
+        String childPath = n.getPath();
+        Privilege[] privs = testAcMgr.getPrivileges(childPath);
+        assertEquals(PrivilegeRegistry.getBits(privilegesFromName(Privilege.JCR_READ)),
+                PrivilegeRegistry.getBits(privs));
+        getTestSession().checkPermission(childPath, org.apache.jackrabbit.api.jsr283.Session.ACTION_READ);
+    }
+
+    public void testNonExistingItem() throws RepositoryException, NotExecutableException {
+        /*
+          precondition:
+          testuser must have READ-only permission on the root node and below
+        */
+        Session testSession = getTestSession();
+        String rootPath = testSession.getRootNode().getPath();
+        checkReadOnly(rootPath);
+        testSession.checkPermission(rootPath + "nonExistingItem", org.apache.jackrabbit.api.jsr283.Session.ACTION_READ);
+    }
+
+    public void testACItemsAreProtected() throws NotExecutableException, RepositoryException {
+        // search for a rep:policy node
+        Node policyNode = findPolicyNode(superuser.getRootNode());
+        if (policyNode == null) {
+            throw new NotExecutableException("no policy node found.");
+        }
+
+        assertTrue("The rep:Policy node must be protected", policyNode.getDefinition().isProtected());
+        try {
+            policyNode.remove();
+            fail("rep:Policy node must be protected.");
+        } catch (ConstraintViolationException e) {
+            // success
+        }
+
+        for (NodeIterator it = policyNode.getNodes(); it.hasNext();) {
+            Node n = it.nextNode();
+            if (n.isNodeType("rep:ACE")) {
+                try {
+                    n.remove();
+                    fail("ACE node must be protected.");
+                } catch (ConstraintViolationException e) {
+                    // success
+                }
+                break;
+            }
+        }
+
+        try {
+            policyNode.setProperty("test", "anyvalue");
+            fail("rep:policy node must be protected.");
+        } catch (ConstraintViolationException e) {
+            // success
+        }
+        try {
+            policyNode.addNode("test", "rep:ACE");
+            fail("rep:policy node must be protected.");
+        } catch (ConstraintViolationException e) {
+            // success
+        }
+    }
+
+    /**
+     * the ADD_CHILD_NODES privileges assigned on a node to a specific principal
+     * grants the corresponding user the permission to add nodes below the
+     * target node but not 'at' the target node.
+     *
+     * @throws RepositoryException
+     * @throws NotExecutableException
+     */
+    public void testAddChildNodePrivilege() throws RepositoryException, NotExecutableException {
+        /*
+         precondition:
+         testuser must have READ-only permission on test-node and below
+        */
+        checkReadOnly(path);
+
+        /* create a child node below node at 'path' */
+        Node n = ((SessionImpl) superuser).getNode(path);
+        n = n.addNode(nodeName2, testNodeType);
+        superuser.save();
+
+        /* add 'add_child_nodes' privilege for testSession at path. */
+        Privilege[] privileges = privilegesFromName(Privilege.JCR_ADD_CHILD_NODES);
+        givePrivileges(path, privileges, getRestrictions(superuser, path));
+
+        /* test permissions. expected result:
+           - testSession cannot add child-nodes at 'path'
+           - testSession can add child-nodes below path
+         */
+        SessionImpl testSession = getTestSession();
+        assertFalse(testSession.hasPermission(path, org.apache.jackrabbit.api.jsr283.Session.ACTION_ADD_NODE));
+        assertTrue(testSession.hasPermission(path+"/anychild", org.apache.jackrabbit.api.jsr283.Session.ACTION_ADD_NODE));
+        String childPath = n.getPath();
+        assertTrue(testSession.hasPermission(childPath, org.apache.jackrabbit.api.jsr283.Session.ACTION_ADD_NODE));
+    }
+
+    public void testAclReferingToRemovedPrincipal() throws
+            NotExecutableException, RepositoryException {
+
+        JackrabbitAccessControlList acl = givePrivileges(path, privilegesFromName(PrivilegeRegistry.REP_WRITE), getRestrictions(superuser, path));
+        String acPath = acl.getPath();
+
+        // remove the test user
+        testUser.remove();
+        testUser = null;
+
+        // try to retrieve the acl again
+        AccessControlManager acMgr = getAccessControlManager(helper.getSuperuserSession());
+        acMgr.getPolicies(acPath);
+    }
+
+    private static Node findPolicyNode(Node start) throws RepositoryException {
+        Node policyNode = null;
+        if (start.isNodeType("rep:Policy")) {
+            policyNode = start;
+        }
+        for (NodeIterator it = start.getNodes(); it.hasNext() && policyNode == null;) {
+            Node n = it.nextNode();
+            if (!"jcr:system".equals(n.getName())) {
+                policyNode = findPolicyNode(n);
+            }
+        }
+        return policyNode;
+    }
+}
\ No newline at end of file

Propchange: jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authorization/AbstractWriteTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authorization/AbstractWriteTest.java
------------------------------------------------------------------------------
    svn:keywords = author date id revision url

Modified: jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authorization/JackrabbitAccessControlListTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authorization/JackrabbitAccessControlListTest.java?rev=732693&r1=732692&r2=732693&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authorization/JackrabbitAccessControlListTest.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authorization/JackrabbitAccessControlListTest.java Thu Jan  8 03:52:38 2009
@@ -113,7 +113,7 @@
                     allows |= bits;
                 }
             }
-            assertEquals(PrivilegeRegistry.ALL, allows);
+            assertEquals(PrivilegeRegistry.getBits(priv), allows);
         } else {
             AccessControlEntry[] entries = templ.getAccessControlEntries();
             assertEquals("Grant ALL not successful -> entries must not have changed.", entriesBefore, Arrays.asList(entries));
@@ -122,7 +122,7 @@
 
     public void testAddEntry2() throws NotExecutableException, RepositoryException {
         Principal princ = getValidPrincipal();
-        Privilege[] privs = privilegesFromName(Privilege.JCR_WRITE);
+        Privilege[] privs = privilegesFromName(PrivilegeRegistry.REP_WRITE);
 
         int allows = 0;
         templ.addEntry(princ, privs, true, Collections.EMPTY_MAP);
@@ -136,12 +136,12 @@
                 allows |= bits;
             }
         }
-        assertTrue("After successfully granting WRITE, the entries must reflect this", allows >= PrivilegeRegistry.WRITE);
+        assertTrue("After successfully granting WRITE, the entries must reflect this", allows >= PrivilegeRegistry.getBits(privs));
     }
 
     public void testAllowWriteDenyRemove() throws NotExecutableException, RepositoryException {
         Principal princ = getValidPrincipal();
-        Privilege[] grPriv = privilegesFromName(Privilege.JCR_WRITE);
+        Privilege[] grPriv = privilegesFromName(PrivilegeRegistry.REP_WRITE);
         Privilege[] dePriv = privilegesFromName(Privilege.JCR_REMOVE_CHILD_NODES);
 
         templ.addEntry(princ, grPriv, true, Collections.EMPTY_MAP);
@@ -154,7 +154,7 @@
             AccessControlEntry en = entries[i];
             if (princ.equals(en.getPrincipal()) && en instanceof JackrabbitAccessControlEntry) {
                 JackrabbitAccessControlEntry ace = (JackrabbitAccessControlEntry) en;
-                int entryBits = ace.getPrivilegeBits();
+                int entryBits = PrivilegeRegistry.getBits(ace.getPrivileges());
                 if (ace.isAllow()) {
                     allows |= Permission.diff(entryBits, denies);
                 } else {
@@ -163,15 +163,15 @@
             }
         }
 
-        int expectedAllows = Permission.diff(PrivilegeRegistry.WRITE, PrivilegeRegistry.REMOVE_CHILD_NODES);
-        assertEquals(expectedAllows, allows & expectedAllows);
-        int expectedDenies = PrivilegeRegistry.REMOVE_CHILD_NODES;
+        int expectedAllows = PrivilegeRegistry.getBits(grPriv) ^ PrivilegeRegistry.getBits(dePriv);
+        assertEquals(expectedAllows, allows);
+        int expectedDenies = PrivilegeRegistry.getBits(dePriv);
         assertEquals(expectedDenies, denies);
     }
 
     public void testRemoveEntry() throws NotExecutableException, RepositoryException {
         Principal princ = getValidPrincipal();
-        Privilege[] grPriv = privilegesFromName(Privilege.JCR_WRITE);
+        Privilege[] grPriv = privilegesFromName(PrivilegeRegistry.REP_WRITE);
 
         templ.addEntry(princ, grPriv, true, Collections.EMPTY_MAP);
         AccessControlEntry[] entries = templ.getAccessControlEntries();

Modified: jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authorization/PrivilegeRegistryTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authorization/PrivilegeRegistryTest.java?rev=732693&r1=732692&r2=732693&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authorization/PrivilegeRegistryTest.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authorization/PrivilegeRegistryTest.java Thu Jan  8 03:52:38 2009
@@ -47,6 +47,8 @@
                     return Name.NS_JCR_URI;
                 } else if (Name.NS_EMPTY_PREFIX.equals(prefix)) {
                     return Name.NS_DEFAULT_URI;
+                } else if (Name.NS_REP_PREFIX.equals(prefix)) {
+                    return Name.NS_REP_URI;
                 } else {
                     throw new NamespaceException();
                 }
@@ -56,6 +58,8 @@
                     return Name.NS_JCR_PREFIX;
                 } else if (Name.NS_DEFAULT_URI.equals(uri)) {
                     return Name.NS_EMPTY_PREFIX;
+                } else if (Name.NS_REP_URI.equals(uri)) {
+                    return Name.NS_REP_PREFIX;
                 } else {
                     throw new NamespaceException();
                 }
@@ -69,6 +73,15 @@
         assertEquals("Privilege names are not the same", resolver.getQName(expected), resolver.getQName(present));
     }
 
+    private Privilege[] privilegesFromNames(String[] privNames)
+            throws RepositoryException {
+        Privilege[] privs = new Privilege[privNames.length];
+        for (int i = 0; i < privNames.length; i++) {
+            privs[i] = privilegeRegistry.getPrivilege(privNames[i]);
+        }
+        return privs;
+    }
+
     public void testRegisteredPrivileges() throws RepositoryException {
         Privilege[] ps = privilegeRegistry.getRegisteredPrivileges();
 
@@ -82,6 +95,12 @@
         assertTrue(l.remove(privilegeRegistry.getPrivilege(Privilege.JCR_MODIFY_ACCESS_CONTROL)));
         assertTrue(l.remove(privilegeRegistry.getPrivilege(Privilege.JCR_WRITE)));
         assertTrue(l.remove(privilegeRegistry.getPrivilege(Privilege.JCR_ALL)));
+        assertTrue(l.remove(privilegeRegistry.getPrivilege(Privilege.JCR_LIFECYCLE_MANAGEMENT)));
+        assertTrue(l.remove(privilegeRegistry.getPrivilege(Privilege.JCR_LOCK_MANAGEMENT)));
+        assertTrue(l.remove(privilegeRegistry.getPrivilege(Privilege.JCR_NODE_TYPE_MANAGEMENT)));
+        assertTrue(l.remove(privilegeRegistry.getPrivilege(Privilege.JCR_RETENTION_MANAGEMENT)));
+        assertTrue(l.remove(privilegeRegistry.getPrivilege(Privilege.JCR_VERSION_MANAGEMENT)));
+        assertTrue(l.remove(privilegeRegistry.getPrivilege(PrivilegeRegistry.REP_WRITE)));        
         assertTrue(l.isEmpty());
     }
 
@@ -99,24 +118,35 @@
         assertTrue(l.remove(privilegeRegistry.getPrivilege(Privilege.JCR_REMOVE_NODE)));
         assertTrue(l.remove(privilegeRegistry.getPrivilege(Privilege.JCR_READ_ACCESS_CONTROL)));
         assertTrue(l.remove(privilegeRegistry.getPrivilege(Privilege.JCR_MODIFY_ACCESS_CONTROL)));
+        assertTrue(l.remove(privilegeRegistry.getPrivilege(Privilege.JCR_LIFECYCLE_MANAGEMENT)));
+        assertTrue(l.remove(privilegeRegistry.getPrivilege(Privilege.JCR_LOCK_MANAGEMENT)));
+        assertTrue(l.remove(privilegeRegistry.getPrivilege(Privilege.JCR_NODE_TYPE_MANAGEMENT)));
+        assertTrue(l.remove(privilegeRegistry.getPrivilege(Privilege.JCR_RETENTION_MANAGEMENT)));
+        assertTrue(l.remove(privilegeRegistry.getPrivilege(Privilege.JCR_VERSION_MANAGEMENT)));
         assertTrue(l.isEmpty());
 
         l = new ArrayList(Arrays.asList(p.getDeclaredAggregatePrivileges()));
         assertTrue(l.remove(privilegeRegistry.getPrivilege(Privilege.JCR_READ)));
         assertTrue(l.remove(privilegeRegistry.getPrivilege(Privilege.JCR_WRITE)));
-        assertTrue(l.remove(privilegeRegistry.getPrivilege(Privilege.JCR_REMOVE_NODE)));
+        assertTrue(l.remove(privilegeRegistry.getPrivilege(PrivilegeRegistry.REP_WRITE)));
         assertTrue(l.remove(privilegeRegistry.getPrivilege(Privilege.JCR_READ_ACCESS_CONTROL)));
         assertTrue(l.remove(privilegeRegistry.getPrivilege(Privilege.JCR_MODIFY_ACCESS_CONTROL)));
+        assertTrue(l.remove(privilegeRegistry.getPrivilege(Privilege.JCR_LIFECYCLE_MANAGEMENT)));
+        assertTrue(l.remove(privilegeRegistry.getPrivilege(Privilege.JCR_LOCK_MANAGEMENT)));
+        assertTrue(l.remove(privilegeRegistry.getPrivilege(Privilege.JCR_RETENTION_MANAGEMENT)));
+        assertTrue(l.remove(privilegeRegistry.getPrivilege(Privilege.JCR_VERSION_MANAGEMENT)));
         assertTrue(l.isEmpty());
     }
 
     public void testGetBits() throws RepositoryException {
-        Privilege[] privs = new Privilege[] {privilegeRegistry.getPrivilege(Privilege.JCR_ADD_CHILD_NODES),
-                                             privilegeRegistry.getPrivilege(Privilege.JCR_REMOVE_CHILD_NODES)};
+        Privilege p1 = privilegeRegistry.getPrivilege(Privilege.JCR_ADD_CHILD_NODES);
+        Privilege p2 = privilegeRegistry.getPrivilege(Privilege.JCR_REMOVE_CHILD_NODES);
+        Privilege[] privs = new Privilege[] {p1, p2};
 
         int bits = PrivilegeRegistry.getBits(privs);
         assertTrue(bits > PrivilegeRegistry.NO_PRIVILEGE);
-        assertTrue(bits == (PrivilegeRegistry.ADD_CHILD_NODES | PrivilegeRegistry.REMOVE_CHILD_NODES));
+        assertTrue(bits == (PrivilegeRegistry.getBits(new Privilege[] {p1}) |
+                PrivilegeRegistry.getBits(new Privilege[] {p2})));
     }
 
     public void testGetBitsFromCustomPrivilege() throws AccessControlException {
@@ -141,7 +171,7 @@
 
     public void testGetBitsFromNull() {
         try {
-            PrivilegeRegistry.getBits((Privilege[]) null);
+            PrivilegeRegistry.getBits(null);
             fail("Should throw AccessControlException");
         } catch (AccessControlException e) {
             // ok
@@ -168,7 +198,7 @@
     }
 
     public void testGetPrivilegesFromBits() throws RepositoryException {
-        Privilege[] pvs = privilegeRegistry.getPrivileges(PrivilegeRegistry.READ_AC);
+        Privilege[] pvs = privilegeRegistry.getPrivileges(PrivilegeRegistry.getBits(privilegesFromNames(new String[] {Privilege.JCR_READ_ACCESS_CONTROL})));
 
         assertTrue(pvs != null);
         assertTrue(pvs.length == 1);
@@ -176,14 +206,58 @@
     }
 
     public void testGetPrivilegesFromBits2() throws RepositoryException {
-        int writeBits = PrivilegeRegistry.ADD_CHILD_NODES | PrivilegeRegistry.REMOVE_CHILD_NODES | PrivilegeRegistry.MODIFY_PROPERTIES;
+        String[] names = new String[] {
+                Privilege.JCR_ADD_CHILD_NODES,
+                Privilege.JCR_REMOVE_CHILD_NODES,
+                Privilege.JCR_REMOVE_NODE,
+                Privilege.JCR_MODIFY_PROPERTIES
+        };
+        int writeBits = PrivilegeRegistry.getBits(privilegesFromNames(names));
         Privilege[] pvs = privilegeRegistry.getPrivileges(writeBits);
 
         assertTrue(pvs != null);
         assertTrue(pvs.length == 1);
         assertSamePrivilegeName(pvs[0].getName(), Privilege.JCR_WRITE);
         assertTrue(pvs[0].isAggregate());
-        assertTrue(pvs[0].getDeclaredAggregatePrivileges().length == 3);
+        assertTrue(pvs[0].getDeclaredAggregatePrivileges().length == names.length);
+    }
+
+    public void testGetPrivilegesFromBits3() throws RepositoryException {
+        String[] names = new String[] {
+                PrivilegeRegistry.REP_WRITE
+        };
+        int writeBits = PrivilegeRegistry.getBits(privilegesFromNames(names));
+        Privilege[] pvs = privilegeRegistry.getPrivileges(writeBits);
+
+        assertTrue(pvs != null);
+        assertTrue(pvs.length == 1);
+        assertSamePrivilegeName(pvs[0].getName(), PrivilegeRegistry.REP_WRITE);
+        assertTrue(pvs[0].isAggregate());
+
+        names = new String[] {
+                PrivilegeRegistry.REP_WRITE,
+                Privilege.JCR_WRITE
+        };
+        writeBits = PrivilegeRegistry.getBits(privilegesFromNames(names));
+        pvs = privilegeRegistry.getPrivileges(writeBits);
+
+        assertTrue(pvs != null);
+        assertTrue(pvs.length == 1);
+        assertSamePrivilegeName(pvs[0].getName(), PrivilegeRegistry.REP_WRITE);
+        assertTrue(pvs[0].isAggregate());
+        assertTrue(pvs[0].getDeclaredAggregatePrivileges().length == names.length);
+    }
+
+    public void testGetPrivilegesFromBits4() throws RepositoryException {
+        String[] names = new String[] {
+                PrivilegeRegistry.REP_WRITE,
+                Privilege.JCR_LIFECYCLE_MANAGEMENT
+        };
+        int writeBits = PrivilegeRegistry.getBits(privilegesFromNames(names));
+        Privilege[] pvs = privilegeRegistry.getPrivileges(writeBits);
+
+        assertTrue(pvs != null);
+        assertTrue(pvs.length == 2);
     }
 
     public void testGetPrivilegeFromName() throws AccessControlException, RepositoryException {

Modified: jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authorization/acl/ACLTemplateTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authorization/acl/ACLTemplateTest.java?rev=732693&r1=732692&r2=732693&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authorization/acl/ACLTemplateTest.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authorization/acl/ACLTemplateTest.java Thu Jan  8 03:52:38 2009
@@ -23,7 +23,6 @@
 import org.apache.jackrabbit.api.security.principal.PrincipalManager;
 import org.apache.jackrabbit.api.security.principal.PrincipalIterator;
 import org.apache.jackrabbit.core.security.authorization.AbstractACLTemplateTest;
-import org.apache.jackrabbit.core.security.authorization.JackrabbitAccessControlEntry;
 import org.apache.jackrabbit.core.security.authorization.JackrabbitAccessControlList;
 import org.apache.jackrabbit.core.security.authorization.PrivilegeRegistry;
 import org.apache.jackrabbit.core.SessionImpl;
@@ -96,24 +95,25 @@
     }
 
     public void testMultipleEntryEffect2() throws RepositoryException, NotExecutableException {
-        Privilege[] privileges = privilegesFromName(Privilege.JCR_WRITE);
+        Privilege[] privileges = privilegesFromName(PrivilegeRegistry.REP_WRITE);
         JackrabbitAccessControlList pt = createEmptyTemplate(getTestPath());
         pt.addAccessControlEntry(testPrincipal, privileges);
 
         // add deny entry for mod_props
-        privileges = privilegesFromName(Privilege.JCR_MODIFY_PROPERTIES);
-        assertTrue(pt.addEntry(testPrincipal, privileges, false, null));
+        Privilege[] privileges2 = privilegesFromName(Privilege.JCR_MODIFY_PROPERTIES);
+        assertTrue(pt.addEntry(testPrincipal, privileges2, false, null));
 
         // net-effect: 2 entries with the allow entry being adjusted
         assertTrue(pt.size() == 2);
         AccessControlEntry[] entries = pt.getAccessControlEntries();
         for (int i = 0; i < entries.length; i++) {
-            JackrabbitAccessControlEntry entry = (JackrabbitAccessControlEntry) entries[i];
+            ACLTemplate.Entry entry = (ACLTemplate.Entry) entries[i];
             int privs = entry.getPrivilegeBits();
             if (entry.isAllow()) {
-                assertEquals(privs, (PrivilegeRegistry.ADD_CHILD_NODES | PrivilegeRegistry.REMOVE_CHILD_NODES));
+                int bits = PrivilegeRegistry.getBits(privileges) ^ PrivilegeRegistry.getBits(privileges2);
+                assertEquals(privs, bits);
             } else {
-                assertEquals(privs, PrivilegeRegistry.MODIFY_PROPERTIES);
+                assertEquals(privs, PrivilegeRegistry.getBits(privileges2));
             }
         }
     }

Added: jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authorization/acl/EvaluationUtil.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authorization/acl/EvaluationUtil.java?rev=732693&view=auto
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authorization/acl/EvaluationUtil.java (added)
+++ jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authorization/acl/EvaluationUtil.java Thu Jan  8 03:52:38 2009
@@ -0,0 +1,55 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.core.security.authorization.acl;
+
+import org.apache.jackrabbit.core.security.authorization.JackrabbitAccessControlList;
+import org.apache.jackrabbit.core.security.authorization.AbstractLockManagementTest;
+import org.apache.jackrabbit.core.security.authorization.AbstractVersionManagementTest;
+import org.apache.jackrabbit.core.security.authorization.AbstractNodeTypeManagementTest;
+import org.apache.jackrabbit.api.jsr283.security.AccessControlManager;
+import org.apache.jackrabbit.api.jsr283.security.AccessControlPolicyIterator;
+import org.apache.jackrabbit.api.jsr283.security.AccessControlPolicy;
+import org.apache.jackrabbit.test.NotExecutableException;
+
+import javax.jcr.RepositoryException;
+import javax.jcr.AccessDeniedException;
+import javax.jcr.Session;
+import java.security.Principal;
+import java.util.Map;
+import java.util.Collections;
+
+/**
+ * <code>EvaluationTest</code>...
+ */
+final class EvaluationUtil {
+
+    static JackrabbitAccessControlList getPolicy(AccessControlManager acM, String path, Principal principal) throws RepositoryException,
+            AccessDeniedException, NotExecutableException {
+        AccessControlPolicyIterator itr = acM.getApplicablePolicies(path);
+        while (itr.hasNext()) {
+            AccessControlPolicy policy = itr.nextAccessControlPolicy();
+            if (policy instanceof ACLTemplate) {
+                return (ACLTemplate) policy;
+            }
+        }
+        throw new NotExecutableException();
+    }
+
+    static Map getRestrictions(Session s, String path) throws RepositoryException, NotExecutableException {
+        return Collections.EMPTY_MAP;
+    }
+}
\ No newline at end of file

Propchange: jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authorization/acl/EvaluationUtil.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authorization/acl/EvaluationUtil.java
------------------------------------------------------------------------------
    svn:keywords = author date id revision url

Added: jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authorization/acl/LockTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authorization/acl/LockTest.java?rev=732693&view=auto
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authorization/acl/LockTest.java (added)
+++ jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authorization/acl/LockTest.java Thu Jan  8 03:52:38 2009
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.core.security.authorization.acl;
+
+import org.apache.jackrabbit.core.security.authorization.AbstractLockManagementTest;
+import org.apache.jackrabbit.core.security.authorization.JackrabbitAccessControlList;
+import org.apache.jackrabbit.api.jsr283.security.AccessControlManager;
+import org.apache.jackrabbit.test.NotExecutableException;
+
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import java.security.Principal;
+import java.util.Map;
+
+/**
+ * <code>LockTest</code>...
+ */
+public class LockTest extends AbstractLockManagementTest {
+    protected JackrabbitAccessControlList getPolicy(AccessControlManager acMgr, String path, Principal princ) throws
+            RepositoryException, NotExecutableException {
+        return EvaluationUtil.getPolicy(acMgr, path, princ);
+    }
+    protected Map getRestrictions(Session s, String path) throws RepositoryException, NotExecutableException {
+        return EvaluationUtil.getRestrictions(s, path);
+    }
+}
\ No newline at end of file

Propchange: jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authorization/acl/LockTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authorization/acl/LockTest.java
------------------------------------------------------------------------------
    svn:keywords = author date id revision url

Added: jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authorization/acl/NodeTypeTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authorization/acl/NodeTypeTest.java?rev=732693&view=auto
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authorization/acl/NodeTypeTest.java (added)
+++ jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authorization/acl/NodeTypeTest.java Thu Jan  8 03:52:38 2009
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.core.security.authorization.acl;
+
+import org.apache.jackrabbit.core.security.authorization.AbstractNodeTypeManagementTest;
+import org.apache.jackrabbit.core.security.authorization.JackrabbitAccessControlList;
+import org.apache.jackrabbit.api.jsr283.security.AccessControlManager;
+import org.apache.jackrabbit.test.NotExecutableException;
+
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import java.security.Principal;
+import java.util.Map;
+
+/**
+ * <code>NodeTypeTest</code>...
+ */
+public class NodeTypeTest extends AbstractNodeTypeManagementTest {
+    protected JackrabbitAccessControlList getPolicy(AccessControlManager acMgr, String path, Principal princ) throws
+            RepositoryException, NotExecutableException {
+        return EvaluationUtil.getPolicy(acMgr, path, princ);
+    }
+    protected Map getRestrictions(Session s, String path) throws RepositoryException, NotExecutableException {
+        return EvaluationUtil.getRestrictions(s, path);
+    }
+}
\ No newline at end of file

Propchange: jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authorization/acl/NodeTypeTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authorization/acl/NodeTypeTest.java
------------------------------------------------------------------------------
    svn:keywords = author date id revision url

Modified: jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authorization/acl/TestAll.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authorization/acl/TestAll.java?rev=732693&r1=732692&r2=732693&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authorization/acl/TestAll.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authorization/acl/TestAll.java Thu Jan  8 03:52:38 2009
@@ -38,8 +38,12 @@
         suite.addTestSuite(ACLTemplateTest.class);
         suite.addTestSuite(EntryTest.class);
 
-        suite.addTestSuite(EvaluationTest.class);
+        suite.addTestSuite(WriteTest.class);
+        suite.addTestSuite(LockTest.class);
+        suite.addTestSuite(VersionTest.class);
+        suite.addTestSuite(NodeTypeTest.class);
 
         return suite;
     }
+
 }

Added: jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authorization/acl/VersionTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authorization/acl/VersionTest.java?rev=732693&view=auto
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authorization/acl/VersionTest.java (added)
+++ jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authorization/acl/VersionTest.java Thu Jan  8 03:52:38 2009
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.core.security.authorization.acl;
+
+import org.apache.jackrabbit.core.security.authorization.JackrabbitAccessControlList;
+import org.apache.jackrabbit.core.security.authorization.AbstractVersionManagementTest;
+import org.apache.jackrabbit.api.jsr283.security.AccessControlManager;
+import org.apache.jackrabbit.test.NotExecutableException;
+
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import java.security.Principal;
+import java.util.Map;
+
+/**
+ * <code>VersionTest</code>...
+ */
+public class VersionTest extends AbstractVersionManagementTest {
+    protected JackrabbitAccessControlList getPolicy(AccessControlManager acMgr, String path, Principal princ) throws
+            RepositoryException, NotExecutableException {
+        return EvaluationUtil.getPolicy(acMgr, path, princ);
+    }
+    protected Map getRestrictions(Session s, String path) throws RepositoryException, NotExecutableException {
+        return EvaluationUtil.getRestrictions(s, path);
+    }
+}
\ No newline at end of file

Propchange: jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authorization/acl/VersionTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authorization/acl/VersionTest.java
------------------------------------------------------------------------------
    svn:keywords = author date id revision url

Added: jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authorization/acl/WriteTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authorization/acl/WriteTest.java?rev=732693&view=auto
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authorization/acl/WriteTest.java (added)
+++ jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authorization/acl/WriteTest.java Thu Jan  8 03:52:38 2009
@@ -0,0 +1,178 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.core.security.authorization.acl;
+
+import org.apache.jackrabbit.api.jsr283.security.AccessControlManager;
+import org.apache.jackrabbit.api.jsr283.security.AccessControlPolicy;
+import org.apache.jackrabbit.api.jsr283.security.AccessControlPolicyIterator;
+import org.apache.jackrabbit.api.jsr283.security.Privilege;
+import org.apache.jackrabbit.core.security.authorization.AbstractWriteTest;
+import org.apache.jackrabbit.core.security.authorization.JackrabbitAccessControlList;
+import org.apache.jackrabbit.core.security.authorization.PrivilegeRegistry;
+import org.apache.jackrabbit.core.SessionImpl;
+import org.apache.jackrabbit.test.NotExecutableException;
+
+import javax.jcr.AccessDeniedException;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import java.util.Collections;
+import java.util.Map;
+import java.security.Principal;
+
+/**
+ * <code>EvaluationTest</code>...
+ */
+public class WriteTest extends AbstractWriteTest {
+
+    protected void setUp() throws Exception {
+        super.setUp();
+        try {
+            AccessControlPolicy[] rootPolicies = acMgr.getPolicies("/");
+            if (rootPolicies.length == 0 || !(rootPolicies[0] instanceof ACLTemplate)) {
+                throw new NotExecutableException();
+            }
+        } catch (RepositoryException e) {
+            throw new NotExecutableException();
+        }
+    }
+
+    protected void clearACInfo() {
+        // nop since ac information is stored with nodes that get removed
+        // during the general tear-down.
+    }
+
+    protected JackrabbitAccessControlList getPolicy(AccessControlManager acM, String path, Principal principal) throws RepositoryException, AccessDeniedException, NotExecutableException {
+        AccessControlPolicyIterator it = acM.getApplicablePolicies(path);
+        while (it.hasNext()) {
+            AccessControlPolicy acp = it.nextAccessControlPolicy();
+            if (acp instanceof ACLTemplate) {
+                return (ACLTemplate) acp;
+            }
+        }
+        throw new NotExecutableException("ACLTemplate expected.");
+    }
+
+    protected Map getRestrictions(Session s, String path) {
+        return Collections.EMPTY_MAP;
+    }
+
+    public void testAccessControlModification2() throws RepositoryException, NotExecutableException {
+        /*
+         precondition:
+         testuser must have READ-only permission on test-node and below
+        */
+        checkReadOnly(path);
+
+        // give 'testUser' READ_AC|MODIFY_AC privileges at 'path'
+        Privilege[] privileges = privilegesFromNames(new String[] {
+                Privilege.JCR_READ_ACCESS_CONTROL,
+                Privilege.JCR_MODIFY_ACCESS_CONTROL
+        });
+        JackrabbitAccessControlList tmpl = givePrivileges(path, privileges, getRestrictions(superuser, path));
+        /*
+         testuser must
+         - still have the inherited READ permission.
+         - must have permission to view AC items at 'path' (and below)
+         - must have permission to modify AC items at 'path'
+
+         testuser must not have
+         - permission to view AC items outside of the tree defined by path.
+        */
+
+        // make sure the 'rep:policy' node has been created.
+        assertTrue(superuser.itemExists(tmpl.getPath() + "/rep:policy"));
+
+        SessionImpl testSession = getTestSession();
+        AccessControlManager testAcMgr = getTestACManager();
+        // test: MODIFY_AC granted at 'path'
+        assertTrue(testAcMgr.hasPrivileges(path, privilegesFromName(Privilege.JCR_MODIFY_ACCESS_CONTROL)));
+
+        // test if testuser can READ access control on the path and on the
+        // entire subtree that gets the policy inherited.
+        AccessControlPolicy[] policies = testAcMgr.getPolicies(path);
+        testAcMgr.getEffectivePolicies(path);
+        testAcMgr.getEffectivePolicies(childNPath);
+
+        // test: READ_AC privilege does not apply outside of the tree.
+        try {
+            testAcMgr.getPolicies(siblingPath);
+            fail("READ_AC privilege must not apply outside of the tree it has applied to.");
+        } catch (AccessDeniedException e) {
+            // success
+        }
+
+        // test: MODIFY_AC privilege does not apply outside of the tree.
+        try {
+            testAcMgr.setPolicy(siblingPath, policies[0]);
+            fail("MODIFY_AC privilege must not apply outside of the tree it has applied to.");
+        } catch (AccessDeniedException e) {
+            // success
+        }
+
+        // test if testuser can modify AC-items
+        // 1) add an ac-entry
+        ACLTemplate acl = (ACLTemplate) policies[0];
+        acl.addAccessControlEntry(getTestUser().getPrincipal(), privilegesFromName(PrivilegeRegistry.REP_WRITE));
+        testAcMgr.setPolicy(path, acl);
+        testSession.save();
+
+        assertTrue(testAcMgr.hasPrivileges(path,
+                privilegesFromName(Privilege.JCR_REMOVE_CHILD_NODES)));
+
+        // 2) remove the policy
+        testAcMgr.removePolicy(path, policies[0]);
+        testSession.save();
+
+        // Finally: testuser removed the policy that granted him permission
+        // to modify the AC content. Since testuser removed the policy, it's
+        // privileges must be gone again...
+        try {
+            testAcMgr.getEffectivePolicies(childNPath);
+            fail("READ_AC privilege has been revoked -> must throw again.");
+        } catch (AccessDeniedException e) {
+            // success
+        }
+        // ... and since the ACE is stored with the policy all right except
+        // READ must be gone.
+        checkReadOnly(path);
+    }
+
+    public void testRemovePermission9() throws NotExecutableException, RepositoryException {
+        AccessControlManager testAcMgr = getTestACManager();
+        /*
+          precondition:
+          testuser must have READ-only permission on test-node and below
+        */
+        checkReadOnly(path);
+        checkReadOnly(childNPath);
+
+        Privilege[] rmChildNodes = privilegesFromName(Privilege.JCR_REMOVE_CHILD_NODES);
+        Privilege[] rmNode = privilegesFromName(Privilege.JCR_REMOVE_NODE);
+
+        // add 'remove_child_nodes' at 'path and allow 'remove_node' at childNPath
+        givePrivileges(path, rmChildNodes, getRestrictions(superuser, path));
+        givePrivileges(childNPath, rmNode, getRestrictions(superuser, childNPath));
+        /*
+         expected result:
+         - rep:policy node can still not be remove for it is access-control
+           content that requires jcr:modifyAccessControl privilege instead.
+         */
+        String policyPath = childNPath + "/rep:policy";
+        assertFalse(getTestSession().hasPermission(policyPath, org.apache.jackrabbit.api.jsr283.Session.ACTION_REMOVE));
+        assertTrue(testAcMgr.hasPrivileges(policyPath, new Privilege[] {rmChildNodes[0], rmNode[0]}));
+    }
+}
\ No newline at end of file

Propchange: jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authorization/acl/WriteTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authorization/acl/WriteTest.java
------------------------------------------------------------------------------
    svn:keywords = author date id revision url

Modified: jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authorization/combined/TestAll.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authorization/combined/TestAll.java?rev=732693&r1=732692&r2=732693&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authorization/combined/TestAll.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authorization/combined/TestAll.java Thu Jan  8 03:52:38 2009
@@ -18,7 +18,7 @@
     public static Test suite() {
         TestSuite suite = new TestSuite("security.authorization.combined tests");
 
-        suite.addTestSuite(EvaluationTest.class);
+        suite.addTestSuite(WriteTest.class);
 
         return suite;
     }