jackrabbit-oak-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ang...@apache.org
Subject svn commit: r1437320 - /jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/security/authorization/
Date Wed, 23 Jan 2013 10:11:47 GMT
Author: angela
Date: Wed Jan 23 10:11:46 2013
New Revision: 1437320

URL: http://svn.apache.org/viewvc?rev=1437320&view=rev
Log:
OAK-51 : Access Control Management

- access control evaluation tests using jcr-api

Added:
    jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/security/authorization/AbstractEvaluationTest.java
    jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/security/authorization/AccessControlManagementTest.java
    jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/security/authorization/MoveTest.java
    jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/security/authorization/NamespaceManagementTest.java
    jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/security/authorization/NodeTypeDefinitionManagementTest.java
    jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/security/authorization/NodeTypeManagementTest.java
    jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/security/authorization/PrivilegeManagementTest.java
    jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/security/authorization/VersionManagementTest.java

Added: jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/security/authorization/AbstractEvaluationTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/security/authorization/AbstractEvaluationTest.java?rev=1437320&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/security/authorization/AbstractEvaluationTest.java (added)
+++ jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/security/authorization/AbstractEvaluationTest.java Wed Jan 23 10:11:46 2013
@@ -0,0 +1,210 @@
+/*
+ * 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.oak.jcr.security.authorization;
+
+import java.security.Principal;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.UUID;
+import javax.jcr.Credentials;
+import javax.jcr.Node;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import javax.jcr.SimpleCredentials;
+import javax.jcr.Value;
+import javax.jcr.security.AccessControlManager;
+import javax.jcr.security.AccessControlPolicy;
+import javax.jcr.security.Privilege;
+
+import org.apache.jackrabbit.api.JackrabbitSession;
+import org.apache.jackrabbit.api.security.JackrabbitAccessControlList;
+import org.apache.jackrabbit.api.security.user.Group;
+import org.apache.jackrabbit.api.security.user.User;
+import org.apache.jackrabbit.api.security.user.UserManager;
+import org.apache.jackrabbit.commons.jackrabbit.authorization.AccessControlUtils;
+import org.apache.jackrabbit.test.NotExecutableException;
+import org.apache.jackrabbit.test.api.security.AbstractAccessControlTest;
+import org.junit.After;
+import org.junit.Before;
+
+import static org.junit.Assert.assertArrayEquals;
+
+/**
+ * Base class for testing access control evaluation using JCR API.
+ */
+public abstract class AbstractEvaluationTest extends AbstractAccessControlTest {
+
+    private static final Map<String, Value> EMPTY_RESTRICTIONS = Collections.emptyMap();
+
+    protected static final String REP_WRITE = "rep:write";
+
+    protected User testUser;
+    protected Credentials creds;
+
+    protected Group testGroup;
+
+    private Session testSession;
+    private AccessControlManager testAccessControlManager;
+    private Node trn;
+    private Set<String> toClear = new HashSet<String>();
+
+    @Override
+    @Before
+    protected void setUp() throws Exception {
+        super.setUp();
+        try {
+            UserManager uMgr = getUserManager(superuser);
+            // create the testUser
+            String uid = "testUser" + UUID.randomUUID();
+            creds = new SimpleCredentials(uid, uid.toCharArray());
+
+            testUser = uMgr.createUser(uid, uid);
+            superuser.save();
+        } catch (Exception e) {
+            superuser.logout();
+            throw e;
+        }
+    }
+
+    @Override
+    @After
+    protected void tearDown() throws Exception {
+        try {
+            if (testSession != null && testSession.isLive()) {
+                testSession.logout();
+            }
+            for (String path : toClear) {
+                AccessControlPolicy[] policies = acMgr.getPolicies(path);
+                for (AccessControlPolicy policy : policies) {
+                    acMgr.removePolicy(path, policy);
+                }
+            }
+            if (testGroup != null) {
+                testGroup.remove();
+            }
+            if (testUser != null) {
+                testUser.remove();
+            }
+            superuser.save();
+        } finally {
+            super.tearDown();
+        }
+    }
+
+    protected static UserManager getUserManager(Session session) throws
+            NotExecutableException {
+        if (!(session instanceof JackrabbitSession)) {
+            throw new NotExecutableException();
+        }
+        try {
+            return ((JackrabbitSession) session).getUserManager();
+        } catch (RepositoryException e) {
+            throw new NotExecutableException();
+        }
+    }
+
+    protected Session getTestSession() throws RepositoryException {
+        if (testSession == null) {
+            testSession = getHelper().getRepository().login(creds);
+        }
+        return testSession;
+    }
+
+    protected AccessControlManager getTestAccessControlManager() throws Exception {
+        if (testAccessControlManager == null) {
+            testAccessControlManager = getAccessControlManager(getTestSession());
+        }
+        return testAccessControlManager;
+    }
+
+    protected Group getTestGroup() throws Exception {
+        if (testGroup == null) {
+            UserManager umgr = getUserManager(superuser);
+            testGroup = umgr.createGroup("testGroup" + UUID.randomUUID());
+            testGroup.addMember(testUser);
+            superuser.save();
+        }
+        return testGroup;
+    }
+
+    protected Node getTestNode() throws RepositoryException {
+        if (trn == null) {
+            trn = getTestSession().getNode(testRootNode.getPath());
+        }
+        return trn;
+    }
+
+    protected void assertPrivilege(String path, String privName, boolean isAllow) throws Exception {
+        Privilege[] privs = privilegesFromName(privName.toString());
+        assertEquals(isAllow, getTestAccessControlManager().hasPrivileges(path, privs));
+    }
+
+    protected void checkReadOnly(String path) throws Exception {
+        Privilege[] privs = getTestAccessControlManager().getPrivileges(path);
+        assertArrayEquals(privilegesFromName(Privilege.JCR_READ), privs);
+    }
+
+    protected JackrabbitAccessControlList modify(String path, String privilege, boolean isAllow) throws Exception {
+        return modify(path, testUser.getPrincipal(), privilegesFromName(privilege), isAllow, EMPTY_RESTRICTIONS);
+    }
+
+    private JackrabbitAccessControlList modify(String path, Principal principal, Privilege[] privileges, boolean isAllow, Map<String, Value> restrictions) throws Exception {
+        JackrabbitAccessControlList tmpl = AccessControlUtils.getAccessControlList(acMgr, path);
+        tmpl.addEntry(principal, privileges, isAllow, restrictions);
+
+        acMgr.setPolicy(tmpl.getPath(), tmpl);
+        superuser.save();
+
+        // remember for clean up during tearDown
+        toClear.add(tmpl.getPath());
+        return tmpl;
+    }
+
+    protected JackrabbitAccessControlList allow(String nPath, Privilege[] privileges)
+            throws Exception {
+        return modify(nPath, testUser.getPrincipal(), privileges, true, EMPTY_RESTRICTIONS);
+    }
+
+    protected JackrabbitAccessControlList allow(String nPath, Privilege[] privileges,
+                                                Map<String, Value> restrictions)
+            throws Exception {
+        return modify(nPath, testUser.getPrincipal(), privileges, true, restrictions);
+    }
+
+    protected JackrabbitAccessControlList allow(String nPath, Principal principal,
+                                                Privilege[] privileges, Map<String, Value> restrictions)
+            throws Exception {
+        return modify(nPath, principal, privileges, true, restrictions);
+    }
+
+    protected JackrabbitAccessControlList deny(String nPath, Privilege[] privileges)
+            throws Exception {
+        return modify(nPath, testUser.getPrincipal(), privileges, false, EMPTY_RESTRICTIONS);
+    }
+
+    protected JackrabbitAccessControlList deny(String nPath, Privilege[] privileges, Map<String, Value> restrictions)
+            throws Exception {
+        return modify(nPath, testUser.getPrincipal(), privileges, false, restrictions);
+    }
+
+    protected JackrabbitAccessControlList deny(String nPath, Principal principal, Privilege[] privileges, Map<String, Value> restrictions)
+            throws Exception {
+        return modify(nPath, principal, privileges, false, restrictions);
+    }
+}
\ No newline at end of file

Added: jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/security/authorization/AccessControlManagementTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/security/authorization/AccessControlManagementTest.java?rev=1437320&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/security/authorization/AccessControlManagementTest.java (added)
+++ jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/security/authorization/AccessControlManagementTest.java Wed Jan 23 10:11:46 2013
@@ -0,0 +1,273 @@
+/*
+ * 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.oak.jcr.security.authorization;
+
+import java.util.HashMap;
+import java.util.Map;
+import javax.jcr.AccessDeniedException;
+import javax.jcr.Node;
+import javax.jcr.NodeIterator;
+import javax.jcr.Property;
+import javax.jcr.PropertyIterator;
+import javax.jcr.Session;
+import javax.jcr.Value;
+import javax.jcr.security.AccessControlList;
+import javax.jcr.security.AccessControlManager;
+import javax.jcr.security.AccessControlPolicy;
+import javax.jcr.security.AccessControlPolicyIterator;
+import javax.jcr.security.Privilege;
+
+import org.apache.jackrabbit.api.security.JackrabbitAccessControlList;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+
+/**
+ * AccessControlManagementTest... TODO
+ *
+ * copied from jr2.x AcReadWriteTest
+ */
+@Ignore("OAK-51")
+public class AccessControlManagementTest extends AbstractEvaluationTest {
+
+    private String path;
+    private String childNPath;
+
+    @Override
+    @Before
+    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();
+    }
+
+    @Test
+    public void testAccessControlPrivileges() throws Exception {
+        /* precondition:
+          testuser must have READ-only permission on test-node and below
+        */
+        checkReadOnly(path);
+
+        /* grant 'testUser' rep:write, rep:readAccessControl and
+           rep:modifyAccessControl privileges at 'path' */
+        Privilege[] privileges = privilegesFromNames(new String[] {
+                REP_WRITE,
+                Privilege.JCR_READ_ACCESS_CONTROL,
+                Privilege.JCR_MODIFY_ACCESS_CONTROL
+        });
+        JackrabbitAccessControlList acl = allow(path, privileges);
+
+        Session testSession = getTestSession();
+        AccessControlManager testAcMgr = getTestAccessControlManager();
+        /*
+         testuser must have
+         - permission to view AC items
+         - permission to modify AC items
+        */
+        // the policy node however must be visible to the test-user
+        assertTrue(testSession.itemExists(acl.getPath() + "/rep:policy"));
+
+        testAcMgr.getPolicies(acl.getPath());
+        testAcMgr.removePolicy(acl.getPath(), acl);
+    }
+
+    /**
+     * Test if a new applicable policy can be applied within a individual
+     * subtree where AC-modification is allowed.
+     *
+     * @see <a href="https://issues.apache.org/jira/browse/JCR-2869">JCR-2869</a>
+     */
+    @Test
+    public void testSetNewPolicy() throws Exception {
+        /* precondition:
+          testuser must have READ-only permission on test-node and below
+        */
+        checkReadOnly(path);
+
+        /* grant 'testUser' rep:write, rep:readAccessControl and
+           rep:modifyAccessControl privileges at 'path' */
+        Privilege[] privileges = privilegesFromNames(new String[] {
+                REP_WRITE,
+                Privilege.JCR_READ_ACCESS_CONTROL,
+                Privilege.JCR_MODIFY_ACCESS_CONTROL
+        });
+        allow(path, privileges);
+
+        AccessControlManager testAcMgr = getTestAccessControlManager();
+        /*
+         testuser must be allowed to set a new policy at a child node.
+        */
+        AccessControlPolicyIterator it = testAcMgr.getApplicablePolicies(childNPath);
+        while (it.hasNext()) {
+            AccessControlPolicy plc = it.nextAccessControlPolicy();
+            testAcMgr.setPolicy(childNPath, plc);
+            testAcMgr.removePolicy(childNPath, plc);
+        }
+    }
+
+    @Test
+    public void testSetModifiedPolicy() throws Exception {
+        /* precondition:
+          testuser must have READ-only permission on test-node and below
+        */
+        checkReadOnly(path);
+
+        /* grant 'testUser' rep:write, rep:readAccessControl and
+           rep:modifyAccessControl privileges at 'path' */
+        Privilege[] privileges = privilegesFromNames(new String[] {
+                REP_WRITE,
+                Privilege.JCR_READ_ACCESS_CONTROL,
+                Privilege.JCR_MODIFY_ACCESS_CONTROL
+        });
+
+        JackrabbitAccessControlList acl = allow(path, privileges);
+        /*
+         testuser must be allowed to set (modified) policy at target node.
+        */
+        Session testSession = getTestSession();
+        AccessControlManager testAcMgr = getTestAccessControlManager();
+
+        AccessControlPolicy[] policies  = testAcMgr.getPolicies(path);
+
+        assertEquals(1, policies.length);
+        assertTrue(policies[0] instanceof AccessControlList);
+
+        AccessControlList policy = (AccessControlList) policies[0];
+        if (policy.addAccessControlEntry(testUser.getPrincipal(), privilegesFromName(Privilege.JCR_LOCK_MANAGEMENT))) {
+            testAcMgr.setPolicy(path, acl);
+            testSession.save();
+        }
+    }
+
+    @Test
+    public void testRetrievePrivilegesOnAcNodes() throws Exception {
+        /* precondition:
+          testuser must have READ-only permission on test-node and below
+        */
+        checkReadOnly(path);
+
+        // give 'testUser' jcr:readAccessControl privileges at 'path'
+        Privilege[] privileges = privilegesFromName(Privilege.JCR_READ_ACCESS_CONTROL);
+        JackrabbitAccessControlList acl = allow(path, privileges);
+
+        /*
+         testuser must be allowed to read ac-content at target node.
+        */
+        Session testSession = getTestSession();
+        AccessControlManager testAcMgr = getTestAccessControlManager();
+
+        assertTrue(testAcMgr.hasPrivileges(path, privileges));
+
+        AccessControlPolicy[] policies  = testAcMgr.getPolicies(path);
+        assertEquals(1, policies.length);
+        assertTrue(policies[0] instanceof JackrabbitAccessControlList);
+
+        String aclNodePath = null;
+        Node n = superuser.getNode(path);
+        for (NodeIterator itr = n.getNodes(); itr.hasNext();) {
+            Node child = itr.nextNode();
+            if (child.isNodeType("rep:Policy")) {
+                aclNodePath = child.getPath();
+            }
+        }
+
+        if (aclNodePath == null) {
+            fail("Expected node at " + path + " to have an ACL child node.");
+        }
+
+        assertTrue(testAcMgr.hasPrivileges(aclNodePath, privileges));
+        assertTrue(testSession.hasPermission(aclNodePath, Session.ACTION_READ));
+
+        for (NodeIterator aceNodes = superuser.getNode(aclNodePath).getNodes(); aceNodes.hasNext();) {
+            String aceNodePath = aceNodes.nextNode().getPath();
+            assertTrue(testAcMgr.hasPrivileges(aceNodePath, privileges));
+            assertTrue(testSession.hasPermission(aceNodePath, Session.ACTION_READ));
+        }
+    }
+
+    @Test
+    public void testReadAccessControl() throws Exception {
+        /* precondition:
+          testuser must have READ-only permission on test-node and below
+        */
+        checkReadOnly(path);
+
+        /* give 'testUser' jcr:readAccessControl privileges at subtree below
+           path excluding the node at path itself. */
+        Privilege[] privileges = privilegesFromNames(new String[] {
+                Privilege.JCR_READ_ACCESS_CONTROL
+        });
+        Map<String, Value> restrictions = new HashMap<String, Value>();
+        restrictions.put("rep:glob", vf.createValue('/' + nodeName2));
+        JackrabbitAccessControlList acl = allow(path, privileges, restrictions);
+
+        /*
+         testuser must not be allowed to read AC content at the target node;
+         however, retrieving potential AC content at 'childPath' is granted.
+        */
+        Session testSession = getTestSession();
+        AccessControlManager testAcMgr = getTestAccessControlManager();
+
+        assertFalse(testAcMgr.hasPrivileges(path, privileges));
+        try {
+            testAcMgr.getPolicies(path);
+            fail("AccessDeniedException expected");
+        } catch (AccessDeniedException e) {
+            // success.
+        }
+
+        assertTrue(testAcMgr.hasPrivileges(childNPath, privileges));
+        assertEquals(0, testAcMgr.getPolicies(childNPath).length);
+
+        /* similarly reading the corresponding AC items at 'path' must be forbidden */
+        String aclNodePath = null;
+        Node n = superuser.getNode(path);
+        for (NodeIterator itr = n.getNodes(); itr.hasNext();) {
+            Node child = itr.nextNode();
+            if (child.isNodeType("rep:Policy")) {
+                aclNodePath = child.getPath();
+            }
+        }
+        if (aclNodePath == null) {
+            fail("Expected node at " + path + " to have an ACL child node.");
+        }
+
+        assertFalse(testSession.nodeExists(aclNodePath));
+
+        for (NodeIterator aceNodes = superuser.getNode(aclNodePath).getNodes(); aceNodes.hasNext();) {
+            Node aceNode = aceNodes.nextNode();
+            String aceNodePath = aceNode.getPath();
+            assertFalse(testSession.nodeExists(aceNodePath));
+
+            for (PropertyIterator it = aceNode.getProperties(); it.hasNext();) {
+                assertFalse(testSession.propertyExists(it.nextProperty().getPath()));
+            }
+        }
+    }
+}
\ No newline at end of file

Added: jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/security/authorization/MoveTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/security/authorization/MoveTest.java?rev=1437320&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/security/authorization/MoveTest.java (added)
+++ jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/security/authorization/MoveTest.java Wed Jan 23 10:11:46 2013
@@ -0,0 +1,188 @@
+/*
+ * 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.oak.jcr.security.authorization;
+
+import java.util.Collections;
+import java.util.Map;
+import javax.jcr.Node;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import javax.jcr.Value;
+import javax.jcr.security.AccessControlManager;
+import javax.jcr.security.Privilege;
+
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+
+/**
+ * MoveTest... TODO
+ */
+@Ignore("OAK-51")
+public class MoveTest extends AbstractEvaluationTest {
+
+    private Privilege[] readPrivileges;
+
+    private Session testSession;
+    private AccessControlManager testAcManager;
+
+    private String path;
+    private String nodePath2;
+    private String nodePath3;
+
+    @Override
+    @Before
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        readPrivileges = privilegesFromName(Privilege.JCR_READ);
+        testSession = getTestSession();
+        testAcManager = getTestAccessControlManager();
+
+        // create some nodes below the test root in order to apply ac-stuff
+        Node node = testRootNode.addNode(nodeName1, testNodeType);
+        Node node2 = node.addNode(nodeName2, testNodeType);
+        Node node3 = node2.addNode(nodeName3);
+        superuser.save();
+
+        nodePath3 = node3.getPath();
+
+        superuser.save();
+
+        path = node.getPath();
+        nodePath2 = node2.getPath();
+
+        /*
+        precondition:
+        testuser must have READ-only permission on test-node and below
+        */
+        checkReadOnly(path);
+        checkReadOnly(nodePath2);
+    }
+
+    private Map<String, Value> createGlobRestriction(String value) throws RepositoryException {
+        return Collections.singletonMap("rep:glob", getTestSession().getValueFactory().createValue(value));
+    }
+
+    @Test
+    public void testMoveAccessControlledNode() throws Exception {
+        // permissions defined @ childNode
+        // -> revoke read permission
+        deny(nodePath2, readPrivileges);
+
+        assertFalse(testSession.nodeExists(nodePath2));
+        assertFalse(testAcManager.hasPrivileges(nodePath2, readPrivileges));
+        assertFalse(testSession.nodeExists(nodePath3));
+        assertFalse(testAcManager.hasPrivileges(nodePath3, readPrivileges));
+
+        // move the ancestor node
+        String movedChildNPath = path + "/movedNode";
+        String movedNode3Path = movedChildNPath + '/' + nodeName3;
+
+        superuser.move(nodePath2, movedChildNPath);
+        superuser.save();
+
+        // expected behavior:
+        // the AC-content present on childNode is still enforced both on
+        // the node itself and on the subtree.
+        assertFalse(testSession.nodeExists(movedChildNPath));
+        assertFalse(testAcManager.hasPrivileges(movedChildNPath, readPrivileges));
+        assertFalse(testSession.nodeExists(movedNode3Path));
+        assertFalse(testAcManager.hasPrivileges(movedNode3Path, readPrivileges));
+    }
+
+    @Test
+    public void testMoveAccessControlledNodeInSubtree() throws Exception {
+        // permissions defined @ node3Path
+        // -> revoke read permission
+        deny(nodePath3, readPrivileges);
+
+        assertFalse(testSession.nodeExists(nodePath3));
+        assertFalse(testAcManager.hasPrivileges(nodePath3, readPrivileges));
+
+        // move the ancestor node
+        String movedChildNPath = path + "/movedNode";
+        String movedNode3Path = movedChildNPath + '/' + nodeName3;
+
+        superuser.move(nodePath2, movedChildNPath);
+        superuser.save();
+
+        // expected behavior:
+        // the AC-content present on node3 is still enforced
+        assertFalse(testSession.nodeExists(movedNode3Path));
+        assertFalse(testAcManager.hasPrivileges(movedNode3Path, readPrivileges));
+    }
+
+    @Test
+    public void testMoveWithDifferentEffectiveAc() throws Exception {
+        // @path read is denied, @childNode its allowed again
+        deny(path, readPrivileges);
+        allow(nodePath2, readPrivileges);
+
+        assertTrue(testSession.nodeExists(nodePath3));
+        assertTrue(testAcManager.hasPrivileges(nodePath3, readPrivileges));
+
+        // move the ancestor node
+        String movedPath = path + "/movedNode";
+
+        superuser.move(nodePath3, movedPath);
+        superuser.save();
+
+        // expected behavior:
+        // due to move node3 should not e visible any more
+        assertFalse(testSession.nodeExists(movedPath));
+        assertFalse(testAcManager.hasPrivileges(movedPath, readPrivileges));
+    }
+
+    @Test
+    public void testMoveNodeWithGlobRestriction() throws Exception {
+        // permissions defined @ path
+        // restriction: remove read priv to nodeName3 node
+        deny(nodePath2, readPrivileges, createGlobRestriction('/' +nodeName3));
+
+        assertFalse(testSession.nodeExists(nodePath3));
+        assertFalse(testAcManager.hasPrivileges(nodePath3, readPrivileges));
+
+        String movedChildNPath = path + "/movedNode";
+        String movedNode3Path = movedChildNPath + '/' + nodeName3;
+
+        superuser.move(nodePath2, movedChildNPath);
+        superuser.save();
+
+        assertFalse(testSession.nodeExists(movedNode3Path));
+        assertFalse(testAcManager.hasPrivileges(movedNode3Path, readPrivileges));
+    }
+
+    @Test
+    public void testMoveNodeWithGlobRestriction2() throws Exception {
+        // permissions defined @ path
+        // restriction: remove read priv to nodeName3 node
+        deny(nodePath2, readPrivileges, createGlobRestriction('/' + nodeName3));
+
+        // don't fill the per-session read-cache by calling Session.nodeExists
+        assertFalse(testAcManager.hasPrivileges(nodePath3, readPrivileges));
+
+        String movedChildNPath = path + "/movedNode";
+        String movedNode3Path = movedChildNPath + '/' + nodeName3;
+
+        superuser.move(nodePath2, movedChildNPath);
+        superuser.save();
+
+        assertFalse(testSession.nodeExists(movedNode3Path));
+        assertFalse(testAcManager.hasPrivileges(movedNode3Path, readPrivileges));
+    }
+}
\ No newline at end of file

Added: jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/security/authorization/NamespaceManagementTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/security/authorization/NamespaceManagementTest.java?rev=1437320&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/security/authorization/NamespaceManagementTest.java (added)
+++ jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/security/authorization/NamespaceManagementTest.java Wed Jan 23 10:11:46 2013
@@ -0,0 +1,132 @@
+/*
+ * 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.oak.jcr.security.authorization;
+
+import java.util.Arrays;
+import java.util.List;
+import javax.annotation.Nonnull;
+import javax.jcr.AccessDeniedException;
+import javax.jcr.RepositoryException;
+import javax.jcr.Workspace;
+import javax.jcr.security.AccessControlPolicy;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+
+/**
+ * NamespaceManagementTest... TODO
+ *
+ * copied from jr2x RepositoryOperationTest
+ */
+@Ignore("OAK-51")
+public class NamespaceManagementTest extends AbstractEvaluationTest {
+
+    private static final String JCR_NAMESPACE_MANAGEMENT = "jcr:namespaceManagement";
+
+    @Override
+    @Before
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        assertPrivilege(null, JCR_NAMESPACE_MANAGEMENT, false);
+    }
+
+    @Override
+    @After
+    protected void tearDown() throws Exception {
+        try {
+            for (AccessControlPolicy policy : acMgr.getPolicies(null)) {
+                acMgr.removePolicy(null, policy);
+            }
+            superuser.save();
+        } finally {
+            super.tearDown();
+        }
+    }
+
+    @Nonnull
+    private String getNewNamespacePrefix(Workspace wsp) throws RepositoryException {
+        String prefix = "prefix";
+        List<String> pfcs = Arrays.asList(wsp.getNamespaceRegistry().getPrefixes());
+        int i = 0;
+        while (pfcs.contains(prefix)) {
+            prefix = "prefix" + i++;
+        }
+        return prefix;
+    }
+
+    @Nonnull
+    private String getNewNamespaceURI(Workspace wsp) throws RepositoryException {
+        String uri = "http://jackrabbit.apache.org/uri";
+        List<String> uris = Arrays.asList(wsp.getNamespaceRegistry().getURIs());
+        int i = 0;
+        while (uris.contains(uri)) {
+            uri = "http://jackrabbit.apache.org/uri_" + i++;
+        }
+        return uri;
+    }
+
+    @Test
+    public void testRegisterNamespace() throws Exception {
+        try {
+            Workspace testWsp = getTestSession().getWorkspace();
+            testWsp.getNamespaceRegistry().registerNamespace(getNewNamespacePrefix(testWsp), getNewNamespaceURI(testWsp));
+            fail("Namespace registration should be denied.");
+        } catch (AccessDeniedException e) {
+            // success
+        }
+    }
+
+    @Test
+    public void testRegisterNamespaceWithPrivilege() throws Exception {
+        modify(null, JCR_NAMESPACE_MANAGEMENT.toString(), true);
+        assertPrivilege(null, JCR_NAMESPACE_MANAGEMENT, true);
+
+        try {
+            Workspace testWsp = getTestSession().getWorkspace();
+            testWsp.getNamespaceRegistry().registerNamespace(getNewNamespacePrefix(testWsp), getNewNamespaceURI(testWsp));
+        } finally {
+            modify(null, JCR_NAMESPACE_MANAGEMENT.toString(), false);
+        }
+
+        assertPrivilege(null, JCR_NAMESPACE_MANAGEMENT, false);
+    }
+
+    @Test
+    public void testUnregisterNamespace() throws Exception {
+        Workspace wsp = superuser.getWorkspace();
+        String pfx = getNewNamespacePrefix(wsp);
+        wsp.getNamespaceRegistry().registerNamespace(pfx, getNewNamespaceURI(wsp));
+
+        try {
+            Workspace testWsp = getTestSession().getWorkspace();
+            testWsp.getNamespaceRegistry().unregisterNamespace(pfx);
+            fail("Namespace unregistration should be denied.");
+        } catch (AccessDeniedException e) {
+            // success
+        } finally {
+            // clean up (not supported by jackrabbit-core)
+            try {
+                superuser.getWorkspace().getNamespaceRegistry().unregisterNamespace(pfx);
+            } catch (Exception e) {
+                // ns unregistration is not supported by jackrabbit-core.
+            }
+        }
+    }
+}
\ No newline at end of file

Added: jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/security/authorization/NodeTypeDefinitionManagementTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/security/authorization/NodeTypeDefinitionManagementTest.java?rev=1437320&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/security/authorization/NodeTypeDefinitionManagementTest.java (added)
+++ jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/security/authorization/NodeTypeDefinitionManagementTest.java Wed Jan 23 10:11:46 2013
@@ -0,0 +1,160 @@
+/*
+ * 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.oak.jcr.security.authorization;
+
+import javax.jcr.AccessDeniedException;
+import javax.jcr.Workspace;
+import javax.jcr.nodetype.NodeTypeManager;
+import javax.jcr.nodetype.NodeTypeTemplate;
+import javax.jcr.security.AccessControlPolicy;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+
+/**
+ * NodeTypeDefinitionManagementTest... TODO
+ *
+ * copied from jr2x RepositoryOperationTest
+ */
+@Ignore("OAK-51")
+public class NodeTypeDefinitionManagementTest extends AbstractEvaluationTest {
+
+    private static final String JCR_NODE_TYPE_DEFINITION_MANAGEMENT = "jcr:nodeTypeDefinitionManagement";
+    @Override
+    @Before
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        assertPrivilege(null, JCR_NODE_TYPE_DEFINITION_MANAGEMENT, false);
+    }
+
+    @Override
+    @After
+    protected void tearDown() throws Exception {
+        try {
+            for (AccessControlPolicy policy : acMgr.getPolicies(null)) {
+                acMgr.removePolicy(null, policy);
+            }
+            superuser.save();
+        } finally {
+            super.tearDown();
+        }
+    }
+
+    @Test
+    public void testRegisterNodeType() throws Exception {
+        Workspace testWsp = getTestSession().getWorkspace();
+        NodeTypeManager ntm = testWsp.getNodeTypeManager();
+        NodeTypeTemplate ntd = ntm.createNodeTypeTemplate();
+        ntd.setName("testNodeType");
+        ntd.setMixin(true);
+
+        try {
+            ntm.registerNodeType(ntd, true);
+            fail("Node type registration should be denied.");
+        } catch (AccessDeniedException e) {
+            // success
+        }
+        try {
+            ntm.registerNodeType(ntd, false);
+            fail("Node type registration should be denied.");
+        } catch (AccessDeniedException e) {
+            // success
+        }
+
+        NodeTypeTemplate[] ntds = new NodeTypeTemplate[2];
+        ntds[0] = ntd;
+        ntds[1] = ntm.createNodeTypeTemplate();
+        ntds[1].setName("anotherNodeType");
+        ntds[1].setDeclaredSuperTypeNames(new String[] {"nt:file"});
+        try {
+            ntm.registerNodeTypes(ntds, true);
+            fail("Node type registration should be denied.");
+        } catch (AccessDeniedException e) {
+            // success
+        }
+
+        try {
+            ntm.registerNodeTypes(ntds, false);
+            fail("Node type registration should be denied.");
+        } catch (AccessDeniedException e) {
+            // success
+        }
+    }
+
+    @Test
+    public void testRegisterNodeTypeWithPrivilege() throws Exception {
+        modify(null, JCR_NODE_TYPE_DEFINITION_MANAGEMENT.toString(), true);
+        assertPrivilege(null, JCR_NODE_TYPE_DEFINITION_MANAGEMENT, true);
+
+        try {
+            Workspace testWsp = getTestSession().getWorkspace();
+            NodeTypeManager ntm = testWsp.getNodeTypeManager();
+            NodeTypeTemplate ntd = ntm.createNodeTypeTemplate();
+            ntd.setName("testNodeType");
+            ntd.setMixin(true);
+            ntm.registerNodeType(ntd, true);
+
+            NodeTypeTemplate[] ntds = new NodeTypeTemplate[2];
+            ntds[0] = ntd;
+            ntds[1] = ntm.createNodeTypeTemplate();
+            ntds[1].setName("anotherNodeType");
+            ntds[1].setDeclaredSuperTypeNames(new String[] {"nt:file"});
+            ntm.registerNodeTypes(ntds, true);
+        } finally {
+            modify(null, JCR_NODE_TYPE_DEFINITION_MANAGEMENT.toString(), false);
+        }
+
+        assertPrivilege(null, JCR_NODE_TYPE_DEFINITION_MANAGEMENT, false);
+    }
+
+    @Test
+    public void testUnRegisterNodeType() throws Exception {
+        NodeTypeManager ntm = superuser.getWorkspace().getNodeTypeManager();
+        NodeTypeTemplate ntd = ntm.createNodeTypeTemplate();
+        ntd.setName("testNodeType");
+        ntd.setMixin(true);
+        ntm.registerNodeType(ntd, true);
+
+        Workspace testWsp = getTestSession().getWorkspace();
+        try {
+            try {
+                NodeTypeManager testNtm = testWsp.getNodeTypeManager();
+                testNtm.unregisterNodeType(ntd.getName());
+                fail("Namespace unregistration should be denied.");
+            } catch (AccessDeniedException e) {
+                // success
+            }
+            try {
+                NodeTypeManager testNtm = testWsp.getNodeTypeManager();
+                testNtm.unregisterNodeTypes(new String[] {ntd.getName()});
+                fail("Namespace unregistration should be denied.");
+            } catch (AccessDeniedException e) {
+                // success
+            }
+        } finally {
+            // clean up (not supported by jackrabbit-core)
+            try {
+                ntm.unregisterNodeType(ntd.getName());
+            } catch (Exception e) {
+                // ns unregistration is not supported by jackrabbit-core.
+            }
+        }
+    }
+}
\ No newline at end of file

Added: jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/security/authorization/NodeTypeManagementTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/security/authorization/NodeTypeManagementTest.java?rev=1437320&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/security/authorization/NodeTypeManagementTest.java (added)
+++ jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/security/authorization/NodeTypeManagementTest.java Wed Jan 23 10:11:46 2013
@@ -0,0 +1,347 @@
+/*
+ * 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.oak.jcr.security.authorization;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import javax.jcr.AccessDeniedException;
+import javax.jcr.ImportUUIDBehavior;
+import javax.jcr.Node;
+import javax.jcr.Session;
+import javax.jcr.Workspace;
+import javax.jcr.security.Privilege;
+
+import org.apache.jackrabbit.test.NotExecutableException;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+
+/**
+ * NodeTypeManagementTest... TODO
+ *
+ * copied from jr2.x NodeTypeTest
+ */
+@Ignore("OAK-51")
+public class NodeTypeManagementTest extends AbstractEvaluationTest {
+
+    private Node childNode;
+    private String mixinName;
+
+    @Override
+    @Before
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        Node child = testRootNode.addNode(nodeName2);
+        if (child.isNodeType(mixReferenceable) || !child.canAddMixin(mixReferenceable)) {
+            throw new NotExecutableException();
+        }
+        superuser.save();
+        
+        mixinName = getTestSession().getNamespacePrefix(NS_MIX_URI) + ":referenceable";
+        childNode = getTestSession().getNode(child.getPath());
+    }
+
+    @Test
+    public void testCanAddMixin() throws Exception {
+        checkReadOnly(childNode.getPath());
+
+        assertFalse(childNode.canAddMixin(mixinName));
+
+        modify(childNode.getPath(), Privilege.JCR_NODE_TYPE_MANAGEMENT, true);
+        assertTrue(childNode.canAddMixin(mixinName));
+
+        modify(childNode.getPath(), Privilege.JCR_NODE_TYPE_MANAGEMENT, false);
+        assertFalse(childNode.canAddMixin(mixinName));
+    }
+
+    @Test
+    public void testAddMixin() throws Exception {
+        checkReadOnly(childNode.getPath());
+
+        try {
+            childNode.addMixin(mixinName);
+            superuser.save();
+            fail("TestSession does not have sufficient privileges to add a mixin type.");
+        } catch (AccessDeniedException e) {
+            // success
+        }
+
+        modify(childNode.getPath(), Privilege.JCR_NODE_TYPE_MANAGEMENT, true);
+        childNode.addMixin(mixinName);
+        superuser.save();
+    }
+
+    @Test
+    public void testRemoveMixin() throws Exception {
+        ((Node) superuser.getItem(childNode.getPath())).addMixin(mixinName);
+        superuser.save();
+
+        checkReadOnly(childNode.getPath());
+
+        try {
+            childNode.removeMixin(mixinName);
+            superuser.save();
+            fail("TestSession does not have sufficient privileges to remove a mixin type.");
+        } catch (AccessDeniedException e) {
+            // success
+        }
+
+        modify(childNode.getPath(), Privilege.JCR_NODE_TYPE_MANAGEMENT, true);
+        childNode.removeMixin(mixinName);
+        superuser.save();
+    }
+
+    @Test
+    public void testSetPrimaryType() throws Exception {
+        Node child = (Node) superuser.getItem(childNode.getPath());
+        String ntName = child.getPrimaryNodeType().getName();
+
+        String changedNtName = "nt:folder";
+        child.setPrimaryType(changedNtName);
+        superuser.save();
+
+        try {
+            checkReadOnly(childNode.getPath());
+
+            try {
+                childNode.setPrimaryType(ntName);
+                superuser.save();
+                fail("TestSession does not have sufficient privileges to change the primary type.");
+            } catch (AccessDeniedException e) {
+                // success
+                getTestSession().refresh(false); // TODO: see JCR-1916
+            }
+
+            modify(childNode.getPath(), Privilege.JCR_NODE_TYPE_MANAGEMENT, true);
+            childNode.setPrimaryType(ntName);
+            superuser.save();
+
+        } finally {
+            if (!ntName.equals(child.getPrimaryNodeType().getName())) {
+                child.setPrimaryType(ntName);
+                superuser.save();
+            }
+        }
+    }
+
+    /**
+     * Test difference between common jcr:write privilege an rep:write privilege
+     * that includes the ability to set the primary node type upon child node
+     * creation.
+     */
+    @Test
+    public void testAddNode() throws Exception {
+        checkReadOnly(childNode.getPath());
+
+        // with simple write privilege a child node can be added BUT no
+        // node type must be specified.
+        modify(childNode.getPath(), Privilege.JCR_WRITE, true);
+        addChildNode(false);
+        try {
+            addChildNode(true);
+            fail("Missing privilege jcr:nodeTypeManagement.");
+        } catch (AccessDeniedException e) {
+            // success
+        }
+
+        // adding jcr:nodeTypeManagement privilege will allow to use any
+        // variant of Node.addNode.
+        modify(childNode.getPath(), Privilege.JCR_NODE_TYPE_MANAGEMENT, true);
+        addChildNode(false);
+        addChildNode(true);
+    }
+
+    private void addChildNode(boolean specifyNodeType) throws Exception {
+        Node n = null;
+        try {
+            n = (specifyNodeType) ? childNode.addNode(nodeName3, testNodeType) : childNode.addNode(nodeName3);
+        } finally {
+            if (n != null) {
+                n.remove();
+                superuser.save();
+            }
+        }
+    }
+
+    @Test
+    public void testCopy() throws Exception {
+        Workspace wsp = getTestSession().getWorkspace();
+        String parentPath = childNode.getParent().getPath();
+        String srcPath = childNode.getPath();
+        String destPath = parentPath + '/' + nodeName3;
+
+        checkReadOnly(parentPath);
+        try {
+            wsp.copy(srcPath, destPath);
+            fail("Missing write privilege.");
+        } catch (AccessDeniedException e) {
+            // success
+        }
+
+        // with simple write privilege copying a node is not allowed.
+        modify(parentPath, Privilege.JCR_WRITE, true);
+        try {
+            wsp.copy(srcPath, destPath);
+            fail("Missing privilege jcr:nodeTypeManagement.");
+        } catch (AccessDeniedException e) {
+            // success
+        }
+
+        // adding jcr:nodeTypeManagement privilege will grant permission to copy.
+        modify(parentPath, REP_WRITE, true);
+        wsp.copy(srcPath, destPath);
+    }
+
+    @Test
+    public void testWorkspaceMove() throws Exception {
+        Workspace wsp = getTestSession().getWorkspace();
+        String parentPath = childNode.getParent().getPath();
+        String srcPath = childNode.getPath();
+        String destPath = parentPath + '/' + nodeName3;
+
+        checkReadOnly(parentPath);
+        try {
+            wsp.move(srcPath, destPath);
+            fail("Missing write privilege.");
+        } catch (AccessDeniedException e) {
+            // success
+        }
+
+        // with simple write privilege moving a node is not allowed.
+        modify(parentPath, Privilege.JCR_WRITE, true);
+        try {
+            wsp.move(srcPath, destPath);
+            fail("Missing privilege jcr:nodeTypeManagement.");
+        } catch (AccessDeniedException e) {
+            // success
+        }
+
+        // adding jcr:nodeTypeManagement privilege will grant permission to move.
+        modify(parentPath, REP_WRITE, true);
+        wsp.move(srcPath, destPath);
+    }
+
+    @Test
+    public void testSessionMove() throws Exception {
+        Session s = getTestSession();
+        String parentPath = childNode.getParent().getPath();
+        String srcPath = childNode.getPath();
+        String destPath = parentPath + '/' + nodeName3;
+
+        checkReadOnly(parentPath);
+        try {
+            s.move(srcPath, destPath);
+            s.save();
+            fail("Missing write privilege.");
+        } catch (AccessDeniedException e) {
+            // success
+        }
+
+        // with simple write privilege moving a node is not allowed.
+        modify(parentPath, Privilege.JCR_WRITE, true);
+        try {
+            s.move(srcPath, destPath);
+            s.save();
+            fail("Missing privilege jcr:nodeTypeManagement.");
+        } catch (AccessDeniedException e) {
+            // success
+        }
+
+        // adding jcr:nodeTypeManagement privilege will grant permission to move.
+        modify(parentPath, REP_WRITE, true);
+        s.move(srcPath, destPath);
+        s.save();
+    }
+
+    @Test
+    public void testSessionImportXML() throws Exception {
+        Session s = getTestSession();
+        String parentPath = childNode.getPath();
+
+        checkReadOnly(parentPath);
+        try {
+            s.importXML(parentPath, getXmlForImport(), ImportUUIDBehavior.IMPORT_UUID_CREATE_NEW);
+            s.save();
+            fail("Missing write privilege.");
+        } catch (AccessDeniedException e) {
+            // success
+        } finally {
+            s.refresh(false);
+        }
+
+        // with simple write privilege moving a node is not allowed.
+        modify(parentPath, Privilege.JCR_WRITE, true);
+        try {
+            s.importXML(parentPath, getXmlForImport(), ImportUUIDBehavior.IMPORT_UUID_CREATE_NEW);
+            s.save();
+            fail("Missing privilege jcr:nodeTypeManagement.");
+        } catch (AccessDeniedException e) {
+            // success
+        } finally {
+            s.refresh(false);
+        }
+
+        // adding jcr:nodeTypeManagement privilege will grant permission to move.
+        modify(parentPath, REP_WRITE, true);
+        s.importXML(parentPath, getXmlForImport(), ImportUUIDBehavior.IMPORT_UUID_CREATE_NEW);
+        s.save();
+    }
+
+    @Test
+    public void testWorkspaceImportXML() throws Exception {
+        Workspace wsp = getTestSession().getWorkspace();
+        String parentPath = childNode.getPath();
+
+        checkReadOnly(parentPath);
+        try {
+            wsp.importXML(parentPath, getXmlForImport(), ImportUUIDBehavior.IMPORT_UUID_CREATE_NEW);
+            fail("Missing write privilege.");
+        } catch (AccessDeniedException e) {
+            // success
+        }
+
+        // with simple write privilege moving a node is not allowed.
+        modify(parentPath, Privilege.JCR_WRITE, true);
+        try {
+            wsp.importXML(parentPath, getXmlForImport(), ImportUUIDBehavior.IMPORT_UUID_CREATE_NEW);
+            fail("Missing privilege jcr:nodeTypeManagement.");
+        } catch (AccessDeniedException e) {
+            // success
+        }
+
+        // adding jcr:nodeTypeManagement privilege will grant permission to move.
+        modify(parentPath, REP_WRITE, true);
+        wsp.importXML(parentPath, getXmlForImport(), ImportUUIDBehavior.IMPORT_UUID_CREATE_NEW);
+    }
+
+    /**
+     * Simple XML for testing permissions upon import.
+     */
+    private InputStream getXmlForImport() {
+        String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
+                "<sv:node xmlns:nt=\"http://www.jcp.org/jcr/nt/1.0\"" +
+                "         xmlns:sv=\"http://www.jcp.org/jcr/sv/1.0\"" +
+                "         xmlns:jcr=\"http://www.jcp.org/jcr/1.0\"" +
+                "         sv:name=\"" + nodeName3 + "\">" +
+                "    <sv:property sv:name=\"jcr:primaryType\" sv:type=\"Name\">" +
+                "        <sv:value>" + testNodeType + "</sv:value>" +
+                "    </sv:property>" +
+                "</sv:node>";
+        return new ByteArrayInputStream(xml.getBytes());
+    }
+}
\ No newline at end of file

Added: jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/security/authorization/PrivilegeManagementTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/security/authorization/PrivilegeManagementTest.java?rev=1437320&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/security/authorization/PrivilegeManagementTest.java (added)
+++ jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/security/authorization/PrivilegeManagementTest.java Wed Jan 23 10:11:46 2013
@@ -0,0 +1,103 @@
+/*
+ * 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.oak.jcr.security.authorization;
+
+import javax.jcr.AccessDeniedException;
+import javax.jcr.RepositoryException;
+import javax.jcr.Workspace;
+import javax.jcr.security.AccessControlManager;
+import javax.jcr.security.AccessControlPolicy;
+import javax.jcr.security.Privilege;
+
+import org.apache.jackrabbit.api.JackrabbitWorkspace;
+import org.apache.jackrabbit.test.NotExecutableException;
+import org.junit.Ignore;
+import org.junit.Test;
+
+/**
+ * PrivilegeManagementTest... TODO
+ *
+ * copied from jr2x RepositoryOperationTest
+ */
+@Ignore("OAK-51")
+public class PrivilegeManagementTest extends AbstractEvaluationTest {
+
+    private static final String REP_PRIVILEGE_MANAGEMENT = "rep:privilegeManagement";
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        // test user must not be allowed
+        assertPrivilege(null, REP_PRIVILEGE_MANAGEMENT, false);
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        try {
+            for (AccessControlPolicy policy : acMgr.getPolicies(null)) {
+                acMgr.removePolicy(null, policy);
+            }
+            superuser.save();
+        } finally {
+            super.tearDown();
+        }
+    }
+
+    private String getNewPrivilegeName(Workspace wsp) throws RepositoryException, NotExecutableException {
+        String privName = null;
+        AccessControlManager acMgr = wsp.getSession().getAccessControlManager();
+        for (int i = 0; i < 100; i++) {
+            try {
+                Privilege p = acMgr.privilegeFromName(privName);
+                privName = "privilege-" + i;
+            } catch (Exception e) {
+                break;
+            }
+        }
+
+        if (privName == null) {
+            throw new NotExecutableException("failed to define new privilege name.");
+        }
+        return privName;
+    }
+
+    @Test
+    public void testRegisterPrivilege() throws Exception {
+        try {
+            Workspace testWsp = getTestSession().getWorkspace();
+            ((JackrabbitWorkspace) testWsp).getPrivilegeManager().registerPrivilege(getNewPrivilegeName(testWsp), false, new String[0]);
+            fail("Privilege registration should be denied.");
+        } catch (AccessDeniedException e) {
+            // success
+        }
+    }
+
+    @Test
+    public void testRegisterPrivilegeWithPrivilege() throws Exception {
+        modify(null, REP_PRIVILEGE_MANAGEMENT, true);
+        assertPrivilege(null, REP_PRIVILEGE_MANAGEMENT, true);
+
+        try {
+            Workspace testWsp = getTestSession().getWorkspace();
+            ((JackrabbitWorkspace) testWsp).getPrivilegeManager().registerPrivilege(getNewPrivilegeName(testWsp), false, new String[0]);        } finally {
+            modify(null, REP_PRIVILEGE_MANAGEMENT, false);
+        }
+
+        assertPrivilege(null, REP_PRIVILEGE_MANAGEMENT, false);
+    }
+}
\ No newline at end of file

Added: jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/security/authorization/VersionManagementTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/security/authorization/VersionManagementTest.java?rev=1437320&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/security/authorization/VersionManagementTest.java (added)
+++ jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/security/authorization/VersionManagementTest.java Wed Jan 23 10:11:46 2013
@@ -0,0 +1,324 @@
+/*
+ * 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.oak.jcr.security.authorization;
+
+import javax.jcr.AccessDeniedException;
+import javax.jcr.Node;
+import javax.jcr.Property;
+import javax.jcr.security.AccessControlEntry;
+import javax.jcr.security.Privilege;
+import javax.jcr.version.Version;
+import javax.jcr.version.VersionHistory;
+import javax.jcr.version.VersionManager;
+
+import org.apache.jackrabbit.api.security.JackrabbitAccessControlList;
+import org.apache.jackrabbit.commons.jackrabbit.authorization.AccessControlUtils;
+import org.apache.jackrabbit.test.NotExecutableException;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+
+/**
+ * VersionManagementTest... TODO
+ *
+ * copied and modified from jr2x VersionTest
+ */
+@Ignore("OAK-51")
+public class VersionManagementTest extends AbstractEvaluationTest {
+
+    private static final String SYSTEM = "/jcr:system";
+    private static final String VERSIONSTORE = SYSTEM + "/jcr:versionStorage";
+
+    private Privilege[] versionPrivileges;
+
+    @Override
+    @Before
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        versionPrivileges = privilegesFromName(Privilege.JCR_VERSION_MANAGEMENT);
+        assertFalse(getTestAccessControlManager().hasPrivileges(VERSIONSTORE, versionPrivileges));
+    }
+
+    private Node createVersionableNode(Node parent) throws Exception {
+        Node n = parent.addNode(nodeName1);
+        if (n.canAddMixin(mixVersionable)) {
+            n.addMixin(mixVersionable);
+        } else {
+            throw new NotExecutableException();
+        }
+        superuser.save();
+        return n;
+    }
+
+    @Test
+    public void testAddMixVersionable() throws Exception {
+        Node trn = getTestNode();
+        modify(trn.getPath(), REP_WRITE, true);
+        modify(trn.getPath(), Privilege.JCR_VERSION_MANAGEMENT, false);
+        Node n = trn.addNode(nodeName1);
+        try {
+            if (n.canAddMixin(mixVersionable)) {
+                n.addMixin(mixVersionable);
+            } else {
+                throw new NotExecutableException();
+            }
+            superuser.save();
+            fail("Test session does not have write permission in the version storage -> adding mixin must fail.");
+        } catch (AccessDeniedException e) {
+            // success
+            // ... but autocreated versionable node properties must not be present
+            assertFalse(n.isNodeType(mixVersionable));
+            assertFalse(n.hasProperty("jcr:isCheckedOut"));
+            assertFalse(n.hasProperty(jcrVersionHistory));
+        }
+    }
+
+    @Test
+    public void testAddMixVersionable2() throws Exception {
+        Node trn = getTestNode();
+        modify(trn.getPath(), REP_WRITE, true);
+        modify(trn.getPath(), Privilege.JCR_NODE_TYPE_MANAGEMENT, true);
+        modify(trn.getPath(), Privilege.JCR_VERSION_MANAGEMENT, true);
+
+        Node n = createVersionableNode(trn);
+        n.checkin();
+        n.checkout();
+    }
+
+    @Test
+    public void testCheckInCheckout() throws Exception {
+        Node trn = getTestNode();
+        modify(trn.getPath(), REP_WRITE, true);
+        modify(trn.getPath(), Privilege.JCR_VERSION_MANAGEMENT, false);
+
+        Node n = createVersionableNode(testRootNode);
+        try {
+            Node n2 = trn.getNode(n.getName());
+            n2.checkin();
+            fail("Missing jcr:versionManagement privilege -> checkin/checkout must fail.");
+        } catch (AccessDeniedException e) {
+            // success
+            // ... but the property must not be modified nor indicating
+            // checkedIn status
+            Property p = n.getProperty("jcr:isCheckedOut");
+            assertFalse(p.isModified());
+            assertTrue(n.getProperty("jcr:isCheckedOut").getValue().getBoolean());
+        }
+    }
+
+    /**
+     * @since oak (DIFF: jr required jcr:versionManagement privilege on the version store)
+     */
+    @Test
+    public void testRemoveVersion() throws Exception {
+        Node n = createVersionableNode(testRootNode);
+
+        Node trn = getTestNode();
+        modify(trn.getPath(), Privilege.JCR_VERSION_MANAGEMENT, true);
+
+        Node testNode = trn.getNode(n.getName());
+        Version v = testNode.checkin();
+        testNode.checkout();
+
+        // removing a version must be allowed
+        testNode.getVersionHistory().removeVersion(v.getName());
+    }
+
+    /**
+     * @since oak (DIFF: jr required jcr:versionManagement privilege on the version store)
+     */
+    @Test
+    public void testRemoveVersion2() throws Exception {
+        Node n = createVersionableNode(testRootNode);
+
+        Node trn = getTestNode();
+        modify(trn.getPath(), Privilege.JCR_VERSION_MANAGEMENT, true);
+
+        Node testNode = trn.getNode(n.getName());
+        Version v = testNode.checkin();
+        testNode.checkout();
+
+        // remove ability to edit version information
+        // -> VersionHistory.removeVersion must not be allowed.
+        modify(trn.getPath(), Privilege.JCR_VERSION_MANAGEMENT, false);
+        try {
+            testNode.getVersionHistory().removeVersion(v.getName());
+            fail("Missing jcr:versionManagement privilege -> remove a version must fail.");
+        } catch (AccessDeniedException e) {
+            // success
+        }
+    }
+
+    /**
+     * @since oak (DIFF: jr required jcr:versionManagement privilege on the version store)
+     */
+    @Test
+    public void testRemoveVersion3() throws Exception {
+        Node n = createVersionableNode(testRootNode);
+        Version v = n.checkin();
+        n.checkout();
+
+        assertFalse(getTestAccessControlManager().hasPrivileges(n.getPath(), versionPrivileges));
+        allow(SYSTEM, versionPrivileges);
+
+        try {
+            Node testNode = getTestNode().getNode(n.getName());
+            testNode.getVersionHistory().removeVersion(v.getName());
+
+            fail("Missing jcr:versionManagement privilege -> remove a version must fail.");
+        } catch (AccessDeniedException e) {
+            // success
+        } finally {
+            // revert privilege modification (manually remove the ACE added)
+            JackrabbitAccessControlList systemAcl = AccessControlUtils.getAccessControlList(acMgr, SYSTEM);
+            for (AccessControlEntry entry : systemAcl.getAccessControlEntries()) {
+                if (entry.getPrincipal().equals(testUser.getPrincipal())) {
+                    systemAcl.removeAccessControlEntry(entry);
+                }
+            }
+            acMgr.setPolicy(SYSTEM, systemAcl);
+            superuser.save();
+        }
+    }
+
+    /**
+     * @since oak
+     */
+    @Test
+    public void testAccessVersionContentWithoutStoreAccess() throws Exception {
+        Node n = createVersionableNode(testRootNode);
+        Version v = n.checkin();
+        VersionHistory vh = v.getVersionHistory();
+        n.checkout();
+        Version v2 = n.checkin();
+        n.checkout();
+
+        assertFalse(getTestAccessControlManager().hasPrivileges(n.getPath(), versionPrivileges));
+        deny(SYSTEM, privilegesFromName(Privilege.JCR_READ));
+
+        try {
+            // version information must still be accessible
+            assertTrue(getTestSession().nodeExists(v.getPath()));
+            assertTrue(getTestSession().nodeExists(v2.getPath()));
+            assertTrue(getTestSession().nodeExists(vh.getPath()));
+
+        } finally {
+            JackrabbitAccessControlList systemAcl = AccessControlUtils.getAccessControlList(acMgr, SYSTEM);
+            for (AccessControlEntry entry : systemAcl.getAccessControlEntries()) {
+                if (entry.getPrincipal().equals(testUser.getPrincipal())) {
+                    systemAcl.removeAccessControlEntry(entry);
+                }
+            }
+            acMgr.setPolicy("/jcr:system", systemAcl);
+            superuser.save();
+        }
+    }
+
+    /**
+     * @since oak (DIFF: jr required jcr:versionManagement privilege on the version store)
+     */
+    @Test
+    public void testAccessVersionHistory() throws Exception {
+        Node n = createVersionableNode(testRootNode);
+        allow(n.getPath(), versionPrivileges);
+
+        Node testNode = getTestNode().getNode(n.getName());
+        testNode.checkin();
+        testNode.checkout();
+
+        // accessing the version history must be allowed if the versionable node
+        // is readable to the editing test session.
+        VersionHistory vh = testNode.getVersionHistory();
+        String vhPath = vh.getPath();
+        String vhUUID = vh.getIdentifier();
+        assertTrue(vh.isSame(testNode.getSession().getNode(vhPath)));
+        assertTrue(vh.isSame(testNode.getSession().getNodeByIdentifier(vhUUID)));
+        assertTrue(vh.isSame(testNode.getSession().getNodeByUUID(vhUUID)));
+    }
+
+    /**
+     * @since oak (DIFF: jr required jcr:versionManagement privilege on the version store)
+     */
+    @Test
+    public void testAccessVersionHistoryVersionableNodeNotAccessible() throws Exception {
+        Node n = createVersionableNode(testRootNode);
+        allow(n.getPath(), versionPrivileges);
+
+        Node trn = getTestNode();
+        Node testNode = trn.getNode(n.getName());
+        testNode.checkin();
+        testNode.checkout();
+
+        VersionHistory vh = testNode.getVersionHistory();
+        String vhPath = vh.getPath();
+        String vhUUID = vh.getIdentifier();
+
+        // revert read permission on the versionable node
+        modify(n.getPath(), Privilege.JCR_READ, false);
+
+        // versionable node is not readable any more for test session.
+        assertFalse(getTestSession().nodeExists(n.getPath()));
+
+        // access version history directly => should fail
+        try {
+            VersionHistory history = (VersionHistory) getTestSession().getNode(vhPath);
+            fail("Access to version history should be denied if versionable node is not accessible");
+        } catch (AccessDeniedException e) {
+            // success
+        }
+
+        try {
+            VersionHistory history = (VersionHistory) getTestSession().getNodeByIdentifier(vhUUID);
+            fail("Access to version history should be denied if versionable node is not accessible");
+        } catch (AccessDeniedException e) {
+            // success
+        }
+
+        try {
+            VersionHistory history = (VersionHistory) getTestSession().getNodeByUUID(vhUUID);
+            fail("Access to version history should be denied if versionable node is not accessible");
+        } catch (AccessDeniedException e) {
+            // success
+        }
+    }
+
+    /**
+     * @since oak
+     */
+    @Test
+    public void testAddVersionLabel() throws Exception {
+        Node n = createVersionableNode(testRootNode);
+        allow(n.getPath(), versionPrivileges);
+
+        Node trn = getTestNode();
+        Node testNode = trn.getNode(n.getName());
+        Version v = testNode.checkin();
+        testNode.checkout();
+        Version v2 = testNode.checkin();
+        testNode.checkout();
+
+        // -> VersionHistory.addVersionLabel must be allowed
+        VersionHistory history = testNode.getVersionHistory();
+        history.addVersionLabel(v.getName(), "testLabel", false);
+        history.addVersionLabel(v2.getName(), "testLabel", true);
+
+        VersionManager vMgr = getTestSession().getWorkspace().getVersionManager();
+        history = vMgr.getVersionHistory(testNode.getPath());
+        history.addVersionLabel(v.getName(), "testLabel", true);
+    }
+}
\ No newline at end of file



Mime
View raw message