Package org.apache.jackrabbit.oak.jcr.security.authorization

Source Code of org.apache.jackrabbit.oak.jcr.security.authorization.ReadTest

/*
* 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.Set;
import javax.jcr.Node;
import javax.jcr.PathNotFoundException;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.security.AccessControlEntry;
import javax.jcr.security.AccessControlList;
import javax.jcr.security.Privilege;
import javax.jcr.util.TraversingItemVisitor;

import com.google.common.collect.Sets;
import org.apache.jackrabbit.api.security.JackrabbitAccessControlManager;
import org.apache.jackrabbit.api.security.user.Group;
import org.apache.jackrabbit.commons.jackrabbit.authorization.AccessControlUtils;
import org.apache.jackrabbit.oak.spi.security.principal.EveryonePrincipal;
import org.junit.Test;

import static org.junit.Assert.assertArrayEquals;

/**
* Permission evaluation tests related to {@link javax.jcr.security.Privilege#JCR_READ} privilege.
*/
public class ReadTest extends AbstractEvaluationTest {

    @Test
    public void testChildNodes() throws Exception {
        /* create some new nodes below 'path' */
        Node n = superuser.getNode(path);
        for (int i = 0; i < 5; i++) {
            n = n.addNode(nodeName4, testNodeType);
        }
        superuser.save();

        /* make sure the same privileges/permissions are granted as at path. */
        testSession.refresh(false);
        String childPath = n.getPath();
        assertArrayEquals(readPrivileges, testAcMgr.getPrivileges(childPath));
        testSession.checkPermission(childPath, Session.ACTION_READ);
    }

    @Test
    public void testNonExistingItem() throws Exception {
        /*
          precondition:
          testuser must have READ-only permission on the root node and below
        */
        String rootPath = testSession.getRootNode().getPath();
        assertReadOnly(rootPath);
        testSession.checkPermission(rootPath + "nonExistingItem", Session.ACTION_READ);
    }

    @Test
    public void testGetItem() throws Exception {
        // withdraw READ privilege to 'testUser' at 'path'
        deny(path, readPrivileges);
        allow(childNPath, readPrivileges);
        testSession.getItem(childNPath);
    }

    @Test
    public void testItemExists() throws Exception {
        // withdraw READ privilege to 'testUser' at 'path'
        deny(path, readPrivileges);
        allow(childNPath, readPrivileges);

        assertFalse(testSession.itemExists(path));
        assertTrue(testSession.itemExists(childNPath));
    }

    @Test
    public void testDeniedReadOnSubTree() throws Exception, InterruptedException {
        // withdraw READ privilege to 'testUser' at 'path'
        deny(childNPath, readPrivileges);
        /*
         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, ...
        assertTrue(testSession.hasPermission(path, Session.ACTION_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.
        }
    }

    @Test
    public void testAllowWriteDenyRead() throws Exception {
        // allow 'testUser' to write at 'path'
        allow(path, repWritePrivileges);
        // deny read access
        deny(path, readPrivileges);

        // testuser must not be able to access that node
        assertFalse(testSession.nodeExists(path));
    }

    @Test
    public void testDenyRoot() throws Exception {
        Set<AccessControlEntry> acesBefore = getACEs("/");
        try {
            deny("/", readPrivileges);
            testSession.getRootNode();
            fail("root should not be accessible");
        } catch (Exception e) {
            // expected exception
        } finally {
            restoreAces("/", acesBefore);
        }
    }

    private Set<AccessControlEntry> getACEs(String path) throws RepositoryException {
        AccessControlList acl = AccessControlUtils.getAccessControlList(superuser, path);
        Set<AccessControlEntry> acesBefore = Sets.newHashSet();
        if (acl != null) {
            Collections.addAll(acesBefore, acl.getAccessControlEntries());
        }
        return acesBefore;
    }

    private void restoreAces(String path, Set<AccessControlEntry> acesToKeep) throws RepositoryException {
        AccessControlList acl = AccessControlUtils.getAccessControlList(superuser, path);
        if (acl != null) {
            for (AccessControlEntry ace : acl.getAccessControlEntries()) {
                if (!acesToKeep.contains(ace)) {
                    acl.removeAccessControlEntry(ace);
                }
            }
            acMgr.setPolicy("/", acl);
            superuser.save();
        }
    }

    @Test
    public void testDenyPath() throws Exception {
        try {
            deny(path, readPrivileges);
            testSession.getNode(path);
            fail("nodet should not be accessible");
        } catch (Exception e) {
            // expected exception
        }
    }

    @Test
    public void testReadDenied() throws Exception {
        /* deny READ privilege for testUser at 'path' */
        deny(path, readPrivileges);
        /*
         allow READ privilege for testUser at 'childNPath'
         */
        allow(childNPath, readPrivileges);

        assertFalse(testSession.nodeExists(path));
        assertTrue(testSession.nodeExists(childNPath));
        Node n = testSession.getNode(childNPath);
        n.getDefinition();
    }

    @Test
    public void testDenyUserAllowGroup() throws Exception {
        /*
         deny READ privilege for testUser at 'path'
         */
        deny(path, testUser.getPrincipal(), readPrivileges);
        /*
         allow READ privilege for group at 'path'
         */
        allow(path, getTestGroup().getPrincipal(), readPrivileges);

        assertFalse(testSession.nodeExists(path));
    }

    @Test
    public void testAllowGroupDenyUser() throws Exception {
        /*
        allow READ privilege for group at 'path'
        */
        allow(path, getTestGroup().getPrincipal(), readPrivileges);
        /*
        deny READ privilege for testUser at 'path'
        */
        deny(path, testUser.getPrincipal(), readPrivileges);

        assertFalse(testSession.nodeExists(path));
    }

    @Test
    public void testAllowUserDenyGroup() throws Exception {
        /*
         allow READ privilege for testUser at 'path'
         */
        allow(path, testUser.getPrincipal(), readPrivileges);
        /*
         deny READ privilege for group at 'path'
         */
        deny(path, getTestGroup().getPrincipal(), readPrivileges);

        assertTrue(testSession.nodeExists(path));
    }

    @Test
    public void testDenyGroupAllowUser() throws Exception {
        /*
         deny READ privilege for group at 'path'
         */
        deny(path, getTestGroup().getPrincipal(), readPrivileges);

        /*
         allow READ privilege for testUser at 'path'
         */
        allow(path, testUser.getPrincipal(), readPrivileges);

        assertTrue(testSession.nodeExists(path));
    }

    @Test
    public void testDenyGroupAllowEveryone() throws Exception {
        /*
         deny READ privilege for group at 'path'
         */
        deny(path, getTestGroup().getPrincipal(), readPrivileges);

        /*
         allow READ privilege for everyone at 'path'
         */
        allow(path, EveryonePrincipal.getInstance(), readPrivileges);

        assertTrue(testSession.nodeExists(path));
    }

    @Test
    public void testAllowEveryoneDenyGroup() throws Exception {
        /*
         allow READ privilege for everyone at 'path'
         */
        allow(path, EveryonePrincipal.getInstance(), readPrivileges);

        /*
         deny READ privilege for group at 'path'
         */
        deny(path, getTestGroup().getPrincipal(), readPrivileges);

        assertFalse(testSession.nodeExists(path));
    }

    @Test
    public void testDenyGroupPathAllowEveryoneChildPath() throws Exception {
        /*
         deny READ privilege for group at 'path'
         */
        deny(path, getTestGroup().getPrincipal(), readPrivileges);

        /*
         allow READ privilege for everyone at 'childNPath'
         */
        allow(path, EveryonePrincipal.getInstance(), readPrivileges);

        assertTrue(testSession.nodeExists(childNPath));
    }

    @Test
    public void testAllowEveryonePathDenyGroupChildPath() throws Exception {
        /*
         allow READ privilege for everyone at 'path'
         */
        allow(path, EveryonePrincipal.getInstance(), readPrivileges);

        /*
         deny READ privilege for group at 'childNPath'
         */
        deny(childNPath, getTestGroup().getPrincipal(), readPrivileges);

        assertFalse(testSession.nodeExists(childNPath));
    }

    @Test
    public void testAllowUserPathDenyGroupChildPath() throws Exception {
        /*
         allow READ privilege for testUser at 'path'
         */
        allow(path, testUser.getPrincipal(), readPrivileges);
        /*
         deny READ privilege for group at 'childPath'
         */
        deny(path, getTestGroup().getPrincipal(), readPrivileges);

        assertTrue(testSession.nodeExists(childNPath));
    }

    @Test
    public void testDenyGroupPathAllowUserChildPath() throws Exception {
        /*
         deny READ privilege for group at 'path'
         */
        deny(path, getTestGroup().getPrincipal(), readPrivileges);

        /*
         allow READ privilege for testUser at 'childNPath'
         */
        allow(path, testUser.getPrincipal(), readPrivileges);

        assertTrue(testSession.nodeExists(childNPath));
    }

    @Test
    public void testDenyUserPathAllowGroupChildPath() throws Exception {
        /*
         deny READ privilege for testUser at 'path'
         */
        deny(path, testUser.getPrincipal(), readPrivileges);
        /*
         allow READ privilege for group at 'childNPath'
         */
        allow(path, getTestGroup().getPrincipal(), readPrivileges);

        assertFalse(testSession.nodeExists(childNPath));
    }

    @Test
    public void testAllowGroupPathDenyUserChildPath() throws Exception {
        /*
        allow READ privilege for the group at 'path'
        */
        allow(path, getTestGroup().getPrincipal(), readPrivileges);
        /*
        deny READ privilege for testUser at 'childNPath'
        */
        deny(path, testUser.getPrincipal(), readPrivileges);

        assertFalse(testSession.nodeExists(childNPath));
    }

    @Test
    public void testGlobRestriction() throws Exception {
        deny(path, readPrivileges, createGlobRestriction("*/" + jcrPrimaryType));

        assertTrue(testAcMgr.hasPrivileges(path, readPrivileges));
        assertTrue(testSession.hasPermission(path, javax.jcr.Session.ACTION_READ));
        testSession.getNode(path);

        assertTrue(testAcMgr.hasPrivileges(childNPath, readPrivileges));
        assertTrue(testSession.hasPermission(childNPath, javax.jcr.Session.ACTION_READ));
        testSession.getNode(childNPath);

        String propPath = path + '/' + jcrPrimaryType;
        assertFalse(testSession.hasPermission(propPath, javax.jcr.Session.ACTION_READ));
        assertFalse(testSession.propertyExists(propPath));

        propPath = childNPath + '/' + jcrPrimaryType;
        assertFalse(testSession.hasPermission(propPath, javax.jcr.Session.ACTION_READ));
        assertFalse(testSession.propertyExists(propPath));
    }

    @Test
    public void testGlobRestriction2() throws Exception {
        Group group2 = getUserManager(superuser).createGroup("group2");
        Group group3 = getUserManager(superuser).createGroup("group3");
        superuser.save();

        try {
            Privilege[] readPrivs = privilegesFromName(Privilege.JCR_READ);

            modify(path, getTestGroup().getPrincipal(), readPrivs, true, createGlobRestriction("/*"));
            allow(path, group2.getPrincipal(), readPrivs);
            deny(path, group3.getPrincipal(), readPrivs);

            Set<Principal> principals = new HashSet();
            principals.add(getTestGroup().getPrincipal());
            principals.add(group2.getPrincipal());
            principals.add(group3.getPrincipal());

            assertFalse(((JackrabbitAccessControlManager) acMgr).hasPrivileges(path, principals, readPrivs));
            assertFalse(((JackrabbitAccessControlManager) acMgr).hasPrivileges(childNPath, principals, readPrivs));
        } finally {
            group2.remove();
            group3.remove();
            superuser.save();
        }
    }

    @Test
    public void testGlobRestriction3() throws Exception {
        Group group2 = getUserManager(superuser).createGroup("group2");
        Group group3 = getUserManager(superuser).createGroup("group3");
        superuser.save();

        try {
            Privilege[] readPrivs = privilegesFromName(Privilege.JCR_READ);

            allow(path, group2.getPrincipal(), readPrivs);
            deny(path, group3.getPrincipal(), readPrivs);
            modify(path, getTestGroup().getPrincipal(), readPrivs, true, createGlobRestriction("/*"));

            Set<Principal> principals = new HashSet();
            principals.add(getTestGroup().getPrincipal());
            principals.add(group2.getPrincipal());
            principals.add(group3.getPrincipal());

            assertFalse(((JackrabbitAccessControlManager) acMgr).hasPrivileges(path, principals, readPrivs));
            assertTrue(((JackrabbitAccessControlManager) acMgr).hasPrivileges(childNPath, principals, readPrivs));
        } finally {
            group2.remove();
            group3.remove();
            superuser.save();
        }
    }

    @Test
    public void testGlobRestriction4()throws Exception{
        Node a = superuser.getNode(path).addNode("a");
        allow(path, readPrivileges);
        deny(path, readPrivileges, createGlobRestriction("*/anotherpath"));

        String aPath = a.getPath();
        assertTrue(testSession.nodeExists(aPath));
        Node n = testSession.getNode(aPath);

        Node test = testSession.getNode(path);
        assertTrue(test.hasNode("a"));
        Node n2 = test.getNode("a");
        assertTrue(n.isSame(n2));
    }

    @Test
    public void testGlobRestriction5()throws Exception{
        Node a = superuser.getNode(path).addNode("a");
        allow(path, readPrivileges);
        deny(path, readPrivileges, createGlobRestriction("*/anotherpath"));
        allow(a.getPath(), repWritePrivileges);

        String aPath = a.getPath();
        assertTrue(testSession.nodeExists(aPath));
        Node n = testSession.getNode(aPath);

        Node test = testSession.getNode(path);
        assertTrue(test.hasNode("a"));
        Node n2 = test.getNode("a");
        assertTrue(n.isSame(n2));
    }

    /**
     * @see <a href="https://issues.apache.org/jira/browse/OAK-878">OAK-878 :
     * IllegalArgumentException while adding/removing permission to user/group</a>
     */
    @Test
    public void testImplicitReorder() throws Exception{
        allow(path, testUser.getPrincipal(), readPrivileges);
        assertEntry(0, true);

        allow(path, getTestGroup().getPrincipal(), readPrivileges);
        assertEntry(0, true);

        deny(path, testUser.getPrincipal(), readPrivileges);
        assertEntry(1, false);

        deny(path, getTestGroup().getPrincipal(), readPrivileges);
        assertEntry(0, false);

        allow(path, testUser.getPrincipal(), readPrivileges);
    }

    private void assertEntry(final int index, final boolean isAllow) throws RepositoryException {
        AccessControlEntry first = AccessControlUtils.getAccessControlList(superuser, path).getAccessControlEntries()[index];

        assertEquals(testUser.getPrincipal(), first.getPrincipal());

        Node n = superuser.getNode("/jcr:system/rep:permissionStore/default/" + testUser.getPrincipal().getName());
        TraversingItemVisitor v = new TraversingItemVisitor.Default(true, -1) {
            @Override
            protected void entering(Node node, int level) throws RepositoryException {
                if (node.isNodeType("rep:Permissions") && path.equals(node.getProperty("rep:accessControlledPath").getString())) {
                    assertEquals(index, node.getProperty("rep:index").getLong());
                    assertEquals(isAllow, node.getProperty("rep:isAllow").getBoolean());
                }
            }
        };
        v.visit(n);
    }
}
TOP

Related Classes of org.apache.jackrabbit.oak.jcr.security.authorization.ReadTest

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.