Author: angela
Date: Tue Apr 23 09:34:55 2019
New Revision: 1857999

URL: http://svn.apache.org/viewvc?rev=1857999&view=rev
Log:
OAK-8240 : Improve test coverage for 
org.apache.jackrabbit.oak.security.authorization.permission

Added:
    
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/permission/AdministrativePermissionProviderTest.java
   (with props)
    
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/permission/ChildOrderDiffTest.java
   (with props)
    
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/permission/CompiledPermissionImplTest.java
   (with props)
    
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/permission/EntryPredicateTest.java
   (with props)
    
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/permission/PermissionEntryTest.java
   (with props)
    
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/permission/PermissionUtilTest.java
   (with props)
    
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/permission/ReadStatusTest.java
   (with props)
Modified:
    
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/permission/PermissionCacheBuilderTest.java
    
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/permission/PermissionEntryCacheTest.java
    
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/permission/PermissionProviderImplTest.java
    
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/permission/PermissionStoreImplTest.java
    
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/permission/PermissionValidatorTest.java
    
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/permission/PrincipalPermissionEntriesTest.java
    
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/permission/VersionTreePermissionTest.java

Added: 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/permission/AdministrativePermissionProviderTest.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/permission/AdministrativePermissionProviderTest.java?rev=1857999&view=auto
==============================================================================
--- 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/permission/AdministrativePermissionProviderTest.java
 (added)
+++ 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/permission/AdministrativePermissionProviderTest.java
 Tue Apr 23 09:34:55 2019
@@ -0,0 +1,126 @@
+/*
+ * 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.security.authorization.permission;
+
+import com.google.common.collect.ImmutableMap;
+import org.apache.jackrabbit.api.security.user.Authorizable;
+import org.apache.jackrabbit.api.security.user.Group;
+import org.apache.jackrabbit.api.security.user.UserManager;
+import org.apache.jackrabbit.oak.AbstractSecurityTest;
+import org.apache.jackrabbit.oak.api.ContentSession;
+import org.apache.jackrabbit.oak.api.Root;
+import org.apache.jackrabbit.oak.api.Tree;
+import org.apache.jackrabbit.oak.plugins.tree.TreeLocation;
+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.permission.AggregatedPermissionProvider;
+import 
org.apache.jackrabbit.oak.spi.security.authorization.permission.PermissionConstants;
+import 
org.apache.jackrabbit.oak.spi.security.authorization.permission.PermissionProvider;
+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.authorization.permission.TreePermission;
+import org.apache.jackrabbit.oak.spi.version.VersionConstants;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+
+public class AdministrativePermissionProviderTest extends AbstractSecurityTest 
{
+
+    private static final String ADMINISTRATOR_GROUP = "admins";
+
+    private ContentSession testSession;
+    private PermissionProvider permissionProvider;
+
+    @Before
+    public void before() throws Exception {
+        super.before();
+
+        UserManager uMgr = getUserManager(root);
+        Group adminstrators = uMgr.createGroup(ADMINISTRATOR_GROUP);
+        adminstrators.addMember(getTestUser());
+        root.commit();
+
+        testSession = createTestSession();
+        permissionProvider = 
getConfig(AuthorizationConfiguration.class).getPermissionProvider(testSession.getLatestRoot(),
 testSession.getWorkspaceName(), testSession.getAuthInfo().getPrincipals());
+    }
+
+    @After
+    public void after() throws Exception {
+        try {
+            testSession.close();
+            Authorizable a = 
getUserManager(root).getAuthorizable(ADMINISTRATOR_GROUP);
+            if (a != null) {
+                a.remove();
+                root.commit();
+            }
+        } finally {
+            super.after();
+        }
+    }
+
+    @Override
+    protected ConfigurationParameters getSecurityConfigParameters() {
+        ConfigurationParameters acConfig = ConfigurationParameters.of(
+                PermissionConstants.PARAM_ADMINISTRATIVE_PRINCIPALS, new 
String[] {ADMINISTRATOR_GROUP});
+        return 
ConfigurationParameters.of(ImmutableMap.of(AuthorizationConfiguration.NAME, 
acConfig));
+    }
+
+    @Test
+    public void testRepositoryPermissions() {
+        RepositoryPermission rp = permissionProvider.getRepositoryPermission();
+        assertSame(RepositoryPermission.ALL, rp);
+    }
+
+    @Test
+    public void testRootTreePermissions() {
+        Root r = testSession.getLatestRoot();
+        assertTrue(r.getTree("/").exists());
+
+        TreePermission tp = 
permissionProvider.getTreePermission(r.getTree("/"), TreePermission.EMPTY);
+        assertSame(TreePermission.ALL, tp);
+    }
+
+    @Test
+    public void testReadPaths() {
+        Root r = testSession.getLatestRoot();
+        for (String path : PermissionConstants.DEFAULT_READ_PATHS) {
+            Tree tree = r.getTree(path);
+            assertTrue(tree.exists());
+            assertSame(TreePermission.ALL, 
permissionProvider.getTreePermission(tree, TreePermission.EMPTY));
+        }
+    }
+
+    @Test
+    public void testIsGrantedNonExistingLocation() {
+        assertTrue(permissionProvider instanceof AggregatedPermissionProvider);
+
+        TreeLocation location = 
TreeLocation.create(testSession.getLatestRoot(), "/test/non/existing/tree");
+        assertTrue(((AggregatedPermissionProvider) 
permissionProvider).isGranted(location, Permissions.ALL));
+    }
+
+    @Test
+    public void testIsGrantedNonExistingVersionStoreLocation() {
+        assertTrue(permissionProvider instanceof AggregatedPermissionProvider);
+        TreeLocation location = 
TreeLocation.create(testSession.getLatestRoot(), 
VersionConstants.VERSION_STORE_PATH + "/non/existing/tree");
+
+        assertFalse(((AggregatedPermissionProvider) 
permissionProvider).isGranted(location, Permissions.ALL));
+    }
+}
\ No newline at end of file

Propchange: 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/permission/AdministrativePermissionProviderTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/permission/ChildOrderDiffTest.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/permission/ChildOrderDiffTest.java?rev=1857999&view=auto
==============================================================================
--- 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/permission/ChildOrderDiffTest.java
 (added)
+++ 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/permission/ChildOrderDiffTest.java
 Tue Apr 23 09:34:55 2019
@@ -0,0 +1,168 @@
+/*
+ * 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.security.authorization.permission;
+
+import com.google.common.collect.ImmutableList;
+import org.apache.jackrabbit.oak.api.PropertyState;
+import org.apache.jackrabbit.oak.api.Type;
+import org.apache.jackrabbit.oak.plugins.memory.PropertyStates;
+import org.jetbrains.annotations.NotNull;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+
+public class ChildOrderDiffTest {
+
+    @NotNull
+    private static PropertyState createPropertyState(@NotNull String... names) 
{
+        return PropertyStates.createProperty("any", 
ImmutableList.copyOf(names), Type.NAMES);
+    }
+
+    @Test
+    public void testBeforeEmptyAfterEmpty() {
+        PropertyState before = createPropertyState();
+        PropertyState after = createPropertyState();
+        assertNull(ChildOrderDiff.firstReordered(before, after));
+    }
+
+    @Test
+    public void testBeforeEmpty() {
+        PropertyState before = createPropertyState();
+        PropertyState after = createPropertyState("n1", "n2");
+        assertNull(ChildOrderDiff.firstReordered(before, after));
+    }
+
+    @Test
+    public void testAfterEmpty() {
+        PropertyState before = createPropertyState("n1", "n2");
+        PropertyState after = createPropertyState();
+        assertNull(ChildOrderDiff.firstReordered(before, after));
+    }
+
+    @Test
+        public void testAfterEqualsBefore() {
+        PropertyState eq = createPropertyState("n1", "n2");
+        assertNull(ChildOrderDiff.firstReordered(eq, eq));
+    }
+
+    @Test
+    public void testAppendedAtEnd() {
+        PropertyState before = createPropertyState("n1", "n2", "n3");
+        PropertyState after = createPropertyState("n1", "n2", "n3", "n4");
+        assertNull(ChildOrderDiff.firstReordered(before, after));
+    }
+
+    @Test
+    public void testInsertedAtBeginning() {
+        PropertyState before = createPropertyState("n1", "n2", "n3");
+        PropertyState after = createPropertyState("n0", "n1", "n2", "n3");
+        assertNull(ChildOrderDiff.firstReordered(before, after));
+    }
+
+    @Test
+    public void testInserted() {
+        PropertyState before = createPropertyState("n1", "n2", "n3");
+        PropertyState after = createPropertyState("n1", "n11", "n2", "n3");
+        assertNull(ChildOrderDiff.firstReordered(before, after));
+    }
+
+    @Test
+    public void testLastReplaced() {
+        PropertyState before = createPropertyState("n1", "n2", "n3");
+        PropertyState after = createPropertyState("n1", "n2", "n4");
+        assertNull(ChildOrderDiff.firstReordered(before, after));
+    }
+
+    @Test
+    public void testFirstRemoved() {
+        PropertyState before = createPropertyState("n1", "n2", "n3");
+        PropertyState after = createPropertyState("n2", "n3");
+        assertNull(ChildOrderDiff.firstReordered(before, after));
+    }
+
+    @Test
+    public void testSecondRemoved() {
+        PropertyState before = createPropertyState("n1", "n2", "n3");
+        PropertyState after = createPropertyState("n1", "n3");
+        assertNull(ChildOrderDiff.firstReordered(before, after));
+    }
+
+    @Test
+    public void testLastRemoved() {
+        PropertyState before = createPropertyState("n1", "n2", "n3");
+        PropertyState after = createPropertyState("n1", "n2");
+        assertNull(ChildOrderDiff.firstReordered(before, after));
+    }
+
+
+    @Test
+    public void testReorderedFirstToEnd() {
+        PropertyState before = createPropertyState("n1", "n2", "n3");
+        PropertyState after = createPropertyState("n2", "n3", "n1");
+        assertEquals("n2", ChildOrderDiff.firstReordered(before, after));
+    }
+
+    @Test
+    public void testReorderedLastBeforeSecond() {
+        PropertyState before = createPropertyState("n1", "n2", "n3");
+        PropertyState after = createPropertyState("n1", "n3", "n2");
+        assertEquals("n3", ChildOrderDiff.firstReordered(before, after));
+    }
+
+    @Test
+    public void testRemovedAndReordered() {
+        PropertyState before = createPropertyState("n1", "n2", "n3", "n4");
+        PropertyState after = createPropertyState("n1", "n4", "n3");
+        assertEquals("n4", ChildOrderDiff.firstReordered(before, after));
+    }
+
+    @Test
+    public void testInsertedRemovedAndReordered() {
+        PropertyState before = createPropertyState("n1", "n2", "n3", "n4");
+        PropertyState after = createPropertyState("n1", "n11", "n4", "n3");
+        assertEquals("n4", ChildOrderDiff.firstReordered(before, after));
+    }
+
+    @Test
+    public void testRemovedAndReorderedAppended() {
+        PropertyState before = createPropertyState("n1", "n2", "n3", "n4");
+        PropertyState after = createPropertyState("n1", "n4", "n3", "n33");
+        assertEquals("n4", ChildOrderDiff.firstReordered(before, after));
+    }
+
+    @Test
+    public void testReorderedAndReplaced() {
+        PropertyState before = createPropertyState("n1", "n2", "n3", "n4");
+        PropertyState after = createPropertyState("n4", "n1", "n6");
+        assertEquals("n4", ChildOrderDiff.firstReordered(before, after));
+    }
+
+    @Test
+    public void testOnlyLastEquals() {
+        PropertyState before = createPropertyState("n1", "n2");
+        PropertyState after = createPropertyState("n5", "n6", "n7", "n2");
+        assertNull(ChildOrderDiff.firstReordered(before, after));
+    }
+
+    @Test
+    public void testAllDifferent() {
+        PropertyState before = createPropertyState("n1", "n2", "n3", "n4");
+        PropertyState after = createPropertyState("n5", "n6", "n7", "n8", 
"n9");
+        assertNull(ChildOrderDiff.firstReordered(before, after));
+    }
+}
\ No newline at end of file

Propchange: 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/permission/ChildOrderDiffTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/permission/CompiledPermissionImplTest.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/permission/CompiledPermissionImplTest.java?rev=1857999&view=auto
==============================================================================
--- 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/permission/CompiledPermissionImplTest.java
 (added)
+++ 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/permission/CompiledPermissionImplTest.java
 Tue Apr 23 09:34:55 2019
@@ -0,0 +1,513 @@
+/*
+ * 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.security.authorization.permission;
+
+import com.google.common.collect.ImmutableSet;
+import org.apache.jackrabbit.api.security.JackrabbitAccessControlList;
+import 
org.apache.jackrabbit.commons.jackrabbit.authorization.AccessControlUtils;
+import org.apache.jackrabbit.oak.AbstractSecurityTest;
+import org.apache.jackrabbit.oak.api.ContentSession;
+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.memory.PropertyStates;
+import org.apache.jackrabbit.oak.plugins.tree.TreeUtil;
+import org.apache.jackrabbit.oak.plugins.version.ReadOnlyVersionManager;
+import 
org.apache.jackrabbit.oak.security.authorization.AuthorizationConfigurationImpl;
+import org.apache.jackrabbit.oak.security.authorization.ProviderCtx;
+import 
org.apache.jackrabbit.oak.security.authorization.composite.CompositeAuthorizationConfiguration;
+import org.apache.jackrabbit.oak.spi.nodetype.NodeTypeConstants;
+import org.apache.jackrabbit.oak.spi.security.ConfigurationParameters;
+import org.apache.jackrabbit.oak.spi.security.Context;
+import 
org.apache.jackrabbit.oak.spi.security.authorization.AuthorizationConfiguration;
+import 
org.apache.jackrabbit.oak.spi.security.authorization.permission.PermissionConstants;
+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.principal.EveryonePrincipal;
+import org.apache.jackrabbit.oak.spi.security.principal.PrincipalImpl;
+import org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.junit.Test;
+
+import javax.jcr.security.AccessControlList;
+import javax.jcr.security.AccessControlManager;
+import java.security.Principal;
+import java.util.HashSet;
+import java.util.Set;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static org.apache.jackrabbit.JcrConstants.JCR_FROZENNODE;
+import static org.apache.jackrabbit.JcrConstants.JCR_ISCHECKEDOUT;
+import static org.apache.jackrabbit.JcrConstants.JCR_PRIMARYTYPE;
+import static org.apache.jackrabbit.JcrConstants.MIX_VERSIONABLE;
+import static org.apache.jackrabbit.JcrConstants.NT_VERSION;
+import static org.apache.jackrabbit.oak.plugins.tree.TreeUtil.addChild;
+import static 
org.apache.jackrabbit.oak.spi.security.authorization.permission.PermissionConstants.PARAM_READ_PATHS;
+import static 
org.apache.jackrabbit.oak.spi.security.authorization.permission.PermissionConstants.PERMISSIONS_STORE_PATH;
+import static 
org.apache.jackrabbit.oak.spi.security.authorization.permission.Permissions.SET_PROPERTY;
+import static 
org.apache.jackrabbit.oak.spi.security.authorization.permission.Permissions.VERSION_MANAGEMENT;
+import static 
org.apache.jackrabbit.oak.spi.security.authorization.permission.TreePermission.ALL;
+import static 
org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants.JCR_READ;
+import static 
org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants.JCR_VERSION_MANAGEMENT;
+import static 
org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants.JCR_WRITE;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.anyLong;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+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 CompiledPermissionImplTest extends AbstractSecurityTest {
+
+    private static String TEST_PATH = "/test";
+    private static String SUBTREE_PATH = TEST_PATH + "/subtree";
+    private static String ACCESS_CONTROLLED_PATH = TEST_PATH + 
"/accessControlled";
+
+    private ContentSession testSession;
+    private Set<String> accessControlledPaths = new HashSet<>();
+
+    @Override
+    public void before() throws Exception {
+        super.before();
+
+        Tree t = addChild(root.getTree(PathUtils.ROOT_PATH), "test", 
NodeTypeConstants.NT_OAK_UNSTRUCTURED);
+        addChild(t, "subtree", NodeTypeConstants.NT_OAK_UNSTRUCTURED);
+        addChild(t, "accessControlled", NodeTypeConstants.NT_OAK_UNSTRUCTURED);
+
+        grant(ACCESS_CONTROLLED_PATH, EveryonePrincipal.getInstance(), 
JCR_READ, JCR_WRITE);
+        root.commit();
+
+        testSession = createTestSession();
+    }
+
+    @Override
+    public void after() throws Exception {
+        try {
+            testSession.close();
+            AccessControlManager acMgr = getAccessControlManager(root);
+            for (String path : accessControlledPaths) {
+                if (root.getTree(path).exists()) {
+                    AccessControlList acl = 
AccessControlUtils.getAccessControlList(acMgr, path);
+                    if (acl != null) {
+                        acMgr.removePolicy(path, acl);
+                    }
+                }
+            }
+            root.getTree(TEST_PATH).remove();
+            root.commit();
+        } finally {
+            super.after();
+        }
+    }
+
+    @NotNull
+    private CompiledPermissionImpl create(@NotNull ConfigurationParameters 
options, @NotNull Set<Principal> principals, @Nullable PermissionStore store) {
+        AuthorizationConfiguration config = 
getConfig(AuthorizationConfiguration.class);
+        assertTrue(config instanceof CompositeAuthorizationConfiguration);
+
+        AuthorizationConfiguration defConfig = 
((CompositeAuthorizationConfiguration) config).getDefaultConfig();
+        assertTrue(defConfig instanceof AuthorizationConfigurationImpl);
+
+        Root r = 
getRootProvider().createReadOnlyRoot(testSession.getLatestRoot());
+        String workspaceName = testSession.getWorkspaceName();
+        PermissionStore pStore = (store == null) ? new PermissionStoreImpl(r, 
workspaceName, config.getRestrictionProvider()) : store;
+
+        CompiledPermissions cp = CompiledPermissionImpl.create(r, 
workspaceName, pStore, principals, options, config.getContext(), 
(AuthorizationConfigurationImpl) defConfig);
+        assertTrue(cp instanceof CompiledPermissionImpl);
+
+        return (CompiledPermissionImpl) cp;
+    }
+
+    @NotNull
+    private CompiledPermissionImpl createForTestSession(@NotNull 
ConfigurationParameters options) {
+        return create(options, testSession.getAuthInfo().getPrincipals(), 
null);
+    }
+
+    @NotNull
+    private Tree createReadonlyTree(@NotNull String path) {
+        return getRootProvider().createReadOnlyRoot(root).getTree(path);
+    }
+
+    @NotNull
+    private TreePermission createTreePermission(@NotNull 
CompiledPermissionImpl cp, @NotNull String path) {
+        Tree t = createReadonlyTree(PathUtils.ROOT_PATH);
+        TreePermission tp = cp.getTreePermission(t, TreePermission.EMPTY);
+        for (String elem : PathUtils.elements(path)) {
+            Tree child = t.getChild(elem);
+            tp = cp.getTreePermission(child, tp);
+            t = child;
+        }
+        return tp;
+    }
+
+    private void grant(@Nullable String path, @NotNull Principal principal, 
@NotNull String... privNames) throws Exception {
+        AccessControlManager acMgr = getAccessControlManager(root);
+        JackrabbitAccessControlList acl = 
AccessControlUtils.getAccessControlList(acMgr, path);
+        acl.addAccessControlEntry(principal, privilegesFromNames(privNames));
+        acMgr.setPolicy(acl.getPath(), acl);
+        accessControlledPaths.add(path);
+    }
+
+    @NotNull
+    private Tree createVersions(@NotNull String path) throws Exception {
+        Tree tree = root.getTree(path);
+        TreeUtil.addMixin(tree, MIX_VERSIONABLE, 
root.getTree(NodeTypeConstants.NODE_TYPES_PATH), "uid");
+        root.commit();
+        for (int i = 0; i < 3; i++) {
+            tree.setProperty(PropertyStates.createProperty(JCR_ISCHECKEDOUT, 
false));
+            root.commit();
+            tree.setProperty(PropertyStates.createProperty(JCR_ISCHECKEDOUT, 
true));
+            root.commit();
+        }
+
+        ReadOnlyVersionManager vm = ReadOnlyVersionManager.getInstance(root, 
getNamePathMapper());
+        return checkNotNull(vm.getVersionHistory(tree));
+    }
+
+    @Test
+    public void testCreateFromEmptyPrincipals() {
+        Set<Principal> principals = ImmutableSet.of();
+        assertSame(NoPermissions.getInstance(), 
CompiledPermissionImpl.create(root, "wspName", mock(PermissionStore.class), 
principals, ConfigurationParameters.EMPTY, mock(Context.class), 
mock(ProviderCtx.class)));
+    }
+
+    @Test
+    public void testCreateNonExistingPermissionStore() {
+        Tree t = when(mock(Tree.class).exists()).thenReturn(false).getMock();
+        Root r = 
when(mock(Root.class).getTree(anyString())).thenReturn(t).getMock();
+        Set<Principal> principals = ImmutableSet.of(new 
PrincipalImpl("principalName"));
+
+        assertSame(NoPermissions.getInstance(), 
CompiledPermissionImpl.create(r, "wspName", mock(PermissionStore.class), 
principals, ConfigurationParameters.EMPTY, mock(Context.class), 
mock(ProviderCtx.class)));
+    }
+
+    @Test
+    public void testEmpyReadPaths() {
+        CompiledPermissionImpl cp = 
createForTestSession(ConfigurationParameters.of(PARAM_READ_PATHS, 
ImmutableSet.of()));
+        // cp with EmptyReadPolicy
+        for (String readPath : PermissionConstants.DEFAULT_READ_PATHS) {
+            assertFalse(cp.isGranted(readPath, Permissions.READ_NODE));
+            assertFalse(cp.isGranted(readPath, Permissions.READ));
+
+            Tree t = createReadonlyTree(readPath);
+            assertFalse(cp.isGranted(t, null, Permissions.READ_NODE));
+            assertFalse(cp.isGranted(t, t.getProperty(JCR_PRIMARYTYPE), 
Permissions.READ_PROPERTY));
+
+            assertFalse(cp.hasPrivileges(t, 
PrivilegeConstants.REP_READ_NODES));
+            assertFalse(cp.hasPrivileges(t, JCR_READ));
+
+            assertEquals(0, cp.getPrivileges(t).size());
+
+            TreePermission tp = createTreePermission(cp, readPath);
+            assertFalse(tp.canRead());
+            assertFalse(tp.canRead(mock(PropertyState.class)));
+            assertFalse(tp.canReadAll());
+        }
+    }
+
+    @Test
+    public void testDefaultReadPath() {
+        // cp with DefaultReadPolicy
+        CompiledPermissionImpl cp = 
createForTestSession(ConfigurationParameters.EMPTY);
+        for (String readPath : PermissionConstants.DEFAULT_READ_PATHS) {
+            assertTrue(cp.isGranted(readPath, Permissions.READ_NODE));
+
+            Tree t = createReadonlyTree(readPath);
+            assertTrue(cp.isGranted(t, null, Permissions.READ_NODE));
+            assertTrue(cp.isGranted(t, t.getProperty(JCR_PRIMARYTYPE), 
Permissions.READ_PROPERTY));
+
+            assertTrue(cp.hasPrivileges(t, PrivilegeConstants.REP_READ_NODES));
+            assertTrue(cp.hasPrivileges(t, JCR_READ));
+
+            assertEquals(ImmutableSet.of(JCR_READ), cp.getPrivileges(t));
+
+            TreePermission tp = createTreePermission(cp, readPath);
+            assertTrue(tp.canRead());
+            assertTrue(tp.canRead(mock(PropertyState.class)));
+            assertFalse(tp.canReadAll());
+        }
+    }
+
+    @Test
+    public void testNonDefaultReadPath() {
+        // cp with DefaultReadPolicy but not default paths
+        CompiledPermissionImpl cp = 
createForTestSession(ConfigurationParameters.of(PARAM_READ_PATHS, 
ImmutableSet.of(TEST_PATH, "/another", "/yet/another")));
+
+        for (String readPath : new String[]{TEST_PATH, SUBTREE_PATH, TEST_PATH 
+ "/nonExisting"}) {
+            assertTrue(cp.isGranted(readPath, Permissions.READ_NODE));
+
+            Tree t = createReadonlyTree(readPath);
+            assertTrue(cp.isGranted(t, null, Permissions.READ_NODE));
+            assertTrue(cp.isGranted(t, t.getProperty(JCR_PRIMARYTYPE), 
Permissions.READ_PROPERTY));
+
+            assertTrue(cp.hasPrivileges(t, PrivilegeConstants.REP_READ_NODES));
+            assertTrue(cp.hasPrivileges(t, JCR_READ));
+
+            assertEquals(ImmutableSet.of(JCR_READ), cp.getPrivileges(t));
+
+            TreePermission tp = createTreePermission(cp, readPath);
+            assertTrue(tp.canRead());
+            assertTrue(tp.canRead(mock(PropertyState.class)));
+            assertFalse(tp.canReadAll());
+        }
+    }
+
+    @Test
+    public void testHidden() {
+        CompiledPermissionImpl cp = 
createForTestSession(ConfigurationParameters.of(PARAM_READ_PATHS, 
ImmutableSet.of()));
+
+        String hiddenPath = "/oak:index/acPrincipalName/:index";
+        Tree hiddenTree = createReadonlyTree(hiddenPath);
+        assertTrue(hiddenTree.exists());
+
+        assertTrue(cp.isGranted(hiddenTree, null, Permissions.ALL));
+        // isGranted(String, long) serves as fallback for non-existing items
+        // -> just regular permission eval without tree-type handling
+        assertFalse(cp.isGranted(hiddenPath, Permissions.ALL));
+        assertTrue(cp.getPrivileges(hiddenTree).isEmpty());
+
+        TreePermission tp = createTreePermission(cp, hiddenPath);
+        assertSame(ALL, tp);
+    }
+
+    @Test
+    public void testInternal() throws Exception {
+        // grant read permissions at root path
+        grant(PathUtils.ROOT_PATH, EveryonePrincipal.getInstance(), JCR_READ);
+        root.commit();
+
+        CompiledPermissionImpl cp = 
createForTestSession(ConfigurationParameters.EMPTY);
+
+        // FIXME: wrong TreePermission for child of internal path -> not EMPTY
+//        String[] internalPaths = new String[] {
+//                PERMISSIONS_STORE_PATH,
+//                PathUtils.concat(PERMISSIONS_STORE_PATH, 
testSession.getWorkspaceName())
+//        };
+        String[] internalPaths = new String[]{
+                PERMISSIONS_STORE_PATH
+        };
+        for (String internalPath : internalPaths) {
+            Tree internalTree = createReadonlyTree(internalPath);
+            assertTrue(internalTree.exists());
+
+            assertFalse(cp.isGranted(internalTree, null, 
Permissions.READ_NODE));
+            // isGranted(String, long) serves as fallback for non-existing 
items
+            // -> just regular permission eval without tree-type handling
+            assertTrue(cp.isGranted(internalPath, Permissions.READ_NODE));
+            assertTrue(cp.getPrivileges(internalTree).isEmpty());
+
+            TreePermission tp = createTreePermission(cp, internalPath);
+            assertSame(TreePermission.EMPTY, tp);
+        }
+    }
+
+    @Test
+    public void testVersionHistory() throws Exception {
+        Tree versionHistory = createVersions(SUBTREE_PATH);
+
+        // subtree path is made readable through PARAM_READ_PATHS
+        CompiledPermissionImpl cp = 
createForTestSession(ConfigurationParameters.of(PARAM_READ_PATHS, 
ImmutableSet.of(TEST_PATH)));
+
+        assertTrue(cp.isGranted(versionHistory, null, Permissions.READ));
+        // isGranted(String, long) serves as fallback when no versionable node 
available
+        // -> just regular permission eval based on path, no tree-type taken 
into account
+        assertFalse(cp.isGranted(versionHistory.getPath(), Permissions.READ));
+        assertEquals(ImmutableSet.of(JCR_READ), 
cp.getPrivileges(versionHistory));
+        assertTrue(cp.hasPrivileges(versionHistory, JCR_READ));
+
+        TreePermission tp = createTreePermission(cp, versionHistory.getPath());
+        assertTrue(tp instanceof VersionTreePermission);
+    }
+
+    @Test
+    public void testVersion() throws Exception {
+        Tree version = createVersions(SUBTREE_PATH).getChild("1.2");
+        assertEquals(NT_VERSION, TreeUtil.getPrimaryTypeName(version));
+
+        // subtree path is made readable through PARAM_READ_PATHS
+        CompiledPermissionImpl cp = 
createForTestSession(ConfigurationParameters.of(PARAM_READ_PATHS, 
ImmutableSet.of(TEST_PATH)));
+
+        assertTrue(cp.isGranted(version, null, Permissions.READ));
+        // isGranted(String, long) serves as fallback when no versionable node 
available
+        // -> just regular permission eval based on path, no tree-type taken 
into account
+        assertFalse(cp.isGranted(version.getPath(), Permissions.READ));
+        assertEquals(ImmutableSet.of(JCR_READ), cp.getPrivileges(version));
+        assertTrue(cp.hasPrivileges(version, JCR_READ));
+
+        TreePermission tp = createTreePermission(cp, version.getPath());
+        assertTrue(tp instanceof VersionTreePermission);
+    }
+
+    @Test
+    public void testFrozenNode() throws Exception {
+        Tree version = 
createVersions(TEST_PATH).getChildren().iterator().next();
+        Tree frozenNode = version.getChild(JCR_FROZENNODE);
+
+        // default read-paths -> only accessControlled tree readable
+        CompiledPermissionImpl cp = 
createForTestSession(ConfigurationParameters.EMPTY);
+
+        for (Tree tree : new Tree[]{
+                frozenNode,
+                frozenNode.getChild("subtree"),
+                frozenNode.getChild("nonExistingChild")}) {
+
+            String path = tree.getPath();
+            assertFalse(path, cp.isGranted(tree, null, Permissions.READ));
+            assertFalse(path, cp.isGranted(path, Permissions.READ));
+            assertTrue(path, cp.getPrivileges(tree).isEmpty());
+            assertFalse(path, cp.hasPrivileges(tree, JCR_READ));
+
+            TreePermission tp = createTreePermission(cp, path);
+            assertTrue(tp instanceof VersionTreePermission);
+        }
+    }
+
+    @Test
+    public void testAccessControlledChildInFrozenNode() throws Exception {
+        Tree version = createVersions(TEST_PATH).getChild("1.2");
+        Tree frozenNode = version.getChild(JCR_FROZENNODE);
+        Tree copiedAccessControlledChild = 
frozenNode.getChild("accessControlled");
+
+        // default read-paths -> only accessControlled tree readable
+        CompiledPermissionImpl cp = 
createForTestSession(ConfigurationParameters.EMPTY);
+
+        assertTrue(cp.isGranted(copiedAccessControlledChild, null, 
Permissions.READ | Permissions.SET_PROPERTY));
+        // isGranted(String, long) serves as fallback when no versionable node 
available
+        // -> just regular permission eval based on path, no tree-type taken 
into account
+        assertFalse(cp.isGranted(copiedAccessControlledChild.getPath(), 
Permissions.READ));
+        assertEquals(ImmutableSet.of(JCR_READ, JCR_WRITE), 
cp.getPrivileges(copiedAccessControlledChild));
+        assertTrue(cp.hasPrivileges(copiedAccessControlledChild, JCR_READ, 
JCR_WRITE));
+
+        TreePermission tp = createTreePermission(cp, version.getPath());
+        assertTrue(tp instanceof VersionTreePermission);
+    }
+
+    @Test
+    public void testVersionStoreTree() throws Exception {
+        Tree versionStoreTree = createVersions(SUBTREE_PATH).getParent();
+
+        // subtree path is made readable through PARAM_READ_PATHS
+        CompiledPermissionImpl cp = 
createForTestSession(ConfigurationParameters.of(PARAM_READ_PATHS, 
ImmutableSet.of(TEST_PATH)));
+
+        // but: permissions for version store tree is evaluated based on 
regular permissions
+        // and not tied to a versionable tree
+        assertFalse(cp.isGranted(versionStoreTree, null, Permissions.READ));
+        // isGranted(String, long) serves as fallback when no versionable node 
available
+        // -> just regular permission eval based on path, no tree-type taken 
into account
+        assertFalse(cp.isGranted(versionStoreTree.getPath(), 
Permissions.READ));
+        assertTrue(cp.getPrivileges(versionStoreTree).isEmpty());
+        assertFalse(cp.hasPrivileges(versionStoreTree, JCR_READ));
+
+        TreePermission tp = createTreePermission(cp, 
versionStoreTree.getPath());
+        assertFalse(tp instanceof VersionTreePermission);
+    }
+
+    @Test
+    public void testVersionableTreeRemoved() throws Exception {
+        Tree version = createVersions(ACCESS_CONTROLLED_PATH).getChild("1.2");
+        assertEquals(NT_VERSION, TreeUtil.getPrimaryTypeName(version));
+
+        Tree accessControlled = root.getTree(ACCESS_CONTROLLED_PATH);
+        PropertyState property = accessControlled.getProperty(JCR_PRIMARYTYPE);
+        accessControlled.remove();
+        root.commit();
+
+        CompiledPermissionImpl cp = 
createForTestSession(ConfigurationParameters.EMPTY);
+
+        assertFalse(cp.isGranted(version, null, Permissions.READ));
+        assertFalse(cp.isGranted(version, property, Permissions.READ));
+        // isGranted(String, long) serves as fallback when no versionable node 
available
+        // -> just regular permission eval based on path, no tree-type taken 
into account
+        assertFalse(cp.isGranted(version.getPath(), Permissions.READ));
+        assertTrue(cp.getPrivileges(version).isEmpty());
+        assertFalse(cp.hasPrivileges(version, JCR_READ));
+
+        TreePermission tp = createTreePermission(cp, version.getPath());
+        assertTrue(tp instanceof VersionTreePermission);
+    }
+
+    @Test
+    public void testMissingGroupStore() throws Exception {
+        grant(ACCESS_CONTROLLED_PATH, getTestUser().getPrincipal(), 
JCR_VERSION_MANAGEMENT);
+        root.commit();
+
+        Root readOnlyRoot = 
getRootProvider().createReadOnlyRoot(testSession.getLatestRoot());
+        String wspName = testSession.getWorkspaceName();
+
+        // create cp for user principal only (no group principals that hold 
the permission setup)
+        PermissionStore store = spy(new PermissionStoreImpl(readOnlyRoot, 
wspName, getConfig(AuthorizationConfiguration.class).getRestrictionProvider()));
+        CompiledPermissionImpl cp = create(ConfigurationParameters.EMPTY, 
ImmutableSet.of(getTestUser().getPrincipal()), store);
+
+        verify(store, times(1)).getNumEntries(anyString(), anyLong());
+
+        cp.refresh(readOnlyRoot, wspName);
+
+        verify(store, times(2)).getNumEntries(anyString(), anyLong());
+
+        assertFalse(cp.isGranted(ACCESS_CONTROLLED_PATH, SET_PROPERTY));
+        assertTrue(cp.isGranted(ACCESS_CONTROLLED_PATH, VERSION_MANAGEMENT));
+        Tree t = createReadonlyTree(ACCESS_CONTROLLED_PATH);
+        assertFalse(cp.hasPrivileges(t, JCR_WRITE));
+        assertTrue(cp.hasPrivileges(t, JCR_VERSION_MANAGEMENT));
+        assertEquals(ImmutableSet.of(JCR_VERSION_MANAGEMENT), 
cp.getPrivileges(createReadonlyTree(ACCESS_CONTROLLED_PATH)));
+
+        TreePermission tp = createTreePermission(cp, ACCESS_CONTROLLED_PATH);
+        assertTrue(tp.isGranted(VERSION_MANAGEMENT));
+        assertFalse(tp.canRead());
+        assertFalse(tp.canRead(mock(PropertyState.class)));
+        assertFalse(tp.canReadAll());
+
+        verify(store, times(2)).getNumEntries(anyString(), anyLong());
+        verify(store, times(2)).load(anyString());
+        verify(store, never()).load(anyString(), anyString());
+    }
+
+    @Test
+    public void testMissingUserStore() throws Exception {
+        Root readOnlyRoot = 
getRootProvider().createReadOnlyRoot(testSession.getLatestRoot());
+        String wspName = testSession.getWorkspaceName();
+
+        // create cp for group principal only (no user principal)
+        PermissionStore store = spy(new PermissionStoreImpl(readOnlyRoot, 
wspName, getConfig(AuthorizationConfiguration.class).getRestrictionProvider()));
+        CompiledPermissionImpl cp = create(ConfigurationParameters.EMPTY, 
ImmutableSet.of(EveryonePrincipal.getInstance()), store);
+
+        verify(store, times(1)).getNumEntries(anyString(), anyLong());
+
+        cp.refresh(readOnlyRoot, wspName);
+
+        verify(store, times(2)).getNumEntries(anyString(), anyLong());
+
+        assertTrue(cp.isGranted(ACCESS_CONTROLLED_PATH, SET_PROPERTY));
+        
assertTrue(cp.hasPrivileges(createReadonlyTree(ACCESS_CONTROLLED_PATH), 
JCR_WRITE));
+        assertEquals(ImmutableSet.of(JCR_READ, JCR_WRITE), 
cp.getPrivileges(createReadonlyTree(ACCESS_CONTROLLED_PATH)));
+
+        TreePermission tp = createTreePermission(cp, ACCESS_CONTROLLED_PATH);
+        assertTrue(tp.isGranted(SET_PROPERTY));
+        assertTrue(tp.canRead());
+        assertTrue(tp.canRead(mock(PropertyState.class)));
+        assertFalse(tp.canReadAll());
+
+        verify(store, times(2)).load(anyString());
+        verify(store, never()).load(anyString(), anyString());
+    }
+}
\ No newline at end of file

Propchange: 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/permission/CompiledPermissionImplTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/permission/EntryPredicateTest.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/permission/EntryPredicateTest.java?rev=1857999&view=auto
==============================================================================
--- 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/permission/EntryPredicateTest.java
 (added)
+++ 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/permission/EntryPredicateTest.java
 Tue Apr 23 09:34:55 2019
@@ -0,0 +1,369 @@
+/*
+ * 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.security.authorization.permission;
+
+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.spi.security.authorization.restriction.RestrictionPattern;
+import org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeBits;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+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.spy;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+public class EntryPredicateTest {
+
+    private String path = "/some/path";
+    private String parentPath = PathUtils.getParentPath(path);
+
+    private RestrictionPattern pattern = mock(RestrictionPattern.class);
+    private PermissionEntry entry = new PermissionEntry(path, true, 1, 
PrivilegeBits.EMPTY, pattern);
+
+    private Tree mockTree(@NotNull String path, @Nullable Tree parent) {
+        Tree t = mock(Tree.class);
+        if (parent != null) {
+            when(t.getParent()).thenReturn(parent);
+        }
+        when(t.getPath()).thenReturn(path);
+        return t;
+    }
+
+    @Test
+    public void testPredicateRepositoryLevel() {
+        EntryPredicate pred = new EntryPredicate();
+        assertNull(pred.getPath());
+
+        when(pattern.matches()).thenReturn(true);
+
+        assertFalse(pred.apply(null));
+        assertFalse(pred.apply(null, true));
+        assertFalse(pred.apply(null, false));
+
+        assertTrue(pred.apply(entry));
+        assertTrue(pred.apply(entry, true));
+        assertTrue(pred.apply(entry, false));
+
+        verify(pattern, times(3)).matches();
+    }
+
+    @Test
+    public void testPredicatePathRespectParent() {
+        EntryPredicate pred = new EntryPredicate(path, true);
+        assertEquals(path, pred.getPath());
+
+        // pattern neither matches path nor parent path
+        when(pattern.matches(path)).thenReturn(false);
+        when(pattern.matches(parentPath)).thenReturn(false);
+
+        assertFalse(pred.apply(entry));
+        assertFalse(pred.apply(entry, true));
+        assertFalse(pred.apply(entry, false));
+
+        // pattern matches path and parent path
+        when(pattern.matches(path)).thenReturn(true);
+        when(pattern.matches(parentPath)).thenReturn(true);
+
+        assertFalse(pred.apply(null));
+        assertFalse(pred.apply(null, true));
+        assertFalse(pred.apply(null, false));
+
+        assertTrue(pred.apply(entry));
+        assertTrue(pred.apply(entry, true));
+        assertTrue(pred.apply(entry, false));
+
+        // pattern only matches path
+        when(pattern.matches(path)).thenReturn(true);
+        when(pattern.matches(parentPath)).thenReturn(false);
+
+        assertTrue(pred.apply(entry));
+        assertTrue(pred.apply(entry, true));
+        assertTrue(pred.apply(entry, false));
+
+        // pattern only matches parent path
+        when(pattern.matches(path)).thenReturn(false);
+        when(pattern.matches(parentPath)).thenReturn(true);
+
+        assertTrue(pred.apply(entry));
+        assertTrue(pred.apply(entry, true));
+        assertFalse(pred.apply(entry, false));
+
+        verify(pattern, times(12)).matches(path);
+        verify(pattern, times(4)).matches(parentPath);
+    }
+
+    @Test
+    public void testPredicatePathDontRespectParent() {
+        EntryPredicate pred = new EntryPredicate(path, false);
+        assertEquals(path, pred.getPath());
+
+        // pattern neither matches path nor parent path
+        when(pattern.matches(path)).thenReturn(false);
+        when(pattern.matches(parentPath)).thenReturn(false);
+
+        assertFalse(pred.apply(entry));
+        assertFalse(pred.apply(entry, true));
+        assertFalse(pred.apply(entry, false));
+
+        // pattern matches path and parent path
+        when(pattern.matches(path)).thenReturn(true);
+        when(pattern.matches(parentPath)).thenReturn(true);
+
+        assertFalse(pred.apply(null));
+        assertFalse(pred.apply(null, true));
+        assertFalse(pred.apply(null, false));
+
+        assertTrue(pred.apply(entry));
+        assertTrue(pred.apply(entry, true));
+        assertTrue(pred.apply(entry, false));
+
+        // pattern only matches path
+        when(pattern.matches(path)).thenReturn(true);
+        when(pattern.matches(parentPath)).thenReturn(false);
+
+        assertTrue(pred.apply(entry));
+        assertTrue(pred.apply(entry, true));
+        assertTrue(pred.apply(entry, false));
+
+        // pattern only matches parent path
+        when(pattern.matches(path)).thenReturn(false);
+        when(pattern.matches(parentPath)).thenReturn(true);
+
+        assertFalse(pred.apply(entry));
+        assertFalse(pred.apply(entry, true));
+        assertFalse(pred.apply(entry, false));
+
+        verify(pattern, times(12)).matches(path);
+        verify(pattern, never()).matches(parentPath);
+    }
+
+    @Test
+    public void testPredicateTreeRespectParent() {
+        Tree parent = mockTree(parentPath, null);
+        Tree tree = mockTree(path, parent);
+        PropertyState ps = mock(PropertyState.class);
+        when(ps.getName()).thenReturn("property");
+
+        EntryPredicate pred = new EntryPredicate(tree, ps, true);
+        assertEquals(path, pred.getPath());
+
+        // pattern neither matches path nor parent path
+        when(pattern.matches(tree, ps)).thenReturn(false);
+        when(pattern.matches(parent, ps)).thenReturn(false);
+        when(pattern.matches(parent, null)).thenReturn(false);
+
+        assertFalse(pred.apply(entry));
+        assertFalse(pred.apply(entry, true));
+        assertFalse(pred.apply(entry, false));
+
+        // pattern matches path and parent path
+        when(pattern.matches(tree, ps)).thenReturn(true);
+        when(pattern.matches(parent, ps)).thenReturn(true);
+        when(pattern.matches(parent, null)).thenReturn(true);
+
+        assertFalse(pred.apply(null));
+        assertFalse(pred.apply(null, true));
+        assertFalse(pred.apply(null, false));
+
+        assertTrue(pred.apply(entry));
+        assertTrue(pred.apply(entry, true));
+        assertTrue(pred.apply(entry, false));
+
+        // pattern only matches path
+        when(pattern.matches(tree, ps)).thenReturn(true);
+        when(pattern.matches(parent, ps)).thenReturn(false);
+        when(pattern.matches(parent, null)).thenReturn(false);
+
+        assertTrue(pred.apply(entry));
+        assertTrue(pred.apply(entry, true));
+        assertTrue(pred.apply(entry, false));
+
+        // pattern only matches parent path
+        when(pattern.matches(tree, ps)).thenReturn(false);
+        when(pattern.matches(parent, ps)).thenReturn(true);
+        when(pattern.matches(parent, null)).thenReturn(true);
+
+        assertTrue(pred.apply(entry));
+        assertTrue(pred.apply(entry, true));
+        assertFalse(pred.apply(entry, false));
+
+        verify(pattern, times(12)).matches(tree, ps);
+        verify(pattern, times(4)).matches(parent, null);
+        verify(pattern, never()).matches(parent, ps);
+    }
+
+    @Test
+    public void testPredicateTreeDontRespectParent() {
+        Tree parent = mockTree(parentPath, null);
+        Tree tree = mockTree(path, parent);
+        PropertyState ps = mock(PropertyState.class);
+        when(ps.getName()).thenReturn("property");
+
+        EntryPredicate pred = new EntryPredicate(tree, ps,false);
+        assertEquals(path, pred.getPath());
+
+        // pattern neither matches path nor parent path
+        when(pattern.matches(tree, ps)).thenReturn(false);
+        when(pattern.matches(parent, ps)).thenReturn(false);
+        when(pattern.matches(parent, null)).thenReturn(false);
+
+        assertFalse(pred.apply(entry));
+        assertFalse(pred.apply(entry, true));
+        assertFalse(pred.apply(entry, false));
+
+        // pattern matches path and parent path
+        when(pattern.matches(tree, ps)).thenReturn(true);
+        when(pattern.matches(parent, ps)).thenReturn(true);
+        when(pattern.matches(parent, null)).thenReturn(true);
+
+        assertFalse(pred.apply(null));
+        assertFalse(pred.apply(null, true));
+        assertFalse(pred.apply(null, false));
+
+        assertTrue(pred.apply(entry));
+        assertTrue(pred.apply(entry, true));
+        assertTrue(pred.apply(entry, false));
+
+        // pattern only matches path
+        when(pattern.matches(tree, ps)).thenReturn(true);
+        when(pattern.matches(parent, ps)).thenReturn(false);
+        when(pattern.matches(parent, null)).thenReturn(false);
+
+        assertTrue(pred.apply(entry));
+        assertTrue(pred.apply(entry, true));
+        assertTrue(pred.apply(entry, false));
+
+        // pattern only matches parent path
+        when(pattern.matches(tree, ps)).thenReturn(false);
+        when(pattern.matches(parent, ps)).thenReturn(true);
+        when(pattern.matches(parent, null)).thenReturn(true);
+
+        assertFalse(pred.apply(entry));
+        assertFalse(pred.apply(entry, true));
+        assertFalse(pred.apply(entry, false));
+
+        verify(pattern, times(12)).matches(tree, ps);
+        verify(pattern, never()).matches(parent, ps);
+        verify(pattern, never()).matches(parent, null);
+    }
+
+    @Test
+    public void testPredicateRootPath() {
+        EntryPredicate pred = new EntryPredicate(PathUtils.ROOT_PATH, true);
+        assertEquals(PathUtils.ROOT_PATH, pred.getPath());
+
+        // pattern doesn't match path
+        when(pattern.matches(PathUtils.ROOT_PATH)).thenReturn(false);
+
+        assertFalse(pred.apply(entry));
+        assertFalse(pred.apply(entry, true));
+        assertFalse(pred.apply(entry, false));
+
+        // pattern matches path
+        when(pattern.matches(PathUtils.ROOT_PATH)).thenReturn(true);
+
+        assertTrue(pred.apply(entry));
+        assertTrue(pred.apply(entry, true));
+        assertTrue(pred.apply(entry, false));
+
+        verify(pattern, times(6)).matches(PathUtils.ROOT_PATH);
+    }
+
+    @Test
+    public void testPredicateRootPathDontRespectParent() {
+        EntryPredicate pred = new EntryPredicate(PathUtils.ROOT_PATH, false);
+        assertEquals(PathUtils.ROOT_PATH, pred.getPath());
+
+        // pattern doesn't match path
+        when(pattern.matches(PathUtils.ROOT_PATH)).thenReturn(false);
+
+        assertFalse(pred.apply(entry));
+        assertFalse(pred.apply(entry, true));
+        assertFalse(pred.apply(entry, false));
+
+        // pattern matches path
+        when(pattern.matches(PathUtils.ROOT_PATH)).thenReturn(true);
+
+        assertTrue(pred.apply(entry));
+        assertTrue(pred.apply(entry, true));
+        assertTrue(pred.apply(entry, false));
+
+        verify(pattern, times(6)).matches(PathUtils.ROOT_PATH);
+    }
+
+    @Test
+    public void testPredicateRootTree() {
+        Tree tree = mockTree(PathUtils.ROOT_PATH, null);
+        when(tree.isRoot()).thenReturn(true);
+
+        EntryPredicate pred = new EntryPredicate(tree, null,true);
+        assertEquals(PathUtils.ROOT_PATH, pred.getPath());
+
+        // pattern doesn't match path
+        when(pattern.matches(tree, null)).thenReturn(false);
+
+        assertFalse(pred.apply(entry));
+        assertFalse(pred.apply(entry, true));
+        assertFalse(pred.apply(entry, false));
+
+        // pattern matches path
+        when(pattern.matches(tree, null)).thenReturn(true);
+
+        assertTrue(pred.apply(entry));
+        assertTrue(pred.apply(entry, true));
+        assertTrue(pred.apply(entry, false));
+
+        verify(tree, never()).getParent();
+        verify(pattern, times(6)).matches(tree, null);
+    }
+
+    @Test
+    public void testPredicateRootTreeDontRespectParent() {
+        Tree tree = mockTree(PathUtils.ROOT_PATH, null);
+        when(tree.isRoot()).thenReturn(true);
+
+        EntryPredicate pred = new EntryPredicate(tree, null,false);
+        assertEquals(PathUtils.ROOT_PATH, pred.getPath());
+
+        // pattern doesn't match path
+        when(pattern.matches(tree, null)).thenReturn(false);
+
+        assertFalse(pred.apply(entry));
+        assertFalse(pred.apply(entry, true));
+        assertFalse(pred.apply(entry, false));
+
+        // pattern matches path
+        when(pattern.matches(tree, null)).thenReturn(true);
+
+        assertTrue(pred.apply(entry));
+        assertTrue(pred.apply(entry, true));
+        assertTrue(pred.apply(entry, false));
+
+        verify(tree, never()).getParent();
+        verify(pattern, times(6)).matches(tree, null);
+    }
+}
\ No newline at end of file

Propchange: 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/permission/EntryPredicateTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/permission/PermissionCacheBuilderTest.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/permission/PermissionCacheBuilderTest.java?rev=1857999&r1=1857998&r2=1857999&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/permission/PermissionCacheBuilderTest.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/permission/PermissionCacheBuilderTest.java
 Tue Apr 23 09:34:55 2019
@@ -16,25 +16,35 @@
  */
 package org.apache.jackrabbit.oak.security.authorization.permission;
 
-import java.util.Set;
-
 import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Sets;
+import org.apache.jackrabbit.oak.api.Tree;
+import org.apache.jackrabbit.oak.commons.PathUtils;
 import 
org.apache.jackrabbit.oak.spi.security.authorization.restriction.RestrictionPattern;
 import org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeBits;
+import org.jetbrains.annotations.NotNull;
 import org.junit.Before;
 import org.junit.Test;
-import org.mockito.Mockito;
 
+import java.util.Set;
+
+import static 
org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants.JCR_MODIFY_ACCESS_CONTROL;
+import static 
org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants.REP_READ_NODES;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 import static org.mockito.Matchers.anyLong;
 import static org.mockito.Matchers.anyString;
+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 PermissionCacheBuilderTest {
 
+    private static final int MAX_PATH_SIZE = 10;
+
     private static final String EMPTY_CLASS_NAME = 
"org.apache.jackrabbit.oak.security.authorization.permission.PermissionCacheBuilder$EmptyCache";
     private static final String SIMPLE_CLASS_NAME = 
"org.apache.jackrabbit.oak.security.authorization.permission.PermissionCacheBuilder$PathEntryMapCache";
     private static final String DEFAULT_CLASS_NAME = 
"org.apache.jackrabbit.oak.security.authorization.permission.PermissionCacheBuilder$DefaultPermissionCache";
@@ -44,10 +54,17 @@ public class PermissionCacheBuilderTest
 
     @Before
     public void before() {
-        store = Mockito.mock(PermissionStore.class);
+        store = mock(PermissionStore.class);
         permissionCacheBuilder = new PermissionCacheBuilder(store);
     }
 
+    @NotNull
+    private static PrincipalPermissionEntries 
generatedPermissionEntries(@NotNull String path, boolean isAllow, int index, 
@NotNull String privilegeName) {
+        PrincipalPermissionEntries ppe = new PrincipalPermissionEntries(1);
+        ppe.putEntriesByPath(path, ImmutableSet.of(new PermissionEntry(path, 
isAllow, index, PrivilegeBits.BUILT_IN.get(privilegeName), 
RestrictionPattern.EMPTY)));
+        return ppe;
+    }
+
     @Test(expected = IllegalStateException.class)
     public void testBuildBeforeInitialized() {
         permissionCacheBuilder.build();
@@ -56,30 +73,38 @@ public class PermissionCacheBuilderTest
     @Test
     public void testBuildForEmptyPrincipals() {
         assertTrue(permissionCacheBuilder.init(ImmutableSet.of(), 
Long.MAX_VALUE));
-        permissionCacheBuilder.init(ImmutableSet.of(), Long.MAX_VALUE);
         PermissionCache cache = permissionCacheBuilder.build();
         assertEquals(EMPTY_CLASS_NAME, cache.getClass().getName());
+
+        verify(store, never()).getNumEntries(anyString(), anyLong());
+        verify(store, never()).load(anyString());
+        verify(store, never()).load(anyString(), anyString());
     }
 
     @Test
-    public void testBuildNoExistingEntries() throws Exception {
+    public void testBuildNoExistingEntries() {
         when(store.getNumEntries(anyString(), 
anyLong())).thenReturn(NumEntries.ZERO);
         when(store.load(anyString())).thenReturn(new 
PrincipalPermissionEntries(0));
 
         Set<String> principalNames = Sets.newHashSet("noEntries", 
"noEntries2", "noEntries3");
 
         assertTrue(permissionCacheBuilder.init(principalNames, 
Long.MAX_VALUE));
+
         PermissionCache cache = permissionCacheBuilder.build();
         assertEquals(EMPTY_CLASS_NAME, cache.getClass().getName());
+
+        assertTrue(cache.getEntries(PathUtils.ROOT_PATH).isEmpty());
+        assertTrue(cache.getEntries(mock(Tree.class)).isEmpty());
+
+        verify(store, times(3)).getNumEntries(anyString(), anyLong());
+        verify(store, never()).load(anyString());
+        verify(store, never()).load(anyString(), anyString());
     }
 
     @Test
-    public void testBuildFewEntriesSamePath() throws Exception {
-        PrincipalPermissionEntries ppeA = new PrincipalPermissionEntries(1);
-        ppeA.putEntriesByPath("/path", ImmutableSet.of(new 
PermissionEntry("/path", false, 0, 
PrivilegeBits.BUILT_IN.get(PrivilegeBits.REP_READ_NODES), 
RestrictionPattern.EMPTY)));
-
-        PrincipalPermissionEntries ppeB = new PrincipalPermissionEntries(1);
-        ppeB.putEntriesByPath("/path", ImmutableSet.of(new 
PermissionEntry("/path", false, 1, 
PrivilegeBits.BUILT_IN.get(PrivilegeBits.REP_READ_NODES), 
RestrictionPattern.EMPTY)));
+    public void testBuildFewEntriesSamePath() {
+        PrincipalPermissionEntries ppeA = generatedPermissionEntries("/path", 
false, 0, REP_READ_NODES);
+        PrincipalPermissionEntries ppeB = 
generatedPermissionEntries("/path",false, 1, REP_READ_NODES);
 
         when(store.load("a")).thenReturn(ppeA);
         when(store.load("b")).thenReturn(ppeB);
@@ -90,18 +115,16 @@ public class PermissionCacheBuilderTest
 
         PermissionCache cache = permissionCacheBuilder.build();
         assertEquals(SIMPLE_CLASS_NAME, cache.getClass().getName());
+
+        verify(store, times(2)).getNumEntries(anyString(), anyLong());
+        verify(store, times(2)).load(anyString());
+        verify(store, never()).load(anyString(), anyString());
     }
 
     @Test
-    public void testBuildFewEntriesDifferentPaths() throws Exception {
-        PrincipalPermissionEntries ppeA = new PrincipalPermissionEntries(1);
-        ppeA.putEntriesByPath("/path", ImmutableSet.of(new 
PermissionEntry("/path", false, 0, 
PrivilegeBits.BUILT_IN.get(PrivilegeBits.REP_READ_NODES), 
RestrictionPattern.EMPTY)));
-
-        PrincipalPermissionEntries ppeB = new PrincipalPermissionEntries(1);
-        ppeB.putEntriesByPath("/path", ImmutableSet.of(new 
PermissionEntry("/path", false, 1, 
PrivilegeBits.BUILT_IN.get(PrivilegeBits.REP_READ_NODES), 
RestrictionPattern.EMPTY)));
-
-        when(store.load("a")).thenReturn(ppeA);
-        when(store.load("b")).thenReturn(ppeB);
+    public void testBuildFewEntriesDifferentPaths() {
+        when(store.load("a")).thenReturn(generatedPermissionEntries("/path1", 
false, 0, REP_READ_NODES));
+        when(store.load("b")).thenReturn(generatedPermissionEntries("/path2", 
false, 0, REP_READ_NODES));
         when(store.getNumEntries(anyString(), 
anyLong())).thenReturn(NumEntries.valueOf(1, true));
 
         Set<String> principalNames = Sets.newHashSet("a", "b");
@@ -109,28 +132,49 @@ public class PermissionCacheBuilderTest
 
         PermissionCache cache = permissionCacheBuilder.build();
         assertEquals(SIMPLE_CLASS_NAME, cache.getClass().getName());
+
+        verify(store, times(2)).getNumEntries(anyString(), anyLong());
+        verify(store, times(2)).load(anyString());
+        verify(store, never()).load(anyString(), anyString());
     }
 
     @Test
-    public void testNoEntriesNonExactCnt() throws Exception {
-        when(store.load("a")).thenReturn(new PrincipalPermissionEntries());
-        when(store.load("b")).thenReturn(new PrincipalPermissionEntries());
+    public void testBuildPathEntryMapNonExactCnt() {
+        
when(store.load("a")).thenReturn(generatedPermissionEntries("/path1",false, 0, 
REP_READ_NODES));
+        when(store.load("b")).thenReturn(generatedPermissionEntries("/path2", 
true, 0, JCR_MODIFY_ACCESS_CONTROL));
         when(store.getNumEntries(anyString(), 
anyLong())).thenReturn(NumEntries.valueOf(1, false));
 
         Set<String> principalNames = Sets.newHashSet("a", "b");
         assertFalse(permissionCacheBuilder.init(principalNames, 
Long.MAX_VALUE));
 
         PermissionCache cache = permissionCacheBuilder.build();
+        assertEquals(SIMPLE_CLASS_NAME, cache.getClass().getName());
+
+        verify(store, times(2)).getNumEntries(anyString(), anyLong());
+        verify(store, times(2)).load(anyString());
+        verify(store, never()).load(anyString(), anyString());
+    }
+
+    @Test
+    public void testBuildPathEntryMapResultsInEmptyCache() {
+        when(store.load(anyString())).thenReturn(new 
PrincipalPermissionEntries());
+        when(store.getNumEntries(anyString(), 
anyLong())).thenReturn(NumEntries.valueOf(MAX_PATH_SIZE+1, false));
+
+        Set<String> principalNames = Sets.newHashSet("a", "b");
+        assertFalse(permissionCacheBuilder.init(principalNames, 
Long.MAX_VALUE));
+
+        PermissionCache cache = permissionCacheBuilder.build();
         assertEquals(EMPTY_CLASS_NAME, cache.getClass().getName());
+
+        verify(store, times(2)).getNumEntries(anyString(), anyLong());
+        verify(store, times(2)).load(anyString());
+        verify(store, never()).load(anyString(), anyString());
     }
 
     @Test
     public void testBuildMaxEntriesReached() throws Exception {
-        PrincipalPermissionEntries ppeA = new PrincipalPermissionEntries(1);
-        ppeA.putEntriesByPath("/path1", ImmutableSet.of(new 
PermissionEntry("/path1", false, 0, 
PrivilegeBits.BUILT_IN.get(PrivilegeBits.REP_READ_NODES), 
RestrictionPattern.EMPTY)));
-
-        PrincipalPermissionEntries ppeB = new PrincipalPermissionEntries(1);
-        ppeA.putEntriesByPath("/path2", ImmutableSet.of(new 
PermissionEntry("/path2", false, 0, 
PrivilegeBits.BUILT_IN.get(PrivilegeBits.REP_READ_NODES), 
RestrictionPattern.EMPTY)));
+        PrincipalPermissionEntries ppeA = 
generatedPermissionEntries("/path1",false, 0, REP_READ_NODES);
+        PrincipalPermissionEntries ppeB = 
generatedPermissionEntries("/path2",false, 0, REP_READ_NODES);
 
         when(store.load("a")).thenReturn(ppeA);
         when(store.load("b")).thenReturn(ppeB);
@@ -142,5 +186,42 @@ public class PermissionCacheBuilderTest
 
         PermissionCache cache = permissionCacheBuilder.build();
         assertEquals(DEFAULT_CLASS_NAME, cache.getClass().getName());
+
+        verify(store, times(2)).getNumEntries(anyString(), anyLong());
+        verify(store, times(2)).load(anyString());
+        verify(store, never()).load(anyString(), anyString());
+    }
+
+    @Test
+    public void testInitNumEntriesExceedMaxPathExact() {
+        when(store.getNumEntries(anyString(), 
anyLong())).thenReturn(NumEntries.valueOf(MAX_PATH_SIZE+1, true));
+
+        assertFalse(permissionCacheBuilder.init(ImmutableSet.of("a", "b", 
"c"), Long.MAX_VALUE));
+
+        verify(store, times(3)).getNumEntries(anyString(), anyLong());
+        verify(store, never()).load(anyString());
+        verify(store, never()).load(anyString(), anyString());
+    }
+
+    @Test
+    public void testInitNumEntriesExceedMaxPathNotExact() {
+        when(store.getNumEntries(anyString(), 
anyLong())).thenReturn(NumEntries.valueOf(MAX_PATH_SIZE+1, false));
+
+        assertFalse(permissionCacheBuilder.init(ImmutableSet.of("a", "b", 
"c"), Long.MAX_VALUE));
+
+        verify(store, times(3)).getNumEntries(anyString(), anyLong());
+        verify(store, never()).load(anyString());
+        verify(store, never()).load(anyString(), anyString());
+    }
+
+    @Test
+    public void testInitNumEntriesExceedsMaxLong() {
+        when(store.getNumEntries(anyString(), 
anyLong())).thenReturn(NumEntries.valueOf(Long.MAX_VALUE, false));
+
+        assertFalse(permissionCacheBuilder.init(ImmutableSet.of("a", "b", 
"c"), Long.MAX_VALUE));
+
+        verify(store, times(3)).getNumEntries(anyString(), anyLong());
+        verify(store, never()).load(anyString());
+        verify(store, never()).load(anyString(), anyString());
     }
 }
\ No newline at end of file

Modified: 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/permission/PermissionEntryCacheTest.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/permission/PermissionEntryCacheTest.java?rev=1857999&r1=1857998&r2=1857999&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/permission/PermissionEntryCacheTest.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/permission/PermissionEntryCacheTest.java
 Tue Apr 23 09:34:55 2019
@@ -74,8 +74,29 @@ public class PermissionEntryCacheTest {
         assertNotNull(entries);
         assertFalse(entries.isFullyLoaded());
         assertEquals(0, entries.getSize());
+    }
+
+    @Test
+    public void testInitTwice() throws Exception {
+        cache.init("a", 5);
+        cache.init("a", 25);
+
+        PrincipalPermissionEntries entries = inspectEntries(cache, "a");
+        assertNotNull(entries);
+
+        Field f = 
PrincipalPermissionEntries.class.getDeclaredField("expectedSize");
+        f.setAccessible(true);
+
+        long expectedSize = (long) f.get(entries);
+        assertEquals(5, expectedSize);
+        assertFalse(entries.isFullyLoaded());
+    }
+
+    @Test
+    public void testInitDifferentPrincipal() throws Exception {
+        cache.init("a", 5);
 
-        entries = inspectEntries(cache, "notInitialized");
+        PrincipalPermissionEntries entries = inspectEntries(cache, 
"notInitialized");
         assertNull(entries);
     }
 

Added: 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/permission/PermissionEntryTest.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/permission/PermissionEntryTest.java?rev=1857999&view=auto
==============================================================================
--- 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/permission/PermissionEntryTest.java
 (added)
+++ 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/permission/PermissionEntryTest.java
 Tue Apr 23 09:34:55 2019
@@ -0,0 +1,207 @@
+/*
+ * 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.security.authorization.permission;
+
+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.spi.security.authorization.restriction.RestrictionPattern;
+import org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeBits;
+import org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.nullable;
+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 PermissionEntryTest {
+
+    private String path = "/path";
+    private int index = 15;
+    private PermissionEntry entry = new PermissionEntry(path, true, index, 
PrivilegeBits.BUILT_IN.get(PrivilegeConstants.REP_READ_NODES), 
RestrictionPattern.EMPTY);
+
+    private RestrictionPattern pattern = mock(RestrictionPattern.class);
+    private PermissionEntry entryWithNonEmptyPattern = new 
PermissionEntry(path, false, index, 
PrivilegeBits.BUILT_IN.get(PrivilegeConstants.REP_ADD_PROPERTIES), pattern);
+
+    @Test
+    public void testMatchesEmptyPattern() {
+        assertTrue(entry.matches());
+    }
+
+    @Test
+    public void testMatches() {
+        when(pattern.matches()).thenReturn(true);
+        assertTrue(entryWithNonEmptyPattern.matches());
+
+        when(pattern.matches()).thenReturn(false);
+        assertFalse(entryWithNonEmptyPattern.matches());
+    }
+
+    @Test
+    public void testMatchesTreeEmptyPattern() {
+        // restriction pattern is empty => matches
+        assertTrue(entry.matches(mock(Tree.class), mock(PropertyState.class)));
+        assertTrue(entry.matches(mock(Tree.class), null));
+    }
+
+    @Test
+    public void testMatchesTree() {
+        Tree t = mock(Tree.class);
+        PropertyState ps = mock(PropertyState.class);
+
+        when(pattern.matches(any(Tree.class), 
nullable(PropertyState.class))).thenReturn(true);
+        assertTrue(entryWithNonEmptyPattern.matches(t, ps));
+        assertTrue(entryWithNonEmptyPattern.matches(t, null));
+
+        when(pattern.matches(any(Tree.class), 
nullable(PropertyState.class))).thenReturn(false);
+        assertFalse(entryWithNonEmptyPattern.matches(t, ps));
+        assertFalse(entryWithNonEmptyPattern.matches(t, null));
+
+        verify(pattern, times(2)).matches(t, ps);
+        verify(pattern, times(2)).matches(t, null);
+    }
+
+    @Test
+    public void testMatchesPathEmptyPattern() {
+        // restriction patterrn is empty => matches
+        assertTrue(entry.matches(path));
+        assertTrue(entry.matches(PathUtils.getParentPath(path)));
+        assertTrue(entry.matches(PathUtils.concat(path, "some", "child")));
+        assertTrue(entry.matches(""));
+        assertTrue(entry.matches("/some/other/path"));
+    }
+
+    @Test
+    public void testMatchesPath() {
+        String[] paths = new String[] {path, PathUtils.getParentPath(path), 
PathUtils.concat(path, "some", "child"), "/some/other/path", ""};
+        when(pattern.matches(anyString())).thenReturn(true);
+        for (String p : paths) {
+            assertTrue(entryWithNonEmptyPattern.matches(p));
+        }
+
+        when(pattern.matches(anyString())).thenReturn(false);
+        for (String p : paths) {
+            assertFalse(entryWithNonEmptyPattern.matches(p));
+        }
+
+        for (String p : paths) {
+            verify(pattern, times(2)).matches(p);
+        }
+    }
+
+    @Test
+    public void testMatchesParentEmptyPattern() {
+        // the entry matchesParent if the parent of the path to be evaluated 
is equal or a descendant of the entry-path
+        assertTrue(entry.matchesParent(path));
+        assertTrue(entry.matchesParent(PathUtils.concat(path, "parent", "of", 
"target")));
+        assertFalse(entry.matchesParent(PathUtils.getParentPath(path)));
+        assertFalse(entry.matchesParent("/another/path"));
+    }
+
+    @Test
+    public void testMatchesParent() {
+        // the entry matchesParent if the parent of the path to be evaluated 
is equal or a descendant of the entry-path
+        // and the pattern evaluates to true (which is always the case here)
+        when(pattern.matches(anyString())).thenReturn(true);
+        assertTrue(entryWithNonEmptyPattern.matchesParent(path));
+        
assertTrue(entryWithNonEmptyPattern.matchesParent(PathUtils.concat(path, 
"parent", "of", "target")));
+        
assertFalse(entryWithNonEmptyPattern.matchesParent(PathUtils.getParentPath(path)));
+        assertFalse(entryWithNonEmptyPattern.matchesParent("/another/path"));
+
+        // pattern doesn't match => always false
+        when(pattern.matches(anyString())).thenReturn(false);
+        assertFalse(entryWithNonEmptyPattern.matchesParent(path));
+        
assertFalse(entryWithNonEmptyPattern.matchesParent(PathUtils.concat(path, 
"parent", "of", "target")));
+        
assertFalse(entryWithNonEmptyPattern.matchesParent(PathUtils.getParentPath(path)));
+        assertFalse(entryWithNonEmptyPattern.matchesParent("/another/path"));
+    }
+
+    @Test
+    public void testCompareToEqualPath() {
+        assertEquals(0, entry.compareTo(entry));
+        assertEquals(0, entry.compareTo(new PermissionEntry(path, 
entry.isAllow, index, entry.privilegeBits, entry.restriction)));
+
+        PermissionEntry higherIndexEntry = new PermissionEntry(path, 
entry.isAllow, index + 1, entry.privilegeBits, entry.restriction);
+        assertEquals(1, entry.compareTo(higherIndexEntry));
+        assertEquals(-1, higherIndexEntry.compareTo(entry));
+    }
+
+    @Test
+    public void testCompareToDifferentPathSameDepth() {
+        String sameDepthPath = "/another";
+        PermissionEntry anotherEntry = new PermissionEntry(sameDepthPath, 
entry.isAllow, index, entry.privilegeBits, entry.restriction);
+        PermissionEntry anotherEntry2 = new PermissionEntry(sameDepthPath, 
!entry.isAllow, 3, 
PrivilegeBits.BUILT_IN.get(PrivilegeConstants.JCR_LOCK_MANAGEMENT), 
mock(RestrictionPattern.class));
+
+        assertEquals(path.compareTo(sameDepthPath), 
entry.compareTo(anotherEntry));
+        assertEquals(path.compareTo(sameDepthPath), 
entry.compareTo(anotherEntry2));
+
+        assertNotEquals(sameDepthPath.compareTo(path), 
entry.compareTo(anotherEntry));
+        assertNotEquals(sameDepthPath.compareTo(path), 
entry.compareTo(anotherEntry2));
+    }
+
+    @Test
+    public void testCompareToDifferentPathHigherDepth() {
+        String higherDepthPath = PathUtils.concat(path, "to", "higher", 
"depth");
+        PermissionEntry higherDepthEntry = new 
PermissionEntry(higherDepthPath, entry.isAllow, index, entry.privilegeBits, 
entry.restriction);
+
+        assertEquals(1, entry.compareTo(higherDepthEntry));
+    }
+
+    @Test
+    public void testCompareToDifferentPathLowerDepth() {
+        String lowerDepthPath = PathUtils.getParentPath(path);
+        PermissionEntry lowerDepthEntry = new PermissionEntry(lowerDepthPath, 
entry.isAllow, index, entry.privilegeBits, entry.restriction);
+
+        assertEquals(-1, entry.compareTo(lowerDepthEntry));
+    }
+
+    @Test
+    public void testEquals() {
+        assertTrue(entry.equals(entry));
+        assertTrue(entry.equals(new PermissionEntry(path, entry.isAllow, 
index, entry.privilegeBits, entry.restriction)));
+        assertTrue(entry.equals(new PermissionEntry(path, entry.isAllow, 
index, PrivilegeBits.getInstance(entry.privilegeBits).unmodifiable(), 
entry.restriction)));
+    }
+
+    @Test
+    public void testNotEqual() {
+        // path different
+        assertNotEquals(entry, new PermissionEntry("/", entry.isAllow, index, 
entry.privilegeBits, entry.restriction));
+        assertNotEquals(entry, new PermissionEntry("/path2", entry.isAllow, 
index, entry.privilegeBits, entry.restriction));
+
+        // isAllow different
+        assertNotEquals(entry, new PermissionEntry(path, !entry.isAllow, 
index, entry.privilegeBits, entry.restriction));
+
+        // index different
+        assertNotEquals(entry, new PermissionEntry(path, entry.isAllow, 2, 
entry.privilegeBits, entry.restriction));
+
+        // privbits different
+        assertNotEquals(entry, new PermissionEntry(path, entry.isAllow, index, 
PrivilegeBits.BUILT_IN.get(PrivilegeConstants.JCR_READ), entry.restriction));
+
+        // restrictions different
+        assertNotEquals(entry, new PermissionEntry(path, entry.isAllow, index, 
entry.privilegeBits, mock(RestrictionPattern.class)));
+
+        assertFalse(entry.equals(null));
+    }
+}
\ No newline at end of file

Propchange: 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/permission/PermissionEntryTest.java
------------------------------------------------------------------------------
    svn:eol-style = native


Reply via email to