Added: 
jackrabbit/oak/trunk/oak-authorization-principalbased/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/PrincipalPolicyImplTest.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-authorization-principalbased/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/PrincipalPolicyImplTest.java?rev=1857551&view=auto
==============================================================================
--- 
jackrabbit/oak/trunk/oak-authorization-principalbased/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/PrincipalPolicyImplTest.java
 (added)
+++ 
jackrabbit/oak/trunk/oak-authorization-principalbased/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/PrincipalPolicyImplTest.java
 Mon Apr 15 07:16:49 2019
@@ -0,0 +1,653 @@
+/*
+ * 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.spi.security.authorization.principalbased.impl;
+
+import com.google.common.base.Function;
+import com.google.common.base.Strings;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Iterables;
+import org.apache.jackrabbit.api.security.authorization.PrivilegeManager;
+import org.apache.jackrabbit.oak.api.PropertyState;
+import org.apache.jackrabbit.oak.api.Tree;
+import org.apache.jackrabbit.oak.api.Type;
+import org.apache.jackrabbit.oak.plugins.memory.PropertyStates;
+import org.apache.jackrabbit.oak.spi.nodetype.NodeTypeConstants;
+import 
org.apache.jackrabbit.oak.spi.security.authorization.accesscontrol.AccessControlConstants;
+import 
org.apache.jackrabbit.oak.spi.security.authorization.principalbased.PrincipalPolicy;
+import 
org.apache.jackrabbit.oak.spi.security.authorization.restriction.Restriction;
+import 
org.apache.jackrabbit.oak.spi.security.authorization.restriction.RestrictionDefinition;
+import 
org.apache.jackrabbit.oak.spi.security.authorization.restriction.RestrictionDefinitionImpl;
+import 
org.apache.jackrabbit.oak.spi.security.authorization.restriction.RestrictionProvider;
+import org.apache.jackrabbit.oak.spi.security.principal.EveryonePrincipal;
+import org.apache.jackrabbit.oak.spi.security.principal.PrincipalImpl;
+import org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeBitsProvider;
+import org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.junit.Before;
+import org.junit.Test;
+
+import javax.jcr.PropertyType;
+import javax.jcr.RepositoryException;
+import javax.jcr.Value;
+import javax.jcr.ValueFactory;
+import javax.jcr.ValueFormatException;
+import javax.jcr.security.AccessControlEntry;
+import javax.jcr.security.AccessControlException;
+import javax.jcr.security.Privilege;
+import java.security.Principal;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+import static 
org.apache.jackrabbit.oak.spi.security.authorization.accesscontrol.AccessControlConstants.REP_GLOB;
+import static 
org.apache.jackrabbit.oak.spi.security.authorization.accesscontrol.AccessControlConstants.REP_ITEM_NAMES;
+import static 
org.apache.jackrabbit.oak.spi.security.authorization.accesscontrol.AccessControlConstants.REP_NODE_PATH;
+import static 
org.apache.jackrabbit.oak.spi.security.authorization.principalbased.impl.Constants.REP_EFFECTIVE_PATH;
+import static 
org.apache.jackrabbit.oak.spi.security.authorization.principalbased.impl.Constants.REP_PRIVILEGES;
+import static 
org.apache.jackrabbit.oak.spi.security.authorization.principalbased.impl.Constants.REP_RESTRICTIONS;
+import static 
org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants.JCR_ALL;
+import static 
org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants.JCR_NAMESPACE_MANAGEMENT;
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+public class PrincipalPolicyImplTest extends AbstractPrincipalBasedTest {
+
+    private static final String TEST_OAK_PATH = "/oak:test";
+    private static final String POLICY_OAK_PATH = SUPPORTED_PATH + 
"/oak:testPath";
+
+    private Principal principal;
+
+    private String testJcrPath;
+    private String policyJcrPath;
+
+    private PrincipalPolicyImpl emptyPolicy;
+    private PrincipalPolicyImpl policy;
+
+    private PrivilegeBitsProvider privilegeBitsProvider;
+
+    @Before
+    public void before() throws Exception {
+        super.before();
+
+        testJcrPath = getNamePathMapper().getJcrPath(TEST_OAK_PATH);
+        policyJcrPath = getNamePathMapper().getJcrPath(POLICY_OAK_PATH);
+
+        principal = new PrincipalImpl("principalName");
+
+        emptyPolicy = createPolicy(POLICY_OAK_PATH);
+
+        policy = createPolicy(POLICY_OAK_PATH);
+        policy.addEntry(testJcrPath, 
privilegesFromNames(PrivilegeConstants.JCR_NODE_TYPE_MANAGEMENT, 
PrivilegeConstants.REP_WRITE));
+        policy.addEntry(null, 
privilegesFromNames(PrivilegeConstants.JCR_NODE_TYPE_DEFINITION_MANAGEMENT));
+
+        privilegeBitsProvider = new PrivilegeBitsProvider(root);
+    }
+
+    private PrincipalPolicyImpl createPolicy(@NotNull String oakPath) {
+        return new PrincipalPolicyImpl(principal, oakPath, 
getMgrProvider(root));
+    }
+
+    private Tree createEntryTree(@NotNull PrincipalPolicyImpl.EntryImpl entry) 
{
+        Tree t = mock(Tree.class);
+        PropertyState path = PropertyStates.createProperty(REP_EFFECTIVE_PATH, 
Strings.nullToEmpty(entry.getOakPath()));
+        when(t.getProperty(REP_EFFECTIVE_PATH)).thenReturn(path);
+        PropertyState privs = PropertyStates.createProperty(REP_PRIVILEGES, 
privilegeBitsProvider.getPrivilegeNames(entry.getPrivilegeBits()), Type.NAMES);
+        when(t.getProperty(REP_PRIVILEGES)).thenReturn(privs);
+
+        Iterable props = Iterables.transform(entry.getRestrictions(), 
(Function<Restriction, PropertyState>) restriction -> 
restriction.getProperty());
+        Tree rTree = mock(Tree.class);
+        when(rTree.getProperties()).thenReturn(props);
+        when(t.getChild(REP_RESTRICTIONS)).thenReturn(rTree);
+        return t;
+    }
+
+    private Tree createEntryTree(@NotNull String oakPath, @NotNull String... 
privilegeNames) {
+        Tree t = mock(Tree.class);
+        PropertyState path = PropertyStates.createProperty(REP_EFFECTIVE_PATH, 
oakPath);
+        when(t.getProperty(REP_EFFECTIVE_PATH)).thenReturn(path);
+        PropertyState privs = PropertyStates.createProperty(REP_PRIVILEGES, 
ImmutableList.copyOf(privilegeNames), Type.NAMES);
+        when(t.getProperty(REP_PRIVILEGES)).thenReturn(privs);
+        Tree rTree = 
when(mock(Tree.class).getProperties()).thenReturn(Collections.emptySet()).getMock();
+        when(t.getChild(REP_RESTRICTIONS)).thenReturn(rTree);
+        return t;
+    }
+
+    private Map<String, Value> createGlobRestriction(@NotNull String value) 
throws ValueFormatException {
+        return ImmutableMap.of(getJcrName(REP_GLOB), 
getValueFactory(root).createValue(value));
+    }
+
+    private Map<String, Value> createRestrictions(@NotNull String oakName, 
@NotNull String value) throws ValueFormatException {
+        return ImmutableMap.of(getJcrName(oakName), 
getValueFactory(root).createValue(value));
+    }
+
+    private Map<String, Value[]> createMvRestrictions(@NotNull String oakName, 
int propertyType, @NotNull String... values) throws ValueFormatException {
+        ValueFactory vf = getValueFactory(root);
+        Value[] vs = new Value[values.length];
+        for (int i = 0; i<values.length; i++) {
+            vs[i] = vf.createValue(values[i], propertyType);
+        }
+        return ImmutableMap.of(getJcrName(oakName), vs);
+    }
+
+    private String getJcrName(@NotNull String oakName) {
+        return getNamePathMapper().getJcrName(oakName);
+    }
+
+    @Test
+    public void testGetInitialSize() {
+        assertEquals(0, emptyPolicy.size());
+    }
+
+    @Test
+    public void testGetSize() {
+        assertEquals(policy.getEntries().size(), policy.size());
+    }
+
+    @Test
+    public void testInitiallyIsEmpty() {
+        assertTrue(emptyPolicy.isEmpty());
+    }
+
+    @Test
+    public void testIsEmpty() {
+        assertEquals(policy.getEntries().isEmpty(), policy.isEmpty());
+    }
+
+    @Test
+    public void testGetPath() {
+        assertEquals(policyJcrPath, policy.getPath());
+    }
+
+    @Test
+    public void testGetOakPath() {
+        assertEquals(POLICY_OAK_PATH, policy.getOakPath());
+    }
+
+    @Test
+    public void testGetNamePathMapper() {
+        assertSame(getMgrProvider(root).getNamePathMapper(), 
policy.getNamePathMapper());
+    }
+
+    @Test
+    public void testGetPrincipal() {
+        assertSame(principal, policy.getPrincipal());
+    }
+
+    @Test
+    public void testAddEntry() throws Exception {
+        assertTrue(emptyPolicy.addEntry(testJcrPath, 
privilegesFromNames(PrivilegeConstants.JCR_ADD_CHILD_NODES)));
+        assertEquals(1, emptyPolicy.size());
+    }
+
+    @Test
+    public void testAddEntryTwice() throws Exception {
+        assertTrue(emptyPolicy.addEntry(testJcrPath, 
privilegesFromNames(PrivilegeConstants.JCR_ADD_CHILD_NODES)));
+        assertFalse(emptyPolicy.addEntry(testJcrPath, 
privilegesFromNames(PrivilegeConstants.JCR_ADD_CHILD_NODES)));
+        assertEquals(1, emptyPolicy.getEntries().size());
+    }
+
+    @Test
+    public void testAddEntriesForSamePath() throws Exception {
+        assertTrue(emptyPolicy.addEntry(testJcrPath, 
privilegesFromNames(PrivilegeConstants.JCR_ADD_CHILD_NODES)));
+        assertTrue(emptyPolicy.addEntry(testJcrPath, 
privilegesFromNames(PrivilegeConstants.JCR_REMOVE_CHILD_NODES, 
PrivilegeConstants.JCR_REMOVE_NODE)));
+        List<PrincipalPolicyImpl.EntryImpl> entries = emptyPolicy.getEntries();
+        assertEquals(2, entries.size());
+
+        PrivilegeBitsProvider bitsProvider = new PrivilegeBitsProvider(root);
+
+        assertEquals(testJcrPath, entries.get(0).getEffectivePath());
+        
assertEquals(bitsProvider.getBits(PrivilegeConstants.JCR_ADD_CHILD_NODES), 
entries.get(0).getPrivilegeBits());
+        
assertEquals(bitsProvider.getBits(PrivilegeConstants.JCR_REMOVE_CHILD_NODES, 
PrivilegeConstants.JCR_REMOVE_NODE), entries.get(1).getPrivilegeBits());
+    }
+
+    @Test
+    public void testAddEntriesWithRestrictionsForSamePath() throws Exception {
+        assertTrue(emptyPolicy.addEntry(testJcrPath, 
privilegesFromNames(PrivilegeConstants.JCR_ADD_CHILD_NODES)));
+        assertTrue(emptyPolicy.addEntry(testJcrPath, 
privilegesFromNames(PrivilegeConstants.JCR_REMOVE_CHILD_NODES), 
ImmutableMap.of(), createMvRestrictions(REP_ITEM_NAMES, PropertyType.NAME, 
"removable")));
+
+        PrivilegeBitsProvider bitsProvider = new PrivilegeBitsProvider(root);
+
+        List<PrincipalPolicyImpl.EntryImpl> entries = emptyPolicy.getEntries();
+        assertEquals(2, entries.size());
+
+        PrincipalPolicyImpl.EntryImpl entry = entries.get(0);
+        assertEquals(testJcrPath, entry.getEffectivePath());
+        
assertEquals(bitsProvider.getBits(PrivilegeConstants.JCR_ADD_CHILD_NODES), 
entry.getPrivilegeBits());
+        assertTrue(entry.getRestrictions().isEmpty());
+
+        entry = entries.get(1);
+        assertEquals(testJcrPath, entry.getEffectivePath());
+        
assertEquals(bitsProvider.getBits(PrivilegeConstants.JCR_REMOVE_CHILD_NODES), 
entry.getPrivilegeBits());
+        assertEquals(1, entry.getRestrictions().size());
+        assertEquals(REP_ITEM_NAMES, 
entry.getRestrictions().iterator().next().getDefinition().getName());
+    }
+
+    @Test
+    public void testAddEntriesWithMultipleRestrictionsForSamePath() throws 
Exception {
+        assertTrue(emptyPolicy.addEntry(testJcrPath, 
privilegesFromNames(PrivilegeConstants.JCR_ADD_CHILD_NODES), 
createGlobRestriction("/any*/glob"), ImmutableMap.of()));
+        assertTrue(emptyPolicy.addEntry(testJcrPath, 
privilegesFromNames(PrivilegeConstants.JCR_REMOVE_CHILD_NODES), 
ImmutableMap.of(), createMvRestrictions(REP_ITEM_NAMES, PropertyType.NAME, 
"removable")));
+
+        PrivilegeBitsProvider bitsProvider = new PrivilegeBitsProvider(root);
+
+        List<PrincipalPolicyImpl.EntryImpl> entries = emptyPolicy.getEntries();
+        assertEquals(2, entries.size());
+
+        PrincipalPolicyImpl.EntryImpl entry = entries.get(0);
+        assertEquals(testJcrPath, entry.getEffectivePath());
+        
assertEquals(bitsProvider.getBits(PrivilegeConstants.JCR_ADD_CHILD_NODES), 
entry.getPrivilegeBits());
+        assertEquals(1, entry.getRestrictions().size());
+        assertEquals(REP_GLOB, 
entry.getRestrictions().iterator().next().getDefinition().getName());
+
+        entry = entries.get(1);
+        assertEquals(testJcrPath, entry.getEffectivePath());
+        
assertEquals(bitsProvider.getBits(PrivilegeConstants.JCR_REMOVE_CHILD_NODES), 
entry.getPrivilegeBits());
+        
assertEquals(bitsProvider.getBits(PrivilegeConstants.JCR_REMOVE_CHILD_NODES), 
entry.getPrivilegeBits());
+        assertEquals(1, entry.getRestrictions().size());
+        assertEquals(REP_ITEM_NAMES, 
entry.getRestrictions().iterator().next().getDefinition().getName());
+    }
+
+    @Test
+    public void testAddEntryWithRestrictions() throws Exception {
+        Map<String, Value[]> mvRestrictions = 
createMvRestrictions(AccessControlConstants.REP_ITEM_NAMES, PropertyType.NAME, 
getNamePathMapper().getJcrName("oak:test"), "abc");
+
+        int expectedSize = policy.getEntries().size()+1;
+        assertTrue(policy.addEntry(testJcrPath, 
privilegesFromNames(PrivilegeConstants.JCR_WRITE), Collections.emptyMap(), 
mvRestrictions));
+        assertEquals(expectedSize, policy.size());
+    }
+
+    @Test
+    public void testAddEntryWithRestrictionsTwice() throws Exception {
+        Map<String, Value> restrictions = createGlobRestriction("*/some*glob");
+
+        assertTrue(policy.addEntry(testJcrPath, 
privilegesFromNames(PrivilegeConstants.JCR_READ_ACCESS_CONTROL, 
PrivilegeConstants.JCR_MODIFY_ACCESS_CONTROL), restrictions, 
Collections.emptyMap()));
+        assertFalse(policy.addEntry(testJcrPath, 
privilegesFromNames(PrivilegeConstants.JCR_READ_ACCESS_CONTROL, 
PrivilegeConstants.JCR_MODIFY_ACCESS_CONTROL), restrictions, 
Collections.emptyMap()));
+    }
+
+    @Test(expected = AccessControlException.class)
+    public void testAddEntryMissingMandatoryRestriction() throws Exception {
+        RestrictionProvider restrictionProvider = 
mock(RestrictionProvider.class);
+        
when(restrictionProvider.getSupportedRestrictions(anyString())).thenReturn(
+                ImmutableSet.of(new RestrictionDefinitionImpl("oak:mandatory", 
Type.LONG, true)));
+        MgrProvider mp = 
when(mock(MgrProvider.class).getRestrictionProvider()).thenReturn(restrictionProvider).getMock();
+        when(mp.getNamePathMapper()).thenReturn(getNamePathMapper());
+
+        PrincipalPolicyImpl plc = new PrincipalPolicyImpl(principal, 
POLICY_OAK_PATH, mp);
+        String jcrName = namePathMapper.getJcrName("oak:mandatory");
+        Map<String,Value[]> mvRestrictions = ImmutableMap.of(jcrName, new 
Value[] {getValueFactory(root).createValue(1)});
+        plc.addEntry(testJcrPath, 
privilegesFromNames(PrivilegeConstants.JCR_VERSION_MANAGEMENT), 
ImmutableMap.of(), mvRestrictions);
+    }
+
+    @Test(expected = AccessControlException.class)
+    public void testAddEntryMissingMandatoryMVRestriction() throws Exception {
+        RestrictionProvider restrictionProvider = 
mock(RestrictionProvider.class);
+        
when(restrictionProvider.getSupportedRestrictions(anyString())).thenReturn(
+                ImmutableSet.of(new RestrictionDefinitionImpl("oak:mandatory", 
Type.LONGS, true)));
+        MgrProvider mp = 
when(mock(MgrProvider.class).getRestrictionProvider()).thenReturn(restrictionProvider).getMock();
+        when(mp.getNamePathMapper()).thenReturn(getNamePathMapper());
+
+        PrincipalPolicyImpl plc = new PrincipalPolicyImpl(principal, 
POLICY_OAK_PATH, mp);
+        String jcrName = namePathMapper.getJcrName("oak:mandatory");
+        Map<String,Value> svRestrictions = ImmutableMap.of(jcrName, 
getValueFactory(root).createValue(1));
+        plc.addEntry(testJcrPath, 
privilegesFromNames(PrivilegeConstants.JCR_VERSION_MANAGEMENT), svRestrictions, 
ImmutableMap.of());
+    }
+
+    @Test(expected = AccessControlException.class)
+    public void testAddEntryMandatoryRestrictionWithOakName() throws Exception 
{
+        RestrictionProvider restrictionProvider = 
when(mock(RestrictionProvider.class).getSupportedRestrictions(anyString())).thenReturn(
+                ImmutableSet.of(new RestrictionDefinitionImpl("oak:mandatory", 
Type.LONG, true))).getMock();
+        MgrProvider mp = 
when(mock(MgrProvider.class).getRestrictionProvider()).thenReturn(restrictionProvider).getMock();
+        when(mp.getNamePathMapper()).thenReturn(getNamePathMapper());
+
+        PrincipalPolicyImpl plc = new PrincipalPolicyImpl(principal, 
POLICY_OAK_PATH, mp);
+        Map<String,Value> svRestrictions = ImmutableMap.of("oak:mandatory", 
getValueFactory(root).createValue(1));
+        plc.addEntry(testJcrPath, 
privilegesFromNames(PrivilegeConstants.JCR_VERSION_MANAGEMENT), svRestrictions, 
ImmutableMap.of());
+    }
+
+    @Test
+    public void testAddEntryMandatoryRestriction() throws Exception {
+        RestrictionDefinition def = new RestrictionDefinitionImpl("mandatory", 
Type.LONG, true);
+        Restriction r = mock(Restriction.class);
+
+        RestrictionProvider restrictionProvider = 
mock(RestrictionProvider.class);
+        
when(restrictionProvider.getSupportedRestrictions(anyString())).thenReturn(ImmutableSet.of(def));
+        when(restrictionProvider.createRestriction(anyString(), anyString(), 
any(Value.class))).thenReturn(r);
+
+        MgrProvider mp = 
when(mock(MgrProvider.class).getRestrictionProvider()).thenReturn(restrictionProvider).getMock();
+        when(mp.getNamePathMapper()).thenReturn(getNamePathMapper());
+        when(mp.getPrivilegeManager()).thenReturn(getPrivilegeManager(root));
+        when(mp.getPrivilegeBitsProvider()).thenReturn(new 
PrivilegeBitsProvider(root));
+
+        PrincipalPolicyImpl plc = new PrincipalPolicyImpl(principal, 
POLICY_OAK_PATH, mp);
+        Map<String,Value> svRestrictions = ImmutableMap.of("mandatory", 
getValueFactory(root).createValue(1));
+        plc.addEntry(testJcrPath, 
privilegesFromNames(PrivilegeConstants.JCR_VERSION_MANAGEMENT), svRestrictions, 
ImmutableMap.of());
+
+        assertTrue(plc.getEntries().get(0).getRestrictions().contains(r));
+    }
+
+    @Test
+    public void testAddEntryForRepositoryLevel() throws Exception {
+        assertTrue(emptyPolicy.addEntry(null, 
privilegesFromNames(PrivilegeConstants.JCR_WORKSPACE_MANAGEMENT)));
+        assertEquals(1, emptyPolicy.getEntries().size());
+    }
+
+    @Test(expected = AccessControlException.class)
+    public void testAddEntryEmptyPrivileges() throws Exception {
+        policy.addEntry(testJcrPath, new Privilege[0]);
+    }
+
+    @Test(expected = AccessControlException.class)
+    public void testAddEntryUnknownPrivilege() throws Exception {
+        Privilege privilege = 
when(mock(Privilege.class).getName()).thenReturn("unknown").getMock();
+        policy.addEntry(testJcrPath, new Privilege[] {privilege});
+    }
+
+    @Test(expected = AccessControlException.class)
+    public void testAddEntryAbstractPrivilege() throws Exception {
+        Privilege privilege = 
when(mock(Privilege.class).isAbstract()).thenReturn(true).getMock();
+        when(privilege.getName()).thenReturn("abstract");
+
+        PrivilegeManager privilegeManager = 
when(mock(PrivilegeManager.class).getPrivilege("abstract")).thenReturn(privilege).getMock();
+        MgrProvider mp = 
when(mock(MgrProvider.class).getPrivilegeManager()).thenReturn(privilegeManager).getMock();
+        when(mp.getNamePathMapper()).thenReturn(getNamePathMapper());
+        
when(mp.getRestrictionProvider()).thenReturn(RestrictionProvider.EMPTY);
+
+        PrincipalPolicyImpl policy = new PrincipalPolicyImpl(principal, 
POLICY_OAK_PATH, mp);
+        policy.addEntry(testJcrPath, new Privilege[] {privilege});
+    }
+
+    @Test(expected = AccessControlException.class)
+    public void testAddAccessControlEntryDifferentPrincipal() throws Exception 
{
+        policy.addEntry(EveryonePrincipal.getInstance(), 
privilegesFromNames(JCR_ALL), true, null, Collections.emptyMap());
+    }
+
+    @Test(expected = AccessControlException.class)
+    public void testAddDenyingAccessControlEntry() throws Exception {
+        policy.addEntry(principal, 
privilegesFromNames(PrivilegeConstants.REP_READ_NODES), false, 
Collections.emptyMap(), null);
+    }
+
+    @Test(expected = AccessControlException.class)
+    public void testAddAccessControlEntryMissingNodePath() throws Exception {
+        policy.addEntry(principal, 
privilegesFromNames(PrivilegeConstants.REP_USER_MANAGEMENT), true, 
Collections.emptyMap(), 
Collections.singletonMap(AccessControlConstants.REP_NT_NAMES, new Value[] 
{getValueFactory(root).createValue(NodeTypeConstants.NT_REP_SYSTEM)}));
+    }
+
+    @Test(expected = AccessControlException.class)
+    public void testAddAccessControlEntryMissingNodePath2() throws Exception {
+        policy.addEntry(principal, 
privilegesFromNames(PrivilegeConstants.REP_WRITE), true, null, null);
+    }
+
+    @Test
+    public void testAddAccessControlEntryWithEmptyNodePathRestriction() throws 
Exception {
+        ValueFactory vf = getValueFactory(root);
+        assertTrue(emptyPolicy.addEntry(principal, 
privilegesFromNames(PrivilegeConstants.REP_ADD_PROPERTIES), true,
+                createRestrictions(REP_NODE_PATH, ""), null));
+
+        List<PrincipalPolicyImpl.EntryImpl> entries = emptyPolicy.getEntries();
+        assertEquals(1, entries.size());
+
+        PrincipalPolicyImpl.EntryImpl entry = entries.get(0);
+        assertNull(entry.getOakPath());
+        // effective-path restriction must be filtered out
+        assertNull(entry.getRestrictions(getJcrName(REP_NODE_PATH)));
+    }
+
+    @Test
+    public void testAddAccessControlEntryWithNodePathRestriction() throws 
Exception {
+        ValueFactory vf = getValueFactory(root);
+        assertTrue(emptyPolicy.addEntry(principal, 
privilegesFromNames(PrivilegeConstants.REP_ADD_PROPERTIES), true,
+                createRestrictions(REP_NODE_PATH, testJcrPath),
+                createMvRestrictions(AccessControlConstants.REP_ITEM_NAMES, 
PropertyType.NAME, "itemName")));
+        List<PrincipalPolicyImpl.EntryImpl> entries = emptyPolicy.getEntries();
+        assertEquals(1, entries.size());
+
+        PrincipalPolicyImpl.EntryImpl entry = entries.get(0);
+        assertEquals(TEST_OAK_PATH, entry.getOakPath());
+        // effective-path restriction must be filtered out
+        assertNull(entry.getRestrictions(getJcrName(REP_NODE_PATH)));
+    }
+
+    @Test
+    public void testAddAccessControlEntryWithRestrictions() throws Exception {
+        ValueFactory vf = getValueFactory(root);
+        Map<String, Value> restr = ImmutableMap.of(getJcrName(REP_NODE_PATH), 
vf.createValue(testJcrPath), getJcrName(REP_GLOB), vf.createValue("string"));
+        assertTrue(emptyPolicy.addEntry(principal, 
privilegesFromNames(PrivilegeConstants.REP_USER_MANAGEMENT), true,
+                restr, null));
+        List<PrincipalPolicyImpl.EntryImpl> entries = emptyPolicy.getEntries();
+        assertEquals(1, entries.size());
+
+        PrincipalPolicyImpl.EntryImpl entry = entries.get(0);
+        assertEquals(TEST_OAK_PATH, entry.getOakPath());
+        // effective-path restriction must be filtered out
+        assertNull(entry.getRestrictions(getJcrName(REP_NODE_PATH)));
+        assertNotNull(entry.getRestrictions(getJcrName(REP_GLOB)));
+    }
+
+    @Test
+    public void addEntryTree() throws Exception {
+        assertTrue(emptyPolicy.addEntry(createEntryTree(TEST_OAK_PATH, 
PrivilegeConstants.JCR_READ, PrivilegeConstants.JCR_WRITE)));
+
+        PrincipalPolicyImpl.EntryImpl entry = emptyPolicy.getEntries().get(0);
+        assertEquals(testJcrPath, entry.getEffectivePath());
+        assertEquals(TEST_OAK_PATH, entry.getOakPath());
+        
assertEquals(privilegeBitsProvider.getBits(PrivilegeConstants.JCR_READ, 
PrivilegeConstants.JCR_WRITE), entry.getPrivilegeBits());
+    }
+
+    @Test
+    public void addEntryTreeRepositoryLevel() throws Exception {
+        assertTrue(emptyPolicy.addEntry(createEntryTree("", 
PrivilegeConstants.JCR_READ, PrivilegeConstants.JCR_WRITE)));
+
+        PrincipalPolicyImpl.EntryImpl entry = emptyPolicy.getEntries().get(0);
+        assertNull(entry.getEffectivePath());
+        assertNull(entry.getOakPath());
+    }
+
+    @Test
+    public void addEntryTreeJcrAll() throws Exception {
+        assertTrue(emptyPolicy.addEntry(createEntryTree(TEST_OAK_PATH, 
JCR_ALL)));
+
+        PrincipalPolicyImpl.EntryImpl entry = emptyPolicy.getEntries().get(0);
+        assertArrayEquals(privilegesFromNames(JCR_ALL), entry.getPrivileges());
+    }
+
+    @Test
+    public void addEntryTreeExistingEntry() throws Exception {
+        
assertFalse(policy.addEntry(createEntryTree(policy.getEntries().get(0))));
+    }
+
+    @Test
+    public void testRemoveEntry() throws Exception {
+        for (AccessControlEntry entry : policy.getAccessControlEntries()) {
+            assertFalse(policy.isEmpty());
+            policy.removeAccessControlEntry(entry);
+        };
+        assertTrue(policy.isEmpty());
+    }
+
+    @Test(expected = AccessControlException.class)
+    public void testRemoveEntryTwice() throws Exception  {
+        AccessControlEntry entry = policy.getAccessControlEntries()[0];
+        policy.removeAccessControlEntry(entry);
+        policy.removeAccessControlEntry(entry);
+    }
+
+    @Test(expected = AccessControlException.class)
+    public void testRemoveEntryInvalidEntry() throws Exception  {
+        
policy.removeAccessControlEntry(invalidEntry(policy.getEntries().get(0)));
+    }
+
+    @Test
+    public void testOrderBefore() throws Exception {
+        PrincipalPolicy.Entry entryA = policy.getEntries().get(0);
+        PrincipalPolicy.Entry entryB = policy.getEntries().get(1);
+
+        policy.orderBefore(entryB, entryA);
+        assertArrayEquals(new AccessControlEntry[] {entryB, entryA}, 
policy.getAccessControlEntries());
+    }
+
+    @Test
+    public void testOrderBeforeDestNull() throws Exception {
+        PrincipalPolicy.Entry entry = policy.getEntries().get(0);
+        policy.orderBefore(entry, null);
+        assertEquals(entry, policy.getAccessControlEntries()[1]);
+    }
+
+    @Test
+    public void testOrderBeforeSame() throws Exception {
+        policy.orderBefore(policy.getEntries().get(1), 
policy.getEntries().get(1));
+    }
+
+    @Test(expected = AccessControlException.class)
+    public void testOrderBeforeNonExistingSrc() throws Exception {
+        PrincipalPolicy.Entry entry = policy.getEntries().get(0);
+        policy.removeAccessControlEntry(entry);
+        policy.orderBefore(entry, null);
+    }
+
+    @Test(expected = AccessControlException.class)
+    public void testOrderBeforeNonExistingDest() throws Exception {
+        PrincipalPolicy.Entry entry = policy.getEntries().get(1);
+        policy.removeAccessControlEntry(entry);
+        policy.orderBefore(policy.getEntries().get(0), entry);
+    }
+
+    @Test(expected = AccessControlException.class)
+    public void testOrderBeforeInvalidSrc() throws Exception {
+        policy.orderBefore(invalidEntry(policy.getEntries().get(1)), 
policy.getEntries().get(0));
+    }
+
+    @Test(expected = AccessControlException.class)
+    public void testOrderBeforeInvalidDest() throws Exception {
+        policy.orderBefore(policy.getEntries().get(1), 
invalidEntry(policy.getEntries().get(0)));
+    }
+
+    @Test
+    public void testEntry() throws Exception {
+        Privilege[] privs = privilegesFromNames(PrivilegeConstants.JCR_ALL);
+        emptyPolicy.addEntry(testJcrPath, privs);
+
+        PrincipalPolicyImpl.EntryImpl entry = emptyPolicy.getEntries().get(0);
+        assertEquals(TEST_OAK_PATH, entry.getOakPath());
+        assertEquals(testJcrPath, entry.getEffectivePath());
+        assertArrayEquals(privs, entry.getPrivileges());
+        assertEquals(privilegeBitsProvider.getBits(JCR_ALL), 
entry.getPrivilegeBits());
+        assertSame(principal, entry.getPrincipal());
+        assertTrue(entry.isAllow());
+    }
+
+    @Test
+    public void testEntryRepositoryLevel() throws Exception {
+        Privilege[] privs = privilegesFromNames(JCR_NAMESPACE_MANAGEMENT);
+        emptyPolicy.addEntry(null, privs);
+
+        PrincipalPolicyImpl.EntryImpl entry = emptyPolicy.getEntries().get(0);
+        assertEquals(null, entry.getOakPath());
+        assertEquals(null, entry.getEffectivePath());
+        assertArrayEquals(privs, entry.getPrivileges());
+        assertEquals(privilegeBitsProvider.getBits(JCR_NAMESPACE_MANAGEMENT), 
entry.getPrivilegeBits());
+        assertSame(principal, entry.getPrincipal());
+        assertTrue(entry.isAllow());
+    }
+
+    @Test
+    public void testEntryHashCode() throws Exception {
+        PrincipalPolicyImpl.EntryImpl entryA = policy.getEntries().get(0);
+        PrincipalPolicyImpl.EntryImpl entryB = policy.getEntries().get(1);
+        assertNotEquals(entryA.hashCode(), entryB.hashCode());
+
+        // same entry -> same hash
+        assertEquals(entryA.hashCode(), policy.getEntries().get(0).hashCode());
+
+        // equivalent entry on different policy -> same hash
+        emptyPolicy.addEntry(entryB.getEffectivePath(), 
entryB.getPrivileges(), Collections.emptyMap(), Collections.emptyMap());
+        assertEquals(entryB.hashCode(), 
emptyPolicy.getEntries().get(0).hashCode());
+
+        // different restrictions -> different hash
+        emptyPolicy.addEntry(entryA.getEffectivePath(), 
entryA.getPrivileges(), createGlobRestriction("*"), Collections.emptyMap());
+        assertNotEquals(entryA.hashCode(), 
emptyPolicy.getEntries().get(1).hashCode());
+    }
+
+    @Test
+    public void testEntryEquals() throws Exception {
+        PrincipalPolicyImpl.EntryImpl entryA = policy.getEntries().get(0);
+        PrincipalPolicyImpl.EntryImpl entryB = policy.getEntries().get(1);
+        assertNotEquals(entryA, entryB);
+        assertNotEquals(entryB, entryA);
+
+        assertEquals(entryA, entryA);
+        assertEquals(entryA, policy.getEntries().get(0));
+
+        // equivalent entry on different policy -> same hash
+        emptyPolicy.addEntry(entryB.getEffectivePath(), 
entryB.getPrivileges(), Collections.emptyMap(), Collections.emptyMap());
+        assertEquals(entryB, emptyPolicy.getEntries().get(0));
+
+        // different restrictions -> different hash
+        emptyPolicy.addEntry(entryA.getEffectivePath(), 
entryA.getPrivileges(), createGlobRestriction("*"), Collections.emptyMap());
+        assertNotEquals(entryA, emptyPolicy.getEntries().get(1));
+    }
+
+
+    private static PrincipalPolicy.Entry invalidEntry(@NotNull 
PrincipalPolicy.Entry entry) {
+        return new PrincipalPolicy.Entry() {
+            @Override
+            public @Nullable String getEffectivePath() {
+                return entry.getEffectivePath();
+            }
+
+            @Override
+            public boolean isAllow() {
+                return entry.isAllow();
+            }
+
+            @Override
+            public String[] getRestrictionNames() throws RepositoryException {
+                return entry.getRestrictionNames();
+            }
+
+            @Override
+            public Value getRestriction(String s) throws ValueFormatException, 
RepositoryException {
+                return entry.getRestriction(s);
+            }
+
+            @Override
+            public Value[] getRestrictions(String s) throws 
RepositoryException {
+                return entry.getRestrictions(s);
+            }
+
+            @Override
+            public Principal getPrincipal() {
+                return entry.getPrincipal();
+            }
+
+            @Override
+            public Privilege[] getPrivileges() {
+                return entry.getPrivileges();
+            }
+        };
+    }
+}
\ No newline at end of file

Propchange: 
jackrabbit/oak/trunk/oak-authorization-principalbased/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/PrincipalPolicyImplTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: 
jackrabbit/oak/trunk/oak-authorization-principalbased/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/PrincipalPolicyImporterTest.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-authorization-principalbased/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/PrincipalPolicyImporterTest.java?rev=1857551&view=auto
==============================================================================
--- 
jackrabbit/oak/trunk/oak-authorization-principalbased/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/PrincipalPolicyImporterTest.java
 (added)
+++ 
jackrabbit/oak/trunk/oak-authorization-principalbased/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/PrincipalPolicyImporterTest.java
 Mon Apr 15 07:16:49 2019
@@ -0,0 +1,699 @@
+/*
+ * 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.spi.security.authorization.principalbased.impl;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import org.apache.jackrabbit.api.security.user.User;
+import org.apache.jackrabbit.oak.api.Tree;
+import org.apache.jackrabbit.oak.commons.PathUtils;
+import org.apache.jackrabbit.oak.plugins.tree.TreeUtil;
+import org.apache.jackrabbit.oak.spi.security.ConfigurationParameters;
+import 
org.apache.jackrabbit.oak.spi.security.authorization.AuthorizationConfiguration;
+import 
org.apache.jackrabbit.oak.spi.security.authorization.accesscontrol.AccessControlConstants;
+import 
org.apache.jackrabbit.oak.spi.security.authorization.principalbased.FilterProvider;
+import org.apache.jackrabbit.oak.spi.security.principal.PrincipalImpl;
+import org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants;
+import org.apache.jackrabbit.oak.spi.xml.ImportBehavior;
+import org.apache.jackrabbit.oak.spi.xml.NodeInfo;
+import org.apache.jackrabbit.oak.spi.xml.PropInfo;
+import org.apache.jackrabbit.oak.spi.xml.ProtectedItemImporter;
+import org.apache.jackrabbit.oak.spi.xml.ReferenceChangeTracker;
+import org.apache.jackrabbit.oak.spi.xml.TextValue;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.junit.Test;
+
+import javax.jcr.ImportUUIDBehavior;
+import javax.jcr.PropertyType;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import javax.jcr.Value;
+import javax.jcr.ValueFactory;
+import javax.jcr.ValueFormatException;
+import javax.jcr.nodetype.ConstraintViolationException;
+import javax.jcr.nodetype.NodeType;
+import javax.jcr.nodetype.PropertyDefinition;
+import javax.jcr.security.AccessControlException;
+import javax.jcr.security.AccessControlPolicy;
+import java.security.Principal;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import static 
org.apache.jackrabbit.oak.spi.security.authorization.accesscontrol.AccessControlConstants.REP_GLOB;
+import static 
org.apache.jackrabbit.oak.spi.security.authorization.accesscontrol.AccessControlConstants.REP_ITEM_NAMES;
+import static 
org.apache.jackrabbit.oak.spi.security.authorization.accesscontrol.AccessControlConstants.REP_NODE_PATH;
+import static 
org.apache.jackrabbit.oak.spi.security.authorization.accesscontrol.AccessControlConstants.REP_NT_NAMES;
+import static 
org.apache.jackrabbit.oak.spi.security.authorization.principalbased.impl.Constants.NT_REP_PRINCIPAL_ENTRY;
+import static 
org.apache.jackrabbit.oak.spi.security.authorization.principalbased.impl.Constants.NT_REP_PRINCIPAL_POLICY;
+import static 
org.apache.jackrabbit.oak.spi.security.authorization.principalbased.impl.Constants.NT_REP_RESTRICTIONS;
+import static 
org.apache.jackrabbit.oak.spi.security.authorization.principalbased.impl.Constants.REP_EFFECTIVE_PATH;
+import static 
org.apache.jackrabbit.oak.spi.security.authorization.principalbased.impl.Constants.REP_PRINCIPAL_NAME;
+import static 
org.apache.jackrabbit.oak.spi.security.authorization.principalbased.impl.Constants.REP_PRINCIPAL_POLICY;
+import static 
org.apache.jackrabbit.oak.spi.security.authorization.principalbased.impl.Constants.REP_PRIVILEGES;
+import static 
org.apache.jackrabbit.oak.spi.security.authorization.principalbased.impl.Constants.REP_RESTRICTIONS;
+import static 
org.apache.jackrabbit.oak.spi.security.authorization.principalbased.impl.MockUtility.mockTree;
+import static 
org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants.JCR_READ;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+public class PrincipalPolicyImporterTest extends AbstractPrincipalBasedTest {
+
+    private FilterProvider filterProvider;
+    private PrincipalPolicyImporter importer;
+
+    @Override
+    public void before() throws Exception {
+        super.before();
+        filterProvider = spy(getFilterProvider());
+        importer = new PrincipalPolicyImporter(filterProvider, 
getMgrProvider(root));
+    }
+
+    @Override
+    protected ConfigurationParameters getSecurityConfigParameters() {
+        ConfigurationParameters params = 
ConfigurationParameters.of(ProtectedItemImporter.PARAM_IMPORT_BEHAVIOR, 
ImportBehavior.NAME_BESTEFFORT);
+        return ConfigurationParameters.of(AuthorizationConfiguration.NAME, 
params);
+    }
+
+    private boolean  init(boolean isWorkspaceImport, int uuidBehavior) {
+        return importer.init(mock(Session.class), root, getNamePathMapper(), 
isWorkspaceImport, uuidBehavior, new ReferenceChangeTracker(), 
getSecurityProvider());
+    }
+
+    private PropInfo mockPropInfo(@NotNull String jcrName) {
+        return 
when(mock(PropInfo.class).getName()).thenReturn(jcrName).getMock();
+    }
+
+    private PropInfo mockPropInfo(@NotNull Principal principal) throws 
RepositoryException {
+        TextValue tx = 
when(mock(TextValue.class).getString()).thenReturn(principal.getName()).getMock();
+        PropInfo propInfo = mockPropInfo(getJcrName(REP_PRINCIPAL_NAME));
+        when(propInfo.getTextValue()).thenReturn(tx);
+        return propInfo;
+    }
+
+    private List<PropInfo> mockPropInfos(@Nullable String effectivePath,  
@NotNull String... privNames) throws RepositoryException {
+        List<PropInfo> propInfos = new ArrayList();
+        if (effectivePath != null) {
+            TextValue tx = 
when(mock(TextValue.class).getString()).thenReturn(effectivePath).getMock();
+            PropInfo propInfo = mockPropInfo(getJcrName(REP_EFFECTIVE_PATH));
+            when(propInfo.getTextValue()).thenReturn(tx);
+            when(propInfo.getType()).thenReturn(PropertyType.PATH);
+            propInfos.add(propInfo);
+        }
+        List privTxtValues = new ArrayList();
+        for (String privName : privNames) {
+            TextValue tx = 
when(mock(TextValue.class).getString()).thenReturn(getJcrName(privName)).getMock();
+            privTxtValues.add(tx);
+        }
+        if (!privTxtValues.isEmpty()) {
+            PropInfo propInfo = mockPropInfo(getJcrName(REP_PRIVILEGES));
+            when(propInfo.getTextValues()).thenReturn(privTxtValues);
+            when(propInfo.getType()).thenReturn(PropertyType.NAME);
+            propInfos.add(propInfo);
+        }
+        return propInfos;
+    }
+
+    private List<PropInfo> mockPropInfos(@NotNull Map<String, String> 
restrictions, int propertyType) throws RepositoryException {
+        return mockPropInfos(Maps.transformValues(restrictions, string -> {
+            try {
+                return new Value[] {getValueFactory(root).createValue(string, 
propertyType)};
+            } catch (ValueFormatException e) {
+                throw new RuntimeException(e);
+            }
+        }));
+    }
+
+    private List<PropInfo> mockPropInfos(@NotNull Map<String, Value[]> 
restrictions) throws RepositoryException {
+        List<PropInfo> propInfos = new ArrayList();
+        for (Map.Entry<String,Value[]> r : restrictions.entrySet()) {
+            String jcrName = r.getKey();
+            List<Value> vs = ImmutableList.copyOf(r.getValue());
+            PropInfo propInfo = mockPropInfo(jcrName);
+            if (!vs.isEmpty()) {
+                TextValue first = 
when(mock(TextValue.class).getString()).thenReturn(vs.get(0).getString()).getMock();
+                when(propInfo.getTextValue()).thenReturn(first);
+                when(propInfo.getValues(anyInt())).thenReturn(vs);
+            }
+            propInfos.add(propInfo);
+        }
+        return propInfos;
+    }
+
+    private PropertyDefinition mockPropertyDefinition(@NotNull String jcrName) 
{
+        NodeType nt = 
when(mock(NodeType.class).getName()).thenReturn(jcrName).getMock();
+        PropertyDefinition def = 
when(mock(PropertyDefinition.class).getDeclaringNodeType()).thenReturn(nt).getMock();
+        return def;
+    }
+
+    private NodeInfo mockNodeInfo(@NotNull String jcrName, @NotNull String 
jcrPrimaryType) {
+        NodeInfo ni = 
when(mock(NodeInfo.class).getName()).thenReturn(jcrName).getMock();
+        when(ni.getPrimaryTypeName()).thenReturn(jcrPrimaryType);
+        return ni;
+    }
+
+    private Tree createPolicyTree(@NotNull User user) throws 
RepositoryException {
+        Tree t = root.getTree(getNamePathMapper().getOakPath(user.getPath()));
+        return TreeUtil.getOrAddChild(t, REP_PRINCIPAL_POLICY, 
NT_REP_PRINCIPAL_POLICY);
+    }
+
+    private String getJcrName(@NotNull String oakName) {
+        return getNamePathMapper().getJcrName(oakName);
+    }
+
+    @Nullable
+    private static PrincipalPolicyImpl.EntryImpl assertPolicy(@NotNull 
AccessControlPolicy[] policies, int expectedEntries) {
+        assertEquals(1, policies.length);
+        assertTrue(policies[0] instanceof PrincipalPolicyImpl);
+        assertEquals(expectedEntries, (((PrincipalPolicyImpl) 
policies[0])).size());
+        if (expectedEntries > 0) {
+            return ((PrincipalPolicyImpl) policies[0]).getEntries().get(0);
+        } else {
+            return null;
+        }
+    }
+
+    @Test
+    public void testInitWorkspaceImport() {
+        assertTrue(init(true, ImportUUIDBehavior.IMPORT_UUID_COLLISION_THROW));
+    }
+
+    @Test
+    public void testInitSessionImport() {
+        assertTrue(init(false, 
ImportUUIDBehavior.IMPORT_UUID_COLLISION_REPLACE_EXISTING));
+    }
+
+    @Test(expected = IllegalStateException.class)
+    public void testInitTwice() {
+        assertTrue(init(true, ImportUUIDBehavior.IMPORT_UUID_CREATE_NEW));
+        init(false, ImportUUIDBehavior.IMPORT_UUID_COLLISION_REMOVE_EXISTING);
+    }
+
+    @Test
+    public void testInitResetMgrProviderRoot() {
+        MgrProvider mp = 
when(mock(MgrProvider.class).getSecurityProvider()).thenReturn(getSecurityProvider()).getMock();
+        importer = new PrincipalPolicyImporter(filterProvider, mp);
+        init(true, ImportUUIDBehavior.IMPORT_UUID_CREATE_NEW);
+        verify(mp, times(1)).reset(root, getNamePathMapper());
+    }
+
+    @Test
+    public void testInitGetsFilter() {
+        init(false,ImportUUIDBehavior.IMPORT_UUID_COLLISION_THROW);
+        verify(filterProvider, times(1)).getFilter(getSecurityProvider(), 
root, getNamePathMapper());
+    }
+
+    @Test
+    public void testProcessReferencesIsNop() {
+        // no initialization required
+        importer.processReferences();
+
+        init(false, ImportUUIDBehavior.IMPORT_UUID_COLLISION_THROW);
+        importer.processReferences();
+    }
+
+    @Test(expected = IllegalStateException.class)
+    public void testHandlePropInfoNotInitialized() throws Exception {
+        importer.handlePropInfo(mock(Tree.class), mock(PropInfo.class), 
mock(PropertyDefinition.class));
+    }
+
+    @Test
+    public void testHandlePropInfoNonExistingTree() throws Exception {
+        init(true, ImportUUIDBehavior.IMPORT_UUID_COLLISION_REPLACE_EXISTING);
+        Tree tree = 
when(mock(Tree.class).exists()).thenReturn(false).getMock();
+        assertFalse(importer.handlePropInfo(tree, mock(PropInfo.class), 
mock(PropertyDefinition.class)));
+    }
+
+    @Test
+    public void testHandlePropInfoWrongTreeName() throws Exception {
+        init(true, ImportUUIDBehavior.IMPORT_UUID_COLLISION_THROW);
+
+        // wrong policy name
+        Tree tree = mockTree(AccessControlConstants.REP_POLICY, 
NT_REP_PRINCIPAL_POLICY, true);
+        assertFalse(importer.handlePropInfo(tree, mock(PropInfo.class), 
mock(PropertyDefinition.class)));
+    }
+
+    @Test
+    public void testHandlePropInfoWrongTreeNt() throws Exception {
+        init(true, ImportUUIDBehavior.IMPORT_UUID_COLLISION_THROW);
+
+        // wrong nt name
+        Tree tree = mockTree(REP_PRINCIPAL_POLICY, 
AccessControlConstants.NT_REP_ACL, true);
+        assertFalse(importer.handlePropInfo(tree, mock(PropInfo.class), 
mock(PropertyDefinition.class)));
+    }
+
+    @Test
+    public void testHandlePropInfoInvalidPropInfoName() throws Exception {
+        init(true, ImportUUIDBehavior.IMPORT_UUID_COLLISION_THROW);
+
+        Tree tree = mockTree(REP_PRINCIPAL_POLICY, NT_REP_PRINCIPAL_POLICY, 
true);
+        assertFalse(importer.handlePropInfo(tree, mockPropInfo("wrongName"), 
mock(PropertyDefinition.class)));
+    }
+
+    @Test
+    public void testHandlePropInfoNullPropInfoName() throws Exception {
+        init(false, ImportUUIDBehavior.IMPORT_UUID_COLLISION_REPLACE_EXISTING);
+
+        Tree tree = mockTree(REP_PRINCIPAL_POLICY, NT_REP_PRINCIPAL_POLICY, 
true);
+        assertFalse(importer.handlePropInfo(tree, mock(PropInfo.class), 
mock(PropertyDefinition.class)));
+    }
+
+    @Test
+    public void testHandlePropInfoOakPropInfoName() throws Exception {
+        init(false, ImportUUIDBehavior.IMPORT_UUID_COLLISION_REPLACE_EXISTING);
+
+        Tree tree = mockTree(REP_PRINCIPAL_POLICY, NT_REP_PRINCIPAL_POLICY, 
true);
+        PropInfo propInfo = mockPropInfo(REP_PRINCIPAL_NAME);
+
+        assertFalse(importer.handlePropInfo(tree, mock(PropInfo.class), 
mock(PropertyDefinition.class)));
+    }
+
+    @Test
+    public void testHandlePropInfoDefinitionMultiple() throws Exception {
+        init(false, ImportUUIDBehavior.IMPORT_UUID_COLLISION_REMOVE_EXISTING);
+
+        Tree tree = mockTree(REP_PRINCIPAL_POLICY, NT_REP_PRINCIPAL_POLICY, 
true);
+        PropInfo propInfo = mockPropInfo(getJcrName(REP_PRINCIPAL_NAME));
+        PropertyDefinition def = 
when(mock(PropertyDefinition.class).isMultiple()).thenReturn(true).getMock();
+
+        assertFalse(importer.handlePropInfo(tree, propInfo, def));
+    }
+
+    @Test
+    public void testHandlePropInfoInvalidDeclaringNtName() throws Exception {
+        init(false, ImportUUIDBehavior.IMPORT_UUID_COLLISION_REMOVE_EXISTING);
+
+        Tree tree = mockTree(REP_PRINCIPAL_POLICY, NT_REP_PRINCIPAL_POLICY, 
true);
+        PropInfo propInfo = mockPropInfo(getJcrName(REP_PRINCIPAL_NAME));
+        PropertyDefinition def = 
mockPropertyDefinition("wrongDeclaringNtName");
+
+        assertFalse(importer.handlePropInfo(tree, propInfo, def));
+    }
+
+    @Test
+    public void testHandlePropInfoOakDeclaringNtName() throws Exception {
+        init(false, ImportUUIDBehavior.IMPORT_UUID_COLLISION_REMOVE_EXISTING);
+
+        Tree tree = mockTree(REP_PRINCIPAL_POLICY, NT_REP_PRINCIPAL_POLICY, 
true);
+        PropInfo propInfo = mockPropInfo(getJcrName(REP_PRINCIPAL_NAME));
+        PropertyDefinition def = 
mockPropertyDefinition(NT_REP_PRINCIPAL_POLICY);
+
+        assertFalse(importer.handlePropInfo(tree, propInfo, def));
+    }
+
+    @Test
+    public void testHandlePropInfoUnsupportedPath() throws Exception {
+        init(false, ImportUUIDBehavior.IMPORT_UUID_COLLISION_REMOVE_EXISTING);
+
+        Tree tree = mockTree(REP_PRINCIPAL_POLICY, NT_REP_PRINCIPAL_POLICY, 
"/some/unsupported/path");
+        PropInfo propInfo = mockPropInfo(getJcrName(REP_PRINCIPAL_NAME));
+        PropertyDefinition def = 
mockPropertyDefinition(getJcrName(NT_REP_PRINCIPAL_POLICY));
+
+        assertFalse(importer.handlePropInfo(tree, propInfo, def));
+    }
+
+    @Test(expected = ConstraintViolationException.class)
+    public void testHandlePropInfoPrincipalNameMismatch() throws Exception {
+        init(true, ImportUUIDBehavior.IMPORT_UUID_CREATE_NEW);
+
+        importer.handlePropInfo(createPolicyTree(getTestSystemUser()), 
mockPropInfo(new PrincipalImpl("mismatch")), 
mockPropertyDefinition(getJcrName(NT_REP_PRINCIPAL_POLICY)));
+    }
+
+    @Test
+    public void testHandlePropInfoPrincipalNotHandled() throws Exception {
+        init(false, ImportUUIDBehavior.IMPORT_UUID_COLLISION_REPLACE_EXISTING);
+
+        User testUser = getTestUser();
+        String wrongUserPath = PathUtils.concat(SUPPORTED_PATH , "testUser");
+
+        Tree tree = mockTree(REP_PRINCIPAL_POLICY, NT_REP_PRINCIPAL_POLICY, 
PathUtils.concat(wrongUserPath, REP_PRINCIPAL_POLICY));
+        assertFalse(importer.handlePropInfo(tree, 
mockPropInfo(testUser.getPrincipal()), 
mockPropertyDefinition(getJcrName(NT_REP_PRINCIPAL_POLICY))));
+    }
+
+    @Test
+    public void testHandlePropInfoPrincipalByNameReturnsNull() throws 
Exception {
+        init(false, ImportUUIDBehavior.IMPORT_UUID_COLLISION_THROW);
+
+        String oakPath = PathUtils.concat(SUPPORTED_PATH, "unknownSystemUser", 
REP_PRINCIPAL_POLICY);
+        Tree tree = mockTree(REP_PRINCIPAL_POLICY, NT_REP_PRINCIPAL_POLICY, 
oakPath);
+        assertFalse(importer.handlePropInfo(tree, mockPropInfo(new 
PrincipalImpl("notFound")), 
mockPropertyDefinition(getJcrName(NT_REP_PRINCIPAL_POLICY))));
+    }
+
+    @Test
+    public void testHandlePropInfoValidPrincipal() throws Exception {
+        init(true, ImportUUIDBehavior.IMPORT_UUID_COLLISION_REMOVE_EXISTING);
+
+        User user = getTestSystemUser();
+        assertTrue(importer.handlePropInfo(createPolicyTree(user), 
mockPropInfo(user.getPrincipal()), 
mockPropertyDefinition(getJcrName(NT_REP_PRINCIPAL_POLICY))));
+    }
+
+    @Test(expected = IllegalStateException.class)
+    public void testPropertiesCompletedNotInitialized() throws Exception  {
+        importer.propertiesCompleted(mock(Tree.class));
+    }
+
+    @Test
+    public void testPropertiesCompletedNoPolicy() throws Exception {
+        init(false, ImportUUIDBehavior.IMPORT_UUID_CREATE_NEW);
+        importer.propertiesCompleted(mock(Tree.class));
+        assertFalse(root.hasPendingChanges());
+    }
+
+    @Test
+    public void testPropertiesCompletedWrongTree() throws Exception {
+        init(true, ImportUUIDBehavior.IMPORT_UUID_CREATE_NEW);
+
+        User user = getTestSystemUser();
+        importer.handlePropInfo(createPolicyTree(user), 
mockPropInfo(user.getPrincipal()), 
mockPropertyDefinition(getJcrName(NT_REP_PRINCIPAL_POLICY)));
+
+        importer.propertiesCompleted(mockTree("/another/path", true));
+        assertEquals(0, 
getAccessControlManager(root).getPolicies(user.getPrincipal()).length);
+        
assertFalse(root.getTree(getNamePathMapper().getOakPath(user.getPath())).hasChild(REP_PRINCIPAL_POLICY));
+    }
+
+    @Test
+    public void testPropertiesCompletedSetsPolicy() throws Exception {
+        init(true, ImportUUIDBehavior.IMPORT_UUID_COLLISION_THROW);
+
+        User user = getTestSystemUser();
+        Tree policyTree = createPolicyTree(user);
+        String oakPath = policyTree.getPath();
+        importer.handlePropInfo(policyTree, mockPropInfo(user.getPrincipal()), 
mockPropertyDefinition(getJcrName(NT_REP_PRINCIPAL_POLICY)));
+
+        importer.propertiesCompleted(policyTree);
+
+        assertTrue(root.getTree(oakPath).hasProperty(REP_PRINCIPAL_NAME));
+        
assertPolicy(getAccessControlManager(root).getPolicies(user.getPrincipal()), 0);
+    }
+
+    @Test(expected = IllegalStateException.class)
+    public void testStartNotInitialized() throws Exception {
+        importer.start(mock(Tree.class));
+    }
+
+    @Test
+    public void testStartWithoutPolicy() throws Exception {
+        init(true, ImportUUIDBehavior.IMPORT_UUID_COLLISION_THROW);
+        assertFalse(importer.start(mock(Tree.class)));
+    }
+
+
+    @Test
+    public void testStartWithPolicyAndValidTree() throws Exception {
+        init(false, ImportUUIDBehavior.IMPORT_UUID_COLLISION_REPLACE_EXISTING);
+        User user = getTestSystemUser();
+        Tree policyTree = createPolicyTree(user);
+        importer.handlePropInfo(policyTree, mockPropInfo(user.getPrincipal()), 
mockPropertyDefinition(getJcrName(NT_REP_PRINCIPAL_POLICY)));
+        importer.propertiesCompleted(policyTree);
+
+        assertTrue(importer.start(policyTree));
+    }
+
+    @Test
+    public void testStartInvalidTree() throws Exception {
+        init(true, ImportUUIDBehavior.IMPORT_UUID_COLLISION_THROW);
+        User user = getTestSystemUser();
+        Tree policyTree = createPolicyTree(user);
+        importer.handlePropInfo(policyTree, mockPropInfo(user.getPrincipal()), 
mockPropertyDefinition(getJcrName(NT_REP_PRINCIPAL_POLICY)));
+        importer.propertiesCompleted(policyTree);
+
+        assertFalse(importer.start(mockTree("/another/path", true)));
+    }
+
+    @Test(expected = IllegalStateException.class)
+    public void testEndWithoutPolicy() throws Exception {
+        importer.end(mock(Tree.class));
+    }
+
+    @Test
+    public void testEndWithInvalidTree() throws Exception {
+        init(true, ImportUUIDBehavior.IMPORT_UUID_CREATE_NEW);
+        User user = getTestSystemUser();
+        Tree policyTree = createPolicyTree(user);
+        importer.handlePropInfo(policyTree, mockPropInfo(user.getPrincipal()), 
mockPropertyDefinition(getJcrName(NT_REP_PRINCIPAL_POLICY)));
+        importer.propertiesCompleted(policyTree);
+
+        importer.end(mockTree("/another/path", true));
+
+        // end-call must have removed the policy due to the mismatch
+        assertFalse(root.getTree(policyTree.getPath()).exists());
+    }
+
+    @Test
+    public void testEndWithPolicyAndValidTree() throws Exception {
+        init(true, ImportUUIDBehavior.IMPORT_UUID_CREATE_NEW);
+        User user = getTestSystemUser();
+        Tree policyTree = createPolicyTree(user);
+        importer.handlePropInfo(policyTree, mockPropInfo(user.getPrincipal()), 
mockPropertyDefinition(getJcrName(NT_REP_PRINCIPAL_POLICY)));
+        importer.propertiesCompleted(policyTree);
+
+        importer.end(policyTree);
+
+        policyTree = root.getTree(policyTree.getPath());
+        assertTrue(policyTree.exists());
+        assertTrue(policyTree.hasProperty(REP_PRINCIPAL_NAME));
+        assertTrue(Iterables.isEmpty(policyTree.getChildren()));
+    }
+
+    @Test(expected = IllegalStateException.class)
+    public void testStartChildInfoWithoutPolicy() throws Exception {
+        importer.startChildInfo(mock(NodeInfo.class), mock(List.class));
+    }
+
+    @Test(expected = ConstraintViolationException.class)
+    public void testStartChildInfoInvalidPrimaryType() throws Exception {
+        init(true, ImportUUIDBehavior.IMPORT_UUID_CREATE_NEW);
+        User user = getTestSystemUser();
+        Tree policyTree = createPolicyTree(user);
+        importer.handlePropInfo(policyTree, mockPropInfo(user.getPrincipal()), 
mockPropertyDefinition(getJcrName(NT_REP_PRINCIPAL_POLICY)));
+
+        importer.startChildInfo(mockNodeInfo("invalidACE", 
getJcrName(AccessControlConstants.NT_REP_GRANT_ACE)), mock(List.class));
+    }
+
+    @Test(expected = ConstraintViolationException.class)
+    public void testStartChildInfoOakPrimaryType() throws Exception {
+        init(true, ImportUUIDBehavior.IMPORT_UUID_COLLISION_THROW);
+        User user = getTestSystemUser();
+        Tree policyTree = createPolicyTree(user);
+        importer.handlePropInfo(policyTree, mockPropInfo(user.getPrincipal()), 
mockPropertyDefinition(getJcrName(NT_REP_PRINCIPAL_POLICY)));
+
+        importer.startChildInfo(mockNodeInfo("oakName", 
NT_REP_PRINCIPAL_ENTRY), mock(List.class));
+    }
+
+    @Test(expected = ConstraintViolationException.class)
+    public void testStartChildInfoNestedEntry() throws Exception {
+        init(true, ImportUUIDBehavior.IMPORT_UUID_CREATE_NEW);
+        User user = getTestSystemUser();
+        Tree policyTree = createPolicyTree(user);
+        importer.handlePropInfo(policyTree, mockPropInfo(user.getPrincipal()), 
mockPropertyDefinition(getJcrName(NT_REP_PRINCIPAL_POLICY)));
+
+        importer.startChildInfo(mockNodeInfo("entry", 
getJcrName(NT_REP_PRINCIPAL_ENTRY)), mockPropInfos("/anyPath", 
PrivilegeConstants.JCR_READ_ACCESS_CONTROL));
+        importer.startChildInfo(mockNodeInfo("anotherEntry", 
getJcrName(NT_REP_PRINCIPAL_ENTRY)), mockPropInfos("/anyPath", 
PrivilegeConstants.JCR_READ_ACCESS_CONTROL));
+    }
+
+    @Test(expected = ConstraintViolationException.class)
+    public void testStartChildInfoMissingPrivileges() throws Exception {
+        init(false, ImportUUIDBehavior.IMPORT_UUID_CREATE_NEW);
+        User user = getTestSystemUser();
+        Tree policyTree = createPolicyTree(user);
+        importer.handlePropInfo(policyTree, mockPropInfo(user.getPrincipal()), 
mockPropertyDefinition(getJcrName(NT_REP_PRINCIPAL_POLICY)));
+
+        importer.startChildInfo(mockNodeInfo("entry", 
getJcrName(NT_REP_PRINCIPAL_ENTRY)), mockPropInfos("/effective/path"));
+    }
+
+    @Test(expected = ConstraintViolationException.class)
+    public void testStartChildInfoRestrictionNotNestedInEntry() throws 
Exception {
+        init(false, ImportUUIDBehavior.IMPORT_UUID_CREATE_NEW);
+        User user = getTestSystemUser();
+        Tree policyTree = createPolicyTree(user);
+        importer.handlePropInfo(policyTree, mockPropInfo(user.getPrincipal()), 
mockPropertyDefinition(getJcrName(NT_REP_PRINCIPAL_POLICY)));
+
+        importer.startChildInfo(mockNodeInfo(getJcrName(REP_RESTRICTIONS), 
getJcrName(NT_REP_RESTRICTIONS)), mock(List.class));
+    }
+
+    @Test(expected = ConstraintViolationException.class)
+    public void testStartChildInfoUnsupportedProperty() throws Exception {
+        init(true, ImportUUIDBehavior.IMPORT_UUID_COLLISION_REPLACE_EXISTING);
+        User user = getTestSystemUser();
+        Tree policyTree = createPolicyTree(user);
+        importer.handlePropInfo(policyTree, mockPropInfo(user.getPrincipal()), 
mockPropertyDefinition(getJcrName(NT_REP_PRINCIPAL_POLICY)));
+
+        List<PropInfo> propInfos = mockPropInfos("/effective/path", 
PrivilegeConstants.JCR_REMOVE_CHILD_NODES);
+        propInfos.add(mockPropInfo("unsupportedProperty"));
+        importer.startChildInfo(mockNodeInfo("entry", 
getJcrName(NT_REP_PRINCIPAL_ENTRY)), propInfos);
+    }
+
+    @Test(expected = ConstraintViolationException.class)
+    public void testStartChildInfoWrongEffectivePathPropertyType() throws 
Exception {
+        init(true, ImportUUIDBehavior.IMPORT_UUID_COLLISION_REPLACE_EXISTING);
+        User user = getTestSystemUser();
+        Tree policyTree = createPolicyTree(user);
+        importer.handlePropInfo(policyTree, mockPropInfo(user.getPrincipal()), 
mockPropertyDefinition(getJcrName(NT_REP_PRINCIPAL_POLICY)));
+
+        List<PropInfo> propInfos = mockPropInfos(null, 
PrivilegeConstants.JCR_REMOVE_CHILD_NODES);
+        // effective path with wrong type
+        TextValue tx = 
when(mock(TextValue.class).getString()).thenReturn("/effective/path").getMock();
+        PropInfo propInfo = mockPropInfo(getJcrName(REP_EFFECTIVE_PATH));
+        when(propInfo.getTextValue()).thenReturn(tx);
+        when(propInfo.getType()).thenReturn(PropertyType.STRING);
+        propInfos.add(propInfo);
+
+        importer.startChildInfo(mockNodeInfo("entry", 
getJcrName(NT_REP_PRINCIPAL_ENTRY)), propInfos);
+    }
+
+    @Test(expected = ConstraintViolationException.class)
+    public void testStartChildInfoWrongPrivilegesPropertyType() throws 
Exception {
+        init(true, ImportUUIDBehavior.IMPORT_UUID_COLLISION_REPLACE_EXISTING);
+        User user = getTestSystemUser();
+        Tree policyTree = createPolicyTree(user);
+        importer.handlePropInfo(policyTree, mockPropInfo(user.getPrincipal()), 
mockPropertyDefinition(getJcrName(NT_REP_PRINCIPAL_POLICY)));
+
+        List<PropInfo> propInfos = mockPropInfos("/effective/path");
+        // rep:privileges with wrong type
+        PropInfo propInfo = mockPropInfo(getJcrName(REP_PRIVILEGES));
+        TextValue tx = 
when(mock(TextValue.class).getString()).thenReturn(getJcrName(JCR_READ)).getMock();
+        List values = ImmutableList.of(tx);
+        when(propInfo.getTextValues()).thenReturn(values);
+        when(propInfo.getType()).thenReturn(PropertyType.STRING);
+        propInfos.add(propInfo);
+
+        importer.startChildInfo(mockNodeInfo("entry", 
getJcrName(NT_REP_PRINCIPAL_ENTRY)), propInfos);
+    }
+
+    @Test(expected = IllegalStateException.class)
+    public void testStartChildInfoNestedRestriction() throws Exception {
+        init(false, ImportUUIDBehavior.IMPORT_UUID_CREATE_NEW);
+        User user = getTestSystemUser();
+        Tree policyTree = createPolicyTree(user);
+        importer.handlePropInfo(policyTree, mockPropInfo(user.getPrincipal()), 
mockPropertyDefinition(getJcrName(NT_REP_PRINCIPAL_POLICY)));
+
+        importer.startChildInfo(mockNodeInfo("entry", 
getJcrName(NT_REP_PRINCIPAL_ENTRY)), mockPropInfos("/effective/path", 
PrivilegeConstants.REP_WRITE));
+        importer.startChildInfo(mockNodeInfo(getJcrName(REP_RESTRICTIONS), 
getJcrName(NT_REP_RESTRICTIONS)), 
mockPropInfos(ImmutableMap.of(getJcrName(REP_GLOB), "/some/glob"), 
PropertyType.STRING));
+        importer.startChildInfo(mockNodeInfo(getJcrName(REP_RESTRICTIONS), 
getJcrName(NT_REP_RESTRICTIONS)), mockPropInfos(ImmutableMap.of()));
+    }
+
+    @Test(expected = IllegalStateException.class)
+    public void testStartChildInfoNestedMvRestriction() throws Exception {
+        init(false, ImportUUIDBehavior.IMPORT_UUID_CREATE_NEW);
+        User user = getTestSystemUser();
+        Tree policyTree = createPolicyTree(user);
+        importer.handlePropInfo(policyTree, mockPropInfo(user.getPrincipal()), 
mockPropertyDefinition(getJcrName(NT_REP_PRINCIPAL_POLICY)));
+
+        importer.startChildInfo(mockNodeInfo("entry", 
getJcrName(NT_REP_PRINCIPAL_ENTRY)), mockPropInfos("/effective/path", 
PrivilegeConstants.REP_WRITE));
+        importer.startChildInfo(mockNodeInfo(getJcrName(REP_RESTRICTIONS), 
getJcrName(NT_REP_RESTRICTIONS)), 
mockPropInfos(ImmutableMap.of(getJcrName(REP_NT_NAMES), new Value[0])));
+        importer.startChildInfo(mockNodeInfo(getJcrName(REP_RESTRICTIONS), 
getJcrName(NT_REP_RESTRICTIONS)), mockPropInfos(ImmutableMap.of()));
+    }
+
+    @Test(expected = IllegalStateException.class)
+    public void testStartChildInfoRepNodeRestrictionOverwritesEffectivePath() 
throws Exception {
+        init(false, ImportUUIDBehavior.IMPORT_UUID_CREATE_NEW);
+        User user = getTestSystemUser();
+        Tree policyTree = createPolicyTree(user);
+        importer.handlePropInfo(policyTree, mockPropInfo(user.getPrincipal()), 
mockPropertyDefinition(getJcrName(NT_REP_PRINCIPAL_POLICY)));
+
+        importer.startChildInfo(mockNodeInfo("entry", 
getJcrName(NT_REP_PRINCIPAL_ENTRY)), mockPropInfos("/effective/path", 
PrivilegeConstants.REP_READ_PROPERTIES));
+        importer.startChildInfo(mockNodeInfo(getJcrName(REP_RESTRICTIONS), 
getJcrName(NT_REP_RESTRICTIONS)), mockPropInfos(ImmutableMap.of(
+                getJcrName(REP_NODE_PATH), "/effective/path"), 
PropertyType.STRING));
+    }
+
+    @Test
+    public void testStartChildInfoRepNodeRestriction() throws Exception {
+        init(true, ImportUUIDBehavior.IMPORT_UUID_COLLISION_THROW);
+        User user = getTestSystemUser();
+        Tree policyTree = createPolicyTree(user);
+        importer.handlePropInfo(policyTree, mockPropInfo(user.getPrincipal()), 
mockPropertyDefinition(getJcrName(NT_REP_PRINCIPAL_POLICY)));
+
+        importer.start(policyTree);
+        importer.startChildInfo(mockNodeInfo("entry", 
getJcrName(NT_REP_PRINCIPAL_ENTRY)), mockPropInfos(null, 
PrivilegeConstants.REP_READ_PROPERTIES));
+        importer.startChildInfo(mockNodeInfo(getJcrName(REP_RESTRICTIONS), 
getJcrName(NT_REP_RESTRICTIONS)), mockPropInfos(ImmutableMap.of(
+                getJcrName(REP_NODE_PATH), "/effective/path"), 
PropertyType.STRING));
+
+        importer.endChildInfo();
+        importer.endChildInfo();
+        importer.end(policyTree);
+
+        PrincipalPolicyImpl.EntryImpl entry = 
assertPolicy(getAccessControlManager(root).getPolicies(user.getPrincipal()), 1);
+        assertEquals("/effective/path", entry.getEffectivePath());
+    }
+
+    @Test
+    public void testStartChildInfoMvRestrictions() throws Exception {
+        init(false, ImportUUIDBehavior.IMPORT_UUID_CREATE_NEW);
+        User user = getTestSystemUser();
+        Tree policyTree = createPolicyTree(user);
+        importer.handlePropInfo(policyTree, mockPropInfo(user.getPrincipal()), 
mockPropertyDefinition(getJcrName(NT_REP_PRINCIPAL_POLICY)));
+
+        importer.start(policyTree);
+        importer.startChildInfo(mockNodeInfo("entry", 
getJcrName(NT_REP_PRINCIPAL_ENTRY)), mockPropInfos("/effective/path", 
PrivilegeConstants.REP_WRITE));
+
+        ValueFactory vf = getValueFactory(root);
+        Value[] nameValues = new Value[] 
{vf.createValue(getJcrName("jcr:content"), PropertyType.NAME), 
vf.createValue(getJcrName("jcr:data"), PropertyType.NAME)};
+        importer.startChildInfo(mockNodeInfo(getJcrName(REP_RESTRICTIONS), 
getJcrName(NT_REP_RESTRICTIONS)), mockPropInfos(ImmutableMap.of(
+                getJcrName(REP_ITEM_NAMES), nameValues,
+                getJcrName(REP_GLOB), new Value[] 
{vf.createValue("/some/*/globbing")})
+        ));
+        importer.endChildInfo();
+        importer.endChildInfo();
+        importer.end(policyTree);
+
+        PrincipalPolicyImpl.EntryImpl entry = 
assertPolicy(getAccessControlManager(root).getPolicies(user.getPrincipal()), 1);
+        assertNotNull(entry.getRestrictions(getJcrName(REP_ITEM_NAMES)));
+        assertNotNull(entry.getRestriction(getJcrName(REP_GLOB)));
+    }
+
+    @Test(expected = AccessControlException.class)
+    public void testStartChildInfoUnsupportedRestrictions() throws Exception {
+        init(false, ImportUUIDBehavior.IMPORT_UUID_CREATE_NEW);
+        User user = getTestSystemUser();
+        Tree policyTree = createPolicyTree(user);
+        importer.handlePropInfo(policyTree, mockPropInfo(user.getPrincipal()), 
mockPropertyDefinition(getJcrName(NT_REP_PRINCIPAL_POLICY)));
+
+        importer.start(policyTree);
+        importer.startChildInfo(mockNodeInfo("entry", 
getJcrName(NT_REP_PRINCIPAL_ENTRY)), mockPropInfos("/effective/path", 
PrivilegeConstants.REP_WRITE));
+        importer.startChildInfo(mockNodeInfo(getJcrName(REP_RESTRICTIONS), 
getJcrName(NT_REP_RESTRICTIONS)), mockPropInfos(ImmutableMap.of(
+                "unsupported", "x"), PropertyType.STRING));
+        // adding entry to policy must already throw the exception
+        importer.endChildInfo();
+    }
+
+    @Test(expected = IllegalStateException.class)
+    public void testEndChildInfoWithoutPolicyNorEntry() throws Exception {
+        importer.endChildInfo();
+    }
+
+    @Test(expected = ConstraintViolationException.class)
+    public void testEndChildInfoMissingEffectivePath() throws Exception {
+        init(false, ImportUUIDBehavior.IMPORT_UUID_CREATE_NEW);
+        User user = getTestSystemUser();
+        Tree policyTree = createPolicyTree(user);
+        importer.handlePropInfo(policyTree, mockPropInfo(user.getPrincipal()), 
mockPropertyDefinition(getJcrName(NT_REP_PRINCIPAL_POLICY)));
+
+        importer.startChildInfo(mockNodeInfo("entry", 
getJcrName(NT_REP_PRINCIPAL_ENTRY)), mockPropInfos(null, JCR_READ));
+        importer.endChildInfo();
+    }
+}
\ No newline at end of file

Propchange: 
jackrabbit/oak/trunk/oak-authorization-principalbased/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/PrincipalPolicyImporterTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: 
jackrabbit/oak/trunk/oak-authorization-principalbased/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/RegularTreePermissionTest.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-authorization-principalbased/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/RegularTreePermissionTest.java?rev=1857551&view=auto
==============================================================================
--- 
jackrabbit/oak/trunk/oak-authorization-principalbased/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/RegularTreePermissionTest.java
 (added)
+++ 
jackrabbit/oak/trunk/oak-authorization-principalbased/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/RegularTreePermissionTest.java
 Mon Apr 15 07:16:49 2019
@@ -0,0 +1,195 @@
+/*
+ * 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.spi.security.authorization.principalbased.impl;
+
+import org.apache.jackrabbit.JcrConstants;
+import org.apache.jackrabbit.oak.api.Tree;
+import org.apache.jackrabbit.oak.commons.PathUtils;
+import org.apache.jackrabbit.oak.namepath.NamePathMapper;
+import org.apache.jackrabbit.oak.plugins.tree.TreeType;
+import org.apache.jackrabbit.oak.spi.nodetype.NodeTypeConstants;
+import 
org.apache.jackrabbit.oak.spi.security.authorization.permission.Permissions;
+import 
org.apache.jackrabbit.oak.spi.security.authorization.permission.TreePermission;
+import org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants;
+import org.apache.jackrabbit.oak.spi.state.NodeState;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.security.Principal;
+
+import static 
org.apache.jackrabbit.oak.spi.security.authorization.principalbased.impl.Constants.REP_PRINCIPAL_POLICY;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.mock;
+
+public class RegularTreePermissionTest extends AbstractPrincipalBasedTest {
+
+    private PrincipalBasedPermissionProvider permissionProvider;
+
+    @Before
+    public void before() throws Exception {
+        super.before();
+
+        Principal principal = getTestSystemUser().getPrincipal();
+        setupContentTrees(TEST_OAK_PATH);
+        setupPrincipalBasedAccessControl(principal, testContentJcrPath, 
PrivilegeConstants.JCR_READ);
+        root.commit();
+
+        permissionProvider = createPermissionProvider(root, principal);
+    }
+
+    @Override
+    protected NamePathMapper getNamePathMapper() {
+        return NamePathMapper.DEFAULT;
+    }
+
+    @Test
+    public void testGetTreePermissionRootTree() {
+        Tree rootTree = root.getTree(PathUtils.ROOT_PATH);
+        TreePermission tp = permissionProvider.getTreePermission(rootTree, 
TreePermission.EMPTY);
+
+        assertTrue(tp instanceof AbstractTreePermission);
+        AbstractTreePermission atp = (AbstractTreePermission) tp;
+        assertNotEquals(rootTree, atp.getTree());
+        assertEquals(TreeType.DEFAULT, atp.getType());
+    }
+
+    @Test
+    public void testGetTreePermissionReadOnlyRootTree() {
+        Tree rootTree = 
getRootProvider().createReadOnlyRoot(root).getTree(PathUtils.ROOT_PATH);
+        TreePermission tp = permissionProvider.getTreePermission(rootTree, 
TreeType.VERSION, mock(TreePermission.class));
+
+        assertTrue(tp instanceof AbstractTreePermission);
+        AbstractTreePermission atp = (AbstractTreePermission) tp;
+        assertSame(rootTree, atp.getTree());
+        assertEquals(TreeType.DEFAULT, atp.getType());
+    }
+
+    @Test
+    public void testIsGrantedForRootTree() throws Exception {
+        TreePermission tp = 
permissionProvider.getTreePermission(root.getTree(PathUtils.ROOT_PATH), 
TreeType.DEFAULT, mock(TreePermission.class));
+        assertFalse(tp.isGranted(Permissions.READ));
+    }
+
+    @Test
+    public void testCanReadForRootTree() throws Exception {
+        TreePermission tp = 
permissionProvider.getTreePermission(root.getTree(PathUtils.ROOT_PATH), 
TreeType.DEFAULT, mock(TreePermission.class));
+        assertFalse(tp.canRead());
+        
assertFalse(tp.canRead(MockUtility.createPrimaryTypeProperty(NodeTypeConstants.NT_REP_ROOT)));
+    }
+
+    @Test
+    public void testRefreshReflectedOnTreePermission() throws Exception {
+        TreePermission tp = 
permissionProvider.getTreePermission(root.getTree(PathUtils.ROOT_PATH), 
TreePermission.EMPTY);
+
+        setupPrincipalBasedAccessControl(getTestSystemUser().getPrincipal(), 
PathUtils.ROOT_PATH, PrivilegeConstants.REP_READ_NODES);
+        root.commit();
+        permissionProvider.refresh();
+
+        assertTrue(tp.canRead());
+        
assertFalse(tp.canRead(MockUtility.createPrimaryTypeProperty(NodeTypeConstants.NT_REP_ROOT)));
+    }
+
+    @Test
+    public void testGetTreePermissionMockedParentPermission() throws Exception 
{
+        Tree tree = 
getRootProvider().createReadOnlyRoot(root).getTree(getNamePathMapper().getOakPath(getTestSystemUser().getPath())).getChild(REP_PRINCIPAL_POLICY);
+        assertTrue(tree.exists());
+        TreePermission tp = permissionProvider.getTreePermission(tree, 
mock(TreePermission.class));
+
+        assertTrue(tp instanceof AbstractTreePermission);
+        AbstractTreePermission atp = (AbstractTreePermission) tp;
+        assertSame(tree, atp.getTree());
+        assertEquals(TreeType.ACCESS_CONTROL, atp.getType());
+    }
+
+    @Test
+    public void testGetTreePermissionNonExistingTree() throws Exception {
+        Tree tree = 
getRootProvider().createReadOnlyRoot(root).getTree("/nonExisting");
+        assertFalse(tree.exists());
+
+        TreePermission tp = permissionProvider.getTreePermission(tree, 
permissionProvider.getTreePermission(root.getTree(PathUtils.ROOT_PATH), 
TreePermission.EMPTY));
+
+        assertTrue(tp instanceof AbstractTreePermission);
+        AbstractTreePermission atp = (AbstractTreePermission) tp;
+    }
+
+    @Test
+    public void testIsGrantedForTestTree() throws Exception {
+        Tree tree = root.getTree(PathUtils.ROOT_PATH);
+        TreePermission tp = permissionProvider.getTreePermission(tree, 
TreePermission.EMPTY);
+        for (String elem : PathUtils.elements(TEST_OAK_PATH)) {
+            tree = tree.getChild(elem);
+            tp = permissionProvider.getTreePermission(tree, tp);
+        }
+
+        assertTrue(tp.isGranted(Permissions.READ));
+        assertTrue(tp.isGranted(Permissions.READ, 
tree.getProperty(JcrConstants.JCR_PRIMARYTYPE)));
+
+        assertFalse(tp.isGranted(Permissions.READ_ACCESS_CONTROL));
+        assertFalse(tp.isGranted(Permissions.WRITE));
+    }
+
+    @Test
+    public void testCanReadForTestTree() throws Exception {
+        Tree tree = root.getTree(PathUtils.ROOT_PATH);
+        TreePermission tp = permissionProvider.getTreePermission(tree, 
TreePermission.EMPTY);
+        for (String elem : PathUtils.elements(TEST_OAK_PATH)) {
+            tree = tree.getChild(elem);
+            tp = permissionProvider.getTreePermission(tree, tp);
+        }
+
+        assertTrue(tp.canRead());
+        assertTrue(tp.canRead(tree.getProperty(JcrConstants.JCR_PRIMARYTYPE)));
+    }
+
+    @Test
+    public void testCanReadForTypeAccessControl() throws Exception {
+        String prinipalPath = 
getNamePathMapper().getOakPath(getTestSystemUser().getPath());
+        String policyPath = PathUtils.concat(prinipalPath, 
REP_PRINCIPAL_POLICY);
+
+        Tree tree = root.getTree(PathUtils.ROOT_PATH);
+        TreePermission tp = permissionProvider.getTreePermission(tree, 
TreePermission.EMPTY);
+        for (String elem : PathUtils.elements(policyPath)) {
+            tree = tree.getChild(elem);
+            tp = permissionProvider.getTreePermission(tree, tp);
+        }
+
+        assertFalse(tp.canRead());
+
+        setupPrincipalBasedAccessControl(getTestSystemUser().getPrincipal(), 
getTestSystemUser().getPath(), PrivilegeConstants.JCR_READ_ACCESS_CONTROL);
+        root.commit();
+        permissionProvider.refresh();
+
+        assertTrue(tp.canRead());
+    }
+
+    @Test
+    public void testGetChildTreePermission() {
+        Tree readOnly = 
getRootProvider().createReadOnlyRoot(root).getTree(PathUtils.ROOT_PATH);
+        TreePermission tp = (AbstractTreePermission) 
permissionProvider.getTreePermission(readOnly, TreePermission.EMPTY);
+        NodeState ns = getTreeProvider().asNodeState(readOnly);
+        for (String elem : PathUtils.elements(TEST_OAK_PATH)) {
+            ns = ns.getChildNode(elem);
+            tp = permissionProvider.getTreePermission(elem, ns, 
(AbstractTreePermission) tp);
+            assertTrue(tp instanceof AbstractTreePermission);
+            assertSame(TreeType.DEFAULT, ((AbstractTreePermission) 
tp).getType());
+        }
+    }
+}
\ No newline at end of file

Propchange: 
jackrabbit/oak/trunk/oak-authorization-principalbased/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/RegularTreePermissionTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: 
jackrabbit/oak/trunk/oak-authorization-principalbased/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/RepositoryPermissionTest.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-authorization-principalbased/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/RepositoryPermissionTest.java?rev=1857551&view=auto
==============================================================================
--- 
jackrabbit/oak/trunk/oak-authorization-principalbased/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/RepositoryPermissionTest.java
 (added)
+++ 
jackrabbit/oak/trunk/oak-authorization-principalbased/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/RepositoryPermissionTest.java
 Mon Apr 15 07:16:49 2019
@@ -0,0 +1,148 @@
+/*
+ * 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.spi.security.authorization.principalbased.impl;
+
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Iterables;
+import org.apache.jackrabbit.oak.namepath.NamePathMapper;
+import 
org.apache.jackrabbit.oak.spi.security.authorization.permission.Permissions;
+import 
org.apache.jackrabbit.oak.spi.security.authorization.permission.RepositoryPermission;
+import org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.lang.reflect.Field;
+import java.util.Set;
+
+import static 
org.apache.jackrabbit.oak.spi.security.authorization.permission.Permissions.NAMESPACE_MANAGEMENT;
+import static 
org.apache.jackrabbit.oak.spi.security.authorization.permission.Permissions.NODE_TYPE_DEFINITION_MANAGEMENT;
+import static 
org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants.JCR_NAMESPACE_MANAGEMENT;
+import static 
org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants.JCR_NODE_TYPE_DEFINITION_MANAGEMENT;
+import static 
org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants.JCR_WORKSPACE_MANAGEMENT;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+
+public class RepositoryPermissionTest extends AbstractPrincipalBasedTest {
+
+    private PrincipalBasedPermissionProvider permissionProvider;
+
+    @Before
+    public void before() throws Exception {
+        super.before();
+        permissionProvider = createPermissionProvider(root, 
getTestSystemUser().getPrincipal());
+    }
+
+    @Override
+    protected NamePathMapper getNamePathMapper() {
+        return NamePathMapper.DEFAULT;
+    }
+
+    private void setupPermissions(@Nullable String effectivePath, @NotNull 
String... privNames) throws Exception {
+        // set principal-based policy for 'testPrincipal'
+        setupPrincipalBasedAccessControl(getTestSystemUser().getPrincipal(), 
effectivePath, privNames);
+        if (root.hasPendingChanges()) {
+            root.commit();
+        }
+    }
+
+    @Test
+    public void testGetRepositoryPermissionsTwice() {
+        assertSame(permissionProvider.getRepositoryPermission(), 
permissionProvider.getRepositoryPermission());
+    }
+
+    @Test
+    public void testGetRepositoryPermissionsAfterRefresh() throws Exception {
+        RepositoryPermission rp = permissionProvider.getRepositoryPermission();
+        permissionProvider.refresh();
+        assertSame(rp, permissionProvider.getRepositoryPermission());
+    }
+
+    @Test
+    public void testRefreshResetsRepositoryPermissions() throws Exception {
+        RepositoryPermission rp = permissionProvider.getRepositoryPermission();
+        Field f = rp.getClass().getDeclaredField("grantedPermissions");
+        f.setAccessible(true);
+        assertEquals(Long.valueOf(-1), f.get(rp));
+
+        // force evaluation
+        rp.isGranted(NAMESPACE_MANAGEMENT);
+        assertEquals(Permissions.NO_PERMISSION, f.get(rp));
+
+        // reset permission provider
+        permissionProvider.refresh();
+        assertEquals(Long.valueOf(-1), f.get(rp));
+    }
+
+    @Test
+    public void testIsGrantedNoPermissions() {
+        
assertTrue(permissionProvider.getRepositoryPermission().isGranted(Permissions.NO_PERMISSION));
+    }
+
+    @Test
+    public void testIsGrantedNoPermissionSetup() {
+        
assertFalse(permissionProvider.getRepositoryPermission().isGranted(NAMESPACE_MANAGEMENT));
+    }
+
+    @Test
+    public void testIsGrantedNoRepoPermissionSetup() throws Exception {
+        setupPermissions(testContentJcrPath, PrivilegeConstants.JCR_ALL);
+
+        permissionProvider.refresh();
+        
assertFalse(permissionProvider.getRepositoryPermission().isGranted(NAMESPACE_MANAGEMENT));
+    }
+
+    @Test
+    public void testIsGrantedRepoPermissionSetup() throws Exception {
+        setupPermissions(null, 
PrivilegeConstants.JCR_NODE_TYPE_DEFINITION_MANAGEMENT);
+
+        permissionProvider.refresh();
+
+        
assertFalse(permissionProvider.getRepositoryPermission().isGranted(NAMESPACE_MANAGEMENT));
+        
assertFalse(permissionProvider.getRepositoryPermission().isGranted(NAMESPACE_MANAGEMENT|
 NODE_TYPE_DEFINITION_MANAGEMENT));
+        
assertFalse(permissionProvider.getRepositoryPermission().isGranted(Permissions.ALL));
+
+        
assertTrue(permissionProvider.getRepositoryPermission().isGranted(NODE_TYPE_DEFINITION_MANAGEMENT));
+    }
+
+    @Test
+    public void getPrivileges() throws Exception {
+        assertTrue(permissionProvider.getPrivileges(null).isEmpty());
+
+        setupPermissions(null, JCR_WORKSPACE_MANAGEMENT);
+        permissionProvider.refresh();
+
+        Set<String> privNames = permissionProvider.getPrivileges(null);
+        
assertTrue(Iterables.elementsEqual(ImmutableSet.of(JCR_WORKSPACE_MANAGEMENT), 
privNames));
+    }
+
+    @Test
+    public void hasPrivileges() throws Exception {
+        assertFalse(permissionProvider.hasPrivileges(null, 
JCR_NAMESPACE_MANAGEMENT));
+
+        setupPermissions(null, JCR_NAMESPACE_MANAGEMENT);
+        permissionProvider.refresh();
+
+        assertTrue(permissionProvider.hasPrivileges(null, 
JCR_NAMESPACE_MANAGEMENT));
+
+        assertFalse(permissionProvider.hasPrivileges(null, 
JCR_NAMESPACE_MANAGEMENT, JCR_WORKSPACE_MANAGEMENT));
+        assertFalse(permissionProvider.hasPrivileges(null, 
JCR_NODE_TYPE_DEFINITION_MANAGEMENT));
+    }
+}
\ No newline at end of file

Propchange: 
jackrabbit/oak/trunk/oak-authorization-principalbased/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/RepositoryPermissionTest.java
------------------------------------------------------------------------------
    svn:eol-style = native


Reply via email to