Return-Path: X-Original-To: apmail-jackrabbit-oak-commits-archive@minotaur.apache.org Delivered-To: apmail-jackrabbit-oak-commits-archive@minotaur.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 7A6F4E7DD for ; Mon, 21 Jan 2013 11:09:37 +0000 (UTC) Received: (qmail 7241 invoked by uid 500); 21 Jan 2013 11:09:37 -0000 Delivered-To: apmail-jackrabbit-oak-commits-archive@jackrabbit.apache.org Received: (qmail 7176 invoked by uid 500); 21 Jan 2013 11:09:35 -0000 Mailing-List: contact oak-commits-help@jackrabbit.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: oak-dev@jackrabbit.apache.org Delivered-To: mailing list oak-commits@jackrabbit.apache.org Received: (qmail 7136 invoked by uid 99); 21 Jan 2013 11:09:33 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 21 Jan 2013 11:09:33 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=5.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 21 Jan 2013 11:09:28 +0000 Received: from eris.apache.org (localhost [127.0.0.1]) by eris.apache.org (Postfix) with ESMTP id C7D2623888D2; Mon, 21 Jan 2013 11:09:07 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1436273 - in /jackrabbit/oak/trunk/oak-core/src: main/java/org/apache/jackrabbit/oak/security/authorization/ main/java/org/apache/jackrabbit/oak/security/authorization/restriction/ main/java/org/apache/jackrabbit/oak/security/privilege/ te... Date: Mon, 21 Jan 2013 11:09:07 -0000 To: oak-commits@jackrabbit.apache.org From: angela@apache.org X-Mailer: svnmailer-1.0.8-patched Message-Id: <20130121110907.C7D2623888D2@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: angela Date: Mon Jan 21 11:09:06 2013 New Revision: 1436273 URL: http://svn.apache.org/viewvc?rev=1436273&view=rev Log: OAK-51 : Access Control Management (WIP) Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/AccessControlConstants.java jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/AccessControlValidator.java jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/restriction/RestrictionProviderImpl.java jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/privilege/PrivilegeDefinitionReaderImpl.java jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/privilege/PrivilegeValidator.java jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/AccessControlManagerImplTest.java jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/AccessControlValidatorTest.java Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/AccessControlConstants.java URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/AccessControlConstants.java?rev=1436273&r1=1436272&r2=1436273&view=diff ============================================================================== --- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/AccessControlConstants.java (original) +++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/AccessControlConstants.java Mon Jan 21 11:09:06 2013 @@ -51,7 +51,7 @@ public interface AccessControlConstants Collection POLICY_NODE_NAMES = ImmutableSet.of(REP_POLICY, REP_REPO_POLICY); - Collection AC_PROPERTY_NAMES = ImmutableSet.of(REP_PRINCIPAL_NAME, REP_PRIVILEGES, REP_GLOB); - Collection AC_NODE_NAMES = ImmutableSet.of(REP_POLICY, REP_REPO_POLICY, REP_RESTRICTIONS); + Collection ACE_PROPERTY_NAMES = ImmutableSet.of(REP_PRINCIPAL_NAME, REP_PRIVILEGES); + Collection AC_NODETYPE_NAMES = ImmutableSet.of(NT_REP_POLICY, NT_REP_ACL, NT_REP_ACE, NT_REP_DENY_ACE, NT_REP_GRANT_ACE, NT_REP_RESTRICTIONS); } \ No newline at end of file Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/AccessControlValidator.java URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/AccessControlValidator.java?rev=1436273&r1=1436272&r2=1436273&view=diff ============================================================================== --- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/AccessControlValidator.java (original) +++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/AccessControlValidator.java Mon Jan 21 11:09:06 2013 @@ -16,12 +16,14 @@ */ package org.apache.jackrabbit.oak.security.authorization; +import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.Map; import javax.jcr.RepositoryException; import javax.jcr.security.AccessControlException; +import org.apache.jackrabbit.JcrConstants; import org.apache.jackrabbit.oak.api.CommitFailedException; import org.apache.jackrabbit.oak.api.PropertyState; import org.apache.jackrabbit.oak.api.Tree; @@ -63,6 +65,9 @@ class AccessControlValidator implements if (isAccessControlEntry(parentAfter)) { checkValidAccessControlEntry(parentAfter); } + if (JcrConstants.JCR_MIXINTYPES.equals(after.getName())) { + checkMixinTypes(parentAfter); + } } @Override @@ -70,6 +75,9 @@ class AccessControlValidator implements if (isAccessControlEntry(parentAfter)) { checkValidAccessControlEntry(parentAfter); } + if (JcrConstants.JCR_MIXINTYPES.equals(after.getName())) { + checkMixinTypes(parentAfter); + } } @Override @@ -79,8 +87,7 @@ class AccessControlValidator implements @Override public Validator childNodeAdded(String name, NodeState after) throws CommitFailedException { - NodeUtil nodeAfter = parentAfter.getChild(name); - checkNotNull(nodeAfter); + NodeUtil nodeAfter = checkNotNull(parentAfter.getChild(name)); checkValidNode(parentAfter, nodeAfter); return new AccessControlValidator(null, nodeAfter, privilegeDefinitions, restrictionProvider, ntMgr); @@ -88,10 +95,8 @@ class AccessControlValidator implements @Override public Validator childNodeChanged(String name, NodeState before, NodeState after) throws CommitFailedException { - NodeUtil nodeBefore = parentBefore.getChild(name); - NodeUtil nodeAfter = parentAfter.getChild(name); - checkNotNull(nodeBefore); - checkNotNull(nodeAfter); + NodeUtil nodeBefore = checkNotNull(parentBefore.getChild(name)); + NodeUtil nodeAfter = checkNotNull(parentAfter.getChild(name)); checkValidNode(parentAfter, nodeAfter); return new AccessControlValidator(nodeBefore, nodeAfter, privilegeDefinitions, restrictionProvider, ntMgr); @@ -110,14 +115,14 @@ class AccessControlValidator implements checkValidPolicy(parentAfter, nodeAfter); } else if (isAccessControlEntry(nodeAfter)) { checkValidAccessControlEntry(nodeAfter); - } else if (REP_RESTRICTIONS.equals(nodeAfter.getName())) { + } else if (NT_REP_RESTRICTIONS.equals(nodeAfter.getPrimaryNodeTypeName())) { checkIsAccessControlEntry(parentAfter); checkValidRestrictions(parentAfter); } } private static boolean isPolicy(NodeUtil node) { - return POLICY_NODE_NAMES.contains(node.getName()); + return NT_REP_ACL.equals(node.getPrimaryNodeTypeName()); } private static boolean isAccessControlEntry(NodeUtil node) { @@ -160,8 +165,8 @@ class AccessControlValidator implements throw new CommitFailedException(msg, e); } - if (MIX_REP_REPO_ACCESS_CONTROLLABLE.equals(requiredMixin) && !accessControlledTree.isRoot()) { - fail("Only root can store repository level policies."); + if (MIX_REP_REPO_ACCESS_CONTROLLABLE.equals(requiredMixin)) { + checkValidRepoAccessControlled(accessControlledTree); } } @@ -219,6 +224,20 @@ class AccessControlValidator implements } } + + private static void checkMixinTypes(NodeUtil parentNode) throws CommitFailedException { + String[] mixinNames = parentNode.getNames(JcrConstants.JCR_MIXINTYPES); + if (mixinNames != null && Arrays.asList(mixinNames).contains(MIX_REP_REPO_ACCESS_CONTROLLABLE)) { + checkValidRepoAccessControlled(parentNode.getTree()); + } + } + + private static void checkValidRepoAccessControlled(Tree accessControlledTree) throws CommitFailedException { + if (!accessControlledTree.isRoot()) { + fail("Only root can store repository level policies."); + } + } + private static void fail(String msg) throws CommitFailedException { throw new CommitFailedException(new AccessControlException(msg)); } Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/restriction/RestrictionProviderImpl.java URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/restriction/RestrictionProviderImpl.java?rev=1436273&r1=1436272&r2=1436273&view=diff ============================================================================== --- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/restriction/RestrictionProviderImpl.java (original) +++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/restriction/RestrictionProviderImpl.java Mon Jan 21 11:09:06 2013 @@ -22,6 +22,7 @@ import java.util.HashSet; import java.util.Map; import java.util.Set; import javax.annotation.Nonnull; +import javax.jcr.NamespaceRegistry; import javax.jcr.PropertyType; import javax.jcr.RepositoryException; import javax.jcr.Value; @@ -33,7 +34,6 @@ import org.apache.jackrabbit.oak.api.Pro import org.apache.jackrabbit.oak.api.Tree; import org.apache.jackrabbit.oak.namepath.NamePathMapper; import org.apache.jackrabbit.oak.plugins.memory.PropertyStates; -import org.apache.jackrabbit.oak.plugins.name.NamespaceConstants; import org.apache.jackrabbit.oak.security.authorization.AccessControlConstants; import org.apache.jackrabbit.oak.spi.security.authorization.restriction.Restriction; import org.apache.jackrabbit.oak.spi.security.authorization.restriction.RestrictionDefinition; @@ -122,11 +122,16 @@ public class RestrictionProviderImpl imp if (oakPath == null && !restrictionProperties.isEmpty()) { throw new AccessControlException("Restrictions not supported with 'null' path."); } - for (String restrName : restrictionProperties.keySet()) { + for (Map.Entry entry : restrictionProperties.entrySet()) { + String restrName = entry.getKey(); RestrictionDefinition def = supported.get(restrName); - if (def == null || restrictionProperties.get(restrName).getType().tag() != def.getRequiredType()) { + if (def == null) { throw new AccessControlException("Unsupported restriction: " + restrName); } + int type = entry.getValue().getType().tag(); + if (type != def.getRequiredType()) { + throw new AccessControlException("Invalid restriction type '"+PropertyType.nameFromValue(type)+"'. Expected " + PropertyType.nameFromValue(def.getRequiredType())); + } } for (RestrictionDefinition def : supported.values()) { if (def.isMandatory() && !restrictionProperties.containsKey(def.getName())) { @@ -165,8 +170,7 @@ public class RestrictionProviderImpl imp } private static boolean isRestrictionProperty(String propertyName) { - String prefix = Text.getNamespacePrefix(propertyName); - return !NamespaceConstants.RESERVED_PREFIXES.contains(prefix) - && !AccessControlConstants.AC_PROPERTY_NAMES.contains(propertyName); + return !AccessControlConstants.ACE_PROPERTY_NAMES.contains(propertyName) && + !NamespaceRegistry.PREFIX_JCR.equals(Text.getNamespacePrefix(propertyName)); } } Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/privilege/PrivilegeDefinitionReaderImpl.java URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/privilege/PrivilegeDefinitionReaderImpl.java?rev=1436273&r1=1436272&r2=1436273&view=diff ============================================================================== --- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/privilege/PrivilegeDefinitionReaderImpl.java (original) +++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/privilege/PrivilegeDefinitionReaderImpl.java Mon Jan 21 11:09:06 2013 @@ -20,15 +20,19 @@ import java.util.HashMap; import java.util.Map; import javax.annotation.Nonnull; +import org.apache.jackrabbit.JcrConstants; import org.apache.jackrabbit.oak.api.Root; import org.apache.jackrabbit.oak.api.Tree; +import org.apache.jackrabbit.oak.api.TreeLocation; import org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeDefinition; import org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeDefinitionReader; import org.apache.jackrabbit.oak.util.NodeUtil; +import static com.google.common.base.Preconditions.checkNotNull; import static org.apache.jackrabbit.oak.security.privilege.PrivilegeConstants.PRIVILEGES_PATH; import static org.apache.jackrabbit.oak.security.privilege.PrivilegeConstants.REP_AGGREGATES; import static org.apache.jackrabbit.oak.security.privilege.PrivilegeConstants.REP_IS_ABSTRACT; +import static org.apache.jackrabbit.oak.security.privilege.PrivilegeConstants.REP_PRIVILEGES; /** @@ -39,12 +43,19 @@ class PrivilegeDefinitionReaderImpl impl private final Tree privilegesTree; - PrivilegeDefinitionReaderImpl(Tree privilegesTree) { - this.privilegesTree = privilegesTree; + PrivilegeDefinitionReaderImpl(@Nonnull Tree privilegesTree) { + if (privilegesTree.isRoot()) { + TreeLocation location = privilegesTree.getLocation().getChild(JcrConstants.JCR_SYSTEM+'/'+REP_PRIVILEGES); + this.privilegesTree = checkNotNull(location.getTree()); + } else if (PRIVILEGES_PATH.equals(privilegesTree.getPath())) { + this.privilegesTree = privilegesTree; + } else { + throw new IllegalArgumentException("Illegal privilege tree " + privilegesTree); + } } - PrivilegeDefinitionReaderImpl(Root root) { - this(root.getTree(PRIVILEGES_PATH)); + PrivilegeDefinitionReaderImpl(@Nonnull Root root) { + this(checkNotNull(root.getTree(PRIVILEGES_PATH))); } //------------------------------------------< PrivilegeDefinitionReader >--- Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/privilege/PrivilegeValidator.java URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/privilege/PrivilegeValidator.java?rev=1436273&r1=1436272&r2=1436273&view=diff ============================================================================== --- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/privilege/PrivilegeValidator.java (original) +++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/privilege/PrivilegeValidator.java Mon Jan 21 11:09:06 2013 @@ -43,10 +43,9 @@ class PrivilegeValidator implements Priv private final PrivilegeDefinitionReaderImpl reader; PrivilegeValidator(NodeState before) { - NodeState privRootState = getPrivilegesRoot(before); - if (privRootState != null) { - Tree privilegesBefore = new ReadOnlyTree(privRootState); - reader = new PrivilegeDefinitionReaderImpl(privilegesBefore); + Tree privTree = getPrivilegesTree(before); + if (privTree != null) { + reader = new PrivilegeDefinitionReaderImpl(privTree); definitions = reader.readDefinitions(); } else { reader = null; @@ -206,10 +205,11 @@ class PrivilegeValidator implements Priv } } - private static NodeState getPrivilegesRoot(NodeState rootState) { - NodeState system = rootState.getChildNode(JcrConstants.JCR_SYSTEM); + private static Tree getPrivilegesTree(NodeState rootState) { + Tree root = new ReadOnlyTree(rootState); + Tree system = root.getChild(JcrConstants.JCR_SYSTEM); if (system != null) { - return system.getChildNode(REP_PRIVILEGES); + return system.getChild(REP_PRIVILEGES); } return null; } Modified: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/AccessControlManagerImplTest.java URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/AccessControlManagerImplTest.java?rev=1436273&r1=1436272&r2=1436273&view=diff ============================================================================== --- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/AccessControlManagerImplTest.java (original) +++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/AccessControlManagerImplTest.java Mon Jan 21 11:09:06 2013 @@ -107,7 +107,8 @@ public class AccessControlManagerImplTes root.commit(); - testPrincipal = new PrincipalImpl("admin"); // TODO + // TODO + testPrincipal = new PrincipalImpl("admin"); testPrivileges = privilegesFromNames(Privilege.JCR_ADD_CHILD_NODES, Privilege.JCR_READ); } Modified: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/AccessControlValidatorTest.java URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/AccessControlValidatorTest.java?rev=1436273&r1=1436272&r2=1436273&view=diff ============================================================================== --- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/AccessControlValidatorTest.java (original) +++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/AccessControlValidatorTest.java Mon Jan 21 11:09:06 2013 @@ -16,40 +16,304 @@ */ package org.apache.jackrabbit.oak.security.authorization; +import java.security.Principal; +import javax.jcr.security.AccessControlException; + +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.Tree; +import org.apache.jackrabbit.oak.security.principal.PrincipalImpl; +import org.apache.jackrabbit.oak.security.privilege.PrivilegeConstants; +import org.apache.jackrabbit.oak.spi.security.authorization.AbstractAccessControlTest; +import org.apache.jackrabbit.oak.util.NodeUtil; +import org.junit.After; +import org.junit.Before; import org.junit.Test; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + /** * AccessControlValidatorTest... TODO */ -public class AccessControlValidatorTest { +public class AccessControlValidatorTest extends AbstractAccessControlTest implements AccessControlConstants { + + private final String testName = "testRoot"; + private final String testPath = '/' + testName; + private final String aceName = "validAce"; + + private Principal testPrincipal; + + @Before + public void before() throws Exception { + super.before(); + + NodeUtil rootNode = new NodeUtil(root.getTree("/"), getNamePathMapper()); + rootNode.addChild(testName, JcrConstants.NT_UNSTRUCTURED); + + root.commit(); - @Test - public void testPropertyAdded() { // TODO + testPrincipal = new PrincipalImpl("testPrincipal"); + } + + @After + public void after() throws Exception { + try { + Tree testRoot = root.getTree(testPath); + if (testRoot != null) { + testRoot.remove(); + root.commit(); + } + } finally { + super.after(); + } + } + + private NodeUtil getTestRoot() { + return new NodeUtil(root.getTree(testPath)); + } + + private NodeUtil createAcl() { + NodeUtil testRoot = getTestRoot(); + testRoot.setNames(JcrConstants.JCR_MIXINTYPES, MIX_REP_ACCESS_CONTROLLABLE); + + NodeUtil acl = testRoot.addChild(REP_POLICY, NT_REP_ACL); + NodeUtil ace = createACE(acl, aceName, NT_REP_GRANT_ACE, testPrincipal.getName(), PrivilegeConstants.JCR_READ); + ace.addChild(REP_RESTRICTIONS, NT_REP_RESTRICTIONS); + return acl; + } + + private static NodeUtil createACE(NodeUtil acl, String aceName, String ntName, String principalName, String... privilegeNames) { + NodeUtil ace = acl.addChild(aceName, ntName); + ace.setString(REP_PRINCIPAL_NAME, principalName); + ace.setNames(REP_PRIVILEGES, privilegeNames); + return ace; } @Test - public void testPropertyModified() { - // TODO + public void testOnlyRootIsRepoAccessControllable() { + NodeUtil testRoot = getTestRoot(); + testRoot.setNames(JcrConstants.JCR_MIXINTYPES, MIX_REP_REPO_ACCESS_CONTROLLABLE); + try { + root.commit(); + fail("Only the root node can be made RepoAccessControllable."); + } catch (CommitFailedException e) { + // success + assertTrue(e.getCause() instanceof AccessControlException); + } } @Test - public void testPropertyDeleted() { - // TODO + public void testAddInvalidRepoPolicy() { + NodeUtil testRoot = getTestRoot(); + testRoot.setNames(JcrConstants.JCR_MIXINTYPES, MIX_REP_ACCESS_CONTROLLABLE); + NodeUtil policy = getTestRoot().addChild(REP_REPO_POLICY, NT_REP_ACL); + try { + root.commit(); + fail("Attempt to add repo-policy with rep:AccessControllable node."); + } catch (CommitFailedException e) { + // success + assertTrue(e.getCause() instanceof AccessControlException); + } finally { + policy.getTree().remove(); + } } @Test - public void testChildNodeAdded() { - // TODO + public void testAddPolicyWithAcContent() { + NodeUtil acl = createAcl(); + NodeUtil ace = acl.getChild(aceName); + + NodeUtil[] acContent = new NodeUtil[] {acl, ace, ace.getChild(REP_RESTRICTIONS)}; + for (NodeUtil node : acContent) { + NodeUtil policy = node.addChild(REP_POLICY, NT_REP_ACL); + try { + root.commit(); + fail("Adding an ACL below access control content should fail"); + } catch (CommitFailedException e) { + // success + assertTrue(e.getCause() instanceof AccessControlException); + } finally { + policy.getTree().remove(); + } + } } @Test - public void testChildNodeModified() { - // TODO + public void testAddRepoPolicyWithAcContent() { + NodeUtil acl = createAcl(); + NodeUtil ace = acl.getChild(aceName); + + NodeUtil[] acContent = new NodeUtil[] {acl, ace, ace.getChild(REP_RESTRICTIONS)}; + for (NodeUtil node : acContent) { + NodeUtil policy = node.addChild(REP_REPO_POLICY, NT_REP_ACL); + try { + root.commit(); + fail("Adding an ACL below access control content should fail"); + } catch (CommitFailedException e) { + // success + assertTrue(e.getCause() instanceof AccessControlException); + } finally { + policy.getTree().remove(); + } + } } @Test - public void testChildNodeDeleted() { - // TODO + public void testAddAceWithAcContent() { + NodeUtil acl = createAcl(); + NodeUtil ace = acl.getChild(aceName); + + NodeUtil[] acContent = new NodeUtil[] {ace, ace.getChild(REP_RESTRICTIONS)}; + for (NodeUtil node : acContent) { + NodeUtil entry = node.addChild("invalidACE", NT_REP_DENY_ACE); + try { + root.commit(); + fail("Adding an ACE below an ACE or restriction should fail"); + } catch (CommitFailedException e) { + // success + assertTrue(e.getCause() instanceof AccessControlException); + } finally { + entry.getTree().remove(); + } + } + } + + @Test + public void testAddRestrictionWithAcContent() { + NodeUtil acl = createAcl(); + NodeUtil ace = acl.getChild(aceName); + + NodeUtil[] acContent = new NodeUtil[] {acl, ace.getChild(REP_RESTRICTIONS)}; + for (NodeUtil node : acContent) { + NodeUtil entry = node.addChild("invalidRestriction", NT_REP_RESTRICTIONS); + try { + root.commit(); + fail("Adding an ACE below an ACE or restriction should fail"); + } catch (CommitFailedException e) { + // success + assertTrue(e.getCause() instanceof AccessControlException); + } finally { + entry.getTree().remove(); + } + } + } + + @Test + public void testAddIsolatedPolicy() { + String[] policyNames = new String[] {"isolatedACL", REP_POLICY, REP_REPO_POLICY}; + NodeUtil node = getTestRoot(); + + for (String policyName : policyNames) { + NodeUtil policy = node.addChild(policyName, NT_REP_ACL); + try { + root.commit(); + fail("Writing an isolated ACL without the parent being rep:AccessControllable should fail."); + } catch (CommitFailedException e) { + // success + assertTrue(e.getCause() instanceof AccessControlException); + } finally { + // revert pending changes that cannot be saved. + policy.getTree().remove(); + } + } + + } + + @Test + public void testAddIsolatedAce() { + String[] ntNames = new String[] {NT_REP_DENY_ACE, NT_REP_GRANT_ACE}; + NodeUtil node = getTestRoot(); + + for (String aceNtName : ntNames) { + NodeUtil ace = createACE(node, "isolatedACE", aceNtName, testPrincipal.getName(), PrivilegeConstants.JCR_READ); + try { + root.commit(); + fail("Writing an isolated ACE should fail."); + } catch (CommitFailedException e) { + // success + assertTrue(e.getCause() instanceof AccessControlException); + } finally { + // revert pending changes that cannot be saved. + ace.getTree().remove(); + } + } + } + + @Test + public void testAddIsolatedRestriction() { + NodeUtil node = getTestRoot(); + NodeUtil restriction = node.addChild("isolatedRestriction", NT_REP_RESTRICTIONS); + try { + root.commit(); + fail("Writing an isolated Restriction should fail."); + } catch (CommitFailedException e) { + // success + assertTrue(e.getCause() instanceof AccessControlException); + } finally { + // revert pending changes that cannot be saved. + restriction.getTree().remove(); + } + } + + @Test + public void testInvalidPrivilege() { + NodeUtil acl = createAcl(); + + String privName = "invalidPrivilegeName"; + NodeUtil invalidAce = createACE(acl, "invalid", NT_REP_GRANT_ACE, testPrincipal.getName(), privName); + try { + root.commit(); + fail("Creating an ACE with invalid privilege should fail."); + } catch (CommitFailedException e) { + // success + assertTrue(e.getCause() instanceof AccessControlException); + } + } + + @Test + public void testAbstractPrivilege() throws Exception { + PrivilegeManager pMgr = getSecurityProvider().getPrivilegeConfiguration().getPrivilegeManager(root, getNamePathMapper()); + pMgr.registerPrivilege("abstractPrivilege", true, new String[0]); + + root.rebase(); + + NodeUtil acl = createAcl(); + NodeUtil invalidAce = createACE(acl, "invalid", NT_REP_GRANT_ACE, testPrincipal.getName(), "abstractPrivilege"); + try { + root.commit(); + fail("Creating an ACE with an abstract privilege should fail."); + } catch (CommitFailedException e) { + // success + assertTrue(e.getCause() instanceof AccessControlException); + } + } + + @Test + public void testInvalidRestriction() throws Exception { + NodeUtil restriction = createAcl().getChild(aceName).getChild(REP_RESTRICTIONS); + restriction.setString("invalid", "value"); + try { + root.commit(); + fail("Creating an unsupported restriction should fail."); + } catch (CommitFailedException e) { + // success + assertTrue(e.getCause() instanceof AccessControlException); + } + } + + @Test + public void testRestrictionWithInvalidType() throws Exception { + NodeUtil restriction = createAcl().getChild(aceName).getChild(REP_RESTRICTIONS); + restriction.setName(REP_GLOB, "rep:glob"); + try { + root.commit(); + fail("Creating restriction with invalid type should fail."); + } catch (CommitFailedException e) { + // success + assertTrue(e.getCause() instanceof AccessControlException); + } } } \ No newline at end of file