Added: 
jackrabbit/oak/trunk/oak-authorization-principalbased/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/ContextImplTest.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/ContextImplTest.java?rev=1857551&view=auto
==============================================================================
--- 
jackrabbit/oak/trunk/oak-authorization-principalbased/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/ContextImplTest.java
 (added)
+++ 
jackrabbit/oak/trunk/oak-authorization-principalbased/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/ContextImplTest.java
 Mon Apr 15 07:16:49 2019
@@ -0,0 +1,142 @@
+/*
+ * 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.oak.api.PropertyState;
+import org.apache.jackrabbit.oak.api.Root;
+import org.apache.jackrabbit.oak.api.Tree;
+import org.apache.jackrabbit.oak.commons.PathUtils;
+import org.apache.jackrabbit.oak.plugins.tree.TreeLocation;
+import org.apache.jackrabbit.oak.spi.nodetype.NodeTypeConstants;
+import org.apache.jackrabbit.oak.spi.security.Context;
+import 
org.apache.jackrabbit.oak.spi.security.authorization.accesscontrol.AccessControlConstants;
+import 
org.apache.jackrabbit.oak.spi.security.authorization.permission.PermissionConstants;
+import org.jetbrains.annotations.NotNull;
+import org.junit.Test;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+public class ContextImplTest implements Constants {
+
+    private static final Context CTX = ContextImpl.INSTANCE;
+
+    private static Tree mockTree(@NotNull String name, @NotNull String ntName, 
boolean exists, @NotNull String... propertyNames) {
+        return MockUtility.mockTree(name, ntName, exists, propertyNames);
+    }
+
+    @Test
+    public void testDefinesTree() {
+        assertTrue(CTX.definesTree(mockTree(REP_PRINCIPAL_POLICY, 
NT_REP_PRINCIPAL_POLICY, true)));
+        assertTrue(CTX.definesTree(mockTree(REP_RESTRICTIONS, 
NT_REP_RESTRICTIONS, true)));
+        assertTrue(CTX.definesTree(mockTree("anyEntry", 
NT_REP_PRINCIPAL_ENTRY, true)));
+    }
+
+    @Test
+    public void testNotDefinesTree() {
+        assertFalse(CTX.definesTree(mockTree(REP_PRINCIPAL_POLICY, 
NT_REP_PRINCIPAL_POLICY, false)));
+        assertFalse(CTX.definesTree(mockTree(REP_RESTRICTIONS, 
NT_REP_RESTRICTIONS, false)));
+        assertFalse(CTX.definesTree(mockTree("anyEntry", 
NT_REP_PRINCIPAL_ENTRY, false)));
+        assertFalse(CTX.definesTree(mockTree("anyName", "anyNt", false)));
+        assertFalse(CTX.definesTree(mockTree("anyName", "anyNt", true)));
+    }
+
+    @Test
+    public void testDefinesProperty() {
+        PropertyState anyProperty = mock(PropertyState.class);
+
+        assertTrue(CTX.definesProperty(mockTree(REP_PRINCIPAL_POLICY, 
NT_REP_PRINCIPAL_POLICY, true), anyProperty));
+        assertTrue(CTX.definesProperty(mockTree(REP_RESTRICTIONS, 
NT_REP_RESTRICTIONS, true), anyProperty));
+        assertTrue(CTX.definesProperty(mockTree("anyEntry", 
NT_REP_PRINCIPAL_ENTRY, true), anyProperty));
+    }
+
+    @Test
+    public void testDefinesCtxRoot() {
+        assertTrue(CTX.definesContextRoot(mockTree(REP_PRINCIPAL_POLICY, 
NT_REP_PRINCIPAL_POLICY, true)));
+    }
+
+    @Test
+    public void testNotDefinesCtxRoot() {
+        assertFalse(CTX.definesContextRoot(mockTree(REP_PRINCIPAL_POLICY, 
NT_REP_PRINCIPAL_POLICY, false)));
+        
assertFalse(CTX.definesContextRoot(mockTree(AccessControlConstants.REP_POLICY, 
NT_REP_PRINCIPAL_POLICY, true)));
+        assertFalse(CTX.definesContextRoot(mockTree(REP_PRINCIPAL_POLICY, 
AccessControlConstants.NT_REP_POLICY, true)));
+        assertFalse(CTX.definesContextRoot(mockTree(REP_RESTRICTIONS, 
NT_REP_RESTRICTIONS, true)));
+    }
+
+    @Test
+    public void testDefinesNodeLocation() {
+        
assertTrue(CTX.definesLocation(TreeLocation.create(mockTree(REP_PRINCIPAL_POLICY,
 NT_REP_PRINCIPAL_POLICY, true))));
+        
assertTrue(CTX.definesLocation(TreeLocation.create(mockTree(REP_RESTRICTIONS, 
NT_REP_RESTRICTIONS, true))));
+        
assertTrue(CTX.definesLocation(TreeLocation.create(mockTree("anyEntry", 
NT_REP_PRINCIPAL_ENTRY, true))));
+    }
+
+    @Test
+    public void testDefinesPropertyLocation() {
+        String[] propNames = new String[] {REP_PRINCIPAL_NAME, "prop1", 
"prop2"};
+        Tree policyTree = MockUtility.mockTree(REP_PRINCIPAL_POLICY, 
NT_REP_PRINCIPAL_POLICY, PathUtils.ROOT_PATH + REP_PRINCIPAL_POLICY, propNames);
+
+        Tree rootTree = MockUtility.mockTree(PathUtils.ROOT_NAME, 
NodeTypeConstants.NT_REP_ROOT, PathUtils.ROOT_PATH, propNames);
+        when(rootTree.getChild(REP_PRINCIPAL_POLICY)).thenReturn(policyTree);
+
+        Root r = 
when(mock(Root.class).getTree(PathUtils.ROOT_PATH)).thenReturn(rootTree).getMock();
+
+        for (String propName : propNames) {
+            assertTrue(CTX.definesLocation(TreeLocation.create(r, 
PathUtils.concat(policyTree.getPath(), propName))));
+            assertFalse(CTX.definesLocation(TreeLocation.create(r, 
PathUtils.concat(rootTree.getPath(), propName))));
+        }
+    }
+
+    @Test
+    public void testDefinesNonExistingLocation() {
+        
assertTrue(CTX.definesLocation(TreeLocation.create(mockTree(REP_PRINCIPAL_POLICY,
 NT_REP_PRINCIPAL_POLICY, false))));
+        
assertTrue(CTX.definesLocation(TreeLocation.create(mockTree(REP_RESTRICTIONS, 
NT_REP_RESTRICTIONS, false))));
+
+        Tree t = mockTree(REP_RESTRICTIONS, NT_REP_RESTRICTIONS, false, 
"anyResidualProperty");
+        
assertTrue(CTX.definesLocation(TreeLocation.create(t).getChild("anyResidualProperty")));
+
+        t = mockTree(REP_PRINCIPAL_POLICY, NT_REP_PRINCIPAL_POLICY, false, 
"anyResidualAceName");
+        
assertTrue(CTX.definesLocation(TreeLocation.create(t).getChild("anyResidualAceName")));
+
+        String[] propNames = new String[] {REP_EFFECTIVE_PATH, 
REP_PRINCIPAL_NAME, REP_PRIVILEGES};
+        t = mockTree("anyEntry", "anyNt", false, propNames);
+        for (String propName : propNames) {
+            
assertTrue(CTX.definesLocation(TreeLocation.create(t).getChild(propName)));
+        }
+
+        String[] nodeNames = new String[] {REP_PRINCIPAL_POLICY, 
REP_RESTRICTIONS};
+        for (String nodeName : nodeNames) {
+            
assertTrue(CTX.definesLocation(TreeLocation.create(mockTree(nodeName, "anyNt", 
false))));
+        }
+    }
+
+    @Test
+    public void testNotDefinesLocation() {
+        Tree t = mockTree("anyEntry", "anyNt", false, "anyResidualProperty");
+        
assertFalse(CTX.definesLocation(TreeLocation.create(t).getChild("anyResidualProperty")));
+
+        t = mockTree("anyEntry", "anyNt", true, "anyResidualProperty");
+        
assertFalse(CTX.definesLocation(TreeLocation.create(t).getChild("anyResidualProperty")));
+    }
+
+    @Test
+    public void testDefinesInternal() {
+        assertFalse(CTX.definesInternal(mock(Tree.class)));
+        
assertFalse(CTX.definesInternal(when(mock(Tree.class).getName()).thenReturn(PermissionConstants.REP_PERMISSION_STORE).getMock()));
+    }
+}
\ 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/ContextImplTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: 
jackrabbit/oak/trunk/oak-authorization-principalbased/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/EffectivePolicyTest.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/EffectivePolicyTest.java?rev=1857551&view=auto
==============================================================================
--- 
jackrabbit/oak/trunk/oak-authorization-principalbased/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/EffectivePolicyTest.java
 (added)
+++ 
jackrabbit/oak/trunk/oak-authorization-principalbased/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/EffectivePolicyTest.java
 Mon Apr 15 07:16:49 2019
@@ -0,0 +1,152 @@
+/*
+ * 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.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import org.apache.jackrabbit.JcrConstants;
+import org.apache.jackrabbit.api.security.JackrabbitAccessControlEntry;
+import org.apache.jackrabbit.oak.commons.PathUtils;
+import org.apache.jackrabbit.oak.spi.security.authorization.accesscontrol.ACE;
+import 
org.apache.jackrabbit.oak.spi.security.authorization.accesscontrol.ImmutableACL;
+import 
org.apache.jackrabbit.oak.spi.security.authorization.principalbased.PrincipalPolicy;
+import org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants;
+import org.junit.Before;
+import org.junit.Test;
+
+import javax.jcr.PropertyType;
+import javax.jcr.Value;
+import javax.jcr.security.AccessControlPolicy;
+import java.security.Principal;
+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_NT_NAMES;
+import static 
org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants.JCR_NAMESPACE_MANAGEMENT;
+import static 
org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants.JCR_READ;
+import static 
org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants.REP_WRITE;
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+public class EffectivePolicyTest extends AbstractPrincipalBasedTest {
+
+    private PrincipalBasedAccessControlManager acMgr;
+    private Principal validPrincipal;
+    private Principal validPrincipal2;
+    private String jcrEffectivePath;
+
+    @Before
+    public void testBefore() throws Exception {
+        super.before();
+
+        setupContentTrees(TEST_OAK_PATH);
+        jcrEffectivePath = 
PathUtils.getAncestorPath(getNamePathMapper().getJcrPath(TEST_OAK_PATH), 3);
+
+        validPrincipal2 = 
getUserManager(root).createSystemUser("anotherValidPrincipal", 
INTERMEDIATE_PATH).getPrincipal();
+        root.commit();
+
+        acMgr = createAccessControlManager(root);
+        validPrincipal = getTestSystemUser().getPrincipal();
+
+        PrincipalPolicyImpl policy = 
setupPrincipalBasedAccessControl(validPrincipal, jcrEffectivePath, JCR_READ, 
REP_WRITE);
+        addPrincipalBasedEntry(policy, null, JCR_NAMESPACE_MANAGEMENT);
+
+        policy = (PrincipalPolicyImpl) 
acMgr.getApplicablePolicies(validPrincipal2)[0];
+        Map<String, Value> restrictions = 
ImmutableMap.of(getNamePathMapper().getJcrName(REP_GLOB), 
getValueFactory(root).createValue("/*/glob"));
+        policy.addEntry(jcrEffectivePath, privilegesFromNames(JCR_READ), 
restrictions, ImmutableMap.of());
+
+        String ntJcrName = 
getNamePathMapper().getJcrName(JcrConstants.NT_RESOURCE);
+        Map<String, Value[]> mvRestrictions = 
ImmutableMap.of(getNamePathMapper().getJcrName(REP_NT_NAMES), new Value[] 
{getValueFactory(root).createValue(ntJcrName, PropertyType.NAME)});
+        policy.addEntry(PathUtils.ROOT_PATH, 
privilegesFromNames(PrivilegeConstants.JCR_LIFECYCLE_MANAGEMENT), 
ImmutableMap.of(), mvRestrictions);
+
+        acMgr.setPolicy(policy.getPath(), policy);
+
+        root.commit();
+    }
+
+    @Test
+    public void testEffectivePolicyByPrincipal() throws Exception {
+        AccessControlPolicy[] effective = 
acMgr.getEffectivePolicies(ImmutableSet.of(validPrincipal));
+        assertEquals(1, effective.length);
+        assertTrue(effective[0] instanceof ImmutableACL);
+
+        List<JackrabbitAccessControlEntry> entries = 
((ImmutableACL)effective[0]).getEntries();
+        assertEquals(2, entries.size());
+
+        assertTrue(entries.get(0) instanceof PrincipalPolicy.Entry);
+        assertEquals(validPrincipal, entries.get(0).getPrincipal());
+        assertArrayEquals(privilegesFromNames(JCR_READ, REP_WRITE), 
entries.get(0).getPrivileges());
+        assertEquals(jcrEffectivePath, ((PrincipalPolicy.Entry) 
entries.get(0)).getEffectivePath());
+
+        assertNull(((PrincipalPolicy.Entry) 
entries.get(1)).getEffectivePath());
+    }
+
+    @Test
+    public void testEffectivePolicyByPath() throws Exception {
+        AccessControlPolicy[] effective = 
acMgr.getEffectivePolicies(getNamePathMapper().getJcrPath(TEST_OAK_PATH));
+        assertEquals(2, effective.length);
+
+        for (AccessControlPolicy effectivePolicy : effective) {
+            assertTrue(effectivePolicy instanceof ImmutableACL);
+
+            ImmutableACL acl = (ImmutableACL) effectivePolicy;
+            if (jcrEffectivePath.equals(acl.getPath())) {
+                List<JackrabbitAccessControlEntry> entries = acl.getEntries();
+                assertEquals(2, entries.size());
+
+                for (JackrabbitAccessControlEntry entry : entries) {
+                    if (validPrincipal.equals(entry.getPrincipal())) {
+                        assertArrayEquals(privilegesFromNames(JCR_READ, 
REP_WRITE), entry.getPrivileges());
+                        assertEquals(0, entry.getRestrictionNames().length);
+                    } else {
+                        assertEquals(validPrincipal2, entry.getPrincipal());
+                        assertArrayEquals(privilegesFromNames(JCR_READ), 
entry.getPrivileges());
+                        assertArrayEquals(new String[] 
{getNamePathMapper().getJcrName(REP_GLOB)}, entry.getRestrictionNames());
+                    }
+                }
+            } else {
+                assertEquals(PathUtils.ROOT_PATH, acl.getPath());
+
+                List<JackrabbitAccessControlEntry> entries = acl.getEntries();
+                assertEquals(1, entries.size());
+
+                JackrabbitAccessControlEntry entry = entries.get(0);
+                assertTrue(entry instanceof ACE);
+                
assertArrayEquals(privilegesFromNames(PrivilegeConstants.JCR_LIFECYCLE_MANAGEMENT),
 entry.getPrivileges());
+                assertEquals(1, ((ACE) entry).getRestrictions().size());
+                assertArrayEquals(new String[] 
{getNamePathMapper().getJcrName(REP_NT_NAMES)}, entry.getRestrictionNames());
+            }
+        }
+    }
+
+    @Test
+    public void testEffectivePolicyByNullPath() throws Exception {
+        AccessControlPolicy[] effective = acMgr.getEffectivePolicies((String) 
null);
+        assertEquals(1, effective.length);
+        assertTrue(effective[0] instanceof ImmutableACL);
+
+        List<JackrabbitAccessControlEntry> entries = 
((ImmutableACL)effective[0]).getEntries();
+        assertEquals(1, entries.size());
+
+        assertTrue(entries.get(0) instanceof ACE);
+        assertEquals(validPrincipal, entries.get(0).getPrincipal());
+        assertArrayEquals(privilegesFromNames(JCR_NAMESPACE_MANAGEMENT), 
entries.get(0).getPrivileges());
+    }
+}

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

Added: 
jackrabbit/oak/trunk/oak-authorization-principalbased/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/EntryCacheTest.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/EntryCacheTest.java?rev=1857551&view=auto
==============================================================================
--- 
jackrabbit/oak/trunk/oak-authorization-principalbased/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/EntryCacheTest.java
 (added)
+++ 
jackrabbit/oak/trunk/oak-authorization-principalbased/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/EntryCacheTest.java
 Mon Apr 15 07:16:49 2019
@@ -0,0 +1,91 @@
+/*
+ * 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 org.apache.jackrabbit.oak.api.Tree;
+import org.apache.jackrabbit.oak.api.Type;
+import org.apache.jackrabbit.oak.commons.PathUtils;
+import org.apache.jackrabbit.oak.plugins.tree.TreeUtil;
+import org.apache.jackrabbit.oak.spi.nodetype.NodeTypeConstants;
+import 
org.apache.jackrabbit.oak.spi.security.authorization.AuthorizationConfiguration;
+import 
org.apache.jackrabbit.oak.spi.security.authorization.restriction.RestrictionProvider;
+import org.junit.Before;
+import org.junit.Test;
+
+import static 
org.apache.jackrabbit.oak.spi.nodetype.NodeTypeConstants.NT_OAK_UNSTRUCTURED;
+import static 
org.apache.jackrabbit.oak.spi.security.authorization.principalbased.impl.Constants.MIX_REP_PRINCIPAL_BASED_MIXIN;
+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.REP_EFFECTIVE_PATH;
+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.privilege.PrivilegeConstants.JCR_READ;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+public class EntryCacheTest extends AbstractPrincipalBasedTest {
+
+    private RestrictionProvider restrictionProvider;
+    private String accessControlledPath;
+    private Tree accessControlledTree;
+    private Tree policyTree;
+
+    @Before
+    public void before() throws Exception {
+        super.before();
+
+        restrictionProvider = 
getConfig(AuthorizationConfiguration.class).getRestrictionProvider();
+        accessControlledPath = 
getNamePathMapper().getOakPath(getTestSystemUser().getPath());
+        accessControlledTree = root.getTree(accessControlledPath);
+        TreeUtil.addMixin(accessControlledTree, MIX_REP_PRINCIPAL_BASED_MIXIN, 
root.getTree(NodeTypeConstants.NODE_TYPES_PATH), "uid");
+        policyTree = TreeUtil.addChild(accessControlledTree, 
REP_PRINCIPAL_POLICY, NT_REP_PRINCIPAL_POLICY);
+    }
+
+    @Test
+    public void testNoEntries() {
+        EntryCache cache = new EntryCache(root, 
ImmutableSet.of(accessControlledPath), restrictionProvider);
+        assertFalse(cache.getEntries(TEST_OAK_PATH).hasNext());
+    }
+
+    @Test
+    public void testNonEntryChild() throws Exception {
+        TreeUtil.addChild(policyTree, "invalidChild", NT_OAK_UNSTRUCTURED);
+        EntryCache cache = new EntryCache(root, 
ImmutableSet.of(accessControlledPath), restrictionProvider);
+        assertFalse(cache.getEntries(TEST_OAK_PATH).hasNext());
+    }
+
+    @Test
+    public void testMissingEntriesForTestPath() throws Exception {
+        Tree entry = TreeUtil.addChild(policyTree, "entry1", 
NT_REP_PRINCIPAL_ENTRY);
+        entry.setProperty(REP_EFFECTIVE_PATH, PathUtils.ROOT_PATH, Type.PATH);
+        entry.setProperty(REP_PRIVILEGES, ImmutableSet.of(JCR_READ), 
Type.NAMES);
+
+        EntryCache cache = new EntryCache(root, 
ImmutableSet.of(accessControlledPath), restrictionProvider);
+        assertFalse(cache.getEntries(TEST_OAK_PATH).hasNext());
+    }
+
+    @Test
+    public void testEntriesForTestPath() throws Exception {
+        Tree entry = TreeUtil.addChild(policyTree, "entry1", 
NT_REP_PRINCIPAL_ENTRY);
+        entry.setProperty(REP_EFFECTIVE_PATH, TEST_OAK_PATH, Type.PATH);
+        entry.setProperty(REP_PRIVILEGES, ImmutableSet.of(JCR_READ), 
Type.NAMES);
+
+        EntryCache cache = new EntryCache(root, 
ImmutableSet.of(accessControlledPath), restrictionProvider);
+        assertTrue(cache.getEntries(TEST_OAK_PATH).hasNext());
+    }
+}
\ 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/EntryCacheTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: 
jackrabbit/oak/trunk/oak-authorization-principalbased/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/EntryIteratorTest.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/EntryIteratorTest.java?rev=1857551&view=auto
==============================================================================
--- 
jackrabbit/oak/trunk/oak-authorization-principalbased/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/EntryIteratorTest.java
 (added)
+++ 
jackrabbit/oak/trunk/oak-authorization-principalbased/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/EntryIteratorTest.java
 Mon Apr 15 07:16:49 2019
@@ -0,0 +1,51 @@
+/*
+ * 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.Predicates;
+import com.google.common.collect.Iterators;
+import org.junit.Test;
+
+import static org.junit.Assert.assertFalse;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+public class EntryIteratorTest {
+
+    private EntryCache cache = 
when(mock(EntryCache.class).getEntries(anyString())).thenReturn(Iterators.singletonIterator(mock(PermissionEntry.class))).getMock();
+
+    @Test
+    public void testIterationStopsAtRootPath() {
+        EntryIterator it = new EntryIterator("/some/test/path", 
Predicates.alwaysTrue(), cache);
+        while (it.hasNext()) {
+            it.next();
+        }
+        verify(cache, times(4)).getEntries(anyString());
+        for (String path : new String[] {"/some/test/path", "/some/test", 
"/some", "/"}) {
+            verify(cache, times(1)).getEntries(path);
+        }
+    }
+
+    @Test
+    public void testRespectsPredicate() {
+        EntryIterator it = new EntryIterator("/some/test/path", 
Predicates.alwaysFalse(), cache);
+        assertFalse(it.hasNext());
+    }
+}
\ 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/EntryIteratorTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: 
jackrabbit/oak/trunk/oak-authorization-principalbased/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/EntryPredicateTest.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/EntryPredicateTest.java?rev=1857551&view=auto
==============================================================================
--- 
jackrabbit/oak/trunk/oak-authorization-principalbased/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/EntryPredicateTest.java
 (added)
+++ 
jackrabbit/oak/trunk/oak-authorization-principalbased/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/EntryPredicateTest.java
 Mon Apr 15 07:16:49 2019
@@ -0,0 +1,300 @@
+/*
+ * 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.Predicate;
+import com.google.common.base.Predicates;
+import org.apache.jackrabbit.oak.api.PropertyState;
+import org.apache.jackrabbit.oak.api.Tree;
+import org.apache.jackrabbit.oak.commons.PathUtils;
+import org.apache.jackrabbit.oak.plugins.memory.PropertyStates;
+import 
org.apache.jackrabbit.oak.spi.security.authorization.permission.Permissions;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mockito;
+
+import static 
org.apache.jackrabbit.oak.spi.security.authorization.principalbased.impl.MockUtility.mockTree;
+import static org.junit.Assert.assertSame;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+public class EntryPredicateTest {
+
+    private static final String TREE_PATH = "/parent/path";
+    private static final String PROP_PATH = "/parent/path/prop";
+    private final String PARENT_PATH = PathUtils.getParentPath(TREE_PATH);
+
+    private PermissionEntry pe = mock(PermissionEntry.class);
+    private Tree tree;
+    private PropertyState propertyState = 
PropertyStates.createProperty("prop", "value");
+
+    @Before
+    public void before() {
+        tree = mockTree(TREE_PATH, false);
+    }
+
+    @Test
+    public void testCreateNullPath() {
+        Predicate<PermissionEntry> predicate = EntryPredicate.create(null);
+        predicate.apply(pe);
+
+        verify(pe, times(1)).matches();
+        verify(pe, never()).matches(Mockito.anyString());
+        verify(pe, never()).matches(Mockito.any(Tree.class), 
Mockito.any(PropertyState.class));
+        verify(pe, never()).getPrivilegeBits();
+    }
+
+    @Test
+    public void testCreatePath() {
+        Predicate<PermissionEntry> predicate = 
EntryPredicate.create(Mockito.anyString());
+        predicate.apply(pe);
+
+        verify(pe, never()).matches();
+        verify(pe, times(1)).matches(Mockito.anyString());
+        verify(pe, never()).matches(Mockito.any(Tree.class), 
Mockito.any(PropertyState.class));
+        verify(pe, never()).getPrivilegeBits();
+    }
+
+    @Test
+    public void testCreateNonExistingTree() {
+        Predicate<PermissionEntry> predicate = EntryPredicate.create(tree, 
null);
+        predicate.apply(pe);
+
+        verify(pe, never()).matches();
+        verify(pe, times(1)).matches(tree.getPath());
+        verify(pe, times(0)).matches(PathUtils.ROOT_PATH);
+        verify(pe, never()).matches(Mockito.any(Tree.class), 
Mockito.any(PropertyState.class));
+        verify(pe, never()).getPrivilegeBits();
+    }
+
+    @Test
+    public void testCreateNonExistingTreeProperty() {
+        Predicate<PermissionEntry> predicate = EntryPredicate.create(tree, 
propertyState);
+        predicate.apply(pe);
+
+        verify(pe, never()).matches();
+        verify(pe, times(1)).matches(PROP_PATH);
+        verify(pe, never()).matches(tree.getPath());
+        verify(pe, never()).matches(Mockito.any(Tree.class), 
Mockito.any(PropertyState.class));
+        verify(pe, never()).getPrivilegeBits();
+    }
+
+    @Test
+    public void testCreateExistingTree() {
+        when(tree.exists()).thenReturn(true);
+
+        Predicate<PermissionEntry> predicate = EntryPredicate.create(tree, 
null);
+        predicate.apply(pe);
+
+        verify(pe, never()).matches();
+        verify(pe, never()).matches(TREE_PATH);
+        verify(pe, times(1)).matches(tree, null);
+        verify(pe, never()).getPrivilegeBits();
+    }
+
+    @Test
+    public void testCreateExistingTreeProperty() {
+        when(tree.exists()).thenReturn(true);
+
+        Predicate<PermissionEntry> predicate = EntryPredicate.create(tree, 
propertyState);
+        predicate.apply(pe);
+
+        verify(pe, never()).matches();
+        verify(pe, never()).matches(PROP_PATH);
+        verify(pe, times(1)).matches(tree, propertyState);
+        verify(pe, never()).matches(tree, 
PropertyStates.createProperty("another", "value"));
+        verify(pe, never()).getPrivilegeBits();
+    }
+
+    @Test
+    public void testCreateParentPathReadPermission() {
+        assertSame(Predicates.alwaysFalse(), 
EntryPredicate.createParent(tree.getPath(), null, Permissions.READ));
+        assertSame(Predicates.alwaysFalse(), 
EntryPredicate.createParent(tree.getPath(), mock(Tree.class), 
Permissions.READ));
+    }
+
+    @Test
+    public void testCreateParentPathEmpty() {
+        assertSame(Predicates.alwaysFalse(), EntryPredicate.createParent("", 
null, Permissions.ALL));
+        assertSame(Predicates.alwaysFalse(), EntryPredicate.createParent("", 
tree, Permissions.ALL));
+    }
+
+    @Test
+    public void testCreateParentPathRoot() {
+        assertSame(Predicates.alwaysFalse(), 
EntryPredicate.createParent(PathUtils.ROOT_PATH, tree, Permissions.ALL));
+    }
+
+    @Test
+    public void testCreateParentPath() {
+        when(pe.appliesTo(PARENT_PATH)).thenReturn(true);
+
+        Predicate<PermissionEntry> predicate = 
EntryPredicate.createParent(TREE_PATH, null, Permissions.ALL);
+        predicate.apply(pe);
+
+        verify(pe, never()).matches();
+        verify(pe, never()).matches(TREE_PATH);
+        verify(pe, times(1)).appliesTo(PARENT_PATH);
+        verify(pe, times(1)).matches(PARENT_PATH);
+        verify(pe, never()).matches(any(Tree.class), any(PropertyState.class));
+        verify(pe, never()).getPrivilegeBits();
+    }
+
+    @Test
+    public void testCreateParentPathTree() {
+        when(pe.appliesTo(PARENT_PATH)).thenReturn(true);
+
+        Tree parentTree = mockTree(PARENT_PATH, true);
+        Predicate<PermissionEntry> predicate = 
EntryPredicate.createParent(TREE_PATH, parentTree, Permissions.ALL);
+        predicate.apply(pe);
+
+        verify(pe, never()).matches();
+        verify(pe, never()).matches(TREE_PATH);
+        verify(pe, times(1)).appliesTo(PARENT_PATH);
+        verify(pe, times(1)).matches(parentTree, null);
+        verify(pe, never()).matches(PARENT_PATH);
+        verify(pe, never()).getPrivilegeBits();
+    }
+
+    @Test
+    public void testCreateParentPathTreeNotExisting() {
+        when(pe.appliesTo(PARENT_PATH)).thenReturn(true);
+
+        Predicate<PermissionEntry> predicate = 
EntryPredicate.createParent(TREE_PATH, mockTree(PARENT_PATH, false), 
Permissions.ALL);
+        predicate.apply(pe);
+
+        verify(pe, never()).matches();
+        verify(pe, never()).matches(TREE_PATH);
+        verify(pe, times(1)).appliesTo(PARENT_PATH);
+        verify(pe, times(1)).matches(PARENT_PATH);
+        verify(pe, never()).matches(any(Tree.class), any(PropertyState.class));
+        verify(pe, never()).getPrivilegeBits();
+    }
+
+    @Test
+    public void testCreateParentPathMismatch() {
+        Predicate<PermissionEntry> predicate = 
EntryPredicate.createParent(TREE_PATH, null, Permissions.ALL);
+        predicate.apply(pe);
+
+        String parentPath = PathUtils.getParentPath(TREE_PATH);
+        verify(pe, never()).matches();
+        verify(pe, never()).matches(TREE_PATH);
+        verify(pe, times(1)).appliesTo(parentPath);
+        verify(pe, never()).matches(parentPath);
+        verify(pe, never()).matches(any(Tree.class), any(PropertyState.class));
+        verify(pe, never()).getPrivilegeBits();
+    }
+
+    @Test
+    public void testCreateParentPathTreeMismatch() {
+        Tree parentTree = mockTree(PARENT_PATH, true);
+
+        Predicate<PermissionEntry> predicate = 
EntryPredicate.createParent(TREE_PATH, parentTree, Permissions.ALL);
+        predicate.apply(pe);
+
+        String parentPath = PathUtils.getParentPath(TREE_PATH);
+        verify(pe, never()).matches();
+        verify(pe, never()).matches(TREE_PATH);
+        verify(pe, times(1)).appliesTo(parentPath);
+        verify(pe, never()).matches(parentPath);
+        verify(pe, never()).matches(any(Tree.class), any(PropertyState.class));
+        verify(pe, never()).getPrivilegeBits();
+    }
+
+    @Test
+    public void testCreateParentTreeReadPermission() {
+        when(tree.exists()).thenReturn(true);
+
+        assertSame(Predicates.alwaysFalse(), EntryPredicate.createParent(tree, 
Permissions.READ));
+    }
+
+    @Test
+    public void testCreateParentTreeNotExisting() {
+        when(pe.appliesTo(PARENT_PATH)).thenReturn(true);
+
+        Predicate<PermissionEntry> predicate = 
EntryPredicate.createParent(tree, Permissions.ADD_NODE|Permissions.READ_NODE);
+        predicate.apply(pe);
+
+        verify(pe, never()).matches();
+        verify(pe, never()).matches(TREE_PATH);
+        verify(pe, times(1)).appliesTo(PARENT_PATH);
+        verify(pe, times(1)).matches(PARENT_PATH);
+        verify(pe, never()).matches(any(Tree.class), any(PropertyState.class));
+        verify(pe, never()).getPrivilegeBits();
+    }
+
+    @Test
+    public void testCreateParentTreeNotExistingMismatch() {
+        Predicate<PermissionEntry> predicate = 
EntryPredicate.createParent(tree, Permissions.ADD_NODE|Permissions.READ_NODE);
+        predicate.apply(pe);
+
+        verify(pe, never()).matches();
+        verify(pe, never()).matches(TREE_PATH);
+        verify(pe, times(1)).appliesTo(PARENT_PATH);
+        verify(pe, never()).matches(PARENT_PATH);
+        verify(pe, never()).matches(any(Tree.class), any(PropertyState.class));
+        verify(pe, never()).getPrivilegeBits();
+    }
+
+    @Test
+    public void testCreateParentTreeRoot() {
+        Tree rootTree = mockTree(PathUtils.ROOT_PATH, true);
+        assertSame(Predicates.alwaysFalse(), 
EntryPredicate.createParent(rootTree, 
Permissions.REMOVE|Permissions.MODIFY_ACCESS_CONTROL));
+    }
+
+    @Test
+    public void testCreateParentTree() {
+        when(pe.appliesTo(PARENT_PATH)).thenReturn(true);
+
+        Tree parentTree = mockTree(PARENT_PATH, true);
+
+        when(tree.exists()).thenReturn(true);
+        when(tree.getParent()).thenReturn(parentTree);
+
+        Predicate<PermissionEntry> predicate = 
EntryPredicate.createParent(tree, 
Permissions.REMOVE_NODE|Permissions.READ_PROPERTY|Permissions.LOCK_MANAGEMENT);
+        predicate.apply(pe);
+
+        verify(pe, never()).matches();
+        verify(pe, never()).matches(TREE_PATH);
+        verify(pe, never()).matches(PARENT_PATH);
+        verify(pe, times(1)).appliesTo(PARENT_PATH);
+        verify(pe, times(1)).matches(parentTree, null);
+        verify(pe, never()).matches(tree, null);
+        verify(pe, never()).getPrivilegeBits();
+    }
+
+    @Test
+    public void testCreateParentTreeMismatch() {
+        Tree parentTree = mockTree(PARENT_PATH, true);
+
+        when(tree.exists()).thenReturn(true);
+        when(tree.getParent()).thenReturn(parentTree);
+
+        Predicate<PermissionEntry> predicate = 
EntryPredicate.createParent(tree, 
Permissions.REMOVE_NODE|Permissions.READ_PROPERTY|Permissions.LOCK_MANAGEMENT);
+        predicate.apply(pe);
+
+        verify(pe, never()).matches();
+        verify(pe, never()).matches(TREE_PATH);
+        verify(pe, never()).matches(PARENT_PATH);
+        verify(pe, times(1)).appliesTo(PARENT_PATH);
+        verify(pe, never()).matches(parentTree, null);
+        verify(pe, never()).matches(tree, null);
+        verify(pe, never()).getPrivilegeBits();
+    }
+}
\ 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/EntryPredicateTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: 
jackrabbit/oak/trunk/oak-authorization-principalbased/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/FilterImplTest.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/FilterImplTest.java?rev=1857551&view=auto
==============================================================================
--- 
jackrabbit/oak/trunk/oak-authorization-principalbased/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/FilterImplTest.java
 (added)
+++ 
jackrabbit/oak/trunk/oak-authorization-principalbased/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/FilterImplTest.java
 Mon Apr 15 07:16:49 2019
@@ -0,0 +1,308 @@
+/*
+ * 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 org.apache.jackrabbit.api.security.principal.ItemBasedPrincipal;
+import org.apache.jackrabbit.api.security.user.User;
+import org.apache.jackrabbit.oak.commons.PathUtils;
+import org.apache.jackrabbit.oak.namepath.NamePathMapper;
+import org.apache.jackrabbit.oak.spi.security.SecurityProvider;
+import 
org.apache.jackrabbit.oak.spi.security.authorization.principalbased.Filter;
+import 
org.apache.jackrabbit.oak.spi.security.authorization.principalbased.FilterProvider;
+import org.apache.jackrabbit.oak.spi.security.principal.AdminPrincipal;
+import org.apache.jackrabbit.oak.spi.security.principal.PrincipalConfiguration;
+import org.apache.jackrabbit.oak.spi.security.principal.PrincipalProvider;
+import org.apache.jackrabbit.oak.spi.security.principal.SystemUserPrincipal;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.junit.Before;
+import org.junit.Test;
+
+import javax.jcr.RepositoryException;
+import java.security.Principal;
+import java.util.Collections;
+
+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.assertTrue;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+public class FilterImplTest extends AbstractPrincipalBasedTest {
+
+    private Filter filter;
+    private String supportedPath;
+
+    @Before
+    public void before() throws Exception {
+        super.before();
+        FilterProvider fp = getFilterProvider();
+        filter = fp.getFilter(getSecurityProvider(), root, 
getNamePathMapper());
+        supportedPath = fp.getFilterRoot();
+    }
+
+    @Test
+    public void testCanHandleEmptySet() throws Exception  {
+        assertFalse(filter.canHandle(Collections.emptySet()));
+    }
+
+    @Test
+    public void testCanHandleGroupPrincipal() throws Exception {
+        
assertFalse(filter.canHandle(Collections.singleton(getUserManager(root).createGroup("group").getPrincipal())));
+    }
+
+    @Test
+    public void testCanHandleUserPrincipal() throws Exception {
+        
assertFalse(filter.canHandle(Collections.singleton(getTestUser().getPrincipal())));
+    }
+
+    @Test
+    public void testCanHandleUnknownSystemUserPrincipal() {
+        SystemUserPrincipal principal = () -> "systemUserPrincipal";
+        assertFalse(filter.canHandle(Collections.singleton(principal)));
+    }
+
+    @Test
+    public void testCanHandleRandomSystemUserPrincipal() throws Exception {
+        Principal principal = 
getUserManager(root).createSystemUser("anySystemUser", null).getPrincipal();
+        assertFalse(filter.canHandle(Collections.singleton(principal)));
+    }
+
+    @Test
+    public void testCanHandleValidSystemUserPrincipal() throws Exception {
+        
assertTrue(filter.canHandle(Collections.singleton(getTestSystemUser().getPrincipal())));
+    }
+
+    @Test
+    public void testCanHandleValidSystemUserPrincipal2() throws Exception {
+        Principal principal = getTestSystemUser().getPrincipal();
+        
assertTrue(filter.canHandle(Collections.singleton((SystemUserPrincipal) () -> 
principal.getName())));
+    }
+
+    @Test
+    public void testCanHandleWrongPrincipalClass() throws Exception {
+        Principal principal = getTestSystemUser().getPrincipal();
+        assertFalse(filter.canHandle(Collections.singleton((AdminPrincipal) () 
-> principal.getName())));
+        assertFalse(filter.canHandle(Collections.singleton((new 
ItemBasedPrincipal() {
+            @Override
+            public String getPath() throws RepositoryException {
+                return ((ItemBasedPrincipal) principal).getPath();
+            }
+
+            @Override
+            public String getName() {
+                return principal.getName();
+            }
+        }))));
+    }
+
+    @Test
+    public void testCanHandleItemBasedSystemUserPrincipalUnsupportedPath() 
throws Exception {
+        // make sure supported path exists
+        User tu = getTestSystemUser();
+        assertTrue(root.getTree(supportedPath).exists());
+        Principal principal = new TestPrincipal("name", 
PathUtils.getParentPath(supportedPath));
+        assertFalse(filter.canHandle(Collections.singleton(principal)));
+    }
+
+//    @Test
+//    public void testCanHandleItemBasedSystemUserPrincipalSupportedPath() {
+//        Principal principal = new TestPrincipal("name", 
PathUtils.concat(supportedPath, "oak:path/to/oak:principal"));
+//        assertTrue(filter.canHandle(Collections.singleton(principal)));
+//    }
+
+    @Test
+    public void testCanHandleGetPathThrows() {
+        Principal principal = new TestPrincipal("name", null);
+        assertFalse(filter.canHandle(Collections.singleton(principal)));
+    }
+
+    /**
+     * Test that the filter can deal with principals that have been accessed 
with a different {@code NamePathMapper}.
+     * This might actually occure with {@code 
AbstractAccessControlManager#hasPrivilege} and {@code 
AbstractAccessControlManager#getPrivileges},
+     * when a {@link PermissionProvider} is built from the principal set 
passed to the Jackrabbit API methods (and not from
+     * principals obtained on the system level when populating the {@code 
Subject}.
+     */
+    @Test
+    public void testCanHandlePathMapperMismatch() throws Exception {
+        Principal principal = getTestSystemUser().getPrincipal();
+
+        // create filter with a different NamePathMapper than was used to 
build the principal
+        Filter f =  getFilterProvider().getFilter(getSecurityProvider(), root, 
NamePathMapper.DEFAULT);
+        assertTrue(f.canHandle(Collections.singleton(principal)));
+    }
+
+    @Test
+    public void testCanHandlePathMapperMismatchUnknownPrincipal() throws 
Exception {
+        Principal principal = new TestPrincipal("name", 
PathUtils.concat(supportedPath, "oak:path/to/oak:principal"));
+
+        // create filter with a different NamePathMapper than was used to 
build the principal
+        // since the principal is not known to the PrincipalManager, the extra 
lookup doesn't reveal a valid principal.
+        Filter f =  getFilterProvider().getFilter(getSecurityProvider(), root, 
NamePathMapper.DEFAULT);
+        assertFalse(f.canHandle(Collections.singleton(principal)));
+    }
+
+    @Test
+    public void testCanHandleCombination() throws Exception {
+        
assertFalse(filter.canHandle(ImmutableSet.of(getTestSystemUser().getPrincipal(),
 getTestUser().getPrincipal())));
+    }
+
+    @Test
+    public void testCanHandlePopulatesCache() throws Exception  {
+        Principal principal = getTestSystemUser().getPrincipal();
+        PrincipalProvider pp = 
when(mock(PrincipalProvider.class).getPrincipal(principal.getName())).thenReturn(principal).getMock();
+        PrincipalConfiguration pc = 
when(mock(PrincipalConfiguration.class).getPrincipalProvider(root, 
getNamePathMapper())).thenReturn(pp).getMock();
+        SecurityProvider sp = 
when(mock(SecurityProvider.class).getConfiguration(PrincipalConfiguration.class)).thenReturn(pc).getMock();
+
+        Filter filter = getFilterProvider().getFilter(sp, root, 
getNamePathMapper());
+
+        // call 'canHandle' twice
+        
assertTrue(filter.canHandle(Collections.singleton((SystemUserPrincipal) () -> 
principal.getName())));
+        
assertTrue(filter.canHandle(Collections.singleton((SystemUserPrincipal) () -> 
principal.getName())));
+
+        // principalprovider must only be hit once
+        verify(pp, times(1)).getPrincipal(principal.getName());
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testGetPathUserPrincipal() throws Exception {
+        filter.getOakPath(getTestUser().getPrincipal());
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testGetPathInvalidSystemUserPrincipal() throws Exception {
+        filter.getOakPath((SystemUserPrincipal) () -> "name");
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testGetPathValidSystemUserPrincipalNotValidated() throws 
Exception {
+        filter.getOakPath(getTestSystemUser().getPrincipal());
+    }
+
+    @Test
+    public void testGetPathValidatedSystemUserPrincipal() throws Exception {
+        ItemBasedPrincipal principal = (ItemBasedPrincipal) 
getTestSystemUser().getPrincipal();
+        filter.canHandle(Collections.singleton(principal));
+
+        assertNotEquals(principal.getPath(), filter.getOakPath(principal));
+        assertEquals(getNamePathMapper().getOakPath(principal.getPath()), 
filter.getOakPath(principal));
+    }
+
+    @Test
+    public void testGetPathAfterGetValidUserPrincipal() throws Exception {
+        ItemBasedPrincipal principal = (ItemBasedPrincipal) 
getTestSystemUser().getPrincipal();
+        
filter.getValidPrincipal(getNamePathMapper().getOakPath(principal.getPath()));
+
+        assertNotEquals(principal.getPath(), filter.getOakPath(principal));
+        assertEquals(getNamePathMapper().getOakPath(principal.getPath()), 
filter.getOakPath(principal));
+    }
+
+    @Test
+    public void testGetPrincipalUserPath() throws Exception {
+        
assertNull(filter.getValidPrincipal(getNamePathMapper().getOakPath(getTestUser().getPath())));
+    }
+
+    @Test
+    public void testGetPrincipalJcrPath() throws Exception {
+        assertNull(filter.getValidPrincipal(getTestSystemUser().getPath()));
+    }
+
+    @Test
+    public void testGetPrincipalSystemUserPath() throws Exception {
+        User user = getTestSystemUser();
+        Principal principal = user.getPrincipal();
+        assertEquals(principal, 
filter.getValidPrincipal(getNamePathMapper().getOakPath(user.getPath())));
+    }
+
+    @Test
+    public void testGetPrincipalSupportedRootPath() {
+        assertNull(filter.getValidPrincipal(supportedPath));
+    }
+
+    @Test
+    public void testGetPrincipalMockedItemBasedProvider() throws Exception {
+        ItemBasedPrincipal principal = (ItemBasedPrincipal) 
getTestSystemUser().getPrincipal();
+        String oakPath = getNamePathMapper().getOakPath(principal.getPath());
+
+        PrincipalProvider pp = 
when(mock(PrincipalProvider.class).getItemBasedPrincipal(oakPath)).thenReturn(principal).getMock();
+        PrincipalConfiguration pc = 
when(mock(PrincipalConfiguration.class).getPrincipalProvider(root, 
getNamePathMapper())).thenReturn(pp).getMock();
+        SecurityProvider sp = 
when(mock(SecurityProvider.class).getConfiguration(PrincipalConfiguration.class)).thenReturn(pc).getMock();
+
+        Filter filter = getFilterProvider().getFilter(sp, root, 
getNamePathMapper());
+
+        // call 'getValidPrincipal' twice
+        Principal p = filter.getValidPrincipal(oakPath);
+        assertEquals(principal, p);
+        assertEquals(principal.getPath(), ((ItemBasedPrincipal) p).getPath());
+        assertEquals(principal, filter.getValidPrincipal(oakPath));
+
+        verify(pp, times(2)).getItemBasedPrincipal(oakPath);
+        verify(pp, never()).getPrincipal(principal.getName());
+    }
+
+    @Test
+    public void testGetPrincipalMockedPrincipalProvider() throws Exception {
+        ItemBasedPrincipal principal = (ItemBasedPrincipal) 
getTestSystemUser().getPrincipal();
+        String oakPath = getNamePathMapper().getOakPath(principal.getPath());
+
+        PrincipalProvider pp = mock(PrincipalProvider.class);
+        PrincipalConfiguration pc = 
when(mock(PrincipalConfiguration.class).getPrincipalProvider(root, 
getNamePathMapper())).thenReturn(pp).getMock();
+        SecurityProvider sp = 
when(mock(SecurityProvider.class).getConfiguration(PrincipalConfiguration.class)).thenReturn(pc).getMock();
+
+        Filter filter = getFilterProvider().getFilter(sp, root, 
getNamePathMapper());
+
+        assertNull(filter.getValidPrincipal(oakPath));
+        verify(pp, never()).getPrincipal(principal.getName());
+    }
+
+    private final class TestPrincipal implements SystemUserPrincipal, 
ItemBasedPrincipal {
+
+        private final String jcrPath;
+        private final String name;
+
+        private TestPrincipal(@NotNull String name, @Nullable String oakPath) {
+            if (oakPath == null) {
+                jcrPath = null;
+            } else {
+                jcrPath = getNamePathMapper().getJcrPath(oakPath);
+                assertNotNull(jcrPath);
+            }
+            this.name = name;
+        }
+
+        @Override
+        public String getPath() throws RepositoryException {
+            if (jcrPath != null) {
+                return jcrPath;
+            } else {
+                throw new RepositoryException();
+            }
+        }
+
+        @Override
+        public String getName() {
+            return name;
+        }
+    }
+}
\ 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/FilterImplTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: 
jackrabbit/oak/trunk/oak-authorization-principalbased/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/FilterProviderImplTest.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/FilterProviderImplTest.java?rev=1857551&view=auto
==============================================================================
--- 
jackrabbit/oak/trunk/oak-authorization-principalbased/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/FilterProviderImplTest.java
 (added)
+++ 
jackrabbit/oak/trunk/oak-authorization-principalbased/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/FilterProviderImplTest.java
 Mon Apr 15 07:16:49 2019
@@ -0,0 +1,84 @@
+/*
+ * 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.oak.api.Root;
+import org.apache.jackrabbit.oak.commons.PathUtils;
+import org.apache.jackrabbit.oak.namepath.NamePathMapper;
+import org.apache.jackrabbit.oak.security.internal.SecurityProviderBuilder;
+import org.apache.jackrabbit.oak.spi.security.SecurityProvider;
+import 
org.apache.jackrabbit.oak.spi.security.authorization.principalbased.Filter;
+import org.apache.jackrabbit.oak.spi.security.principal.PrincipalConfiguration;
+import org.junit.Test;
+import org.mockito.Mockito;
+
+import java.util.Collections;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+public class FilterProviderImplTest {
+
+    private static final String PATH = "/supported/path";
+
+    private FilterProviderImpl provider = 
AbstractPrincipalBasedTest.createFilterProviderImpl(PATH);
+
+    @Test
+    public void testHandlesPath() {
+        assertFalse(provider.handlesPath(PathUtils.ROOT_PATH));
+        assertFalse(provider.handlesPath(PATH + "sibling"));
+        assertTrue(provider.handlesPath(PATH));
+        assertTrue(provider.handlesPath(PathUtils.concat(PATH, "a", "path", 
"below")));
+    }
+
+    @Test
+    public void testGetSearchRoot() {
+        assertEquals(PATH, provider.getFilterRoot());
+    }
+
+    @Test
+    public void testGetFilter() {
+        SecurityProvider sp = 
Mockito.spy(SecurityProviderBuilder.newBuilder().build());
+        Root root = mock(Root.class);
+
+        Filter filter = provider.getFilter(sp, root, NamePathMapper.DEFAULT);
+        assertNotNull(filter);
+
+        Mockito.verify(sp, 
Mockito.times(1)).getConfiguration(PrincipalConfiguration.class);
+    }
+
+    @Test
+    public void testActivate() {
+        FilterProviderImpl fp = new FilterProviderImpl();
+        assertNull(fp.getFilterRoot());
+
+        
fp.activate(when(mock(FilterProviderImpl.Configuration.class).path()).thenReturn(PATH).getMock(),
 Collections.emptyMap());
+        assertEquals(PATH, fp.getFilterRoot());
+    }
+
+    @Test
+    public void testModified() {
+        String modifiedPath = "/modified/path";
+        
provider.modified(when(mock(FilterProviderImpl.Configuration.class).path()).thenReturn(modifiedPath).getMock(),
 Collections.emptyMap());
+        assertEquals(modifiedPath, provider.getFilterRoot());
+    }
+}
\ 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/FilterProviderImplTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: 
jackrabbit/oak/trunk/oak-authorization-principalbased/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/ImportAbortTest.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/ImportAbortTest.java?rev=1857551&view=auto
==============================================================================
--- 
jackrabbit/oak/trunk/oak-authorization-principalbased/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/ImportAbortTest.java
 (added)
+++ 
jackrabbit/oak/trunk/oak-authorization-principalbased/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/ImportAbortTest.java
 Mon Apr 15 07:16:49 2019
@@ -0,0 +1,58 @@
+/*
+ * 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.api.security.user.User;
+import org.apache.jackrabbit.oak.spi.xml.ImportBehavior;
+import org.junit.Test;
+
+import javax.jcr.Node;
+import javax.jcr.security.AccessControlException;
+import javax.jcr.security.AccessControlPolicy;
+
+import static org.apache.jackrabbit.JcrConstants.JCR_PRIMARYTYPE;
+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.REP_PRINCIPAL_NAME;
+import static 
org.apache.jackrabbit.oak.spi.security.authorization.principalbased.impl.Constants.REP_PRINCIPAL_POLICY;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+public class ImportAbortTest extends ImportBaseTest {
+
+    @Override
+    String getImportBehavior() {
+        return ImportBehavior.NAME_ABORT;
+    }
+
+    @Test(expected = AccessControlException.class)
+    public void testTransientPrincipal() throws Exception {
+        User transientSystemUser = 
getUserManager().createSystemUser("transientSystemUser", INTERMEDIATE_PATH);
+        String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
+                "<sv:node sv:name=\""+REP_PRINCIPAL_POLICY+"\" 
xmlns:mix=\"http://www.jcp.org/jcr/mix/1.0\"; 
xmlns:nt=\"http://www.jcp.org/jcr/nt/1.0\"; 
xmlns:fn_old=\"http://www.w3.org/2004/10/xpath-functions\"; 
xmlns:fn=\"http://www.w3.org/2005/xpath-functions\"; 
xmlns:xs=\"http://www.w3.org/2001/XMLSchema\"; 
xmlns:sv=\"http://www.jcp.org/jcr/sv/1.0\"; xmlns:rep=\"internal\" 
xmlns:jcr=\"http://www.jcp.org/jcr/1.0\";>" +
+                "<sv:property sv:name=\""+JCR_PRIMARYTYPE+"\" 
sv:type=\"Name\"><sv:value>"+NT_REP_PRINCIPAL_POLICY+"</sv:value></sv:property>"
 +
+                "<sv:property sv:name=\""+REP_PRINCIPAL_NAME+"\" 
sv:type=\"String\"><sv:value>"+transientSystemUser.getPrincipal().getName()+"</sv:value></sv:property>"
 +
+                "</sv:node>";
+        doImport(transientSystemUser.getPath(), xml);
+
+        
assertTrue(getSession().getNode(transientSystemUser.getPath()).hasNode(REP_PRINCIPAL_POLICY));
+        Node policy = 
getSession().getNode(transientSystemUser.getPath()).getNode(REP_PRINCIPAL_POLICY);
+        assertTrue(policy.hasProperty(REP_PRINCIPAL_NAME));
+
+        // but looking up policy doesn't work because of transient principal 
-> fails
+        
getAccessControlManager().getPolicies(transientSystemUser.getPrincipal());
+    }
+}
\ 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/ImportAbortTest.java
------------------------------------------------------------------------------
    svn:eol-style = native


Reply via email to