Index: oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/accesscontrol/AccessControlValidator.java =================================================================== --- oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/accesscontrol/AccessControlValidator.java (revision 1686875) +++ oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/accesscontrol/AccessControlValidator.java (working copy) @@ -42,6 +42,7 @@ import org.apache.jackrabbit.oak.plugins.tree.impl.TreeConstants; import org.apache.jackrabbit.oak.spi.commit.DefaultValidator; import org.apache.jackrabbit.oak.spi.commit.Validator; +import org.apache.jackrabbit.oak.spi.commit.VisibleValidator; import org.apache.jackrabbit.oak.spi.security.authorization.accesscontrol.AccessControlConstants; import org.apache.jackrabbit.oak.spi.security.authorization.restriction.Restriction; import org.apache.jackrabbit.oak.spi.security.authorization.restriction.RestrictionProvider; @@ -122,7 +123,7 @@ Tree treeAfter = checkNotNull(parentAfter.getChild(name)); checkValidTree(parentAfter, treeAfter, after); - return new AccessControlValidator(this, treeAfter); + return newValidator(this, treeAfter); } @Override @@ -130,7 +131,7 @@ Tree treeAfter = checkNotNull(parentAfter.getChild(name)); checkValidTree(parentAfter, treeAfter, after); - return new AccessControlValidator(this, treeAfter); + return newValidator(this, treeAfter); } @Override @@ -141,6 +142,14 @@ //------------------------------------------------------------< private >--- + private static Validator newValidator(AccessControlValidator parent, + Tree parentAfter) { + return new VisibleValidator( + new AccessControlValidator(parent, parentAfter), + true, + true); + } + private void checkValidTree(Tree parentAfter, Tree treeAfter, NodeState nodeAfter) throws CommitFailedException { if (isPolicy(treeAfter)) { checkValidPolicy(parentAfter, treeAfter, nodeAfter); Index: oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/UserValidator.java =================================================================== --- oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/UserValidator.java (revision 1686875) +++ oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/UserValidator.java (working copy) @@ -139,12 +139,13 @@ Tree tree = checkNotNull(parentAfter.getChild(name)); validateAuthorizable(tree, UserUtil.getType(tree)); - return new VisibleValidator(new UserValidator(null, tree, provider), true, true); + return newValidator(null, tree, provider); } @Override public Validator childNodeChanged(String name, NodeState before, NodeState after) throws CommitFailedException { - return new UserValidator(parentBefore.getChild(name), parentAfter.getChild(name), provider); + return newValidator(parentBefore.getChild(name), + parentAfter.getChild(name), provider); } @Override @@ -158,12 +159,21 @@ } return null; } else { - return new VisibleValidator(new UserValidator(tree, null, provider), true, true); + return newValidator(tree, null, provider); } } //------------------------------------------------------------< private >--- + private static Validator newValidator(Tree parentBefore, + Tree parentAfter, + UserValidatorProvider provider) { + return new VisibleValidator( + new UserValidator(parentBefore, parentAfter, provider), + true, + true); + } + private boolean isAdminUser(@Nonnull Tree userTree) { if (userTree.exists() && isUser(userTree)) { String id = UserUtil.getAuthorizableId(userTree); Index: oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/accesscontrol/AccessControlValidatorTest.java =================================================================== --- oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/accesscontrol/AccessControlValidatorTest.java (revision 1686875) +++ oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/accesscontrol/AccessControlValidatorTest.java (working copy) @@ -25,9 +25,14 @@ import org.apache.jackrabbit.api.security.authorization.PrivilegeManager; import org.apache.jackrabbit.oak.api.CommitFailedException; import org.apache.jackrabbit.oak.api.Tree; +import org.apache.jackrabbit.oak.plugins.memory.MemoryNodeStore; +import org.apache.jackrabbit.oak.spi.commit.CommitInfo; +import org.apache.jackrabbit.oak.spi.commit.Validator; import org.apache.jackrabbit.oak.spi.security.authorization.accesscontrol.AbstractAccessControlTest; import org.apache.jackrabbit.oak.spi.security.authorization.accesscontrol.AccessControlConstants; import org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants; +import org.apache.jackrabbit.oak.spi.state.NodeBuilder; +import org.apache.jackrabbit.oak.spi.state.NodeState; import org.apache.jackrabbit.oak.util.NodeUtil; import org.junit.After; import org.junit.Before; @@ -34,6 +39,8 @@ import org.junit.Test; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; @@ -351,4 +358,67 @@ assertTrue(e.isAccessControlViolation()); } } + + @Test + public void hiddenNodeAdded() throws CommitFailedException { + AccessControlValidatorProvider provider = new AccessControlValidatorProvider(getSecurityProvider()); + MemoryNodeStore store = new MemoryNodeStore(); + NodeState root = store.getRoot(); + NodeBuilder builder = root.builder(); + NodeBuilder test = builder.child("test"); + NodeBuilder hidden = test.child(":hidden"); + + Validator validator = provider.getRootValidator( + root, builder.getNodeState(), CommitInfo.EMPTY); + Validator childValidator = validator.childNodeAdded( + "test", test.getNodeState()); + assertNotNull(childValidator); + + Validator hiddenValidator = childValidator.childNodeAdded(":hidden", hidden.getNodeState()); + assertNull(hiddenValidator); + } + + @Test + public void hiddenNodeChanged() throws CommitFailedException { + AccessControlValidatorProvider provider = new AccessControlValidatorProvider(getSecurityProvider()); + MemoryNodeStore store = new MemoryNodeStore(); + NodeBuilder builder = store.getRoot().builder(); + builder.child("test").child(":hidden"); + NodeState root = builder.getNodeState(); + + NodeBuilder test = root.builder().child("test"); + NodeBuilder hidden = test.child(":hidden"); + hidden.child("added"); + + Validator validator = provider.getRootValidator( + root, builder.getNodeState(), CommitInfo.EMPTY); + Validator childValidator = validator.childNodeChanged( + "test", root.getChildNode("test"), test.getNodeState()); + assertNotNull(childValidator); + + Validator hiddenValidator = childValidator.childNodeChanged(":hidden", root.getChildNode("test").getChildNode(":hidden"), hidden.getNodeState()); + assertNull(hiddenValidator); + } + + @Test + public void hiddenNodeDeleted() throws CommitFailedException { + AccessControlValidatorProvider provider = new AccessControlValidatorProvider(getSecurityProvider()); + MemoryNodeStore store = new MemoryNodeStore(); + NodeBuilder builder = store.getRoot().builder(); + builder.child("test").child(":hidden"); + NodeState root = builder.getNodeState(); + + builder = root.builder(); + NodeBuilder test = builder.child("test"); + test.child(":hidden").remove(); + + Validator validator = provider.getRootValidator( + root, builder.getNodeState(), CommitInfo.EMPTY); + Validator childValidator = validator.childNodeChanged("test", root.getChildNode("test"), test.getNodeState()); + assertNotNull(childValidator); + + Validator hiddenValidator = childValidator.childNodeDeleted( + ":hidden", root.getChildNode("test").getChildNode(":hidden")); + assertNull(hiddenValidator); + } } \ No newline at end of file Index: oak-core/src/test/java/org/apache/jackrabbit/oak/security/user/UserValidatorTest.java =================================================================== --- oak-core/src/test/java/org/apache/jackrabbit/oak/security/user/UserValidatorTest.java (revision 1686875) +++ oak-core/src/test/java/org/apache/jackrabbit/oak/security/user/UserValidatorTest.java (working copy) @@ -34,9 +34,14 @@ import org.apache.jackrabbit.oak.api.Tree; import org.apache.jackrabbit.oak.api.Type; import org.apache.jackrabbit.oak.plugins.identifier.IdentifierManager; +import org.apache.jackrabbit.oak.plugins.memory.MemoryNodeStore; import org.apache.jackrabbit.oak.plugins.memory.PropertyStates; +import org.apache.jackrabbit.oak.spi.commit.CommitInfo; +import org.apache.jackrabbit.oak.spi.commit.Validator; import org.apache.jackrabbit.oak.spi.security.ConfigurationParameters; import org.apache.jackrabbit.oak.spi.security.user.UserConstants; +import org.apache.jackrabbit.oak.spi.state.NodeBuilder; +import org.apache.jackrabbit.oak.spi.state.NodeState; import org.apache.jackrabbit.oak.util.NodeUtil; import org.apache.jackrabbit.util.Text; import org.junit.Before; @@ -44,6 +49,8 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; import static org.junit.Assert.fail; /** @@ -375,6 +382,72 @@ } } + @Test + public void hiddenNodeAdded() throws CommitFailedException { + UserValidatorProvider provider = new UserValidatorProvider(getConfig()); + MemoryNodeStore store = new MemoryNodeStore(); + NodeState root = store.getRoot(); + NodeBuilder builder = root.builder(); + NodeBuilder test = builder.child("test"); + NodeBuilder hidden = test.child(":hidden"); + + Validator validator = provider.getRootValidator( + root, builder.getNodeState(), CommitInfo.EMPTY); + Validator childValidator = validator.childNodeAdded( + "test", test.getNodeState()); + assertNotNull(childValidator); + + Validator hiddenValidator = childValidator.childNodeAdded( + ":hidden", hidden.getNodeState()); + assertNull(hiddenValidator); + } + + @Test + public void hiddenNodeChanged() throws CommitFailedException { + UserValidatorProvider provider = new UserValidatorProvider(getConfig()); + MemoryNodeStore store = new MemoryNodeStore(); + NodeBuilder builder = store.getRoot().builder(); + builder.child("test").child(":hidden"); + NodeState root = builder.getNodeState(); + + NodeBuilder test = root.builder().child("test"); + NodeBuilder hidden = test.child(":hidden"); + hidden.child("added"); + + Validator validator = provider.getRootValidator( + root, builder.getNodeState(), CommitInfo.EMPTY); + Validator childValidator = validator.childNodeChanged( + "test", root.getChildNode("test"), test.getNodeState()); + assertNotNull(childValidator); + + Validator hiddenValidator = childValidator.childNodeChanged( + ":hidden", root.getChildNode("test").getChildNode(":hidden"), hidden.getNodeState()); + assertNull(hiddenValidator); + } + + @Test + public void hiddenNodeDeleted() throws CommitFailedException { + UserValidatorProvider provider = new UserValidatorProvider(getConfig()); + MemoryNodeStore store = new MemoryNodeStore(); + NodeBuilder builder = store.getRoot().builder(); + builder.child("test").child(":hidden"); + NodeState root = builder.getNodeState(); + + builder = root.builder(); + NodeBuilder test = builder.child("test"); + test.child(":hidden").remove(); + + Validator validator = provider.getRootValidator( + root, builder.getNodeState(), CommitInfo.EMPTY); + Validator childValidator = validator.childNodeChanged( + "test", root.getChildNode("test"), test.getNodeState()); + assertNotNull(childValidator); + + Validator hiddenValidator = childValidator.childNodeDeleted( + ":hidden", root.getChildNode("test").getChildNode(":hidden")); + assertNull(hiddenValidator); + } + private ConfigurationParameters getConfig() { return getUserConfiguration().getParameters(); }