This is an automated email from the ASF dual-hosted git repository.

angela pushed a commit to branch OAK-10135
in repository https://gitbox.apache.org/repos/asf/jackrabbit-oak.git

commit dde38356dc8cb23910c10eb036726844674063d7
Author: angela <anch...@adobe.com>
AuthorDate: Thu Mar 9 13:25:13 2023 +0100

    OAK-10135 : JackrabbitAccessControlManager.getEffectivePolicies(Set 
principals) should include ReadPolicy
---
 .../impl/PrincipalBasedAccessControlManager.java   |  7 ++-
 .../impl/AbstractPrincipalBasedTest.java           | 16 +++++++
 .../impl/AccessControlManagerLimitedUserTest.java  | 10 ++++
 .../principalbased/impl/EffectivePolicyTest.java   |  6 +--
 .../impl/ImmutablePrincipalPolicyTest.java         |  2 +-
 .../PrincipalBasedAccessControlManagerTest.java    | 26 +++++------
 .../impl/ReadablePathsAccessControlTest.java       |  6 ++-
 .../impl/TransientPrincipalTest.java               |  4 +-
 .../accesscontrol/AccessControlManagerImpl.java    |  6 ++-
 .../accesscontrol/PolicyComparator.java            | 33 ++++++++++----
 .../accesscontrol/AbstractAccessControlTest.java   |  8 ++++
 .../AccessControlManagerImplTest.java              | 28 ++++++------
 ...AccessControlManagerLimitedPermissionsTest.java | 53 +++++++++++++++++++---
 .../AccessControlWithUnknownPrincipalTest.java     | 11 ++---
 .../accesscontrol/PolicyComparatorTest.java        | 26 +++++++++++
 .../accesscontrol/ReadPolicyTest.java              | 53 ++++++++++++++++++++--
 .../authorization/accesscontrol/ReadPolicy.java    | 20 ++++++++
 .../authorization/accesscontrol/package-info.java  |  2 +-
 .../accesscontrol/ReadPolicyTest.java              | 20 ++++++++
 19 files changed, 268 insertions(+), 69 deletions(-)

diff --git 
a/oak-authorization-principalbased/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/PrincipalBasedAccessControlManager.java
 
b/oak-authorization-principalbased/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/PrincipalBasedAccessControlManager.java
index 21876483c2..fe00e9695b 100644
--- 
a/oak-authorization-principalbased/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/PrincipalBasedAccessControlManager.java
+++ 
b/oak-authorization-principalbased/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/PrincipalBasedAccessControlManager.java
@@ -69,7 +69,6 @@ import java.text.ParseException;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashMap;
-import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -145,13 +144,17 @@ class PrincipalBasedAccessControlManager extends 
AbstractAccessControlManager im
         // this implementation only takes effect if the complete set of 
principals can be handled. see also
         // PrincipalBasedAuthorizationConfiguration.getPermissionProvider
         if (canHandle(principals)) {
-            Set<AccessControlPolicy> effective = new 
HashSet<>(principals.size());
+            List<AccessControlPolicy> effective = new 
ArrayList<>(principals.size());
             for (Principal principal : principals) {
                 AccessControlPolicy policy = createPolicy(principal, true);
                 if (policy != null) {
                     effective.add(policy);
                 }
             }
+            // add read-policy if there are configured paths
+            if (ReadPolicy.canAccessReadPolicy(getPermissionProvider(), 
readPaths.toArray(new String[0]))) {
+                effective.add(ReadPolicy.INSTANCE);
+            }
             return effective.toArray(new AccessControlPolicy[0]);
         } else {
             return new JackrabbitAccessControlPolicy[0];
diff --git 
a/oak-authorization-principalbased/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/AbstractPrincipalBasedTest.java
 
b/oak-authorization-principalbased/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/AbstractPrincipalBasedTest.java
index b7d64f690b..68e06622f5 100644
--- 
a/oak-authorization-principalbased/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/AbstractPrincipalBasedTest.java
+++ 
b/oak-authorization-principalbased/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/AbstractPrincipalBasedTest.java
@@ -36,6 +36,7 @@ import 
org.apache.jackrabbit.oak.security.internal.SecurityProviderHelper;
 import org.apache.jackrabbit.oak.spi.mount.Mounts;
 import org.apache.jackrabbit.oak.spi.security.SecurityProvider;
 import 
org.apache.jackrabbit.oak.spi.security.authorization.AuthorizationConfiguration;
+import 
org.apache.jackrabbit.oak.spi.security.authorization.accesscontrol.ReadPolicy;
 import 
org.apache.jackrabbit.oak.spi.security.authorization.permission.PermissionProvider;
 import 
org.apache.jackrabbit.oak.spi.security.authorization.principalbased.FilterProvider;
 import org.apache.jackrabbit.oak.spi.security.user.UserConstants;
@@ -46,6 +47,7 @@ import org.junit.Before;
 import javax.jcr.RepositoryException;
 import javax.jcr.Value;
 import javax.jcr.security.AccessControlManager;
+import javax.jcr.security.AccessControlPolicy;
 import javax.jcr.security.Privilege;
 import java.security.Principal;
 import java.util.Collections;
@@ -54,6 +56,8 @@ import java.util.UUID;
 
 import static com.google.common.base.Preconditions.checkNotNull;
 import static 
org.apache.jackrabbit.oak.spi.nodetype.NodeTypeConstants.NT_OAK_UNSTRUCTURED;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
@@ -220,4 +224,16 @@ public abstract class AbstractPrincipalBasedTest extends 
AbstractSecurityTest {
     PrincipalBasedAuthorizationConfiguration 
getPrincipalBasedAuthorizationConfiguration() {
         return principalBasedAuthorizationConfiguration;
     }
+    
+    static void assertEffectivePolicies(@NotNull AccessControlPolicy[] 
effective, int expectedPolicies, 
+                                        int principalPolicySize, boolean 
readPolicyExpected) {
+        assertEquals(expectedPolicies, effective.length);
+        if (principalPolicySize > -1) {
+            assertTrue(effective[0] instanceof ImmutablePrincipalPolicy);
+            assertEquals(principalPolicySize, ((ImmutablePrincipalPolicy) 
effective[0]).size());
+        }
+        if (readPolicyExpected) {
+            assertTrue(effective[effective.length-1] instanceof ReadPolicy);
+        }
+    }
 }
\ No newline at end of file
diff --git 
a/oak-authorization-principalbased/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/AccessControlManagerLimitedUserTest.java
 
b/oak-authorization-principalbased/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/AccessControlManagerLimitedUserTest.java
index fca1d6dccc..52e43e5a5f 100644
--- 
a/oak-authorization-principalbased/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/AccessControlManagerLimitedUserTest.java
+++ 
b/oak-authorization-principalbased/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/AccessControlManagerLimitedUserTest.java
@@ -30,6 +30,7 @@ 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.accesscontrol.ImmutableACL;
+import 
org.apache.jackrabbit.oak.spi.security.authorization.accesscontrol.ReadPolicy;
 import org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
@@ -258,6 +259,15 @@ public class AccessControlManagerLimitedUserTest extends 
AbstractPrincipalBasedT
         root.commit();
         testRoot.refresh();
         
assertPolicies(testAcMgr.getEffectivePolicies(ImmutableSet.of(systemPrincipal)),
 ImmutableACL.class, 1, 2);
+
+        // make sure test-user has read-accesscontrol permission on any 
readable-path
+        grant(testPrincipal, PathUtils.ROOT_PATH, JCR_READ_ACCESS_CONTROL);
+        root.commit();
+        testRoot.refresh();
+
+        AccessControlPolicy[] effective = 
testAcMgr.getEffectivePolicies(ImmutableSet.of(systemPrincipal));;
+        assertPolicies(effective, ImmutableACL.class, 2, 2);
+        assertTrue(effective[1] instanceof ReadPolicy);
     }
 
     @Test(expected = AccessDeniedException.class)
diff --git 
a/oak-authorization-principalbased/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/EffectivePolicyTest.java
 
b/oak-authorization-principalbased/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/EffectivePolicyTest.java
index d12f18b39b..b77477fa57 100644
--- 
a/oak-authorization-principalbased/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/EffectivePolicyTest.java
+++ 
b/oak-authorization-principalbased/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/EffectivePolicyTest.java
@@ -96,8 +96,7 @@ public class EffectivePolicyTest extends 
AbstractPrincipalBasedTest {
     @Test
     public void testEffectivePolicyByPrincipal() throws Exception {
         AccessControlPolicy[] effective = 
acMgr.getEffectivePolicies(ImmutableSet.of(validPrincipal));
-        assertEquals(1, effective.length);
-        assertTrue(effective[0] instanceof ImmutablePrincipalPolicy);
+        assertEffectivePolicies(effective, 2, 2, true);
 
         List<JackrabbitAccessControlEntry> entries = 
((ImmutablePrincipalPolicy)effective[0]).getEntries();
         assertEquals(2, entries.size());
@@ -113,8 +112,7 @@ public class EffectivePolicyTest extends 
AbstractPrincipalBasedTest {
     @Test
     public void testEffectivePolicyByPrincipal2() throws Exception {
         AccessControlPolicy[] effective = 
acMgr.getEffectivePolicies(ImmutableSet.of(validPrincipal2));
-        assertEquals(1, effective.length);
-        assertTrue(effective[0] instanceof ImmutablePrincipalPolicy);
+        assertEffectivePolicies(effective, 2, 2, true);
 
         List<JackrabbitAccessControlEntry> entries = 
((ImmutablePrincipalPolicy)effective[0]).getEntries();
         assertEquals(2, entries.size());
diff --git 
a/oak-authorization-principalbased/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/ImmutablePrincipalPolicyTest.java
 
b/oak-authorization-principalbased/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/ImmutablePrincipalPolicyTest.java
index e17d8af0ff..d36fb64714 100644
--- 
a/oak-authorization-principalbased/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/ImmutablePrincipalPolicyTest.java
+++ 
b/oak-authorization-principalbased/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/ImmutablePrincipalPolicyTest.java
@@ -64,7 +64,7 @@ public class ImmutablePrincipalPolicyTest extends 
AbstractPrincipalBasedTest {
         int expectedHashCode = immutable.hashCode();
         ImmutablePrincipalPolicy ipp = new 
ImmutablePrincipalPolicy(policy.getPrincipal(), policy.getOakPath(), 
policy.getEntries(), policy.getRestrictionProvider(), 
policy.getNamePathMapper());
         assertEquals(expectedHashCode, ipp.hashCode());
-        assertEquals(expectedHashCode, new 
ImmutablePrincipalPolicy(policy).hashCode());
+        assertEquals(ipp.hashCode(), new 
ImmutablePrincipalPolicy(policy).hashCode());
     }
 
     @Test
diff --git 
a/oak-authorization-principalbased/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/PrincipalBasedAccessControlManagerTest.java
 
b/oak-authorization-principalbased/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/PrincipalBasedAccessControlManagerTest.java
index 7cdb2aba30..16fdc18b36 100644
--- 
a/oak-authorization-principalbased/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/PrincipalBasedAccessControlManagerTest.java
+++ 
b/oak-authorization-principalbased/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/PrincipalBasedAccessControlManagerTest.java
@@ -86,12 +86,6 @@ public class PrincipalBasedAccessControlManagerTest extends 
AbstractPrincipalBas
         return new PrincipalPolicyImpl(validPrincipal, oakPath, 
getMgrProvider(root));
     }
 
-    private static void assertEffectivePolicy(@NotNull AccessControlPolicy[] 
effective, int size) {
-        assertEquals(1, effective.length);
-        assertTrue(effective[0] instanceof ImmutablePrincipalPolicy);
-        assertEquals(size, ((ImmutablePrincipalPolicy) effective[0]).size());
-    }
-
     @Test(expected = AccessControlException.class)
     public void testGetApplicablePoliciesNullPrincipal() throws Exception {
         acMgr.getApplicablePolicies((Principal) null);
@@ -160,7 +154,8 @@ public class PrincipalBasedAccessControlManagerTest extends 
AbstractPrincipalBas
 
     @Test
     public void testGetEffectivePoliciesNothingSet() throws Exception {
-        assertEquals(0, 
acMgr.getEffectivePolicies(ImmutableSet.of(validPrincipal)).length);
+        AccessControlPolicy[] effective = 
acMgr.getEffectivePolicies(ImmutableSet.of(validPrincipal));
+        assertEffectivePolicies(effective, 1, -1, true);
     }
 
     @Test
@@ -171,12 +166,12 @@ public class PrincipalBasedAccessControlManagerTest 
extends AbstractPrincipalBas
 
         // transient changes => no effective policy
         AccessControlPolicy[] effective = 
acMgr.getEffectivePolicies(ImmutableSet.of(validPrincipal));
-        assertEquals(0, effective.length);
+        assertEffectivePolicies(effective, 1, -1, true);
 
         // after commit => effective policy present
         root.commit();
         effective = 
acMgr.getEffectivePolicies(ImmutableSet.of(validPrincipal));
-        assertEffectivePolicy(effective, 1);
+        assertEffectivePolicies(effective, 2, 1, true);
     }
 
     @Test
@@ -184,7 +179,8 @@ public class PrincipalBasedAccessControlManagerTest extends 
AbstractPrincipalBas
         JackrabbitAccessControlPolicy emptyPolicy = 
acMgr.getApplicablePolicies(validPrincipal)[0];
         acMgr.setPolicy(emptyPolicy.getPath(), emptyPolicy);
         root.commit();
-        assertEquals(0, 
acMgr.getEffectivePolicies(ImmutableSet.of(validPrincipal)).length);
+        AccessControlPolicy[] effective = 
acMgr.getEffectivePolicies(ImmutableSet.of(validPrincipal));
+        assertEffectivePolicies(effective, 1, -1, true);
     }
 
     @Test
@@ -197,7 +193,7 @@ public class PrincipalBasedAccessControlManagerTest extends 
AbstractPrincipalBas
         getUserManager(latestRoot).getAuthorizable(validPrincipal).remove();
         latestRoot.commit();
         try {
-            assertEquals(0, 
acMgr.getEffectivePolicies(ImmutableSet.of(validPrincipal)).length);
+            
assertEffectivePolicies(acMgr.getEffectivePolicies(ImmutableSet.of(validPrincipal)),
 1, -1, true);
         } finally {
             root.refresh();
             getUserManager(root).createSystemUser(id, INTERMEDIATE_PATH);
@@ -227,7 +223,7 @@ public class PrincipalBasedAccessControlManagerTest extends 
AbstractPrincipalBas
         
latestRoot.getTree(getNamePathMapper().getOakPath(validPrincipal.getPath())).getChild(REP_PRINCIPAL_POLICY).remove();
         latestRoot.commit();
 
-        assertEquals(0, 
acMgr.getEffectivePolicies(ImmutableSet.of(validPrincipal)).length);
+        
assertEffectivePolicies(acMgr.getEffectivePolicies(ImmutableSet.of(validPrincipal)),
 1, -1, true);
     }
 
     @Test(expected = AccessControlException.class)
@@ -445,9 +441,9 @@ public class PrincipalBasedAccessControlManagerTest extends 
AbstractPrincipalBas
         addPrincipalBasedEntry(policy, PathUtils.ROOT_PATH, JCR_READ);
         root.commit();
 
-        assertEffectivePolicy(acMgr.getEffectivePolicies(testJcrPath), 2);
-        assertEffectivePolicy(acMgr.getEffectivePolicies(testContentJcrPath), 
2);
-        assertEffectivePolicy(acMgr.getEffectivePolicies(PathUtils.ROOT_PATH), 
1);
+        assertEffectivePolicies(acMgr.getEffectivePolicies(testJcrPath), 1,2, 
false);
+        
assertEffectivePolicies(acMgr.getEffectivePolicies(testContentJcrPath), 1, 2, 
false);
+        
assertEffectivePolicies(acMgr.getEffectivePolicies(PathUtils.ROOT_PATH), 1,1, 
false);
     }
 
     @Test
diff --git 
a/oak-authorization-principalbased/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/ReadablePathsAccessControlTest.java
 
b/oak-authorization-principalbased/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/ReadablePathsAccessControlTest.java
index 0c94593be5..3f82bdbe7c 100644
--- 
a/oak-authorization-principalbased/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/ReadablePathsAccessControlTest.java
+++ 
b/oak-authorization-principalbased/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/ReadablePathsAccessControlTest.java
@@ -231,7 +231,9 @@ public class ReadablePathsAccessControlTest extends 
AbstractPrincipalBasedTest {
 
     @Test
     public void testGetEffectivePoliciesByPrincipal() throws Exception {
-        // NOTE: lookup by principal currently doesn't include READ_POLICY in 
accordance to default ac implementation
-        assertEquals(0, 
acMgr.getEffectivePolicies(Collections.singleton(testPrincipal)).length);
+        // OAK-10135 : include read-policy in effective policies by principal 
result
+        AccessControlPolicy[] effective = 
acMgr.getEffectivePolicies(Collections.singleton(testPrincipal));
+        assertEquals(1, effective.length);
+        assertTrue(effective[0] instanceof ReadPolicy);
     }
 }
\ No newline at end of file
diff --git 
a/oak-authorization-principalbased/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/TransientPrincipalTest.java
 
b/oak-authorization-principalbased/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/TransientPrincipalTest.java
index eee533f016..0d17776c84 100644
--- 
a/oak-authorization-principalbased/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/TransientPrincipalTest.java
+++ 
b/oak-authorization-principalbased/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/TransientPrincipalTest.java
@@ -140,14 +140,14 @@ public class TransientPrincipalTest extends 
AbstractPrincipalBasedTest {
     @Test
     public void testGetEffectivePolicies() throws Exception {
         AccessControlPolicy[] effective = 
acMgr.getEffectivePolicies(ImmutableSet.of(principal));
-        assertEquals(0, effective.length);
+        assertEffectivePolicies(effective, 1, -1, true);
 
         PrincipalPolicyImpl policy = getApplicable();
         policy.addEntry(testJcrPath, privilegesFromNames(JCR_WRITE));
         acMgr.setPolicy(policy.getPath(), policy);
 
         effective = acMgr.getEffectivePolicies(ImmutableSet.of(principal));
-        assertEquals(0, effective.length);
+        assertEffectivePolicies(effective, 1, -1, true);
     }
 
     @Test
diff --git 
a/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/accesscontrol/AccessControlManagerImpl.java
 
b/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/accesscontrol/AccessControlManagerImpl.java
index 4a040c2125..76e193a36f 100644
--- 
a/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/accesscontrol/AccessControlManagerImpl.java
+++ 
b/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/accesscontrol/AccessControlManagerImpl.java
@@ -370,7 +370,7 @@ public class AccessControlManagerImpl extends 
AbstractAccessControlManager imple
         
         Root r = getLatestRoot();
         Result aceResult = searchAces(principals, r);
-        Set<JackrabbitAccessControlList> effective = Sets.newTreeSet(new 
PolicyComparator());
+        Set<AccessControlPolicy> effective = Sets.newTreeSet(new 
PolicyComparator());
 
         Set<String> processed = Sets.newHashSet();
         Predicate<Tree> predicate = new PrincipalPredicate(principals);
@@ -394,6 +394,10 @@ public class AccessControlManagerImpl extends 
AbstractAccessControlManager imple
                 }
             }
         }
+        // add read-policy if there are readable paths configured where the 
editing session has READ_ACCESS_CONTROL granted
+        if (ReadPolicy.canAccessReadPolicy(getPermissionProvider(), 
readPaths.toArray(new String[0]))) {
+            effective.add(ReadPolicy.INSTANCE);
+        }
         return effective.toArray(new AccessControlPolicy[0]);
     }
 
diff --git 
a/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/accesscontrol/PolicyComparator.java
 
b/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/accesscontrol/PolicyComparator.java
index cfc17ef99b..9a7030ec35 100644
--- 
a/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/accesscontrol/PolicyComparator.java
+++ 
b/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/accesscontrol/PolicyComparator.java
@@ -20,27 +20,40 @@ import com.google.common.primitives.Ints;
 import org.apache.jackrabbit.api.security.JackrabbitAccessControlPolicy;
 import org.apache.jackrabbit.oak.commons.PathUtils;
 
+import javax.jcr.security.AccessControlPolicy;
 import java.util.Comparator;
 
-final class PolicyComparator implements 
Comparator<JackrabbitAccessControlPolicy> {
+final class PolicyComparator implements Comparator<AccessControlPolicy> {
 
     @Override
-    public int compare(JackrabbitAccessControlPolicy policy1, 
JackrabbitAccessControlPolicy policy2) {
+    public int compare(AccessControlPolicy policy1, AccessControlPolicy 
policy2) {
         if (policy1.equals(policy2)) {
             return 0;
+        } else if (policy1 instanceof JackrabbitAccessControlPolicy && policy2 
instanceof JackrabbitAccessControlPolicy) {
+            return compare((JackrabbitAccessControlPolicy) policy1, 
(JackrabbitAccessControlPolicy) policy2);
         } else {
-            String p1 = policy1.getPath();
-            String p2 = policy2.getPath();
-
-            if (p1 == null) {
+            if (policy1 instanceof JackrabbitAccessControlPolicy) {
                 return -1;
-            } else if (p2 == null) {
+            } else if (policy2 instanceof JackrabbitAccessControlPolicy) {
                 return 1;
             } else {
-                int depth1 = PathUtils.getDepth(p1);
-                int depth2 = PathUtils.getDepth(p2);
-                return (depth1 == depth2) ? p1.compareTo(p2) : 
Ints.compare(depth1, depth2);
+                return 0;
             }
         }
     }
+
+    private static int compare(JackrabbitAccessControlPolicy policy1, 
JackrabbitAccessControlPolicy policy2) {
+        String p1 = policy1.getPath();
+        String p2 = policy2.getPath();
+
+        if (p1 == null) {
+            return -1;
+        } else if (p2 == null) {
+            return 1;
+        } else {
+            int depth1 = PathUtils.getDepth(p1);
+            int depth2 = PathUtils.getDepth(p2);
+            return (depth1 == depth2) ? p1.compareTo(p2) : 
Ints.compare(depth1, depth2);
+        }
+    }
 }
\ No newline at end of file
diff --git 
a/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/accesscontrol/AbstractAccessControlTest.java
 
b/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/accesscontrol/AbstractAccessControlTest.java
index 55a2b760bb..4b11e805dd 100644
--- 
a/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/accesscontrol/AbstractAccessControlTest.java
+++ 
b/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/accesscontrol/AbstractAccessControlTest.java
@@ -27,6 +27,7 @@ import org.apache.jackrabbit.oak.namepath.NamePathMapper;
 import org.apache.jackrabbit.oak.plugins.tree.TreeUtil;
 import 
org.apache.jackrabbit.oak.spi.security.authorization.AuthorizationConfiguration;
 import org.apache.jackrabbit.oak.spi.security.authorization.accesscontrol.ACE;
+import 
org.apache.jackrabbit.oak.spi.security.authorization.accesscontrol.ReadPolicy;
 import 
org.apache.jackrabbit.oak.spi.security.authorization.restriction.Restriction;
 import 
org.apache.jackrabbit.oak.spi.security.authorization.restriction.RestrictionProvider;
 import org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeBits;
@@ -179,7 +180,14 @@ public abstract class AbstractAccessControlTest extends 
AbstractSecurityTest {
     }
     
     static void assertPolicies(@Nullable AccessControlPolicy[] policies, long 
expectedSize) {
+        assertPolicies(policies, expectedSize, false);
+    }
+    
+    static void assertPolicies(@Nullable AccessControlPolicy[] policies, long 
expectedSize, boolean readPolicyExpected) {
         assertNotNull(policies);
         assertEquals(expectedSize, policies.length);
+        if (policies.length > 0) {
+            assertEquals(readPolicyExpected, policies[policies.length - 1] 
instanceof ReadPolicy);
+        }
     }
 }
diff --git 
a/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/accesscontrol/AccessControlManagerImplTest.java
 
b/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/accesscontrol/AccessControlManagerImplTest.java
index fc0a33e344..12256cbe37 100644
--- 
a/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/accesscontrol/AccessControlManagerImplTest.java
+++ 
b/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/accesscontrol/AccessControlManagerImplTest.java
@@ -1591,14 +1591,14 @@ public class AccessControlManagerImplTest extends 
AbstractAccessControlTest impl
 
         for (Set<Principal> principals : principalSets) {
             AccessControlPolicy[] policies = 
acMgr.getEffectivePolicies(principals);
-            assertPolicies(policies, 0);
+            assertPolicies(policies, 1, true);
         }
 
         setupPolicy(testPath);
         // changes not yet persisted -> no effecitve policies found for 
testprincipal
         for (Set<Principal> principals : principalSets) {
             AccessControlPolicy[] policies = 
acMgr.getEffectivePolicies(principals);
-            assertPolicies(policies, 0);
+            assertPolicies(policies, 1, true);
         }
 
         root.commit();
@@ -1606,9 +1606,9 @@ public class AccessControlManagerImplTest extends 
AbstractAccessControlTest impl
         for (Set<Principal> principals : principalSets) {
             AccessControlPolicy[] policies = 
acMgr.getEffectivePolicies(principals);
             if (principals.contains(testPrincipal)) {
-                assertPolicies(policies, 1);
+                assertPolicies(policies, 2, true);
             } else {
-                assertPolicies(policies, 0);
+                assertPolicies(policies, 1, true);
             }
         }
 
@@ -1619,9 +1619,9 @@ public class AccessControlManagerImplTest extends 
AbstractAccessControlTest impl
         for (Set<Principal> principals : principalSets) {
             AccessControlPolicy[] policies = 
acMgr.getEffectivePolicies(principals);
             if (principals.contains(testPrincipal)) {
-                assertPolicies(policies, 1);
+                assertPolicies(policies, 2, true);
             } else {
-                assertPolicies(policies, 0);
+                assertPolicies(policies, 1, true);
             }
         }
 
@@ -1630,9 +1630,9 @@ public class AccessControlManagerImplTest extends 
AbstractAccessControlTest impl
         for (Set<Principal> principals : principalSets) {
             AccessControlPolicy[] policies = 
acMgr.getEffectivePolicies(principals);
             if (principals.contains(testPrincipal)) {
-                assertPolicies(policies, 2);
+                assertPolicies(policies, 3, true);
             } else {
-                assertPolicies(policies, 0);
+                assertPolicies(policies, 1, true);
             }
         }
     }
@@ -1651,7 +1651,7 @@ public class AccessControlManagerImplTest extends 
AbstractAccessControlTest impl
         root.commit();
 
         AccessControlPolicy[] policies = 
acMgr.getEffectivePolicies(principalSet);
-        assertPolicies(policies, 1);
+        assertPolicies(policies, 2, true);
 
         // add another policy
         Tree child = TreeUtil.addChild(root.getTree(testPath), "child", 
JcrConstants.NT_UNSTRUCTURED);
@@ -1659,7 +1659,7 @@ public class AccessControlManagerImplTest extends 
AbstractAccessControlTest impl
         setupPolicy(childPath);
         root.commit();
 
-        assertPolicies(acMgr.getEffectivePolicies(principalSet), 2);
+        assertPolicies(acMgr.getEffectivePolicies(principalSet), 3, true);
     }
 
     @Test
@@ -1689,7 +1689,7 @@ public class AccessControlManagerImplTest extends 
AbstractAccessControlTest impl
             root.commit();
 
             AccessControlPolicy[] effectivePolicies = 
acMgr.getEffectivePolicies(principalSet);
-            assertPolicies(effectivePolicies, 3);
+            assertPolicies(effectivePolicies, 4, true);
 
             assertNull(((JackrabbitAccessControlPolicy) 
effectivePolicies[0]).getPath());
             assertEquals(testPath, ((JackrabbitAccessControlPolicy) 
effectivePolicies[1]).getPath());
@@ -1723,7 +1723,7 @@ public class AccessControlManagerImplTest extends 
AbstractAccessControlTest impl
 
         for (Principal princ : principals) {
             AccessControlPolicy[] policies = 
acMgr.getEffectivePolicies(ImmutableSet.of(princ));
-            assertPolicies(policies, 1);
+            assertPolicies(policies, 2, true);
             assertTrue(policies[0] instanceof AccessControlList);
 
             AccessControlList acl = (AccessControlList) policies[0];
@@ -1750,7 +1750,7 @@ public class AccessControlManagerImplTest extends 
AbstractAccessControlTest impl
 
         AccessControlManagerImpl mgr = createAccessControlManager(r, 
getNamePathMapper());
         AccessControlPolicy[] policies = 
mgr.getEffectivePolicies(ImmutableSet.of(testPrincipal));
-        assertPolicies(policies, 0);
+        assertPolicies(policies, 1, true);
     }
 
     @Test
@@ -1770,7 +1770,7 @@ public class AccessControlManagerImplTest extends 
AbstractAccessControlTest impl
 
         AccessControlManagerImpl mgr = createAccessControlManager(r, 
getNamePathMapper());
         AccessControlPolicy[] policies = 
mgr.getEffectivePolicies(ImmutableSet.of(testPrincipal));
-        assertPolicies(policies, 0);
+        assertPolicies(policies, 1, true);
     }
     
     private static QueryEngine mockQueryEngine(@NotNull Tree aceTree) throws 
Exception {
diff --git 
a/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/accesscontrol/AccessControlManagerLimitedPermissionsTest.java
 
b/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/accesscontrol/AccessControlManagerLimitedPermissionsTest.java
index 44aebe340a..68969133a6 100644
--- 
a/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/accesscontrol/AccessControlManagerLimitedPermissionsTest.java
+++ 
b/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/accesscontrol/AccessControlManagerLimitedPermissionsTest.java
@@ -54,6 +54,7 @@ import java.util.Iterator;
 import java.util.List;
 import java.util.Set;
 
+import static 
org.apache.jackrabbit.oak.security.authorization.accesscontrol.AbstractAccessControlTest.assertPolicies;
 import static 
org.apache.jackrabbit.oak.spi.security.authorization.accesscontrol.AccessControlConstants.REP_POLICY;
 import static 
org.apache.jackrabbit.oak.spi.security.authorization.accesscontrol.AccessControlConstants.REP_RESTRICTIONS;
 import static org.junit.Assert.assertArrayEquals;
@@ -120,11 +121,6 @@ public class AccessControlManagerLimitedPermissionsTest 
extends AbstractSecurity
         return npMapper;
     }
 
-    private static void assertPolicies(@Nullable AccessControlPolicy[] 
policies, long expectedSize) {
-        assertNotNull(policies);
-        assertEquals(expectedSize, policies.length);
-    }
-
     private void setupPolicy(@Nullable String path, @Nullable Privilege... 
privileges) throws RepositoryException {
         Privilege[] privs = (privileges == null || privileges.length == 0) ? 
testPrivileges : privileges;
         TestUtility.setupPolicy(getAccessControlManager(root), path, 
testPrincipal, privs, true, TestUtility.getGlobRestriction("*", 
getValueFactory(root)), null);
@@ -515,7 +511,7 @@ public class AccessControlManagerLimitedPermissionsTest 
extends AbstractSecurity
         acMgr.setPolicy(testPath, acl);
 
         // grant access at childpath
-        setupPolicy(childPath, 
privilegesFromNames(PrivilegeConstants.JCR_READ, 
PrivilegeConstants.JCR_READ_ACCESS_CONTROL));
+        setupPolicy(childPath, privs);
         root.commit();
 
         testRoot.refresh();
@@ -524,4 +520,49 @@ public class AccessControlManagerLimitedPermissionsTest 
extends AbstractSecurity
         AccessControlPolicy[] policies = 
testAcMgr.getEffectivePolicies(principals);
         assertPolicies(policies, 1);
     }
+
+    @Test
+    public void testGetEffectivePoliciesByPrincipalsReadPolicy1() throws 
Exception {
+        // grant test-principal READ access at root node (but not 
READ_ACCESS_CONTROL)
+        setupPolicy(PathUtils.ROOT_PATH, 
privilegesFromNames(PrivilegeConstants.JCR_READ));
+        root.commit();
+
+        testRoot.refresh();
+
+        // effective policies must NOT include ReadPolicy 
+        Set<Principal> principals = ImmutableSet.of(testPrincipal, 
EveryonePrincipal.getInstance());
+        AccessControlPolicy[] policies = 
testAcMgr.getEffectivePolicies(principals);
+        assertPolicies(policies, 0, false);
+    }
+
+    @Test
+    public void testGetEffectivePoliciesByPrincipalsReadPolicy2() throws 
Exception {
+        // grant test-principal READ_ACCESS_CONTROL access at root node (but 
not READ)
+        setupPolicy(PathUtils.ROOT_PATH, 
privilegesFromNames(PrivilegeConstants.JCR_READ_ACCESS_CONTROL));
+        root.commit();
+
+        testRoot.refresh();
+
+        // effective policies must include ReadPolicy 
+        // but no path-not-found must be raised if the readable-path is not 
accessible
+        Set<Principal> principals = ImmutableSet.of(testPrincipal, 
EveryonePrincipal.getInstance());
+        AccessControlPolicy[] policies = 
testAcMgr.getEffectivePolicies(principals);
+        // since no other ac-setup exists for 'everyone' principal -> only 
ReadPolicy is found
+        assertPolicies(policies, 1, true);
+    }
+    
+    @Test
+    public void testGetEffectivePoliciesByPrincipalsIncludesReadPolicy3() 
throws Exception {
+        // grant test-principal READ and READ_ACCESS_CONTROL at root node 
+        setupPolicy(PathUtils.ROOT_PATH, 
privilegesFromNames(PrivilegeConstants.JCR_READ, 
PrivilegeConstants.JCR_READ_ACCESS_CONTROL));
+        root.commit();
+
+        testRoot.refresh();
+
+        // effective policies must include ReadPolicy 
+        Set<Principal> principals = ImmutableSet.of(testPrincipal, 
EveryonePrincipal.getInstance());
+        AccessControlPolicy[] policies = 
testAcMgr.getEffectivePolicies(principals);
+        // since no other ac-setup exists for 'everyone' principal -> only 
ReadPolicy is found
+        assertPolicies(policies, 1, true);
+    }
 }
diff --git 
a/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/accesscontrol/AccessControlWithUnknownPrincipalTest.java
 
b/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/accesscontrol/AccessControlWithUnknownPrincipalTest.java
index 889970e8c7..e0a54ce1f9 100644
--- 
a/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/accesscontrol/AccessControlWithUnknownPrincipalTest.java
+++ 
b/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/accesscontrol/AccessControlWithUnknownPrincipalTest.java
@@ -16,13 +16,11 @@
  */
 package org.apache.jackrabbit.oak.security.authorization.accesscontrol;
 
-import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Lists;
 import org.apache.jackrabbit.api.security.JackrabbitAccessControlList;
 import 
org.apache.jackrabbit.commons.jackrabbit.authorization.AccessControlUtils;
 import org.apache.jackrabbit.oak.spi.security.ConfigurationParameters;
 import 
org.apache.jackrabbit.oak.spi.security.authorization.AuthorizationConfiguration;
-import org.apache.jackrabbit.oak.spi.security.principal.EveryonePrincipal;
 import org.apache.jackrabbit.oak.spi.security.principal.PrincipalImpl;
 import org.apache.jackrabbit.oak.spi.xml.ImportBehavior;
 import org.apache.jackrabbit.oak.spi.xml.ProtectedItemImporter;
@@ -33,7 +31,6 @@ import org.junit.runner.RunWith;
 import org.junit.runners.Parameterized;
 
 import javax.jcr.RepositoryException;
-import javax.jcr.ValueFactory;
 import javax.jcr.security.AccessControlException;
 import javax.jcr.security.AccessControlPolicy;
 import java.security.Principal;
@@ -63,7 +60,6 @@ public class AccessControlWithUnknownPrincipalTest extends 
AbstractAccessControl
     private final String importBehaviorName;
 
     private AccessControlManagerImpl acMgr;
-    private ValueFactory valueFactory;
 
     public AccessControlWithUnknownPrincipalTest(int importBehavior, String 
importBehaviorName) {
         this.importBehavior = importBehavior;
@@ -75,7 +71,6 @@ public class AccessControlWithUnknownPrincipalTest extends 
AbstractAccessControl
         super.before();
 
         acMgr = new AccessControlManagerImpl(root, getNamePathMapper(), 
getSecurityProvider());
-        valueFactory = getValueFactory(root);
     }
 
     @Override
@@ -180,8 +175,10 @@ public class AccessControlWithUnknownPrincipalTest extends 
AbstractAccessControl
             AccessControlPolicy[] effective = 
acMgr.getEffectivePolicies(Collections.singleton(unknown));
             switch (importBehavior) {
                 case ImportBehavior.IGNORE:
+                    assertPolicies(effective, 0, false);
+                    break;
                 case ImportBehavior.BESTEFFORT:
-                    assertEquals(0, effective.length);
+                    assertPolicies(effective, 1, true);
                     break;
                 case ImportBehavior.ABORT:
                 default:
@@ -196,7 +193,7 @@ public class AccessControlWithUnknownPrincipalTest extends 
AbstractAccessControl
     public void testGetEffectivePoliciesInternalPrincipal() throws Exception {
         Principal unknown = new PrincipalImpl(getUnknownPrincipalName());
         AccessControlPolicy[] effective = 
acMgr.getEffectivePolicies(Collections.singleton(unknown));
-        assertEquals(0, effective.length);
+        assertPolicies(effective, 1, true);
     }
 
     @Test
diff --git 
a/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/accesscontrol/PolicyComparatorTest.java
 
b/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/accesscontrol/PolicyComparatorTest.java
index 5bed6417c4..87bf7e4f53 100644
--- 
a/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/accesscontrol/PolicyComparatorTest.java
+++ 
b/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/accesscontrol/PolicyComparatorTest.java
@@ -19,10 +19,14 @@ package 
org.apache.jackrabbit.oak.security.authorization.accesscontrol;
 import com.google.common.primitives.Ints;
 import org.apache.jackrabbit.api.security.JackrabbitAccessControlPolicy;
 import org.apache.jackrabbit.oak.commons.PathUtils;
+import 
org.apache.jackrabbit.oak.spi.security.authorization.accesscontrol.ReadPolicy;
 import org.junit.Test;
 
+import javax.jcr.security.AccessControlPolicy;
+
 import static org.junit.Assert.assertEquals;
 import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verifyNoInteractions;
 import static org.mockito.Mockito.when;
 
 public class PolicyComparatorTest {
@@ -97,4 +101,26 @@ public class PolicyComparatorTest {
         int expected = Ints.compare(PathUtils.getDepth("/path"), 
PathUtils.getDepth("/a/deeper/path"));
         assertEquals(expected, comparator.compare(policy1, policy2));
     }
+
+    @Test
+    public void testOneNonJackrabbitPolicy() {
+        JackrabbitAccessControlPolicy p1 = 
mock(JackrabbitAccessControlPolicy.class);
+        AccessControlPolicy p2 = mock(AccessControlPolicy.class);
+        
+        assertEquals(-1, comparator.compare(p1, p2));
+        assertEquals(1, comparator.compare(p2, p1));
+        
+        verifyNoInteractions(p1, p2);
+    }
+    
+    @Test
+    public void testNonJackrabbitPolicies() {
+        AccessControlPolicy p1 = mock(AccessControlPolicy.class);
+        AccessControlPolicy p2 = mock(AccessControlPolicy.class);
+        assertEquals(0, comparator.compare(p1, p2));
+        assertEquals(0, comparator.compare(p2, p1));
+        assertEquals(0, comparator.compare(p1, ReadPolicy.INSTANCE));
+        
+        verifyNoInteractions(p1, p2);
+    }
 }
\ No newline at end of file
diff --git 
a/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/accesscontrol/ReadPolicyTest.java
 
b/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/accesscontrol/ReadPolicyTest.java
index 2ddd85fd9b..08e71d78eb 100644
--- 
a/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/accesscontrol/ReadPolicyTest.java
+++ 
b/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/accesscontrol/ReadPolicyTest.java
@@ -16,21 +16,31 @@
  */
 package org.apache.jackrabbit.oak.security.authorization.accesscontrol;
 
+import java.util.Collection;
+import java.util.Collections;
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.Set;
 import javax.jcr.security.AccessControlPolicy;
 import javax.jcr.security.NamedAccessControlPolicy;
 
+import com.google.common.collect.Lists;
+import org.apache.jackrabbit.JcrConstants;
 import org.apache.jackrabbit.oak.AbstractSecurityTest;
 import org.apache.jackrabbit.oak.api.Tree;
 import org.apache.jackrabbit.oak.spi.security.ConfigurationParameters;
 import 
org.apache.jackrabbit.oak.spi.security.authorization.AuthorizationConfiguration;
 import 
org.apache.jackrabbit.oak.spi.security.authorization.accesscontrol.ReadPolicy;
 import 
org.apache.jackrabbit.oak.spi.security.authorization.permission.PermissionConstants;
+import org.apache.jackrabbit.oak.spi.security.principal.EveryonePrincipal;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
 import org.junit.Before;
 import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
 
+import static 
org.apache.jackrabbit.oak.security.authorization.accesscontrol.AbstractAccessControlTest.assertPolicies;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
@@ -41,11 +51,27 @@ import static org.junit.Assert.fail;
  *
  * @since OAK 1.0
  */
+@RunWith(Parameterized.class)
 public class ReadPolicyTest extends AbstractSecurityTest {
 
+    private final Set<String> configuredPaths;
+
     private Set<String> readPaths;
     private Set<String> subTreePaths = new HashSet<>();
 
+    @Parameterized.Parameters(name = "Configured Readable Paths = {1}")
+    public static Collection<Object[]> parameters() {
+        return Lists.newArrayList(
+                new Object[] {null , "null => default set"},
+                new Object[] {Collections.emptySet(), "empty set"},
+                new Object[] {Collections.emptySet(), 
"/"+JcrConstants.JCR_SYSTEM}
+        );
+    }
+
+    public ReadPolicyTest(@Nullable Set<String> configuredPaths, @NotNull 
String name) {
+        this.configuredPaths = configuredPaths;
+    }
+    
     @Override
     @Before
     public void before() throws Exception {
@@ -63,6 +89,16 @@ public class ReadPolicyTest extends AbstractSecurityTest {
         }
     }
 
+    @Override
+    protected ConfigurationParameters getSecurityConfigParameters() {
+        if (configuredPaths != null) {
+            ConfigurationParameters params = 
ConfigurationParameters.of(PermissionConstants.PARAM_READ_PATHS, 
configuredPaths);
+            return ConfigurationParameters.of(AuthorizationConfiguration.NAME, 
params);
+        } else {
+            return super.getSecurityConfigParameters();
+        }
+    }
+
     @Test
     public void testGetPolicies() throws Exception {
         for (String path : readPaths) {
@@ -119,13 +155,22 @@ public class ReadPolicyTest extends AbstractSecurityTest {
             assertTrue(found);
         }
     }
+    
+    @Test
+    public void testGetEffectivePoliciesPrincipalSet() throws Exception {
+        AccessControlPolicy[] policies = 
getAccessControlManager(root).getEffectivePolicies(Collections.singleton(EveryonePrincipal.getInstance()));
+        long expSize = (readPaths.isEmpty()) ? 0 : 1;
+        assertPolicies(policies, expSize, true);
+    }
 
     @Test
     public void testGetName() throws Exception {
-        AccessControlPolicy[] policies = 
getAccessControlManager(root).getPolicies(readPaths.iterator().next());
-        assertEquals(1, policies.length);
-        assertTrue(policies[0] instanceof NamedAccessControlPolicy);
-        assertNotNull(((NamedAccessControlPolicy) policies[0]).getName());
+        if (!readPaths.isEmpty()) {
+            AccessControlPolicy[] policies = 
getAccessControlManager(root).getPolicies(readPaths.iterator().next());
+            assertEquals(1, policies.length);
+            assertTrue(policies[0] instanceof NamedAccessControlPolicy);
+            assertNotNull(((NamedAccessControlPolicy) policies[0]).getName());
+        }
     }
 
 }
\ No newline at end of file
diff --git 
a/oak-security-spi/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/accesscontrol/ReadPolicy.java
 
b/oak-security-spi/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/accesscontrol/ReadPolicy.java
index 3ed3530eac..b905fb0ae6 100644
--- 
a/oak-security-spi/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/accesscontrol/ReadPolicy.java
+++ 
b/oak-security-spi/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/accesscontrol/ReadPolicy.java
@@ -16,6 +16,8 @@
  */
 package org.apache.jackrabbit.oak.spi.security.authorization.accesscontrol;
 
+import 
org.apache.jackrabbit.oak.spi.security.authorization.permission.PermissionProvider;
+import 
org.apache.jackrabbit.oak.spi.security.authorization.permission.Permissions;
 import org.apache.jackrabbit.util.Text;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
@@ -49,4 +51,22 @@ public final class ReadPolicy implements 
NamedAccessControlPolicy {
         }
         return false;
     }
+    
+    /**
+     * Evaluates if a {@code ReadPolicy} is accessible for a session object. 
Note that this method does not verify if 
+     * the specified paths point to existing/accessible trees.
+     * 
+     * @param permissionProvider A permission provider used for evaluating 
access
+     * @param oakPaths The set of configured readable paths.
+     * @return {@code true} if the given permission provider has 
READ_ACCESS_CONTROL granted on any of the specified 
+     * readable oak paths; {@code false} otherwise.
+     */
+    public static boolean canAccessReadPolicy(@NotNull PermissionProvider 
permissionProvider, @NotNull String... oakPaths) {
+        for (String path : oakPaths) {
+            if (permissionProvider.isGranted(path, 
Permissions.PERMISSION_NAMES.get(Permissions.READ_ACCESS_CONTROL))) {
+                return true;
+            }
+        }
+        return false;
+    }
 }
\ No newline at end of file
diff --git 
a/oak-security-spi/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/accesscontrol/package-info.java
 
b/oak-security-spi/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/accesscontrol/package-info.java
index fdd635b15e..fef70dc81f 100644
--- 
a/oak-security-spi/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/accesscontrol/package-info.java
+++ 
b/oak-security-spi/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/accesscontrol/package-info.java
@@ -14,7 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-@Version("1.10.0")
+@Version("1.11.0")
 package org.apache.jackrabbit.oak.spi.security.authorization.accesscontrol;
 
 import org.osgi.annotation.versioning.Version;
diff --git 
a/oak-security-spi/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/accesscontrol/ReadPolicyTest.java
 
b/oak-security-spi/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/accesscontrol/ReadPolicyTest.java
index 2e8d32b130..f3895e9744 100644
--- 
a/oak-security-spi/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/accesscontrol/ReadPolicyTest.java
+++ 
b/oak-security-spi/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/accesscontrol/ReadPolicyTest.java
@@ -18,6 +18,8 @@ package 
org.apache.jackrabbit.oak.spi.security.authorization.accesscontrol;
 
 import com.google.common.collect.ImmutableSet;
 import org.apache.jackrabbit.oak.commons.PathUtils;
+import 
org.apache.jackrabbit.oak.spi.security.authorization.permission.PermissionProvider;
+import 
org.apache.jackrabbit.oak.spi.security.authorization.permission.Permissions;
 import org.junit.Test;
 
 import java.util.Collections;
@@ -25,6 +27,8 @@ import java.util.Collections;
 import static org.junit.Assert.assertEquals;
 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 ReadPolicyTest {
 
@@ -54,4 +58,20 @@ public class ReadPolicyTest {
         
assertTrue(ReadPolicy.hasEffectiveReadPolicy(ImmutableSet.of("/another/path", 
"/some/random/path"), path));
         
assertTrue(ReadPolicy.hasEffectiveReadPolicy(ImmutableSet.of("/another/path", 
PathUtils.ROOT_PATH), path));
     }
+    
+    @Test
+    public void testCanAccessReadPolicy() {
+        PermissionProvider pp = mock(PermissionProvider.class);
+        
+        assertFalse(ReadPolicy.canAccessReadPolicy(pp));
+        assertFalse(ReadPolicy.canAccessReadPolicy(pp, "/test/path"));
+        
+        when(pp.isGranted("/test/path", 
Permissions.PERMISSION_NAMES.get(Permissions.READ_ACCESS_CONTROL))).thenReturn(true);
+
+        assertFalse(ReadPolicy.canAccessReadPolicy(pp));
+        assertFalse(ReadPolicy.canAccessReadPolicy(pp, "/different/path"));
+
+        assertTrue(ReadPolicy.canAccessReadPolicy(pp, "/test/path"));
+        assertTrue(ReadPolicy.canAccessReadPolicy(pp, "/different/path", 
"/test/path"));
+    }
 }
\ No newline at end of file

Reply via email to