Added: 
jackrabbit/oak/trunk/oak-authorization-principalbased/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/PermissionProviderInternalTypeTest.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-authorization-principalbased/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/PermissionProviderInternalTypeTest.java?rev=1857551&view=auto
==============================================================================
--- 
jackrabbit/oak/trunk/oak-authorization-principalbased/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/PermissionProviderInternalTypeTest.java
 (added)
+++ 
jackrabbit/oak/trunk/oak-authorization-principalbased/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/PermissionProviderInternalTypeTest.java
 Mon Apr 15 07:16:49 2019
@@ -0,0 +1,86 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package 
org.apache.jackrabbit.oak.spi.security.authorization.principalbased.impl;
+
+import com.google.common.collect.ImmutableSet;
+import org.apache.jackrabbit.api.security.principal.ItemBasedPrincipal;
+import org.apache.jackrabbit.oak.api.PropertyState;
+import org.apache.jackrabbit.oak.api.Tree;
+import org.apache.jackrabbit.oak.commons.PathUtils;
+import org.apache.jackrabbit.oak.namepath.NamePathMapper;
+import org.apache.jackrabbit.oak.plugins.tree.TreeType;
+import 
org.apache.jackrabbit.oak.spi.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.privilege.PrivilegeConstants;
+import org.apache.jackrabbit.oak.spi.state.NodeState;
+import org.junit.Before;
+import org.junit.Test;
+
+import static 
org.apache.jackrabbit.oak.spi.security.authorization.principalbased.impl.MockUtility.mockReadOnlyTree;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.mock;
+
+public class PermissionProviderInternalTypeTest extends 
AbstractPrincipalBasedTest {
+
+    private PrincipalBasedPermissionProvider permissionProvider;
+
+    @Before
+    public void before() throws Exception {
+        super.before();
+        permissionProvider = createPermissionProvider(root, 
getTestSystemUser().getPrincipal());
+    }
+
+    @Override
+    protected NamePathMapper getNamePathMapper() {
+        return NamePathMapper.DEFAULT;
+    }
+
+    @Test
+    public void testGetPrivileges() {
+        
assertTrue(permissionProvider.getPrivileges(mockReadOnlyTree(TreeType.INTERNAL)).isEmpty());
+    }
+
+    @Test
+    public void testHasPrivileges() {
+        
assertFalse(permissionProvider.hasPrivileges(mockReadOnlyTree(TreeType.INTERNAL),
 PrivilegeConstants.REP_READ_NODES));
+    }
+
+    @Test
+    public void testIsGranted() {
+        
assertFalse(permissionProvider.isGranted(mockReadOnlyTree(TreeType.INTERNAL), 
null, Permissions.ALL));
+        
assertFalse(permissionProvider.isGranted(mockReadOnlyTree(TreeType.INTERNAL), 
mock(PropertyState.class), Permissions.ALL));
+    }
+    @Test
+    public void testGetTreePermission() throws Exception {
+        assertSame(TreePermission.EMPTY, 
permissionProvider.getTreePermission(mockReadOnlyTree(TreeType.INTERNAL), 
TreeType.INTERNAL, mock(AbstractTreePermission.class)));
+    }
+
+    @Test
+    public void testGetChildTreePermission() {
+        Tree readOnly = 
getRootProvider().createReadOnlyRoot(root).getTree(PathUtils.ROOT_PATH);
+        TreePermission tp = (AbstractTreePermission) 
permissionProvider.getTreePermission(readOnly, TreePermission.EMPTY);
+        NodeState ns = getTreeProvider().asNodeState(readOnly);
+        for (String elem : 
PathUtils.elements(PermissionConstants.PERMISSIONS_STORE_PATH)) {
+            ns = ns.getChildNode(elem);
+            tp = permissionProvider.getTreePermission(elem, ns, 
(AbstractTreePermission) tp);
+        }
+        assertSame(TreePermission.EMPTY, tp);
+    }
+}
\ No newline at end of file

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

Added: 
jackrabbit/oak/trunk/oak-authorization-principalbased/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/PermissionProviderVersionStoreTest.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-authorization-principalbased/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/PermissionProviderVersionStoreTest.java?rev=1857551&view=auto
==============================================================================
--- 
jackrabbit/oak/trunk/oak-authorization-principalbased/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/PermissionProviderVersionStoreTest.java
 (added)
+++ 
jackrabbit/oak/trunk/oak-authorization-principalbased/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/PermissionProviderVersionStoreTest.java
 Mon Apr 15 07:16:49 2019
@@ -0,0 +1,205 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package 
org.apache.jackrabbit.oak.spi.security.authorization.principalbased.impl;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Iterables;
+import org.apache.jackrabbit.JcrConstants;
+import org.apache.jackrabbit.api.security.JackrabbitAccessControlManager;
+import org.apache.jackrabbit.oak.api.Tree;
+import org.apache.jackrabbit.oak.commons.PathUtils;
+import org.apache.jackrabbit.oak.namepath.NamePathMapper;
+import org.apache.jackrabbit.oak.plugins.tree.TreeLocation;
+import org.apache.jackrabbit.oak.plugins.tree.TreeType;
+import org.apache.jackrabbit.oak.plugins.tree.TreeUtil;
+import org.apache.jackrabbit.oak.spi.nodetype.NodeTypeConstants;
+import 
org.apache.jackrabbit.oak.spi.security.authorization.permission.Permissions;
+import 
org.apache.jackrabbit.oak.spi.security.authorization.permission.TreePermission;
+import org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants;
+import org.apache.jackrabbit.oak.spi.state.NodeState;
+import org.junit.Before;
+import org.junit.Test;
+
+import javax.jcr.PropertyType;
+import javax.jcr.Value;
+import java.security.Principal;
+import java.util.Map;
+
+import static javax.jcr.Session.ACTION_READ;
+import static junit.framework.TestCase.assertNotNull;
+import static 
org.apache.jackrabbit.oak.spi.security.authorization.accesscontrol.AccessControlConstants.REP_NT_NAMES;
+import static 
org.apache.jackrabbit.oak.spi.version.VersionConstants.REP_VERSIONSTORAGE;
+import static 
org.apache.jackrabbit.oak.spi.version.VersionConstants.VERSION_STORE_PATH;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+
+public class PermissionProviderVersionStoreTest extends 
AbstractPrincipalBasedTest {
+
+    private Principal testPrincipal;
+    private PrincipalBasedPermissionProvider permissionProvider;
+
+    @Before
+    public void before() throws Exception {
+        super.before();
+
+        testPrincipal = getTestSystemUser().getPrincipal();
+        setupContentTrees(TEST_OAK_PATH);
+
+        String contentPath = PathUtils.getAncestorPath(TEST_OAK_PATH, 3);
+        String andPath = PathUtils.getAncestorPath(TEST_OAK_PATH, 3);
+
+        Tree typeRoot = root.getTree(NodeTypeConstants.NODE_TYPES_PATH);
+        for (String path : new String[] {contentPath, andPath, TEST_OAK_PATH}) 
{
+            TreeUtil.addMixin(root.getTree(path), 
NodeTypeConstants.MIX_VERSIONABLE, typeRoot, "uid");
+        }
+        root.commit();
+
+        permissionProvider = createPermissionProvider(root, testPrincipal);
+    }
+
+    @Override
+    protected NamePathMapper getNamePathMapper() {
+        return NamePathMapper.DEFAULT;
+    }
+
+    private void grantReadOnVersionStoreTrees() throws Exception {
+        JackrabbitAccessControlManager jacm = getAccessControlManager(root);
+        PrincipalPolicyImpl policy = getPrincipalPolicyImpl(testPrincipal, 
jacm);
+        Map<String, Value[]> restr = ImmutableMap.of(REP_NT_NAMES, new Value[] 
{getValueFactory(root).createValue(REP_VERSIONSTORAGE, PropertyType.NAME)});
+        policy.addEntry(PathUtils.ROOT_PATH, 
privilegesFromNames(PrivilegeConstants.JCR_READ), ImmutableMap.of(), restr);
+        jacm.setPolicy(policy.getPath(), policy);
+        root.commit();
+
+        permissionProvider.refresh();
+    }
+
+    @Test
+    public void testGetTreePermission() {
+        Tree tree = 
getRootProvider().createReadOnlyRoot(root).getTree(PathUtils.ROOT_PATH);
+        TreePermission tp = permissionProvider.getTreePermission(tree, 
TreePermission.EMPTY);
+        for (String elem : PathUtils.elements(VERSION_STORE_PATH)) {
+            tree = tree.getChild(elem);
+            tp = permissionProvider.getTreePermission(tree, tp);
+        }
+
+        assertTrue(tp instanceof AbstractTreePermission);
+        AbstractTreePermission atp = (AbstractTreePermission) tp;
+        assertSame(TreeType.VERSION, atp.getType());
+        // must be 'regular' tree permission without extra versionable tree
+        assertSame(tree, atp.getTree());
+    }
+
+    @Test
+    public void testGetTreePermissionFromNodeState() {
+        Tree tree = 
getRootProvider().createReadOnlyRoot(root).getTree(PathUtils.ROOT_PATH);
+        TreePermission tp = permissionProvider.getTreePermission(tree, 
TreePermission.EMPTY);
+
+        NodeState ns = getTreeProvider().asNodeState(tree);
+        for (String elem : PathUtils.elements(VERSION_STORE_PATH)) {
+            ns = ns.getChildNode(elem);
+            tp = permissionProvider.getTreePermission(elem, ns, 
(AbstractTreePermission) tp);
+            assertTrue(tp instanceof AbstractTreePermission);
+        }
+
+        AbstractTreePermission atp = (AbstractTreePermission) tp;
+        assertSame(TreeType.VERSION, atp.getType());
+    }
+
+    @Test
+    public void testIsGranted() throws Exception {
+        Tree versionStore = root.getTree(VERSION_STORE_PATH);
+        assertFalse(permissionProvider.isGranted(versionStore, null, 
Permissions.READ_NODE));
+        assertFalse(permissionProvider.isGranted(versionStore, 
versionStore.getProperty(JcrConstants.JCR_PRIMARYTYPE), 
Permissions.READ_PROPERTY));
+
+        grantReadOnVersionStoreTrees();
+
+        assertTrue(permissionProvider.isGranted(versionStore, null, 
Permissions.READ_NODE));
+        assertTrue(permissionProvider.isGranted(versionStore, 
versionStore.getProperty(JcrConstants.JCR_PRIMARYTYPE), 
Permissions.READ_PROPERTY));
+    }
+
+    @Test
+    public void testIsGrantedTreeLocation() throws Exception {
+        TreeLocation tl = TreeLocation.create(root, VERSION_STORE_PATH);
+        assertFalse(permissionProvider.isGranted(tl, Permissions.READ_NODE));
+
+        grantReadOnVersionStoreTrees();
+
+        assertTrue(permissionProvider.isGranted(tl, Permissions.READ));
+    }
+
+    @Test
+    public void testIsGrantedPropertyLocation() throws Exception {
+        TreeLocation tl = TreeLocation.create(root, 
VERSION_STORE_PATH).getChild(JcrConstants.JCR_PRIMARYTYPE);
+        assertNotNull(tl.getProperty());
+
+        assertFalse(permissionProvider.isGranted(tl, 
Permissions.READ_PROPERTY));
+
+        grantReadOnVersionStoreTrees();
+
+        assertTrue(permissionProvider.isGranted(tl, 
Permissions.READ_PROPERTY));
+    }
+
+    @Test
+    public void testIsGrantedNonExistingLocation() throws Exception {
+        TreeLocation tl = TreeLocation.create(root, VERSION_STORE_PATH + 
"/nonExisting");
+        assertFalse(permissionProvider.isGranted(tl, Permissions.READ_NODE));
+
+        grantReadOnVersionStoreTrees();
+
+        assertFalse(permissionProvider.isGranted(tl, Permissions.READ_NODE));
+    }
+
+    @Test
+    public void testIsGrantedByPath() throws Exception {
+        assertFalse(permissionProvider.isGranted(VERSION_STORE_PATH, 
ACTION_READ));
+
+        grantReadOnVersionStoreTrees();
+
+        assertTrue(permissionProvider.isGranted(VERSION_STORE_PATH, 
ACTION_READ));
+    }
+
+    @Test
+    public void testIsGrantedByNonExistingPath() throws Exception {
+        assertFalse(permissionProvider.isGranted(VERSION_STORE_PATH + 
"/nonExisting", ACTION_READ));
+
+        grantReadOnVersionStoreTrees();
+
+        assertFalse(permissionProvider.isGranted(VERSION_STORE_PATH + 
"/nonExisting", ACTION_READ));
+    }
+
+    @Test
+    public void testGetPrivileges() throws Exception {
+        Tree versionStore = root.getTree(VERSION_STORE_PATH);
+        assertTrue(permissionProvider.getPrivileges(versionStore).isEmpty());
+
+        grantReadOnVersionStoreTrees();
+
+        
assertTrue(Iterables.elementsEqual(ImmutableSet.of(PrivilegeConstants.JCR_READ),
 permissionProvider.getPrivileges(versionStore)));
+    }
+
+    @Test
+    public void testHasPrivileges() throws Exception {
+        Tree versionStore = root.getTree(VERSION_STORE_PATH);
+        assertFalse(permissionProvider.hasPrivileges(versionStore, 
PrivilegeConstants.REP_READ_NODES));
+
+        grantReadOnVersionStoreTrees();
+
+        assertTrue(permissionProvider.hasPrivileges(versionStore, 
PrivilegeConstants.REP_READ_NODES, PrivilegeConstants.REP_READ_PROPERTIES));
+    }
+}
\ No newline at end of file

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

Added: 
jackrabbit/oak/trunk/oak-authorization-principalbased/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/PermissionProviderVersionTest.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-authorization-principalbased/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/PermissionProviderVersionTest.java?rev=1857551&view=auto
==============================================================================
--- 
jackrabbit/oak/trunk/oak-authorization-principalbased/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/PermissionProviderVersionTest.java
 (added)
+++ 
jackrabbit/oak/trunk/oak-authorization-principalbased/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/PermissionProviderVersionTest.java
 Mon Apr 15 07:16:49 2019
@@ -0,0 +1,323 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package 
org.apache.jackrabbit.oak.spi.security.authorization.principalbased.impl;
+
+import com.google.common.collect.Sets;
+import org.apache.jackrabbit.oak.api.PropertyState;
+import org.apache.jackrabbit.oak.api.Tree;
+import org.apache.jackrabbit.oak.api.Type;
+import org.apache.jackrabbit.oak.commons.PathUtils;
+import org.apache.jackrabbit.oak.namepath.NamePathMapper;
+import org.apache.jackrabbit.oak.plugins.identifier.IdentifierManager;
+import org.apache.jackrabbit.oak.plugins.tree.TreeLocation;
+import org.apache.jackrabbit.oak.plugins.tree.TreeType;
+import org.apache.jackrabbit.oak.plugins.tree.TreeUtil;
+import org.apache.jackrabbit.oak.spi.nodetype.NodeTypeConstants;
+import 
org.apache.jackrabbit.oak.spi.security.authorization.permission.Permissions;
+import 
org.apache.jackrabbit.oak.spi.security.authorization.permission.TreePermission;
+import org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants;
+import org.jetbrains.annotations.NotNull;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.security.Principal;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static javax.jcr.Session.ACTION_READ;
+import static org.apache.jackrabbit.JcrConstants.JCR_BASEVERSION;
+import static org.apache.jackrabbit.JcrConstants.JCR_ISCHECKEDOUT;
+import static org.apache.jackrabbit.JcrConstants.JCR_PRIMARYTYPE;
+import static org.apache.jackrabbit.JcrConstants.JCR_VERSIONHISTORY;
+import static 
org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants.JCR_LOCK_MANAGEMENT;
+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.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotSame;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+
+public class PermissionProviderVersionTest extends AbstractPrincipalBasedTest {
+
+    private Principal testPrincipal;
+    private PrincipalBasedPermissionProvider permissionProvider;
+
+    private String contentPath;
+    private String childPath;
+    private String grandchildPath;
+
+    @Before
+    public void before() throws Exception {
+        super.before();
+
+        testPrincipal = getTestSystemUser().getPrincipal();
+        setupContentTrees(TEST_OAK_PATH);
+
+        contentPath = PathUtils.getAncestorPath(TEST_OAK_PATH, 3);
+        childPath = PathUtils.getAncestorPath(TEST_OAK_PATH, 2);
+        grandchildPath = PathUtils.getAncestorPath(TEST_OAK_PATH, 1);
+
+        // setup permissions on childPath + TEST_OAK_PATH
+        PrincipalPolicyImpl policy = 
setupPrincipalBasedAccessControl(testPrincipal, 
getNamePathMapper().getJcrPath(childPath), JCR_READ);
+        addPrincipalBasedEntry(policy, 
getNamePathMapper().getJcrPath(TEST_OAK_PATH), 
PrivilegeConstants.JCR_VERSION_MANAGEMENT);
+
+        // versionabel nodes: contentPath + grandChildPath + TEST_OAK_PATH
+        // -> 1 TEST_OAK_PATH node hold policy, grandchildPath get it 
inherited and contentPath has no permissions granted
+        Tree typeRoot = root.getTree(NodeTypeConstants.NODE_TYPES_PATH);
+        for (String path : new String[] {contentPath, grandchildPath, 
TEST_OAK_PATH}) {
+            Tree versionable = root.getTree(path);
+            TreeUtil.addMixin(root.getTree(path), 
NodeTypeConstants.MIX_VERSIONABLE, typeRoot, "uid");
+        }
+        root.commit();
+
+        // force creation of a new version for grandchildPath, TEST_OAK_PATH 
but not for contentPath
+        // removing tree for contentPath will then also result in removal of 
VH upon removal.
+        for (String path : new String[] {grandchildPath, TEST_OAK_PATH}) {
+            root.getTree(path).setProperty(JCR_ISCHECKEDOUT, false);
+            root.commit();
+            root.getTree(path).setProperty(JCR_ISCHECKEDOUT, true);
+            root.commit();
+        }
+
+        permissionProvider = createPermissionProvider(root, testPrincipal);
+    }
+
+    @Override
+    protected NamePathMapper getNamePathMapper() {
+        return NamePathMapper.DEFAULT;
+    }
+
+    @NotNull
+    private String getVersionPath(@NotNull String versionablePath, boolean 
history) {
+        Tree versionable = root.getTree(versionablePath);
+        String path;
+        if (history) {
+            path = new 
IdentifierManager(root).getPath(versionable.getProperty(JCR_VERSIONHISTORY));
+        } else {
+            path = new 
IdentifierManager(root).getPath(versionable.getProperty(JCR_BASEVERSION));
+        }
+        checkNotNull(path);
+        return path;
+    }
+
+    @NotNull
+    private Tree getVersionTree(@NotNull String versionablePath, boolean 
history) {
+        Tree versionable = root.getTree(versionablePath);
+        PropertyState reference;
+        if (history) {
+            reference = versionable.getProperty(JCR_VERSIONHISTORY);
+        } else {
+            reference = versionable.getProperty(JCR_BASEVERSION);
+        }
+        Tree t = new 
IdentifierManager(root).getTree(reference.getValue(Type.STRING));
+        checkNotNull(t);
+        return t;
+    }
+
+    @Test
+    public void testGetTreePermission() {
+        Tree tree = 
getRootProvider().createReadOnlyRoot(root).getTree(PathUtils.ROOT_PATH);
+        TreePermission tp = permissionProvider.getTreePermission(tree, 
TreePermission.EMPTY);
+
+        for (String elem : PathUtils.elements(getVersionPath(TEST_OAK_PATH, 
false))) {
+            tree = tree.getChild(elem);
+            tp = permissionProvider.getTreePermission(tree, tp);
+        }
+
+        assertTrue(tp instanceof AbstractTreePermission);
+        AbstractTreePermission atp = (AbstractTreePermission) tp;
+        assertSame(TreeType.VERSION, atp.getType());
+        // tree must point to versionable node and NOT to the version tree
+        assertNotSame(tree, atp.getTree());
+        assertEquals(TEST_OAK_PATH, atp.getTree().getPath());
+    }
+
+    @Test
+    public void testGetTreePermissionVersionableNodeRemoved() throws Exception 
{
+        String versionPath = getVersionPath(TEST_OAK_PATH, false);
+
+        root.getTree(TEST_OAK_PATH).remove();
+        root.commit();
+        permissionProvider.refresh();
+
+        Tree tree = 
getRootProvider().createReadOnlyRoot(root).getTree(PathUtils.ROOT_PATH);
+        TreePermission tp = permissionProvider.getTreePermission(tree, 
TreePermission.EMPTY);
+
+        for (String elem : PathUtils.elements(versionPath)) {
+            tree = tree.getChild(elem);
+            tp = permissionProvider.getTreePermission(tree, tp);
+        }
+
+        assertTrue(tp instanceof AbstractTreePermission);
+        AbstractTreePermission atp = (AbstractTreePermission) tp;
+        assertSame(TreeType.VERSION, atp.getType());
+        // tree must point to non-existing versionable node and NOT to the 
version tree
+        assertNotSame(tree, atp.getTree());
+        assertFalse(atp.getTree().exists());
+        assertEquals(TEST_OAK_PATH, atp.getTree().getPath());
+    }
+
+    @Test
+    public void testGetTreePermissionVersionHistoryRemoved() throws Exception {
+        String vhPath = getVersionPath(contentPath, true);
+
+        root.getTree(contentPath).remove();
+        root.commit();
+        permissionProvider.refresh();
+
+        Tree tree = 
getRootProvider().createReadOnlyRoot(root).getTree(PathUtils.ROOT_PATH);
+        TreePermission tp = permissionProvider.getTreePermission(tree, 
TreePermission.EMPTY);
+
+        for (String elem : PathUtils.elements(vhPath)) {
+            tree = tree.getChild(elem);
+            tp = permissionProvider.getTreePermission(tree, tp);
+        }
+
+        assertSame(TreePermission.EMPTY, tp);
+    }
+
+    @Test
+    public void testIsGranted() throws Exception {
+        assertFalse(permissionProvider.isGranted(getVersionTree(contentPath, 
true), null, Permissions.READ_NODE));
+        
assertFalse(permissionProvider.isGranted(getVersionTree(grandchildPath, true), 
null, Permissions.READ_NODE|Permissions.VERSION_MANAGEMENT));
+        assertFalse(permissionProvider.isGranted(getVersionTree(TEST_OAK_PATH, 
true), null, Permissions.READ|Permissions.WRITE));
+
+
+        assertTrue(permissionProvider.isGranted(getVersionTree(grandchildPath, 
true), null, Permissions.READ_NODE));
+        assertTrue(permissionProvider.isGranted(getVersionTree(TEST_OAK_PATH, 
true), null, Permissions.READ|Permissions.VERSION_MANAGEMENT));
+    }
+
+    @Test
+    public void testIsGrantedWithProperty() throws Exception {
+        Tree t = getVersionTree(contentPath, true);
+        assertFalse(permissionProvider.isGranted(t, 
t.getProperty(JCR_PRIMARYTYPE), Permissions.READ_PROPERTY));
+
+        t = getVersionTree(grandchildPath, false);
+        assertFalse(permissionProvider.isGranted(t, 
t.getProperty(JCR_PRIMARYTYPE), 
Permissions.READ_PROPERTY|Permissions.VERSION_MANAGEMENT));
+
+        t = getVersionTree(TEST_OAK_PATH, true);
+        assertFalse(permissionProvider.isGranted(t, 
t.getProperty(JCR_PRIMARYTYPE), Permissions.READ_PROPERTY|Permissions.WRITE));
+
+
+        t = getVersionTree(grandchildPath, true);
+        assertTrue(permissionProvider.isGranted(t, 
t.getProperty(JCR_PRIMARYTYPE), Permissions.READ_PROPERTY));
+
+        t = getVersionTree(TEST_OAK_PATH, false);
+        assertTrue(permissionProvider.isGranted(t, 
t.getProperty(JCR_PRIMARYTYPE), 
Permissions.READ_PROPERTY|Permissions.VERSION_MANAGEMENT));
+    }
+
+    @Test
+    public void testIsGrantedVersionableTreeRemoved() throws Exception {
+        String versionPath = getVersionPath(TEST_OAK_PATH, false);
+
+        root.getTree(TEST_OAK_PATH).remove();
+        root.commit();
+        permissionProvider.refresh();
+
+        Tree versionTree = root.getTree(versionPath);
+        assertTrue(versionTree.exists());
+
+        // permissions not affected as they are stored with the principal.
+        assertTrue(permissionProvider.isGranted(versionTree, null, 
Permissions.READ|Permissions.VERSION_MANAGEMENT));
+    }
+
+    @Test
+    public void testIsGrantedVersionHistoryRemoved() throws Exception {
+        String vhPath = getVersionPath(contentPath, true);
+
+        root.getTree(contentPath).remove();
+        root.commit();
+        permissionProvider.refresh();
+
+        Tree vhTree = root.getTree(vhPath);
+        assertFalse(vhTree.exists());
+
+        // permissions affected because unable to resolve versionable tree
+        assertFalse(permissionProvider.isGranted(vhTree, null, 
Permissions.READ|Permissions.VERSION_MANAGEMENT));
+    }
+
+    @Test
+    public void testIsGrantedTreeLocation() throws Exception {
+        TreeLocation tl = TreeLocation.create(root, 
getVersionPath(contentPath, false));
+        assertFalse(permissionProvider.isGranted(tl, Permissions.READ_NODE));
+
+        tl = TreeLocation.create(root, getVersionPath(grandchildPath, true));
+        assertTrue(permissionProvider.isGranted(tl, Permissions.READ));
+
+        tl = TreeLocation.create(root, getVersionPath(TEST_OAK_PATH, false));
+        assertTrue(permissionProvider.isGranted(tl, 
Permissions.READ|Permissions.VERSION_MANAGEMENT));
+    }
+
+    @Test
+    public void testIsGrantedByPath() throws Exception {
+        assertFalse(permissionProvider.isGranted(getVersionPath(contentPath, 
false), ACTION_READ));
+        
assertFalse(permissionProvider.isGranted(getVersionPath(grandchildPath, true), 
Permissions.getString(Permissions.READ|Permissions.VERSION_MANAGEMENT)));
+        assertFalse(permissionProvider.isGranted(getVersionPath(TEST_OAK_PATH, 
false), Permissions.getString(Permissions.READ|Permissions.WRITE)));
+
+        assertTrue(permissionProvider.isGranted(getVersionPath(grandchildPath, 
false), ACTION_READ));
+        assertTrue(permissionProvider.isGranted(getVersionPath(TEST_OAK_PATH, 
true), Permissions.getString(Permissions.READ|Permissions.VERSION_MANAGEMENT)));
+    }
+
+    @Test
+    public void testGetPrivileges() throws Exception {
+        
assertTrue(permissionProvider.getPrivileges(getVersionTree(contentPath, 
true)).isEmpty());
+        assertEquals(Sets.newHashSet(JCR_READ), 
permissionProvider.getPrivileges(getVersionTree(grandchildPath, false)));
+        assertEquals(Sets.newHashSet(JCR_READ, JCR_VERSION_MANAGEMENT), 
permissionProvider.getPrivileges(getVersionTree(TEST_OAK_PATH, true)));
+    }
+
+    @Test
+    public void testGetPrivilegesVersionableTreeRemoved() throws Exception {
+        String versionPath = getVersionPath(TEST_OAK_PATH, false);
+        String versionHPath = getVersionPath(TEST_OAK_PATH, true);
+        assertTrue(root.getTree(versionPath).exists());
+
+        root.getTree(TEST_OAK_PATH).remove();
+        root.commit();
+        permissionProvider.refresh();
+
+        Tree versionTree = root.getTree(versionPath);
+        assertTrue(versionTree.exists());
+
+        // permissions not affected (as long as no restrictions involved) due 
to the fact that permissions are not
+        // stored with the versionable node.
+        assertEquals(Sets.newHashSet(JCR_READ, JCR_VERSION_MANAGEMENT), 
permissionProvider.getPrivileges(versionTree));
+    }
+
+    @Test
+    public void testGetPrivilegesVersionHistoryRemoved() throws Exception {
+        String vhPath = getVersionPath(contentPath, true);
+        assertTrue(root.getTree(vhPath).exists());
+
+        root.getTree(contentPath).remove();
+        root.commit();
+        permissionProvider.refresh();
+
+        Tree vhTree = root.getTree(vhPath);
+        assertFalse(vhTree.exists());
+        assertTrue(permissionProvider.getPrivileges(vhTree).isEmpty());
+    }
+
+    @Test
+    public void testHasPrivileges() throws Exception {
+        
assertFalse(permissionProvider.hasPrivileges(getVersionTree(contentPath, 
false), JCR_READ));
+        
assertFalse(permissionProvider.hasPrivileges(getVersionTree(grandchildPath, 
true), JCR_VERSION_MANAGEMENT));
+        
assertFalse(permissionProvider.hasPrivileges(getVersionTree(TEST_OAK_PATH, 
false), JCR_READ, JCR_LOCK_MANAGEMENT));
+
+        
assertTrue(permissionProvider.hasPrivileges(getVersionTree(grandchildPath, 
false), JCR_READ));
+        
assertTrue(permissionProvider.hasPrivileges(getVersionTree(TEST_OAK_PATH, 
true), JCR_READ, JCR_VERSION_MANAGEMENT));
+    }
+}
\ No newline at end of file

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

Added: 
jackrabbit/oak/trunk/oak-authorization-principalbased/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/PolicyValidatorLimitedUserTest.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-authorization-principalbased/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/PolicyValidatorLimitedUserTest.java?rev=1857551&view=auto
==============================================================================
--- 
jackrabbit/oak/trunk/oak-authorization-principalbased/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/PolicyValidatorLimitedUserTest.java
 (added)
+++ 
jackrabbit/oak/trunk/oak-authorization-principalbased/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/PolicyValidatorLimitedUserTest.java
 Mon Apr 15 07:16:49 2019
@@ -0,0 +1,165 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package 
org.apache.jackrabbit.oak.spi.security.authorization.principalbased.impl;
+
+import com.google.common.collect.ImmutableSet;
+import org.apache.jackrabbit.api.security.user.User;
+import org.apache.jackrabbit.oak.api.CommitFailedException;
+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.api.Type;
+import org.apache.jackrabbit.oak.commons.PathUtils;
+import org.apache.jackrabbit.oak.plugins.tree.TreeUtil;
+import org.apache.jackrabbit.oak.spi.nodetype.NodeTypeConstants;
+import org.jetbrains.annotations.NotNull;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import javax.jcr.SimpleCredentials;
+
+import static 
org.apache.jackrabbit.oak.spi.security.authorization.accesscontrol.AccessControlConstants.REP_GLOB;
+import static 
org.apache.jackrabbit.oak.spi.security.authorization.principalbased.impl.Constants.MIX_REP_PRINCIPAL_BASED_MIXIN;
+import static 
org.apache.jackrabbit.oak.spi.security.authorization.principalbased.impl.Constants.NT_REP_PRINCIPAL_ENTRY;
+import static 
org.apache.jackrabbit.oak.spi.security.authorization.principalbased.impl.Constants.NT_REP_PRINCIPAL_POLICY;
+import static 
org.apache.jackrabbit.oak.spi.security.authorization.principalbased.impl.Constants.NT_REP_RESTRICTIONS;
+import static 
org.apache.jackrabbit.oak.spi.security.authorization.principalbased.impl.Constants.REP_EFFECTIVE_PATH;
+import static 
org.apache.jackrabbit.oak.spi.security.authorization.principalbased.impl.Constants.REP_PRINCIPAL_NAME;
+import static 
org.apache.jackrabbit.oak.spi.security.authorization.principalbased.impl.Constants.REP_PRINCIPAL_POLICY;
+import static 
org.apache.jackrabbit.oak.spi.security.authorization.principalbased.impl.Constants.REP_PRIVILEGES;
+import static 
org.apache.jackrabbit.oak.spi.security.authorization.principalbased.impl.Constants.REP_RESTRICTIONS;
+import static 
org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants.JCR_NODE_TYPE_MANAGEMENT;
+import static 
org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants.JCR_READ;
+import static 
org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants.JCR_READ_ACCESS_CONTROL;
+import static 
org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants.JCR_WRITE;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+public class PolicyValidatorLimitedUserTest extends AbstractPrincipalBasedTest 
{
+
+    private String accessControlledPath;
+    private ContentSession testSession;
+    private Root testRoot;
+
+    @Before
+    public void before() throws Exception {
+        super.before();
+
+        User systemUser = getTestSystemUser();
+        PrincipalPolicyImpl policy = 
setupPrincipalBasedAccessControl(systemUser.getPrincipal(), testJcrPath, 
JCR_NODE_TYPE_MANAGEMENT);
+        accessControlledPath = policy.getOakPath();
+
+        User testUser = getTestUser();
+        addDefaultEntry(PathUtils.ROOT_PATH, testUser.getPrincipal(), 
JCR_READ, JCR_READ_ACCESS_CONTROL);
+        root.commit();
+
+        testSession = login(new SimpleCredentials(testUser.getID(), 
testUser.getID().toCharArray()));
+        testRoot = testSession.getLatestRoot();
+    }
+
+    @After
+    public void after() throws Exception {
+        try {
+            testRoot.refresh();
+            if (testSession != null) {
+                testSession.close();
+            }
+        } finally {
+            super.after();
+        }
+    }
+
+    @NotNull
+    private Tree createPolicyEntryTree(@NotNull Root r, @NotNull String 
effectiveOakPath, @NotNull String... privNames) throws Exception {
+        Tree t = r.getTree(accessControlledPath);
+        TreeUtil.addMixin(t, MIX_REP_PRINCIPAL_BASED_MIXIN, 
r.getTree(NodeTypeConstants.NODE_TYPES_PATH), "uid");
+        Tree policy = TreeUtil.addChild(t, REP_PRINCIPAL_POLICY, 
NT_REP_PRINCIPAL_POLICY);
+        policy.setProperty(REP_PRINCIPAL_NAME, 
getTestSystemUser().getPrincipal().getName());
+        Tree entry = TreeUtil.addChild(policy, "entry", 
NT_REP_PRINCIPAL_ENTRY);
+        entry.setProperty(REP_EFFECTIVE_PATH, effectiveOakPath, Type.PATH);
+        entry.setProperty(REP_PRIVILEGES, ImmutableSet.copyOf(privNames), 
Type.NAMES);
+        return entry;
+    }
+
+    @Test
+    public void testAddEntryMissingModAcPermission() throws Exception {
+        Tree entry = createPolicyEntryTree(testRoot, TEST_OAK_PATH, JCR_READ);
+        try {
+            testRoot.commit();
+            fail("CommitFailedException expected; type ACCESS; code 3");
+        } catch (CommitFailedException e) {
+            assertEquals(CommitFailedException.ACCESS, e.getType());
+            assertEquals(3, e.getCode());
+        }
+    }
+
+    @Test
+    public void testChangeEntryMissingModAcPermission() throws Exception {
+        Tree entry = createPolicyEntryTree(root, TEST_OAK_PATH, JCR_READ);
+        root.commit();
+        testRoot.refresh();
+
+        entry = testRoot.getTree(entry.getPath());
+        entry.setProperty(REP_PRIVILEGES, ImmutableSet.of(JCR_READ, 
JCR_WRITE), Type.NAMES);
+        try {
+            testRoot.commit();
+            fail("CommitFailedException expected; type ACCESS; code 3");
+        } catch (CommitFailedException e) {
+            assertEquals(CommitFailedException.ACCESS, e.getType());
+            assertEquals(3, e.getCode());
+        }
+    }
+
+    @Test
+    public void testAddRestrictionMissingModAcPermission() throws Exception {
+        Tree entry = createPolicyEntryTree(root, TEST_OAK_PATH, JCR_READ);
+        root.commit();
+        testRoot.refresh();
+
+        entry = testRoot.getTree(entry.getPath());
+        Tree restrictions = TreeUtil.addChild(entry, REP_RESTRICTIONS, 
NT_REP_RESTRICTIONS);
+        restrictions.setProperty(REP_GLOB, "*/glob/*");
+        try {
+            testRoot.commit();
+            fail("CommitFailedException expected; type ACCESS; code 3");
+        } catch (CommitFailedException e) {
+            assertEquals(CommitFailedException.ACCESS, e.getType());
+            assertEquals(3, e.getCode());
+        }
+    }
+
+    @Test
+    public void testModifyRestrictionMissingModAcPermission() throws Exception 
{
+        Tree entry = createPolicyEntryTree(root, TEST_OAK_PATH, JCR_READ);
+        Tree restrictions = TreeUtil.addChild(entry, REP_RESTRICTIONS, 
NT_REP_RESTRICTIONS);
+        restrictions.setProperty(REP_GLOB, "*/glob/*");
+        root.commit();
+        testRoot.refresh();
+
+        restrictions = testRoot.getTree(restrictions.getPath());
+        restrictions.setProperty(REP_GLOB, "*/changedGlob/*");
+        try {
+            testRoot.commit();
+            fail("CommitFailedException expected; type ACCESS; code 3");
+        } catch (CommitFailedException e) {
+            assertEquals(CommitFailedException.ACCESS, e.getType());
+            assertEquals(3, e.getCode());
+        }
+    }
+
+}
\ No newline at end of file

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

Added: 
jackrabbit/oak/trunk/oak-authorization-principalbased/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/PolicyValidatorTest.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-authorization-principalbased/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/PolicyValidatorTest.java?rev=1857551&view=auto
==============================================================================
--- 
jackrabbit/oak/trunk/oak-authorization-principalbased/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/PolicyValidatorTest.java
 (added)
+++ 
jackrabbit/oak/trunk/oak-authorization-principalbased/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/PolicyValidatorTest.java
 Mon Apr 15 07:16:49 2019
@@ -0,0 +1,585 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package 
org.apache.jackrabbit.oak.spi.security.authorization.principalbased.impl;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Iterables;
+import org.apache.jackrabbit.JcrConstants;
+import org.apache.jackrabbit.api.security.authorization.PrivilegeManager;
+import org.apache.jackrabbit.oak.api.CommitFailedException;
+import org.apache.jackrabbit.oak.api.PropertyState;
+import org.apache.jackrabbit.oak.api.Tree;
+import org.apache.jackrabbit.oak.api.Type;
+import org.apache.jackrabbit.oak.commons.PathUtils;
+import org.apache.jackrabbit.oak.namepath.NamePathMapper;
+import org.apache.jackrabbit.oak.plugins.memory.PropertyStates;
+import org.apache.jackrabbit.oak.plugins.tree.TreeUtil;
+import org.apache.jackrabbit.oak.spi.commit.CommitInfo;
+import org.apache.jackrabbit.oak.spi.commit.Validator;
+import org.apache.jackrabbit.oak.spi.commit.VisibleValidator;
+import org.apache.jackrabbit.oak.spi.nodetype.NodeTypeConstants;
+import 
org.apache.jackrabbit.oak.spi.security.authorization.AuthorizationConfiguration;
+import 
org.apache.jackrabbit.oak.spi.security.authorization.restriction.RestrictionProvider;
+import org.apache.jackrabbit.oak.spi.security.principal.EveryonePrincipal;
+import org.apache.jackrabbit.oak.spi.state.NodeState;
+import org.jetbrains.annotations.NotNull;
+import org.junit.Test;
+
+import javax.jcr.RepositoryException;
+import javax.jcr.Value;
+import java.util.Map;
+import java.util.Set;
+
+import static org.apache.jackrabbit.JcrConstants.JCR_MIXINTYPES;
+import static org.apache.jackrabbit.JcrConstants.JCR_SYSTEM;
+import static 
org.apache.jackrabbit.oak.spi.nodetype.NodeTypeConstants.NT_OAK_UNSTRUCTURED;
+import static 
org.apache.jackrabbit.oak.spi.security.authorization.accesscontrol.AccessControlConstants.REP_GLOB;
+import static 
org.apache.jackrabbit.oak.spi.security.authorization.accesscontrol.AccessControlConstants.REP_ITEM_NAMES;
+import static 
org.apache.jackrabbit.oak.spi.security.authorization.principalbased.impl.Constants.MIX_REP_PRINCIPAL_BASED_MIXIN;
+import static 
org.apache.jackrabbit.oak.spi.security.authorization.principalbased.impl.Constants.NT_REP_PRINCIPAL_ENTRY;
+import static 
org.apache.jackrabbit.oak.spi.security.authorization.principalbased.impl.Constants.NT_REP_PRINCIPAL_POLICY;
+import static 
org.apache.jackrabbit.oak.spi.security.authorization.principalbased.impl.Constants.NT_REP_RESTRICTIONS;
+import static 
org.apache.jackrabbit.oak.spi.security.authorization.principalbased.impl.Constants.REP_EFFECTIVE_PATH;
+import static 
org.apache.jackrabbit.oak.spi.security.authorization.principalbased.impl.Constants.REP_PRINCIPAL_NAME;
+import static 
org.apache.jackrabbit.oak.spi.security.authorization.principalbased.impl.Constants.REP_PRINCIPAL_POLICY;
+import static 
org.apache.jackrabbit.oak.spi.security.authorization.principalbased.impl.Constants.REP_PRIVILEGES;
+import static 
org.apache.jackrabbit.oak.spi.security.authorization.principalbased.impl.Constants.REP_RESTRICTIONS;
+import static 
org.apache.jackrabbit.oak.spi.security.authorization.principalbased.impl.MockUtility.createMixinTypesProperty;
+import static 
org.apache.jackrabbit.oak.spi.security.authorization.principalbased.impl.MockUtility.mockNodeState;
+import static 
org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants.JCR_LIFECYCLE_MANAGEMENT;
+import static 
org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants.JCR_READ;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
+
+public class PolicyValidatorTest extends AbstractPrincipalBasedTest {
+
+    private NodeState mockNodeState = mock(NodeState.class);
+
+    @Override
+    protected NamePathMapper getNamePathMapper() {
+        return NamePathMapper.DEFAULT;
+    }
+
+    @NotNull
+    private Validator createRootValidator(@NotNull NodeState rootState) {
+        return createRootValidator(rootState, getMgrProvider(root));
+    }
+
+    @NotNull
+    private Validator createRootValidator(@NotNull NodeState rootState, 
@NotNull MgrProvider mgrProvider) {
+        return new PrincipalPolicyValidatorProvider(mgrProvider, 
adminSession.getAuthInfo().getPrincipals(), 
adminSession.getWorkspaceName()).getRootValidator(rootState, rootState, new 
CommitInfo("anyId", null));
+    }
+
+    @NotNull
+    private Validator getValidatorAtNodeTypeTree(@NotNull NodeState nodeState, 
@NotNull String parentName, boolean isAdd) throws Exception {
+        Validator v = createRootValidator(nodeState);
+        
when(nodeState.getProperty(JcrConstants.JCR_PRIMARYTYPE)).thenReturn(createPrimaryTypeProperty(JcrConstants.NT_BASE));
+        if (isAdd) {
+            return v.childNodeAdded(parentName, 
nodeState).childNodeAdded(NodeTypeConstants.JCR_NODE_TYPES, nodeState);
+        }  else {
+            return v.childNodeChanged(parentName, nodeState, 
nodeState).childNodeChanged(NodeTypeConstants.JCR_NODE_TYPES, nodeState, 
nodeState);
+        }
+    }
+
+    @NotNull
+    private Tree createPolicyEntryTree(@NotNull Set<String> privNames) throws 
Exception {
+        Tree t = 
root.getTree(getNamePathMapper().getOakPath(getTestSystemUser().getPath()));
+        TreeUtil.addMixin(t, MIX_REP_PRINCIPAL_BASED_MIXIN, 
root.getTree(NodeTypeConstants.NODE_TYPES_PATH), "uid");
+        Tree policy = TreeUtil.addChild(t, REP_PRINCIPAL_POLICY, 
NT_REP_PRINCIPAL_POLICY);
+        policy.setProperty(REP_PRINCIPAL_NAME, 
getTestSystemUser().getPrincipal().getName());
+        Tree entry = TreeUtil.addChild(policy, "entry", 
NT_REP_PRINCIPAL_ENTRY);
+        entry.setProperty(REP_EFFECTIVE_PATH, TEST_OAK_PATH, Type.PATH);
+        entry.setProperty(REP_PRIVILEGES, privNames, Type.NAMES);
+        return entry;
+    }
+
+    @NotNull
+    private MgrProvider mockMgrProvider() {
+        MgrProvider mp = mock(MgrProvider.class);
+        when(mp.getRootProvider()).thenReturn(getRootProvider());
+        when(mp.getTreeProvider()).thenReturn(getTreeProvider());
+        when(mp.getSecurityProvider()).thenReturn(getSecurityProvider());
+        return mp;
+    }
+
+    @NotNull
+    private static PropertyState createPrimaryTypeProperty(@NotNull String 
ntName) {
+        return MockUtility.createPrimaryTypeProperty(ntName);
+    }
+
+    private static void assertCommitFailed(@NotNull CommitFailedException e, 
int expectedErrorCode) {
+        assertTrue(e.isAccessControlViolation());
+        assertEquals(expectedErrorCode, e.getCode());
+    }
+
+    private static void failCommitFailedExcpected(int expectedCode) {
+        fail("Expected CommitFailedException with ErrorCode " +expectedCode);
+    }
+
+    @Test
+    public void testArbitraryPropertyAdded() throws Exception {
+        
createRootValidator(mockNodeState).propertyAdded(PropertyStates.createProperty("any",
 NT_REP_PRINCIPAL_POLICY));
+    }
+
+    @Test
+    public void testPrimaryTypePropertyAdded() throws Exception {
+        
createRootValidator(mockNodeState).propertyAdded(createPrimaryTypeProperty(JcrConstants.NT_UNSTRUCTURED));
+    }
+
+    @Test
+    public void testPolicyPrimaryTypePropertyAddedWrongParentName() throws 
Exception {
+        Validator v = 
createRootValidator(mockNodeState).childNodeAdded("wrongName", mockNodeState);
+        try {
+            
v.propertyAdded(createPrimaryTypeProperty(NT_REP_PRINCIPAL_POLICY));
+            failCommitFailedExcpected(30);
+        } catch (CommitFailedException e) {
+            assertCommitFailed(e, 30);
+        }
+    }
+
+    @Test
+    public void testPolicyPrimaryTypePropertyAdded() throws Exception {
+        Tree rootTree = root.getTree(PathUtils.ROOT_PATH);
+        TreeUtil.addMixin(rootTree, MIX_REP_PRINCIPAL_BASED_MIXIN, 
root.getTree(NodeTypeConstants.NODE_TYPES_PATH), "uid");
+
+        NodeState rootState = getTreeProvider().asNodeState(rootTree);
+        NodeState child = mockNodeState(NT_REP_PRINCIPAL_POLICY);
+        Validator v = 
createRootValidator(rootState).childNodeAdded(REP_PRINCIPAL_POLICY, child);
+        v.propertyAdded(createPrimaryTypeProperty(NT_REP_PRINCIPAL_POLICY));
+    }
+
+    @Test
+    public void testArbitraryPropertyChanged() throws Exception {
+        PropertyState before = PropertyStates.createProperty("any", 
NT_REP_PRINCIPAL_POLICY);
+        PropertyState after = PropertyStates.createProperty("any", 
NT_REP_PRINCIPAL_ENTRY);
+        createRootValidator(mockNodeState).propertyChanged(before, after);
+    }
+
+    @Test
+    public void testPrimaryTypePropertyChanged() throws Exception {
+        PropertyState before = 
createPrimaryTypeProperty(JcrConstants.NT_UNSTRUCTURED);
+        PropertyState after = createPrimaryTypeProperty(NT_OAK_UNSTRUCTURED);
+        createRootValidator(mockNodeState).propertyChanged(before, after);
+    }
+
+    @Test
+    public void testPolicyBeforePrimaryTypePropertyChanged() throws Exception {
+        try {
+            PropertyState before = 
createPrimaryTypeProperty(NT_REP_PRINCIPAL_POLICY);
+            PropertyState after = 
createPrimaryTypeProperty(NT_OAK_UNSTRUCTURED);
+            createRootValidator(mockNodeState).propertyChanged(before, after);
+            failCommitFailedExcpected(31);
+        } catch (CommitFailedException e) {
+            assertCommitFailed(e, 31);
+        }
+    }
+
+    @Test
+    public void testPolicyAfterPrimaryTypePropertyChanged() throws Exception {
+        try {
+            PropertyState before = 
createPrimaryTypeProperty(NT_OAK_UNSTRUCTURED);
+            PropertyState after = 
createPrimaryTypeProperty(NT_REP_PRINCIPAL_POLICY);
+            createRootValidator(mockNodeState).propertyChanged(before, after);
+            failCommitFailedExcpected(31);
+        } catch (CommitFailedException e) {
+            assertCommitFailed(e, 31);
+        }
+    }
+
+    @Test
+    public void testArbitraryPropertyDeleted() throws Exception {
+        
createRootValidator(mockNodeState).propertyDeleted(PropertyStates.createProperty("any",
 NT_REP_PRINCIPAL_POLICY));
+    }
+
+    @Test
+    public void testPrimaryTypePropertyDeleted() throws Exception {
+        
createRootValidator(mockNodeState).propertyDeleted(createPrimaryTypeProperty(JcrConstants.NT_UNSTRUCTURED));
+    }
+
+    @Test
+    public void testAccessControlPrimaryTypePropertyDeleted() throws Exception 
{
+        
createRootValidator(mockNodeState).propertyDeleted(createPrimaryTypeProperty(NT_REP_PRINCIPAL_POLICY));
+        
createRootValidator(mockNodeState).propertyDeleted(createPrimaryTypeProperty(NT_REP_RESTRICTIONS));
+        
createRootValidator(mockNodeState).propertyDeleted(createPrimaryTypeProperty(NT_REP_PRINCIPAL_ENTRY));
+    }
+
+    @Test
+    public void testChildAddedToNodeTypeTree() throws Exception {
+        Validator validator = getValidatorAtNodeTypeTree(mockNodeState, 
JCR_SYSTEM, true);
+        validator.childNodeAdded(REP_PRINCIPAL_POLICY, mockNodeState);
+    }
+
+    @Test
+    public void testChildChangedToNodeTypeTree() throws Exception {
+        Validator validator = getValidatorAtNodeTypeTree(mockNodeState, 
JCR_SYSTEM, false);
+        validator.childNodeChanged(REP_PRINCIPAL_POLICY, mockNodeState, 
mockNodeState);
+    }
+
+    @Test
+    public void testChildChangedBelowNodeTypeTree() throws Exception {
+        Validator validator = getValidatorAtNodeTypeTree(mockNodeState, 
JCR_SYSTEM, false);
+        validator.childNodeChanged("any", mockNodeState, 
mockNodeState).childNodeChanged(REP_PRINCIPAL_POLICY, mockNodeState, 
mockNodeState);
+    }
+
+    @Test
+    public void testChildDeletedToNodeTypeTree() throws Exception {
+        Validator validator = getValidatorAtNodeTypeTree(mockNodeState, 
JCR_SYSTEM, false);
+
+        
when(mockNodeState.hasChildNode(REP_PRINCIPAL_POLICY)).thenReturn(true);
+        validator.childNodeDeleted(REP_PRINCIPAL_POLICY, mockNodeState);
+    }
+
+    @Test
+    public void tetPolicyChildAddedWrongType() {
+        NodeState child = mockNodeState(NodeTypeConstants.NT_REP_UNSTRUCTURED);
+        try {
+            
createRootValidator(mockNodeState).childNodeAdded(REP_PRINCIPAL_POLICY, child);
+            failCommitFailedExcpected(32);
+        } catch (CommitFailedException e) {
+            assertCommitFailed(e, 32);
+        }
+    }
+
+    @Test
+    public void tetPolicyChildAddedMissingMixinOnParent() {
+        NodeState rootState = 
getTreeProvider().asNodeState(root.getTree(PathUtils.ROOT_PATH));
+        
assertFalse(Iterables.contains(rootState.getNames(JcrConstants.JCR_MIXINTYPES), 
MIX_REP_PRINCIPAL_BASED_MIXIN));
+
+        NodeState child = mockNodeState(NT_REP_PRINCIPAL_POLICY);
+        try {
+            
createRootValidator(rootState).childNodeAdded(REP_PRINCIPAL_POLICY, child);
+            failCommitFailedExcpected(33);
+        } catch (CommitFailedException e) {
+            assertCommitFailed(e, 33);
+        }
+    }
+
+    @Test
+    public void testPolicyChildAdded() throws Exception {
+        Tree rootTree = root.getTree(PathUtils.ROOT_PATH);
+        TreeUtil.addMixin(rootTree, MIX_REP_PRINCIPAL_BASED_MIXIN, 
root.getTree(NodeTypeConstants.NODE_TYPES_PATH), "uid");
+
+        NodeState child = mockNodeState(NT_REP_PRINCIPAL_POLICY);
+        Validator v = 
createRootValidator(getTreeProvider().asNodeState(rootTree)).childNodeAdded(REP_PRINCIPAL_POLICY,
 child);
+        assertTrue(v instanceof VisibleValidator);
+    }
+
+    @Test
+    public void tetChildChangedWrongType() {
+        NodeState ns = mockNodeState(NT_OAK_UNSTRUCTURED);
+        NodeState child = mockNodeState(NodeTypeConstants.NT_REP_UNSTRUCTURED);
+        when(child.hasChildNode(REP_PRINCIPAL_POLICY)).thenReturn(true);
+        when(child.getChildNode(REP_PRINCIPAL_POLICY)).thenReturn(ns);
+        try {
+            
createRootValidator(mockNodeState).childNodeChanged(REP_PRINCIPAL_POLICY, 
child, child);
+            failCommitFailedExcpected(32);
+        } catch (CommitFailedException e) {
+            assertCommitFailed(e, 32);
+        }
+    }
+
+    @Test
+    public void tetChildChangedMissingMixin() {
+        NodeState rootState = 
spy(getTreeProvider().asNodeState(root.getTree(PathUtils.ROOT_PATH)));
+
+        
when(mockNodeState.getProperty(JcrConstants.JCR_PRIMARYTYPE)).thenReturn(createPrimaryTypeProperty(NT_REP_PRINCIPAL_POLICY));
+
+        NodeState child = mockNodeState(NT_OAK_UNSTRUCTURED);
+        when(child.hasChildNode(REP_PRINCIPAL_POLICY)).thenReturn(true);
+        
when(child.getChildNode(REP_PRINCIPAL_POLICY)).thenReturn(mockNodeState);
+        try {
+            createRootValidator(rootState).childNodeChanged("any", child, 
child);
+            failCommitFailedExcpected(33);
+        } catch (CommitFailedException e) {
+            assertCommitFailed(e, 33);
+        }
+    }
+
+    @Test
+    public void testArbitraryNodeTypeTreeTriggersValidation() throws Exception 
{
+        NodeState rootState = 
spy(getTreeProvider().asNodeState(root.getTree(PathUtils.ROOT_PATH)));
+        Validator validator = getValidatorAtNodeTypeTree(rootState, 
"notJcrSystem", true);
+
+        NodeState child = mockNodeState(NT_REP_PRINCIPAL_POLICY);
+        try {
+            validator.childNodeAdded(REP_PRINCIPAL_POLICY, child);
+            failCommitFailedExcpected(33);
+        } catch (CommitFailedException e) {
+            assertCommitFailed(e, 33);
+        }
+    }
+
+    @Test
+    public void testArbitraryNodeTypeTreeTriggersValidation2() throws 
Exception {
+        NodeState rootState = 
spy(getTreeProvider().asNodeState(root.getTree(PathUtils.ROOT_PATH)));
+        Validator validator = getValidatorAtNodeTypeTree(rootState, 
"notJcrSystem", false);
+
+        
when(mockNodeState.hasChildNode(REP_PRINCIPAL_POLICY)).thenReturn(true);
+        
when(mockNodeState.getChildNode(REP_PRINCIPAL_POLICY)).thenReturn(mockNodeState);;
+        try {
+            validator.childNodeChanged(REP_PRINCIPAL_POLICY, mockNodeState, 
mockNodeState);
+            failCommitFailedExcpected(32);
+        } catch (CommitFailedException e) {
+            assertCommitFailed(e, 32);
+        }
+    }
+
+    @Test
+    public void testAddRestrictionWithWrongNtName() throws Exception {
+        NodeState rootState = 
spy(getTreeProvider().asNodeState(root.getTree(PathUtils.ROOT_PATH)));
+        NodeState restrictions = mockNodeState(NT_OAK_UNSTRUCTURED);
+        try {
+            Validator v = 
createRootValidator(rootState).childNodeAdded(REP_RESTRICTIONS, restrictions);
+            failCommitFailedExcpected(34);
+        } catch (CommitFailedException e) {
+            assertCommitFailed(e, 34);
+        }
+    }
+
+    @Test
+    public void testAddIsolatedRestriction() throws Exception {
+        NodeState rootState = 
spy(getTreeProvider().asNodeState(root.getTree(PathUtils.ROOT_PATH)));
+
+        NodeState restrictions = mockNodeState(NT_REP_RESTRICTIONS);
+        try {
+            createRootValidator(rootState).childNodeAdded(REP_RESTRICTIONS, 
restrictions);
+            failCommitFailedExcpected(2);
+        } catch (CommitFailedException e) {
+            assertCommitFailed(e, 2);
+        }
+    }
+
+    @Test
+    public void testAddUnknownRestriction() throws Exception {
+        Tree entry = createPolicyEntryTree(ImmutableSet.of(JCR_READ));
+        Tree restrictions = TreeUtil.addChild(entry, REP_RESTRICTIONS, 
NT_REP_RESTRICTIONS);
+        restrictions.setProperty("unknown", "test");
+
+        try {
+            root.commit();
+            failCommitFailedExcpected(35);
+        } catch (CommitFailedException e) {
+            assertCommitFailed(e, 35);
+        }
+    }
+
+    @Test
+    public void testAddInvalidRestriction() throws Exception {
+        Tree entry = createPolicyEntryTree(ImmutableSet.of(JCR_READ));
+        Tree restrictions = TreeUtil.addChild(entry, REP_RESTRICTIONS, 
NT_REP_RESTRICTIONS);
+        // wrong type. must be NAMES.
+        restrictions.setProperty(REP_ITEM_NAMES, ImmutableSet.of("test"), 
Type.STRINGS);
+        try {
+            root.commit();
+            failCommitFailedExcpected(35);
+        } catch (CommitFailedException e) {
+            assertCommitFailed(e, 35);
+        }
+    }
+
+    @Test
+    public void testAddRestrictionWithDifferentACE() throws Exception {
+        // validator must not complain about adding restrictions to a 
different authorization model
+        Map<String, Value> restr = 
ImmutableMap.of(getNamePathMapper().getJcrName(REP_GLOB), 
getValueFactory(root).createValue("val"));
+        addDefaultEntry(PathUtils.ROOT_PATH, EveryonePrincipal.getInstance(), 
restr, (Map) null, JCR_LIFECYCLE_MANAGEMENT);
+        root.commit();
+    }
+
+    @Test
+    public void testChangeWithInvalidRestriction() throws Exception {
+        Tree entry = createPolicyEntryTree(ImmutableSet.of(JCR_READ));
+        Tree restrictions = TreeUtil.addChild(entry, REP_RESTRICTIONS, 
NT_REP_RESTRICTIONS);
+        restrictions.setProperty(REP_GLOB, "*/glob/*");
+        root.commit();
+
+        // modify restriction tree changing glob property with 
type-cardinality mismatch
+        restrictions.setProperty(REP_GLOB, ImmutableSet.of("test"), 
Type.STRINGS);
+        try {
+            root.commit();
+            failCommitFailedExcpected(35);
+        } catch (CommitFailedException e) {
+            assertCommitFailed(e, 35);
+        }
+    }
+
+    @Test
+    public void testChangeFromSingleValuedToMvRestriction() throws Exception {
+        Tree entry = createPolicyEntryTree(ImmutableSet.of(JCR_READ));
+        Tree restrictions = TreeUtil.addChild(entry, REP_RESTRICTIONS, 
NT_REP_RESTRICTIONS);
+        restrictions.setProperty(REP_GLOB, "*/glob/*");
+        root.commit();
+
+        restrictions.removeProperty(REP_GLOB);
+        restrictions.setProperty(REP_ITEM_NAMES, ImmutableSet.of("someName", 
"anotherName"), Type.NAMES);
+        root.commit();
+    }
+
+    @Test
+    public void testChangeWithThrowingRestrictionValidation() throws Exception 
{
+        NodeState entryMock = mockNodeState(NT_REP_PRINCIPAL_ENTRY);
+        
when(entryMock.getProperty(REP_EFFECTIVE_PATH)).thenReturn(PropertyStates.createProperty(REP_EFFECTIVE_PATH,
 "/path"));
+        NodeState restrictions = mockNodeState(NT_REP_RESTRICTIONS);
+
+        RestrictionProvider throwingRp = mock(RestrictionProvider.class);
+        doThrow(new 
RepositoryException()).when(throwingRp).validateRestrictions(anyString(), 
any(Tree.class));
+
+        MgrProvider mgrProvider = mockMgrProvider();
+        
when(mgrProvider.getContext()).thenReturn(getConfig(AuthorizationConfiguration.class).getContext());
+        when(mgrProvider.getRestrictionProvider()).thenReturn(throwingRp);
+
+        try {
+            createRootValidator(entryMock, 
mgrProvider).childNodeChanged(REP_RESTRICTIONS, restrictions, restrictions);
+            failCommitFailedExcpected(13);
+        } catch (CommitFailedException e) {
+            assertTrue(e.isOfType(CommitFailedException.OAK));
+            assertEquals(13, e.getCode());        }
+    }
+
+    @Test
+    public void testAddIsolatedEntry() throws Exception {
+        NodeState rootState = 
spy(getTreeProvider().asNodeState(root.getTree(PathUtils.ROOT_PATH)));
+
+        try {
+            Validator v = 
createRootValidator(rootState).childNodeAdded("anyName", 
mockNodeState(NT_REP_PRINCIPAL_ENTRY));
+            failCommitFailedExcpected(36);
+        } catch (CommitFailedException e) {
+            assertCommitFailed(e, 36);
+        }
+    }
+
+    @Test
+    public void testAddEntryWithEmptyPrivilegeSet() throws Exception {
+        Tree entry = createPolicyEntryTree(ImmutableSet.of());
+        try {
+            root.commit();
+            failCommitFailedExcpected(37);
+        } catch (CommitFailedException e) {
+            assertCommitFailed(e, 37);
+        }
+    }
+
+    @Test
+    public void testAddEntryWithAbstractPrivilege() throws Exception {
+        getPrivilegeManager(root).registerPrivilege("abstractPriv", true, new 
String[0]);
+
+        Tree entry = createPolicyEntryTree(ImmutableSet.of("abstractPriv"));
+        try {
+            root.commit();
+            failCommitFailedExcpected(38);
+        } catch (CommitFailedException e) {
+            assertCommitFailed(e, 38);
+        }
+    }
+
+    @Test
+    public void testAddEntryWithInvalidPrivilege() throws Exception {
+        Tree entry = 
createPolicyEntryTree(ImmutableSet.of("invalidPrivilege"));
+        try {
+            root.commit();
+            failCommitFailedExcpected(39);
+        } catch (CommitFailedException e) {
+            assertCommitFailed(e, 39);
+        }
+    }
+
+    @Test
+    public void testAddEntryPrivilegeLookupThrowsRepositoryException() throws 
Exception {
+        PrivilegeManager privMgr = 
when(mock(PrivilegeManager.class).getPrivilege(anyString())).thenThrow(new 
RepositoryException()).getMock();
+        MgrProvider mp = 
when(mockMgrProvider().getPrivilegeManager()).thenReturn(privMgr).getMock();
+
+        NodeState policyState =  mockNodeState(NT_REP_PRINCIPAL_POLICY);
+        
when(policyState.getProperty(REP_PRINCIPAL_NAME)).thenReturn(PropertyStates.createProperty(REP_PRINCIPAL_NAME,
 "name"));
+
+        NodeState ns = mockNodeState(NT_OAK_UNSTRUCTURED);
+        when(ns.hasChildNode(REP_PRINCIPAL_POLICY)).thenReturn(true);
+        when(ns.getChildNode(REP_PRINCIPAL_POLICY)).thenReturn(policyState);
+        
when(ns.getProperty(JCR_MIXINTYPES)).thenReturn(createMixinTypesProperty(MIX_REP_PRINCIPAL_BASED_MIXIN));
+
+        Validator v = 
createRootValidator(getTreeProvider().asNodeState(root.getTree(PathUtils.ROOT_PATH)),
 mp);
+        v = v.childNodeChanged("any", ns, ns);
+        v = v.childNodeChanged(REP_PRINCIPAL_POLICY, policyState, policyState);
+
+        try {
+            NodeState entry = mockNodeState(NT_REP_PRINCIPAL_ENTRY);
+            
when(entry.getProperty(REP_EFFECTIVE_PATH)).thenReturn(PropertyStates.createProperty(REP_EFFECTIVE_PATH,"/path",
 Type.PATH));
+            
when(entry.getNames(REP_PRIVILEGES)).thenReturn(ImmutableList.of("privName"));
+
+            v.childNodeChanged("entryName", entry, entry);
+            fail("CommitFailedException type OAK code 13 expected.");
+        } catch (CommitFailedException e) {
+            assertEquals(CommitFailedException.OAK, e.getType());
+            assertEquals(13, e.getCode());
+        }
+    }
+
+    @Test
+    public void testAddEntryMissingEffectivePath() throws Exception {
+        MgrProvider mp = 
when(mockMgrProvider().getPrivilegeManager()).thenReturn(getPrivilegeManager(root)).getMock();
+
+        NodeState policyState =  mockNodeState(NT_REP_PRINCIPAL_POLICY);
+        
when(policyState.getProperty(REP_PRINCIPAL_NAME)).thenReturn(PropertyStates.createProperty(REP_PRINCIPAL_NAME,
 "name"));
+
+        NodeState ns = mockNodeState(NT_OAK_UNSTRUCTURED);
+        when(ns.hasChildNode(REP_PRINCIPAL_POLICY)).thenReturn(true);
+        when(ns.getChildNode(REP_PRINCIPAL_POLICY)).thenReturn(policyState);
+        
when(ns.getProperty(JCR_MIXINTYPES)).thenReturn(createMixinTypesProperty(MIX_REP_PRINCIPAL_BASED_MIXIN));
+
+        Validator v = 
createRootValidator(getTreeProvider().asNodeState(root.getTree(PathUtils.ROOT_PATH)),
 mp);
+        v = v.childNodeChanged("any", ns, ns);
+        v = v.childNodeChanged(REP_PRINCIPAL_POLICY, policyState, policyState);
+
+        try {
+            NodeState entry = mockNodeState(NT_REP_PRINCIPAL_ENTRY);
+            when(entry.getProperty(REP_EFFECTIVE_PATH)).thenReturn(null);
+            
when(entry.getNames(REP_PRIVILEGES)).thenReturn(ImmutableList.of(JCR_READ));
+
+            v.childNodeChanged("entryName", entry, entry);
+            fail("CommitFailedException type CONSTRAINT code 21 expected.");
+        } catch (CommitFailedException e) {
+            assertEquals(CommitFailedException.CONSTRAINT, e.getType());
+            assertEquals(21, e.getCode());
+        }
+    }
+
+    @Test(expected = IllegalStateException.class)
+    public void testIllegalAddDelete() throws Exception {
+        NodeState rootState = 
spy(getTreeProvider().asNodeState(root.getTree(PathUtils.ROOT_PATH)));
+        NodeState child = mockNodeState(NT_OAK_UNSTRUCTURED);
+
+        Validator v = createRootValidator(rootState).childNodeAdded("added", 
child);
+        v.childNodeDeleted("deleted", child);
+    }
+
+    @Test(expected = IllegalStateException.class)
+    public void testIllegalDeleteAdd() throws Exception {
+        NodeState rootState = 
spy(getTreeProvider().asNodeState(root.getTree(PathUtils.ROOT_PATH)));
+        NodeState child = mockNodeState(NT_OAK_UNSTRUCTURED);
+
+        Validator v = 
createRootValidator(rootState).childNodeDeleted("deleted", child);
+        v.childNodeAdded("added", child);
+    }
+}
\ No newline at end of file

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


Reply via email to