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

Source Code of org.apache.jackrabbit.oak.jcr.security.privilege.PrivilegeManagerImplTest

/*
* 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.privilege;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.jcr.AccessDeniedException;
import javax.jcr.Credentials;
import javax.jcr.GuestCredentials;
import javax.jcr.NamespaceException;
import javax.jcr.Repository;
import javax.jcr.RepositoryException;
import javax.jcr.SimpleCredentials;
import javax.jcr.Workspace;
import javax.jcr.security.AccessControlException;
import javax.jcr.security.Privilege;

import org.apache.jackrabbit.api.JackrabbitWorkspace;
import org.apache.jackrabbit.api.security.authorization.PrivilegeManager;
import org.apache.jackrabbit.oak.jcr.RepositoryImpl;
import org.apache.jackrabbit.oak.security.privilege.PrivilegeConstants;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertNotNull;
import static junit.framework.Assert.assertTrue;
import static org.junit.Assert.fail;

/**
* PrivilegeManagerTest...
*
* TODO: more tests for cyclic aggregation
*/
public class PrivilegeManagerImplTest implements PrivilegeConstants {

    private static final Credentials ADMIN =
            new SimpleCredentials("admin", "admin".toCharArray());

    private Repository repository;

    private PrivilegeManager privilegeManager;

    @Before
    public void setUp() throws RepositoryException {
        repository = new RepositoryImpl();
        privilegeManager = getPrivilegeManager(ADMIN);
    }

    @After
    public void tearDown() {
        privilegeManager = null;
        repository = null;
    }

    private PrivilegeManager getPrivilegeManager(Credentials credentials)
            throws RepositoryException {
        Workspace workspace = repository.login(credentials).getWorkspace();
        return ((JackrabbitWorkspace) workspace).getPrivilegeManager();
    }

    private static String[] getAggregateNames(String... names) {
        return names;
    }

    private static void assertContainsDeclared(Privilege privilege, String aggrName) {
        boolean found = false;
        for (Privilege p : privilege.getDeclaredAggregatePrivileges()) {
            if (aggrName.equals(p.getName())) {
                found = true;
                break;
            }
        }
        assertTrue(found);
    }

    private void assertPrivilege(Privilege priv, String name, boolean isAggregate, boolean isAbstract) {
        assertNotNull(priv);
        assertEquals(name, priv.getName());
        assertEquals(isAggregate, priv.isAggregate());
        assertEquals(isAbstract, priv.isAbstract());
    }

    public void testGetRegisteredPrivileges() throws RepositoryException {
        Privilege[] registered = privilegeManager.getRegisteredPrivileges();
        Set<Privilege> set = new HashSet<Privilege>();
        Privilege all = privilegeManager.getPrivilege(Privilege.JCR_ALL);
        set.add(all);
        set.addAll(Arrays.asList(all.getAggregatePrivileges()));

        for (Privilege p : registered) {
            assertTrue(set.remove(p));
        }
        assertTrue(set.isEmpty());
    }
   
    public void testGetPrivilege() throws RepositoryException {
        for (String privName : NON_AGGR_PRIVILEGES) {
            Privilege p = privilegeManager.getPrivilege(privName);
            assertPrivilege(p, privName, false, false);
        }

        for (String privName : AGGR_PRIVILEGES) {
            Privilege p = privilegeManager.getPrivilege(privName);
            assertPrivilege(p, privName, true, false);
        }
    }

    public void testJcrAll() throws RepositoryException {
        Privilege all = privilegeManager.getPrivilege(Privilege.JCR_ALL);
        assertPrivilege(all, JCR_ALL, true, false);

        List<Privilege> decl = Arrays.asList(all.getDeclaredAggregatePrivileges());
        List<Privilege> aggr = new ArrayList<Privilege>(Arrays.asList(all.getAggregatePrivileges()));

        assertFalse(decl.contains(all));
        assertFalse(aggr.contains(all));

        // declared and aggregated privileges are the same for jcr:all
        assertTrue(decl.containsAll(aggr));

        // test individual built-in privileges are listed in the aggregates
        assertTrue(aggr.remove(privilegeManager.getPrivilege(Privilege.JCR_READ)));
        assertTrue(aggr.remove(privilegeManager.getPrivilege(Privilege.JCR_ADD_CHILD_NODES)));
        assertTrue(aggr.remove(privilegeManager.getPrivilege(Privilege.JCR_REMOVE_CHILD_NODES)));
        assertTrue(aggr.remove(privilegeManager.getPrivilege(Privilege.JCR_MODIFY_PROPERTIES)));
        assertTrue(aggr.remove(privilegeManager.getPrivilege(Privilege.JCR_REMOVE_NODE)));
        assertTrue(aggr.remove(privilegeManager.getPrivilege(Privilege.JCR_READ_ACCESS_CONTROL)));
        assertTrue(aggr.remove(privilegeManager.getPrivilege(Privilege.JCR_MODIFY_ACCESS_CONTROL)));
        assertTrue(aggr.remove(privilegeManager.getPrivilege(Privilege.JCR_LIFECYCLE_MANAGEMENT)));
        assertTrue(aggr.remove(privilegeManager.getPrivilege(Privilege.JCR_LOCK_MANAGEMENT)));
        assertTrue(aggr.remove(privilegeManager.getPrivilege(Privilege.JCR_NODE_TYPE_MANAGEMENT)));
        assertTrue(aggr.remove(privilegeManager.getPrivilege(Privilege.JCR_RETENTION_MANAGEMENT)));
        assertTrue(aggr.remove(privilegeManager.getPrivilege(Privilege.JCR_VERSION_MANAGEMENT)));
        assertTrue(aggr.remove(privilegeManager.getPrivilege(Privilege.JCR_WRITE)));
        assertTrue(aggr.remove(privilegeManager.getPrivilege(PrivilegeConstants.REP_WRITE)));
        assertTrue(aggr.remove(privilegeManager.getPrivilege(PrivilegeConstants.REP_ADD_PROPERTIES)));
        assertTrue(aggr.remove(privilegeManager.getPrivilege(PrivilegeConstants.REP_ALTER_PROPERTIES)));
        assertTrue(aggr.remove(privilegeManager.getPrivilege(PrivilegeConstants.REP_REMOVE_PROPERTIES)));
        assertTrue(aggr.remove(privilegeManager.getPrivilege(PrivilegeConstants.JCR_NAMESPACE_MANAGEMENT)));
        assertTrue(aggr.remove(privilegeManager.getPrivilege(PrivilegeConstants.JCR_NODE_TYPE_DEFINITION_MANAGEMENT)));
        assertTrue(aggr.remove(privilegeManager.getPrivilege(PrivilegeConstants.JCR_WORKSPACE_MANAGEMENT)));
        assertTrue(aggr.remove(privilegeManager.getPrivilege(PrivilegeConstants.REP_PRIVILEGE_MANAGEMENT)));

        // there may be no privileges left
        assertTrue(aggr.isEmpty());
    }

    @Test
    public void testGetPrivilegeFromName() throws AccessControlException, RepositoryException {
        Privilege p = privilegeManager.getPrivilege(Privilege.JCR_READ);

        assertTrue(p != null);
        assertEquals("jcr:read", p.getName());
        assertFalse(p.isAggregate());

        p = privilegeManager.getPrivilege(Privilege.JCR_WRITE);

        assertTrue(p != null);
        assertEquals("jcr:write", p.getName());
        assertTrue(p.isAggregate());
    }

    @Test
    public void testGetPrivilegesFromInvalidName() throws RepositoryException {
        try {
            privilegeManager.getPrivilege("unknown");
            fail("invalid privilege name");
        } catch (AccessControlException e) {
            // OK
        }
    }

    @Test
    public void testGetPrivilegesFromEmptyNames() {
        try {
            privilegeManager.getPrivilege("");
            fail("invalid privilege name array");
        } catch (AccessControlException e) {
            // OK
        } catch (RepositoryException e) {
            // OK
        }
    }

    @Test
    public void testGetPrivilegesFromNullNames() {
        try {
            privilegeManager.getPrivilege(null);
            fail("invalid privilege name (null)");
        } catch (Exception e) {
            // OK
        }
    }

    @Test
    public void testRegisterPrivilegeWithIllegalName() {
        Map<String, String[]> illegal = new HashMap<String, String[]>();
        // invalid privilege name
        illegal.put(null, new String[0]);
        illegal.put("", new String[0]);
        illegal.put("invalid:privilegeName", new String[0]);
        illegal.put(".e:privilegeName", new String[0]);
        // invalid aggregate names
        illegal.put("newPrivilege", new String[] {"invalid:privilegeName"});
        illegal.put("newPrivilege", new String[] {".e:privilegeName"});
        illegal.put("newPrivilege", new String[] {null});
        illegal.put("newPrivilege", new String[] {""});

        for (String illegalName : illegal.keySet()) {
            try {
                privilegeManager.registerPrivilege(illegalName, true, illegal.get(illegalName));
                fail("Illegal name -> Exception expected");
            } catch (NamespaceException e) {
                // success
            } catch (RepositoryException e) {
                // success
            }
        }
    }

    @Test
    public void testRegisterReservedName() {
        Map<String, String[]> illegal = new HashMap<String, String[]>();
        // invalid privilege name
        illegal.put(null, new String[0]);
        illegal.put("jcr:privilegeName", new String[0]);
        illegal.put("rep:privilegeName", new String[0]);
        illegal.put("nt:privilegeName", new String[0]);
        illegal.put("mix:privilegeName", new String[0]);
        illegal.put("sv:privilegeName", new String[0]);
        illegal.put("xml:privilegeName", new String[0]);
        illegal.put("xmlns:privilegeName", new String[0]);
        // invalid aggregate names
        illegal.put("newPrivilege", new String[] {"jcr:privilegeName"});

        for (String illegalName : illegal.keySet()) {
            try {
                privilegeManager.registerPrivilege(illegalName, true, illegal.get(illegalName));
                fail("Illegal name -> Exception expected");
            } catch (RepositoryException e) {
                // success
            }
        }
    }

    @Test
    public void testRegisterPrivilegeWithReadOnly() throws RepositoryException {
        try {
            getPrivilegeManager(new GuestCredentials()).registerPrivilege("test", true, new String[0]);
            fail("Only admin is allowed to register privileges.");
        } catch (AccessDeniedException e) {
            // success
        }
    }

    @Test
    public void testCustomDefinitionsWithCyclicReferences() throws RepositoryException {
        try {
            privilegeManager.registerPrivilege("cycl-1", false, new String[] {"cycl-1"});
            fail("Cyclic definitions must be detected upon registry startup.");
        } catch (RepositoryException e) {
            // success
        }
    }

    @Test
    public void testCustomEquivalentDefinitions() throws RepositoryException {
        privilegeManager.registerPrivilege("custom4", false, new String[0]);
        privilegeManager.registerPrivilege("custom5", false, new String[0]);
        privilegeManager.registerPrivilege("custom2", false, new String[] {"custom4", "custom5"});

        List<String[]> equivalent = new ArrayList<String[]>();
        equivalent.add(new String[] {"custom4", "custom5"});
        equivalent.add(new String[] {"custom2", "custom4"});
        equivalent.add(new String[] {"custom2", "custom5"});
        int cnt = 6;
        for (String[] aggrNames : equivalent) {
            try {
                // the equivalent definition to 'custom1'
                String name = "custom"+(cnt++);
                privilegeManager.registerPrivilege(name, false, aggrNames);
                fail("Equivalent '"+name+"' definitions must be detected.");
            } catch (RepositoryException e) {
                // success
            }
        }
    }

    @Test
    public void testRegisterBuiltInPrivilege() throws RepositoryException {
        Map<String, String[]> builtIns = new HashMap<String, String[]>();
        builtIns.put(PrivilegeConstants.JCR_READ, new String[0]);
        builtIns.put(PrivilegeConstants.JCR_LIFECYCLE_MANAGEMENT, new String[] {PrivilegeConstants.JCR_ADD_CHILD_NODES});
        builtIns.put(PrivilegeConstants.REP_WRITE, new String[0]);
        builtIns.put(PrivilegeConstants.JCR_ALL, new String[0]);

        for (String builtInName : builtIns.keySet()) {
            try {
                privilegeManager.registerPrivilege(builtInName, false, builtIns.get(builtInName));
                fail("Privilege name " +builtInName+ " already in use -> Exception expected");
            } catch (RepositoryException e) {
                // success
            }
        }
    }

    @Test
    public void testRegisterInvalidNewAggregate() throws RepositoryException {
        Map<String, String[]> newAggregates = new LinkedHashMap<String, String[]>();
        // same as jcr:read
        newAggregates.put("jcrReadAggregate", getAggregateNames(PrivilegeConstants.JCR_READ));
        // aggregated combining built-in and an unknown privilege
        newAggregates.put("newAggregate2", getAggregateNames(PrivilegeConstants.JCR_READ, "unknownPrivilege"));
        // aggregate containing unknown privilege
        newAggregates.put("newAggregate3", getAggregateNames("unknownPrivilege"));
        // custom aggregated contains itself
        newAggregates.put("newAggregate4", getAggregateNames("newAggregate"));
        // same as rep:write
        newAggregates.put("repWriteAggregate", getAggregateNames(PrivilegeConstants.JCR_MODIFY_PROPERTIES, PrivilegeConstants.JCR_ADD_CHILD_NODES, PrivilegeConstants.JCR_NODE_TYPE_MANAGEMENT, PrivilegeConstants.JCR_REMOVE_CHILD_NODES, PrivilegeConstants.JCR_REMOVE_NODE));
        // aggregated combining built-in and unknown custom
        newAggregates.put("newAggregate5", getAggregateNames(PrivilegeConstants.JCR_READ, "unknownPrivilege"));

        for (String name : newAggregates.keySet()) {
            try {
                privilegeManager.registerPrivilege(name, true, newAggregates.get(name));
                fail("New aggregate "+ name +" referring to unknown Privilege  -> Exception expected");
            } catch (RepositoryException e) {
                // success
            }
        }
    }

    @Test
    public void testRegisterInvalidNewAggregate2() throws RepositoryException {
        Map<String, String[]> newCustomPrivs = new LinkedHashMap<String, String[]>();
        newCustomPrivs.put("new", new String[0]);
        newCustomPrivs.put("new2", new String[0]);
        Set<String> decl = new HashSet<String>();
        decl.add("new");
        decl.add("new2");
        newCustomPrivs.put("new3", getAggregateNames("new", "new2"));

        for (String name : newCustomPrivs.keySet()) {
            boolean isAbstract = true;
            String[] aggrNames = newCustomPrivs.get(name);
            privilegeManager.registerPrivilege(name, isAbstract, aggrNames);
        }

        Map<String, String[]> newAggregates = new LinkedHashMap<String, String[]>();
         // other illegal aggregates already represented by registered definition.
        newAggregates.put("newA2", getAggregateNames("new"));
        newAggregates.put("newA3", getAggregateNames("new2"));

        for (String name : newAggregates.keySet()) {
            boolean isAbstract = false;
            String[] aggrNames = newAggregates.get(name);

            try {
                privilegeManager.registerPrivilege(name, isAbstract, aggrNames);
                fail("Invalid aggregation in definition '"+ name.toString()+"' : Exception expected");
            } catch (RepositoryException e) {
                // success
            }
        }
    }

    @Test
    public void testRegisterCustomPrivileges() throws RepositoryException {
        Workspace workspace = repository.login(ADMIN).getWorkspace();
        workspace.getNamespaceRegistry().registerNamespace(
                "test", "http://www.apache.org/jackrabbit/test");

        Map<String, String[]> newCustomPrivs = new HashMap<String, String[]>();
        newCustomPrivs.put("new", new String[0]);
        newCustomPrivs.put("test:new", new String[0]);

        for (String name : newCustomPrivs.keySet()) {
            boolean isAbstract = true;
            String[] aggrNames = newCustomPrivs.get(name);

            Privilege registered = privilegeManager.registerPrivilege(name, isAbstract, aggrNames);

            // validate definition
            Privilege privilege = privilegeManager.getPrivilege(name);
            assertNotNull(privilege);
            assertEquals(name, privilege.getName());
            assertTrue(privilege.isAbstract());
            assertEquals(0, privilege.getDeclaredAggregatePrivileges().length);
            assertContainsDeclared(privilegeManager.getPrivilege(PrivilegeConstants.JCR_ALL), name);
        }

        Map<String, String[]> newAggregates = new HashMap<String, String[]>();
        // a new aggregate of custom privileges
        newAggregates.put("newA2", getAggregateNames("test:new", "new"));
        // a new aggregate of custom and built-in privilege
        newAggregates.put("newA1", getAggregateNames("new", PrivilegeConstants.JCR_READ));
        // aggregating built-in privileges
        newAggregates.put("aggrBuiltIn", getAggregateNames(PrivilegeConstants.JCR_MODIFY_PROPERTIES, PrivilegeConstants.JCR_READ));

        for (String name : newAggregates.keySet()) {
            boolean isAbstract = false;
            String[] aggrNames = newAggregates.get(name);
            privilegeManager.registerPrivilege(name, isAbstract, aggrNames);
            Privilege p = privilegeManager.getPrivilege(name);

            assertNotNull(p);
            assertEquals(name, p.getName());
            assertFalse(p.isAbstract());

            for (String n : aggrNames) {
                assertContainsDeclared(p, n);
            }
            assertContainsDeclared(privilegeManager.getPrivilege(PrivilegeConstants.JCR_ALL), name);
        }
    }

    @Test
    public void testCustomPrivilegeVisibleToNewSession() throws RepositoryException {
        boolean isAbstract = false;
        String privName = "testCustomPrivilegeVisibleToNewSession";
        privilegeManager.registerPrivilege(privName, isAbstract, new String[0]);

        PrivilegeManager pm = getPrivilegeManager(ADMIN);
        Privilege priv = pm.getPrivilege(privName);
        assertEquals(privName, priv.getName());
        assertEquals(isAbstract, priv.isAbstract());
        assertFalse(priv.isAggregate());
    }

//    FIXME: Session#refresh must refresh privilege definitions
//    @Test
//    public void testCustomPrivilegeVisibleAfterRefresh() throws RepositoryException {
//        Session s2 = getHelper().getSuperuserSession();
//        try {
//            boolean isAbstract = false;
//            String privName = "testCustomPrivilegeVisibleAfterRefresh";
//            privilegeManager.registerPrivilege(privName, isAbstract, new String[0]);
//
//            // before refreshing: privilege not visible
//            PrivilegeManager pm = getPrivilegeManager(s2);
//            try {
//                Privilege priv = pm.getPrivilege(privName);
//                fail("Custom privilege must show up after Session#refresh()");
//            } catch (AccessControlException e) {
//                // success
//            }
//
//            // after refresh privilege manager must be updated
//            s2.refresh(true);
//            Privilege priv = pm.getPrivilege(privName);
//            assertEquals(privName, priv.getName());
//            assertEquals(isAbstract, priv.isAbstract());
//            assertFalse(priv.isAggregate());
//        } finally {
//            s2.logout();
//        }
//    }
}
TOP

Related Classes of org.apache.jackrabbit.oak.jcr.security.privilege.PrivilegeManagerImplTest

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.