You are viewing a plain text version of this content. The canonical link for it is here.
Posted to oak-commits@jackrabbit.apache.org by an...@apache.org on 2019/02/12 16:24:35 UTC

svn commit: r1853451 - in /jackrabbit/oak/trunk: oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/accesscontrol/AccessControlManagerImplTest.java oak-doc/src/site/markdown/security/accesscontrol/default.md

Author: angela
Date: Tue Feb 12 16:24:35 2019
New Revision: 1853451

URL: http://svn.apache.org/viewvc?rev=1853451&view=rev
Log:
OAK-8000 : AccessControlManagerImpl.getEffectivePolicies(String) doesn't respect restrictions (tests and docu update)

Modified:
    jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/accesscontrol/AccessControlManagerImplTest.java
    jackrabbit/oak/trunk/oak-doc/src/site/markdown/security/accesscontrol/default.md

Modified: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/accesscontrol/AccessControlManagerImplTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/accesscontrol/AccessControlManagerImplTest.java?rev=1853451&r1=1853450&r2=1853451&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/accesscontrol/AccessControlManagerImplTest.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/accesscontrol/AccessControlManagerImplTest.java Tue Feb 12 16:24:35 2019
@@ -16,37 +16,11 @@
  */
 package org.apache.jackrabbit.oak.security.authorization.accesscontrol;
 
-import java.security.Principal;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import javax.jcr.AccessDeniedException;
-import javax.jcr.NamespaceRegistry;
-import javax.jcr.PathNotFoundException;
-import javax.jcr.PropertyType;
-import javax.jcr.RepositoryException;
-import javax.jcr.Value;
-import javax.jcr.ValueFactory;
-import javax.jcr.security.AccessControlEntry;
-import javax.jcr.security.AccessControlException;
-import javax.jcr.security.AccessControlList;
-import javax.jcr.security.AccessControlManager;
-import javax.jcr.security.AccessControlPolicy;
-import javax.jcr.security.AccessControlPolicyIterator;
-import javax.jcr.security.Privilege;
-
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Iterables;
 import com.google.common.collect.Lists;
-
 import org.apache.jackrabbit.JcrConstants;
 import org.apache.jackrabbit.api.security.JackrabbitAccessControlEntry;
 import org.apache.jackrabbit.api.security.JackrabbitAccessControlList;
@@ -59,19 +33,21 @@ import org.apache.jackrabbit.oak.api.Con
 import org.apache.jackrabbit.oak.api.Root;
 import org.apache.jackrabbit.oak.api.Tree;
 import org.apache.jackrabbit.oak.api.Type;
-import org.apache.jackrabbit.oak.namepath.impl.GlobalNameMapper;
-import org.apache.jackrabbit.oak.namepath.impl.LocalNameMapper;
 import org.apache.jackrabbit.oak.namepath.NameMapper;
 import org.apache.jackrabbit.oak.namepath.NamePathMapper;
+import org.apache.jackrabbit.oak.namepath.impl.GlobalNameMapper;
+import org.apache.jackrabbit.oak.namepath.impl.LocalNameMapper;
 import org.apache.jackrabbit.oak.namepath.impl.NamePathMapperImpl;
 import org.apache.jackrabbit.oak.plugins.name.ReadWriteNamespaceRegistry;
-import org.apache.jackrabbit.oak.spi.nodetype.NodeTypeConstants;
+import org.apache.jackrabbit.oak.plugins.tree.TreeUtil;
 import org.apache.jackrabbit.oak.plugins.value.jcr.ValueFactoryImpl;
+import org.apache.jackrabbit.oak.spi.nodetype.NodeTypeConstants;
 import org.apache.jackrabbit.oak.spi.security.authorization.AuthorizationConfiguration;
 import org.apache.jackrabbit.oak.spi.security.authorization.accesscontrol.ACE;
 import org.apache.jackrabbit.oak.spi.security.authorization.accesscontrol.AbstractAccessControlList;
 import org.apache.jackrabbit.oak.spi.security.authorization.accesscontrol.AbstractAccessControlManager;
 import org.apache.jackrabbit.oak.spi.security.authorization.accesscontrol.AccessControlConstants;
+import org.apache.jackrabbit.oak.spi.security.authorization.accesscontrol.ImmutableACL;
 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.principal.EveryonePrincipal;
@@ -80,13 +56,38 @@ import org.apache.jackrabbit.oak.spi.sec
 import org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeBitsProvider;
 import org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants;
 import org.apache.jackrabbit.oak.util.NodeUtil;
-import org.apache.jackrabbit.oak.plugins.tree.TreeUtil;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 
+import javax.jcr.AccessDeniedException;
+import javax.jcr.NamespaceRegistry;
+import javax.jcr.PathNotFoundException;
+import javax.jcr.PropertyType;
+import javax.jcr.RepositoryException;
+import javax.jcr.Value;
+import javax.jcr.ValueFactory;
+import javax.jcr.ValueFormatException;
+import javax.jcr.security.AccessControlEntry;
+import javax.jcr.security.AccessControlException;
+import javax.jcr.security.AccessControlList;
+import javax.jcr.security.AccessControlManager;
+import javax.jcr.security.AccessControlPolicy;
+import javax.jcr.security.AccessControlPolicyIterator;
+import javax.jcr.security.Privilege;
+import java.security.Principal;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
 import static com.google.common.collect.Sets.newHashSet;
 import static java.util.Collections.singletonMap;
 import static org.junit.Assert.assertArrayEquals;
@@ -269,11 +270,20 @@ public class AccessControlManagerImplTes
     @NotNull
     private ACL setupPolicy(@Nullable String path, @Nullable Privilege... privileges) throws RepositoryException {
         Privilege[] privs = (privileges == null || privileges.length == 0) ? testPrivileges : privileges;
+        return setupPolicy(path, privs, true, getGlobRestriction("*"), null);
+    }
+
+    @NotNull
+    private ACL setupPolicy(@Nullable String path,
+                            @NotNull Privilege[] privileges,
+                            boolean isAllow,
+                            @Nullable Map<String, Value> restrictions,
+                            @Nullable Map<String, Value[]> mvRestrictions) throws RepositoryException {
         ACL policy = getApplicablePolicy(path);
         if (path == null) {
-            policy.addAccessControlEntry(testPrincipal, privs);
+            policy.addAccessControlEntry(testPrincipal, privileges);
         } else {
-            policy.addEntry(testPrincipal, privs, true, getGlobRestriction("*"));
+            policy.addEntry(testPrincipal, privileges, isAllow, restrictions, mvRestrictions);
         }
         acMgr.setPolicy(path, policy);
         return policy;
@@ -283,6 +293,14 @@ public class AccessControlManagerImplTes
         return ImmutableMap.of(REP_GLOB, valueFactory.createValue(value));
     }
 
+    private Map<String, Value[]> getMvRestriction(@NotNull String name, int type, @NotNull String... values) throws ValueFormatException {
+        List<Value> list = new ArrayList<>();
+        for (String v : values) {
+            list.add(valueFactory.createValue(v, type));
+        }
+        return ImmutableMap.of(name, list.toArray(new Value[0]));
+    }
+
     protected List<String> getAcContentPaths() throws RepositoryException {
         ACL policy = getApplicablePolicy(testPath);
         policy.addEntry(testPrincipal, testPrivileges, true, getGlobRestriction("*"));
@@ -947,7 +965,7 @@ public class AccessControlManagerImplTes
     }
 
     @Test
-    public void testGetApplicablePoliciesInvalidPath() throws Exception {
+    public void testGetApplicablePoliciesInvalidPath() {
         for (String invalid : getInvalidPaths()) {
             try {
                 acMgr.getPolicies(invalid);
@@ -999,8 +1017,7 @@ public class AccessControlManagerImplTes
         acMgr.setPolicy(testPath, policy);
 
         AccessControlPolicy[] policies = acMgr.getPolicies(testPath);
-        assertNotNull(policies);
-        assertEquals(1, policies.length);
+        assertPolicies(policies, 1);
 
         assertTrue(policies[0] instanceof ACL);
         ACL acl = (ACL) policies[0];
@@ -1011,8 +1028,7 @@ public class AccessControlManagerImplTes
     @Test
     public void testGetPoliciesNodeNotAccessControlled() throws Exception {
         AccessControlPolicy[] policies = acMgr.getPolicies(testPath);
-        assertNotNull(policies);
-        assertEquals(0, policies.length);
+        assertPolicies(policies, 0);
     }
 
     @Test
@@ -1020,8 +1036,7 @@ public class AccessControlManagerImplTes
         setupPolicy(testPath);
 
         AccessControlPolicy[] policies = acMgr.getPolicies(testPath);
-        assertNotNull(policies);
-        assertEquals(1, policies.length);
+        assertPolicies(policies, 1);
 
         assertTrue(policies[0] instanceof ACL);
         ACL acl = (ACL) policies[0];
@@ -1033,14 +1048,12 @@ public class AccessControlManagerImplTes
         setupPolicy(testPath);
 
         AccessControlPolicy[] policies = acMgr.getPolicies(testPath);
-        assertNotNull(policies);
-        assertEquals(1, policies.length);
+        assertPolicies(policies, 1);
 
         acMgr.removePolicy(testPath, policies[0]);
 
         policies = acMgr.getPolicies(testPath);
-        assertNotNull(policies);
-        assertEquals(0, policies.length);
+        assertPolicies(policies, 0);
         assertTrue(acMgr.getApplicablePolicies(testPath).hasNext());
     }
 
@@ -1057,8 +1070,7 @@ public class AccessControlManagerImplTes
 
         // reading policies with unknown principal name should not fail.
         AccessControlPolicy[] policies = acMgr.getPolicies(testPath);
-        assertNotNull(policies);
-        assertEquals(1, policies.length);
+        assertPolicies(policies, 1);
 
         ACL acl = (ACL) policies[0];
         List<String> principalNames = new ArrayList<String>();
@@ -1075,15 +1087,13 @@ public class AccessControlManagerImplTes
         String path = null;
 
         AccessControlPolicy[] policies = acMgr.getPolicies(path);
-        assertNotNull(policies);
-        assertEquals(0, policies.length);
+        assertPolicies(policies, 0);
 
         acMgr.setPolicy(null, acMgr.getApplicablePolicies(path).nextAccessControlPolicy());
         assertFalse(acMgr.getApplicablePolicies(path).hasNext());
 
         policies = acMgr.getPolicies(path);
-        assertNotNull(policies);
-        assertEquals(1, policies.length);
+        assertPolicies(policies, 1);
 
         assertTrue(policies[0] instanceof ACL);
         ACL acl = (ACL) policies[0];
@@ -1093,7 +1103,7 @@ public class AccessControlManagerImplTes
         assertFalse(acMgr.getApplicablePolicies(path).hasNext());
 
         acMgr.removePolicy(path, acl);
-        assertEquals(0, acMgr.getPolicies(path).length);
+        assertPolicies(acMgr.getPolicies(path), 0);
         assertTrue(acMgr.getApplicablePolicies(path).hasNext());
     }
 
@@ -1159,56 +1169,124 @@ public class AccessControlManagerImplTes
         assertPolicies(acMgr.getEffectivePolicies(testPath), 0);
     }
 
-    @Test
     public void testGetEffectivePolicies() throws Exception {
-        AccessControlPolicy[] policies = acMgr.getEffectivePolicies(testPath);
-        assertNotNull(policies);
-        assertEquals(0, policies.length);
+        setupPolicy(testPath);
+        root.commit();
 
+        assertPolicies(acMgr.getEffectivePolicies(testPath), 1);
+    }
+
+    @Test
+    public void testGetEffectivePoliciesOnChild() throws Exception {
         setupPolicy(testPath);
+        Tree child = TreeUtil.addChild(root.getTree(testPath), "child", JcrConstants.NT_UNSTRUCTURED);
         root.commit();
 
-        policies = acMgr.getEffectivePolicies(testPath);
-        assertNotNull(policies);
-        assertEquals(1, policies.length);
+        String childPath = child.getPath();
+        assertPolicies(acMgr.getEffectivePolicies(childPath), 1);
+    }
 
-        NodeUtil child = new NodeUtil(root.getTree(testPath)).addChild("child", JcrConstants.NT_UNSTRUCTURED);
-        String childPath = child.getTree().getPath();
+    @Test
+    public void testGetEffectivePoliciesOnNewChild() throws Exception {
+        setupPolicy(testPath);
+        root.commit();
 
-        policies = acMgr.getEffectivePolicies(childPath);
-        assertNotNull(policies);
-        assertEquals(1, policies.length);
+        Tree child = TreeUtil.addChild(root.getTree(testPath), "child", JcrConstants.NT_UNSTRUCTURED);
+        String childPath = child.getPath();
+
+        assertPolicies(acMgr.getEffectivePolicies(childPath), 1);
+    }
 
+    @Test
+    public void testGetEffectivePoliciesOnChild2() throws Exception {
+        Tree child = TreeUtil.addChild(root.getTree(testPath), "child", JcrConstants.NT_UNSTRUCTURED);
+        String childPath = child.getPath();
         setupPolicy(childPath);
+        setupPolicy(testPath);
         root.commit();
 
-        policies = acMgr.getEffectivePolicies(childPath);
-        assertNotNull(policies);
-        assertEquals(2, policies.length);
+        AccessControlPolicy[] policies = acMgr.getEffectivePolicies(childPath);
+        assertPolicies(policies, 2);
+
+        for (AccessControlPolicy policy : policies) {
+            assertTrue(policy instanceof ImmutableACL);
+        }
+    }
+
+    @Test
+    public void testGetEffectivePoliciesMatchingRestriction() throws Exception {
+        ACL policy = setupPolicy(testPath, privilegesFromNames(PrivilegeConstants.JCR_READ), true, null,
+                getMvRestriction(REP_ITEM_NAMES, PropertyType.NAME,"child"));
+        policy.addEntry(EveryonePrincipal.getInstance(), testPrivileges, false, null,
+                getMvRestriction(REP_ITEM_NAMES, PropertyType.NAME,"notMatching"));
+        acMgr.setPolicy(policy.getPath(), policy);
+
+        Tree child = TreeUtil.addChild(root.getTree(testPath), "child", JcrConstants.NT_UNSTRUCTURED);
+        Tree grandChild = TreeUtil.addChild(child, "child", JcrConstants.NT_UNSTRUCTURED);
+        root.commit();
+
+        assertPolicies(acMgr.getEffectivePolicies(testPath), 1);
+        AccessControlPolicy[] policies = acMgr.getEffectivePolicies(child.getPath());
+        assertPolicies(policies, 1);
+
+        // only the matching ACE must be included in the effective policy
+        AccessControlPolicy effective = policies[0];
+        assertTrue(effective instanceof ImmutableACL);
+        assertEquals(2, ((ImmutableACL) effective).getAccessControlEntries().length);
+
+        assertPolicies(acMgr.getEffectivePolicies(grandChild.getPath()), 1);
+    }
+
+    /**
+     * An ACE restriction matching only a property (like e.g. jcr:primaryType) would not be included in the effective
+     * policies, becauce AccessControlManager.getEffectivePolicies(String) requires the path to point to an existing
+     * JCR node.
+     */
+    @Test
+    public void testGetEffectivePoliciesMatchingPropertyRestriction() throws Exception {
+        ACL policy = setupPolicy(testPath, privilegesFromNames(PrivilegeConstants.JCR_READ), true, null,
+                getMvRestriction(REP_ITEM_NAMES, PropertyType.NAME,JcrConstants.JCR_PRIMARYTYPE));
+        acMgr.setPolicy(policy.getPath(), policy);
+
+        Tree child = TreeUtil.addChild(root.getTree(testPath), "child", JcrConstants.NT_UNSTRUCTURED);
+        Tree grandChild = TreeUtil.addChild(child, "child", JcrConstants.NT_UNSTRUCTURED);
+        root.commit();
+
+        assertPolicies(acMgr.getEffectivePolicies(testPath), 1);
+        assertPolicies(acMgr.getEffectivePolicies(child.getPath()), 1);
+        assertPolicies(acMgr.getEffectivePolicies(grandChild.getPath()), 1);
+    }
+
+    @Test
+    public void testGetEffectivePoliciesNotMatchingRestriction() throws Exception {
+        setupPolicy(testPath, privilegesFromNames(PrivilegeConstants.JCR_READ), true, null,
+                getMvRestriction(REP_ITEM_NAMES, PropertyType.NAME,"child"));
+
+        Tree child = TreeUtil.addChild(root.getTree(testPath), "child", JcrConstants.NT_UNSTRUCTURED);
+        Tree grandChild = TreeUtil.addChild(child, "grandChild", JcrConstants.NT_UNSTRUCTURED);
+        Tree other = TreeUtil.addChild(root.getTree(testPath), "other", JcrConstants.NT_UNSTRUCTURED);
+
+        root.commit();
+
+        assertPolicies(acMgr.getEffectivePolicies(testPath), 1);
+        assertPolicies(acMgr.getEffectivePolicies(grandChild.getPath()), 1);
+        assertPolicies(acMgr.getEffectivePolicies(other.getPath()), 1);
     }
 
     @Test
     public void testGetEffectivePoliciesNewPolicy() throws Exception {
-        AccessControlPolicy[] policies = acMgr.getEffectivePolicies(testPath);
-        assertNotNull(policies);
-        assertEquals(0, policies.length);
+        assertPolicies(acMgr.getEffectivePolicies(testPath), 0);
 
         setupPolicy(testPath);
-        policies = acMgr.getEffectivePolicies(testPath);
-        assertNotNull(policies);
-        assertEquals(0, policies.length);
+        assertPolicies(acMgr.getEffectivePolicies(testPath), 0);
 
-        NodeUtil child = new NodeUtil(root.getTree(testPath)).addChild("child", JcrConstants.NT_UNSTRUCTURED);
-        String childPath = child.getTree().getPath();
+        Tree child = TreeUtil.addChild(root.getTree(testPath),"child", JcrConstants.NT_UNSTRUCTURED);
+        String childPath = child.getPath();
 
-        policies = acMgr.getEffectivePolicies(childPath);
-        assertNotNull(policies);
-        assertEquals(0, policies.length);
+        assertPolicies(acMgr.getEffectivePolicies(childPath), 0);
 
         setupPolicy(childPath);
-        policies = acMgr.getEffectivePolicies(childPath);
-        assertNotNull(policies);
-        assertEquals(0, policies.length);
+        assertPolicies(acMgr.getEffectivePolicies(childPath), 0);
     }
 
     @Test
@@ -1221,8 +1299,8 @@ public class AccessControlManagerImplTes
         acMgr.setPolicy(testPath, acl);
 
         AccessControlPolicy[] policies = acMgr.getEffectivePolicies(testPath);
-        assertNotNull(policies);
-        assertEquals(1, policies.length);
+        assertPolicies(acMgr.getEffectivePolicies(testPath), 1);
+
         assertTrue(policies[0] instanceof AccessControlList);
         AccessControlEntry[] effectiveAces = ((AccessControlList) policies[0]).getAccessControlEntries();
         assertArrayEquals(aces, effectiveAces);
@@ -1230,7 +1308,7 @@ public class AccessControlManagerImplTes
     }
 
     @Test
-    public void testGetEffectivePoliciesInvalidPath() throws Exception {
+    public void testGetEffectivePoliciesInvalidPath() {
         for (String invalid : getInvalidPaths()) {
             try {
                 acMgr.getEffectivePolicies(invalid);
@@ -1241,26 +1319,16 @@ public class AccessControlManagerImplTes
         }
     }
 
-    @Test
+    @Test(expected = PathNotFoundException.class)
     public void testGetEffectivePoliciesForPropertyPath() throws Exception {
         String propertyPath = "/jcr:primaryType";
-        try {
-            acMgr.getEffectivePolicies(propertyPath);
-            fail("Getting policies for property should fail.");
-        } catch (PathNotFoundException e) {
-            // success
-        }
+        acMgr.getEffectivePolicies(propertyPath);
     }
 
-    @Test
+    @Test(expected = PathNotFoundException.class)
     public void testGetEffectivePoliciesNonExistingNodePath() throws Exception {
         String nonExistingPath = "/not/existing";
-        try {
-            acMgr.getEffectivePolicies(nonExistingPath);
-            fail("Getting policies for node that doesn't exist should fail.");
-        } catch (PathNotFoundException e) {
-            // success
-        }
+        acMgr.getEffectivePolicies(nonExistingPath);
     }
 
     @Test
@@ -1294,8 +1362,7 @@ public class AccessControlManagerImplTes
         // diff to jr core: getEffectivePolicies will just return the policies
         // accessible for the editing session but not throw an exception.
         AccessControlPolicy[] effective = testAcMgr.getEffectivePolicies(testPath);
-        assertNotNull(effective);
-        assertEquals(1, effective.length);
+        assertPolicies(effective, 1);
     }
 
     /**
@@ -1319,8 +1386,7 @@ public class AccessControlManagerImplTes
         // diff to jr core: getEffectivePolicies will just return the policies
         // accessible for the editing session but not throw an exception.
         AccessControlPolicy[] effective = testAcMgr.getEffectivePolicies(childPath);
-        assertNotNull(effective);
-        assertEquals(1, effective.length);
+        assertPolicies(effective, 1);
     }
 
     @Test
@@ -1358,7 +1424,7 @@ public class AccessControlManagerImplTes
 
         Root root2 = adminSession.getLatestRoot();
         AccessControlPolicy[] policies = getAccessControlManager(root2).getPolicies(testPath);
-        assertEquals(1, policies.length);
+        assertPolicies(policies, 1);
         assertArrayEquals(acl.getAccessControlEntries(), ((ACL) policies[0]).getAccessControlEntries());
     }
 
@@ -1372,7 +1438,7 @@ public class AccessControlManagerImplTes
 
         Root root2 = adminSession.getLatestRoot();
         AccessControlPolicy[] policies = getAccessControlManager(root2).getPolicies((String) null);
-        assertEquals(1, policies.length);
+        assertPolicies(policies, 1);
         assertArrayEquals(acl.getAccessControlEntries(), ((ACL) policies[0]).getAccessControlEntries());
     }
 
@@ -1623,7 +1689,7 @@ public class AccessControlManagerImplTes
 
         acMgr.removePolicy(testPath, acl);
 
-        assertEquals(0, acMgr.getPolicies(testPath).length);
+        assertPolicies(acMgr.getPolicies(testPath), 0);
         assertTrue(acMgr.getApplicablePolicies(testPath).hasNext());
     }
 
@@ -1633,7 +1699,7 @@ public class AccessControlManagerImplTes
 
         acMgr.removePolicy(null, acl);
 
-        assertEquals(0, acMgr.getPolicies((String) null).length);
+        assertPolicies(acMgr.getPolicies((String) null), 0);
         assertTrue(acMgr.getApplicablePolicies((String) null).hasNext());
     }
 
@@ -1765,7 +1831,7 @@ public class AccessControlManagerImplTes
         }
         unknown = new PrincipalImpl("unknown" + i);
 
-        assertEquals(1, acMgr.getApplicablePolicies(unknown).length);
+        assertPolicies(acMgr.getApplicablePolicies(unknown), 1);
     }
 
     @Test
@@ -1773,9 +1839,7 @@ public class AccessControlManagerImplTes
         List<Principal> principals = ImmutableList.of(testPrincipal, EveryonePrincipal.getInstance());
         for (Principal principal : principals) {
             AccessControlPolicy[] applicable = acMgr.getApplicablePolicies(principal);
-
-            assertNotNull(applicable);
-            assertEquals(1, applicable.length);
+            assertPolicies(applicable, 1);
             assertTrue(applicable[0] instanceof ACL);
         }
     }
@@ -1786,15 +1850,12 @@ public class AccessControlManagerImplTes
 
         // changes not yet persisted -> no existing policies found for user
         AccessControlPolicy[] applicable = acMgr.getApplicablePolicies(testPrincipal);
-        assertNotNull(applicable);
-        assertEquals(1, applicable.length);
+        assertPolicies(applicable, 1);
         assertTrue(applicable[0] instanceof ACL);
 
         // after persisting changes -> no applicable policies present any more.
         root.commit();
-        applicable = acMgr.getApplicablePolicies(testPrincipal);
-        assertNotNull(applicable);
-        assertEquals(0, applicable.length);
+        assertPolicies(acMgr.getApplicablePolicies(testPrincipal), 0);
     }
 
     @Test
@@ -1810,8 +1871,7 @@ public class AccessControlManagerImplTes
             // testRoot can't read access control content -> doesn't see
             // the existing policies and creates a new applicable policy.
             AccessControlPolicy[] applicable = testAcMgr.getApplicablePolicies(principal);
-            assertNotNull(applicable);
-            assertEquals(1, applicable.length);
+            assertPolicies(applicable, 1);
             assertTrue(applicable[0] instanceof ACL);
         }
     }
@@ -1851,17 +1911,14 @@ public class AccessControlManagerImplTes
             unknown = getPrincipalManager(root).getPrincipal("unknown"+i);
         }
         unknown = new PrincipalImpl("unknown" + i);
-        assertEquals(0, acMgr.getPolicies(unknown).length);
+        assertPolicies(acMgr.getPolicies(unknown), 0);
     }
 
     @Test
     public void testGetPoliciesByPrincipal() throws Exception {
         List<Principal> principals = ImmutableList.of(testPrincipal, EveryonePrincipal.getInstance());
         for (Principal principal : principals) {
-            AccessControlPolicy[] policies = acMgr.getPolicies(principal);
-
-            assertNotNull(policies);
-            assertEquals(0, policies.length);
+            assertPolicies(acMgr.getPolicies(principal), 0);
         }
     }
 
@@ -1870,15 +1927,11 @@ public class AccessControlManagerImplTes
         setupPolicy(testPath);
 
         // changes not yet persisted -> no existing policies found for user
-        AccessControlPolicy[] policies = acMgr.getPolicies(testPrincipal);
-        assertNotNull(policies);
-        assertEquals(0, policies.length);
+        assertPolicies(acMgr.getPolicies(testPrincipal), 0);
 
         // after persisting changes -> policies must be found
         root.commit();
-        policies = acMgr.getPolicies(testPrincipal);
-        assertNotNull(policies);
-        assertEquals(1, policies.length);
+        assertPolicies(acMgr.getPolicies(testPrincipal), 1);
     }
 
     @Test
@@ -1932,11 +1985,10 @@ public class AccessControlManagerImplTes
                 // testRoot can't read access control content -> doesn't see
                 // the existing policies and creates a new applicable policy.
                 AccessControlPolicy[] policies = testAcMgr.getPolicies(principal);
-                assertNotNull(policies);
-                assertEquals(0, policies.length);
+                assertPolicies(policies, 0);
             } else {
                 // testRoot can't read principal -> no policies for that principal
-                assertEquals(0, testAcMgr.getPolicies(principal).length);
+                assertPolicies(testAcMgr.getPolicies(principal), 0);
             }
         }
     }
@@ -1992,27 +2044,24 @@ public class AccessControlManagerImplTes
 
         for (Set<Principal> principals : principalSets) {
             AccessControlPolicy[] policies = acMgr.getEffectivePolicies(principals);
-            assertNotNull(policies);
-            assertEquals(0, policies.length);
+            assertPolicies(policies, 0);
         }
 
         setupPolicy(testPath);
         // changes not yet persisted -> no effecitve policies found for testprincipal
         for (Set<Principal> principals : principalSets) {
             AccessControlPolicy[] policies = acMgr.getEffectivePolicies(principals);
-            assertNotNull(policies);
-            assertEquals(0, policies.length);
+            assertPolicies(policies, 0);
         }
 
         root.commit();
         // after persisting changes -> the policy must be found
         for (Set<Principal> principals : principalSets) {
             AccessControlPolicy[] policies = acMgr.getEffectivePolicies(principals);
-            assertNotNull(policies);
             if (principals.contains(testPrincipal)) {
-                assertEquals(1, policies.length);
+                assertPolicies(policies, 1);
             } else {
-                assertEquals(0, policies.length);
+                assertPolicies(policies, 0);
             }
         }
 
@@ -2022,11 +2071,10 @@ public class AccessControlManagerImplTes
         // changes not yet persisted -> no effecitve policies found for testprincipal
         for (Set<Principal> principals : principalSets) {
             AccessControlPolicy[] policies = acMgr.getEffectivePolicies(principals);
-            assertNotNull(policies);
             if (principals.contains(testPrincipal)) {
-                assertEquals(1, policies.length);
+                assertPolicies(policies, 1);
             } else {
-                assertEquals(0, policies.length);
+                assertPolicies(policies, 0);
             }
         }
 
@@ -2034,11 +2082,10 @@ public class AccessControlManagerImplTes
         // after persisting changes -> the policy must be found
         for (Set<Principal> principals : principalSets) {
             AccessControlPolicy[] policies = acMgr.getEffectivePolicies(principals);
-            assertNotNull(policies);
             if (principals.contains(testPrincipal)) {
-                assertEquals(2, policies.length);
+                assertPolicies(policies, 2);
             } else {
-                assertEquals(0, policies.length);
+                assertPolicies(policies, 0);
             }
         }
     }
@@ -2057,7 +2104,7 @@ public class AccessControlManagerImplTes
         root.commit();
 
         AccessControlPolicy[] policies = acMgr.getEffectivePolicies(principalSet);
-        assertEquals(1, policies.length);
+        assertPolicies(policies, 1);
 
         // add another policy
         NodeUtil child = new NodeUtil(root.getTree(testPath)).addChild("child", JcrConstants.NT_UNSTRUCTURED);
@@ -2065,8 +2112,7 @@ public class AccessControlManagerImplTes
         setupPolicy(childPath);
         root.commit();
 
-        policies = acMgr.getEffectivePolicies(principalSet);
-        assertEquals(2, policies.length);
+        assertPolicies(acMgr.getEffectivePolicies(principalSet), 2);
     }
 
     @Test
@@ -2096,7 +2142,7 @@ public class AccessControlManagerImplTes
             root.commit();
 
             AccessControlPolicy[] effectivePolicies = acMgr.getEffectivePolicies(principalSet);
-            assertEquals(3, effectivePolicies.length);
+            assertPolicies(effectivePolicies, 3);
 
             assertNull(((JackrabbitAccessControlPolicy) effectivePolicies[0]).getPath());
             assertEquals(testPath, ((JackrabbitAccessControlPolicy) effectivePolicies[1]).getPath());
@@ -2136,7 +2182,7 @@ public class AccessControlManagerImplTes
 
         for (Principal princ : principals) {
             AccessControlPolicy[] policies = acMgr.getEffectivePolicies(ImmutableSet.of(princ));
-            assertEquals(1, policies.length);
+            assertPolicies(policies, 1);
             assertTrue(policies[0] instanceof AccessControlList);
 
             AccessControlList acl = (AccessControlList) policies[0];
@@ -2162,8 +2208,7 @@ public class AccessControlManagerImplTes
         JackrabbitAccessControlManager testAcMgr = getTestAccessControlManager();
 
         AccessControlPolicy[] effective = testAcMgr.getEffectivePolicies(Collections.singleton(testPrincipal));
-        assertNotNull(effective);
-        assertEquals(2, effective.length);
+        assertPolicies(effective, 2);
     }
 
     /**
@@ -2187,8 +2232,7 @@ public class AccessControlManagerImplTes
         JackrabbitAccessControlManager testAcMgr = getTestAccessControlManager();
 
         AccessControlPolicy[] effective = testAcMgr.getEffectivePolicies(Collections.singleton(testPrincipal));
-        assertNotNull(effective);
-        assertEquals(1, effective.length);
+        assertPolicies(effective, 1);
     }
 
     /**
@@ -2209,8 +2253,7 @@ public class AccessControlManagerImplTes
         JackrabbitAccessControlManager testAcMgr = getTestAccessControlManager();
 
         AccessControlPolicy[] effective = testAcMgr.getEffectivePolicies(Collections.singleton(testPrincipal));
-        assertNotNull(effective);
-        assertEquals(1, effective.length);
+        assertPolicies(effective, 1);
     }
 
     @Test
@@ -2233,8 +2276,7 @@ public class AccessControlManagerImplTes
 
         Set<Principal> principals = ImmutableSet.of(testPrincipal, EveryonePrincipal.getInstance());
         AccessControlPolicy[] policies = testAcMgr.getEffectivePolicies(principals);
-        assertNotNull(policies);
-        assertEquals(2, policies.length);
+        assertPolicies(policies, 2);
     }
 
     /**
@@ -2263,16 +2305,14 @@ public class AccessControlManagerImplTes
 
         Set<Principal> principals = ImmutableSet.of(testPrincipal, EveryonePrincipal.getInstance());
         AccessControlPolicy[] policies = testAcMgr.getEffectivePolicies(principals);
-        assertNotNull(policies);
-        assertEquals(1, policies.length);
+        assertPolicies(policies, 1);
     }
 
     //-----------------------------------------------< setPrincipalPolicy() >---
     @Test
     public void testSetPrincipalPolicy() throws Exception {
         JackrabbitAccessControlPolicy[] applicable = acMgr.getApplicablePolicies(testPrincipal);
-        assertNotNull(applicable);
-        assertEquals(1, applicable.length);
+        assertPolicies(applicable, 1);
         assertTrue(applicable[0] instanceof ACL);
 
         ACL acl = (ACL) applicable[0];
@@ -2283,11 +2323,11 @@ public class AccessControlManagerImplTes
 
         Root root2 = adminSession.getLatestRoot();
         AccessControlPolicy[] policies = getAccessControlManager(root2).getPolicies(testPath);
-        assertEquals(1, policies.length);
+        assertPolicies(policies, 1);
         assertEquals(1, ((ACL) policies[0]).getAccessControlEntries().length);
 
         policies = getAccessControlManager(root2).getPolicies(testPrincipal);
-        assertEquals(1, policies.length);
+        assertPolicies(policies, 1);
         assertArrayEquals(acl.getAccessControlEntries(), ((ACL) policies[0]).getAccessControlEntries());
     }
 
@@ -2416,7 +2456,7 @@ public class AccessControlManagerImplTes
         acMgr.setPolicy(acl.getPath(), acl);
 
         // ... which must not have an effect and the policy must not be re-added.
-        assertEquals(0, acMgr.getPolicies(testPath).length);
+        assertPolicies(acMgr.getPolicies(testPath), 0);
     }
 
     //--------------------------------------------< removePrincipalPolicy() >---
@@ -2424,8 +2464,7 @@ public class AccessControlManagerImplTes
     @Test
     public void testRemovePrincipalPolicy() throws Exception {
         JackrabbitAccessControlPolicy[] applicable = acMgr.getApplicablePolicies(testPrincipal);
-        assertNotNull(applicable);
-        assertEquals(1, applicable.length);
+        assertPolicies(applicable, 1);
         assertTrue(applicable[0] instanceof ACL);
 
         ACL acl = (ACL) applicable[0];
@@ -2437,8 +2476,8 @@ public class AccessControlManagerImplTes
         acMgr.removePolicy(acl.getPath(), acl);
         root.commit();
 
-        assertEquals(0, acMgr.getPolicies(testPrincipal).length);
-        assertEquals(0, acMgr.getPolicies(testPath).length);
+        assertPolicies(acMgr.getPolicies(testPrincipal), 0);
+        assertPolicies(acMgr.getPolicies(testPath), 0);
     }
 
     @Test
@@ -2447,18 +2486,14 @@ public class AccessControlManagerImplTes
         root.commit();
 
         AccessControlPolicy[] policies = acMgr.getPolicies(testPrincipal);
-        assertNotNull(policies);
-        assertEquals(1, policies.length);
+        assertPolicies(policies, 1);
         assertTrue(policies[0] instanceof ACL);
 
         ACL acl = (ACL) policies[0];
         acMgr.removePolicy(acl.getPath(), acl);
 
-        policies = acMgr.getPolicies(testPath);
-        assertEquals(0, policies.length);
-
-        policies = acMgr.getPolicies(testPrincipal);
-        assertEquals(0, policies.length);
+        assertPolicies(acMgr.getPolicies(testPath), 0);
+        assertPolicies(acMgr.getPolicies(testPrincipal), 0);
     }
 
     @Test(expected = AccessControlException.class)

Modified: jackrabbit/oak/trunk/oak-doc/src/site/markdown/security/accesscontrol/default.md
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-doc/src/site/markdown/security/accesscontrol/default.md?rev=1853451&r1=1853450&r2=1853451&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-doc/src/site/markdown/security/accesscontrol/default.md (original)
+++ jackrabbit/oak/trunk/oak-doc/src/site/markdown/security/accesscontrol/default.md Tue Feb 12 16:24:35 2019
@@ -99,6 +99,17 @@ option. However, it is important to note
 accessibility of the namespace, nodetype and privilege information. Removing the
 corresponding paths from the configuration will most probably have undesired effects.
 
+##### Effective Policies
+
+The effective policies exposed by `AccessControlManager.getEffectivePolicies(String)` and 
+`JackrabbitAccessControlManager.getEffectivePolicies(Set<Principal>)` represent an immutable view on the 
+persisted policies taking effect act the given path or for the given set of principals. Transient 
+modifications that are the result of `setPolicy` and `removePolicy` will not be reflected.
+
+Note however, that these methods are defined to be a best-effort. In particular `AccessControlManager.getEffectivePolicies(String)`
+will not evaluate restrictions associated with individual entries that might limit the effect to individual items in the subtree. 
+See also [OAK-8000](https://issues.apache.org/jira/browse/OAK-8000) for details.
+
 #### Access Control Entries
 
 The access control entries present in a given list are subject to the following