blob: dd1b8cc0c8bc1e23274b413e98c31db7f1c3544e [file] [log] [blame]
/*
* 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.cug.impl;
import java.security.Principal;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.jcr.PathNotFoundException;
import javax.jcr.RepositoryException;
import javax.jcr.security.AccessControlException;
import javax.jcr.security.AccessControlPolicy;
import javax.jcr.security.AccessControlPolicyIterator;
import javax.jcr.security.NamedAccessControlPolicy;
import javax.jcr.security.Privilege;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Sets;
import org.apache.jackrabbit.JcrConstants;
import org.apache.jackrabbit.api.security.JackrabbitAccessControlPolicy;
import org.apache.jackrabbit.oak.api.ContentSession;
import org.apache.jackrabbit.oak.api.PropertyState;
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.namepath.NamePathMapper;
import org.apache.jackrabbit.oak.spi.nodetype.NodeTypeConstants;
import org.apache.jackrabbit.oak.plugins.nodetype.ReadOnlyNodeTypeManager;
import org.apache.jackrabbit.oak.plugins.tree.TreeUtil;
import org.apache.jackrabbit.oak.spi.security.ConfigurationParameters;
import org.apache.jackrabbit.oak.spi.security.authorization.AuthorizationConfiguration;
import org.apache.jackrabbit.oak.spi.security.authorization.cug.CugPolicy;
import org.apache.jackrabbit.oak.spi.security.principal.EveryonePrincipal;
import org.apache.jackrabbit.oak.spi.security.principal.PrincipalImpl;
import org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants;
import org.apache.jackrabbit.oak.spi.xml.ImportBehavior;
import org.jetbrains.annotations.NotNull;
import org.junit.Test;
import static org.apache.jackrabbit.oak.api.Type.NAMES;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
public class CugAccessControlManagerTest extends AbstractCugTest {
private CugAccessControlManager cugAccessControlManager;
@Override
public void before() throws Exception {
super.before();
cugAccessControlManager = new CugAccessControlManager(root, NamePathMapper.DEFAULT, getSecurityProvider(), ImmutableSet.copyOf(SUPPORTED_PATHS), getExclude(), getRootProvider());
}
private CugPolicy createCug(@NotNull String path) {
return new CugPolicyImpl(path, NamePathMapper.DEFAULT, getPrincipalManager(root), ImportBehavior.ABORT, getExclude());
}
private CugPolicy getApplicableCug() throws RepositoryException {
return (CugPolicy) cugAccessControlManager.getApplicablePolicies(AbstractCugTest.SUPPORTED_PATH).nextAccessControlPolicy();
}
@Test
public void testGetSupportedPrivileges() throws Exception {
Privilege[] readPrivs = privilegesFromNames(PrivilegeConstants.JCR_READ);
Map<String, Privilege[]> pathMap = ImmutableMap.of(
SUPPORTED_PATH, readPrivs,
SUPPORTED_PATH + "/subtree", readPrivs,
UNSUPPORTED_PATH, new Privilege[0],
NodeTypeConstants.NODE_TYPES_PATH, new Privilege[0]
);
for (String path : pathMap.keySet()) {
Privilege[] expected = pathMap.get(path);
assertArrayEquals(expected, cugAccessControlManager.getSupportedPrivileges(path));
}
}
@Test
public void testGetSupportedPrivilegesNullPath() throws Exception {
assertArrayEquals(new Privilege[0], cugAccessControlManager.getSupportedPrivileges(null));
}
@Test(expected = PathNotFoundException.class)
public void testGetSupportedPrivilegesInvalidPath() throws Exception {
cugAccessControlManager.getSupportedPrivileges(INVALID_PATH);
}
@Test
public void testGetApplicablePolicies() throws Exception {
AccessControlPolicyIterator it = cugAccessControlManager.getApplicablePolicies(SUPPORTED_PATH);
assertTrue(it.hasNext());
AccessControlPolicy policy = cugAccessControlManager.getApplicablePolicies(SUPPORTED_PATH).nextAccessControlPolicy();
assertTrue(policy instanceof CugPolicyImpl);
}
@Test
public void testGetApplicablePoliciesAfterSet() throws Exception {
cugAccessControlManager.setPolicy(SUPPORTED_PATH, getApplicableCug());
AccessControlPolicyIterator it = cugAccessControlManager.getApplicablePolicies(SUPPORTED_PATH);
assertFalse(it.hasNext());
}
@Test(expected = PathNotFoundException.class)
public void testGetApplicablePoliciesInvalidPath() throws Exception {
cugAccessControlManager.getApplicablePolicies(INVALID_PATH);
}
@Test
public void testGetApplicablePoliciesUnsupportedPath() throws Exception {
AccessControlPolicyIterator it = cugAccessControlManager.getApplicablePolicies(UNSUPPORTED_PATH);
assertFalse(it.hasNext());
}
@Test
public void testGetApplicablePoliciesNullPath() throws Exception {
AccessControlPolicyIterator it = cugAccessControlManager.getApplicablePolicies((String) null);
assertFalse(it.hasNext());
}
@Test
public void testGetPolicies() throws Exception {
AccessControlPolicy[] policies = cugAccessControlManager.getPolicies(SUPPORTED_PATH);
assertEquals(0, policies.length);
}
@Test
public void testGetPoliciesAfterSet() throws Exception {
cugAccessControlManager.setPolicy(SUPPORTED_PATH, getApplicableCug());
AccessControlPolicy[] policies = cugAccessControlManager.getPolicies(SUPPORTED_PATH);
assertEquals(1, policies.length);
assertTrue(policies[0] instanceof CugPolicyImpl);
}
@Test
public void testGetPoliciesAfterManualCreation() throws Exception {
Tree n = root.getTree(SUPPORTED_PATH);
Tree cug = TreeUtil.addChild(n, REP_CUG_POLICY, NT_REP_CUG_POLICY);
AccessControlPolicy[] policies = cugAccessControlManager.getPolicies(SUPPORTED_PATH);
assertEquals(1, policies.length);
assertTrue(policies[0] instanceof CugPolicy);
CugPolicy cugPolicy = (CugPolicy) policies[0];
assertTrue(cugPolicy.getPrincipals().isEmpty());
cug.setProperty(REP_PRINCIPAL_NAMES, ImmutableList.of("unknownPrincipalName", EveryonePrincipal.NAME), Type.STRINGS);
policies = cugAccessControlManager.getPolicies(SUPPORTED_PATH);
cugPolicy = (CugPolicy) policies[0];
assertEquals(2, cugPolicy.getPrincipals().size());
}
@Test(expected = PathNotFoundException.class)
public void testGetPoliciesInvalidPath() throws Exception {
cugAccessControlManager.getPolicies(INVALID_PATH);
}
@Test
public void testGetPoliciesUnsupportedPath() throws Exception {
AccessControlPolicy[] policies = cugAccessControlManager.getPolicies(UNSUPPORTED_PATH);
assertEquals(0, policies.length);
}
@Test
public void testGetPoliciesNullPath() throws Exception {
AccessControlPolicy[] policies = cugAccessControlManager.getPolicies((String) null);
assertEquals(0, policies.length);
}
@Test
public void testGetEffectivePolicies() throws Exception {
AccessControlPolicy[] policies = cugAccessControlManager.getEffectivePolicies(SUPPORTED_PATH);
assertEquals(0, policies.length);
cugAccessControlManager.setPolicy(SUPPORTED_PATH, createCug(SUPPORTED_PATH));
root.commit();
policies = cugAccessControlManager.getEffectivePolicies(SUPPORTED_PATH);
assertEquals(1, policies.length);
AccessControlPolicy[] effectiveOnChild = cugAccessControlManager.getEffectivePolicies(SUPPORTED_PATH + "/subtree");
assertEquals(1, policies.length);
assertEquals(policies.length, effectiveOnChild.length);
assertEquals(((JackrabbitAccessControlPolicy) policies[0]).getPath(), ((JackrabbitAccessControlPolicy) effectiveOnChild[0]).getPath());
}
@Test(expected = PathNotFoundException.class)
public void testGetEffectivePoliciesInvalidPath() throws Exception {
cugAccessControlManager.getEffectivePolicies(INVALID_PATH);
}
@Test
public void testGetEffectivePoliciesUnsupportedPath() throws Exception {
AccessControlPolicy[] policies = cugAccessControlManager.getEffectivePolicies(UNSUPPORTED_PATH);
assertEquals(0, policies.length);
}
@Test
public void testGetEffectivePoliciesNullPath() throws Exception {
AccessControlPolicy[] policies = cugAccessControlManager.getEffectivePolicies((String) null);
assertEquals(0, policies.length);
}
@Test
public void testGetEffectivePoliciesNotEnabled() throws Exception {
cugAccessControlManager.setPolicy(SUPPORTED_PATH, createCug(SUPPORTED_PATH));
root.commit();
ConfigurationParameters config = ConfigurationParameters.of(AuthorizationConfiguration.NAME, ConfigurationParameters.of(
CugConstants.PARAM_CUG_SUPPORTED_PATHS, SUPPORTED_PATHS,
CugConstants.PARAM_CUG_ENABLED, false));
CugAccessControlManager acMgr = new CugAccessControlManager(root, NamePathMapper.DEFAULT, CugSecurityProvider.newTestSecurityProvider(config), ImmutableSet.copyOf(SUPPORTED_PATHS), getExclude(), getRootProvider());
AccessControlPolicy[] policies = acMgr.getEffectivePolicies(SUPPORTED_PATH);
assertEquals(0, policies.length);
AccessControlPolicy[] effectiveOnChild = acMgr.getEffectivePolicies(SUPPORTED_PATH + "/subtree");
assertEquals(0, policies.length);
assertEquals(policies.length, effectiveOnChild.length);
}
@Test(expected = AccessControlException.class)
public void testGetEffectivePoliciesNoReadAcPermission() throws Exception {
setupCugsAndAcls();
// test-user only has read-access on /content (no read-ac permission)
try (ContentSession cs = createTestSession()) {
Root r = cs.getLatestRoot();
CugAccessControlManager m = new CugAccessControlManager(r, NamePathMapper.DEFAULT, getSecurityProvider(), ImmutableSet.copyOf(SUPPORTED_PATHS), getExclude(), getRootProvider());
AccessControlPolicy[] effective = m.getEffectivePolicies("/content");
assertEquals(0, effective.length);
}
}
@Test(expected = PathNotFoundException.class)
public void testGetEffectivePoliciesNoReadPermission() throws Exception {
setupCugsAndAcls();
// test-user only has read-access on /content (no read-ac permission)
try (ContentSession cs = createTestSession()) {
Root r = cs.getLatestRoot();
CugAccessControlManager m = new CugAccessControlManager(r, NamePathMapper.DEFAULT, getSecurityProvider(), ImmutableSet.copyOf(SUPPORTED_PATHS), getExclude(), getRootProvider());
m.getEffectivePolicies("/content2");
}
}
@Test
public void testGetEffectivePoliciesLimitedReadAcPermission() throws Exception {
setupCugsAndAcls();
// test-user2 only has read-ac permission on /content but not on /content2
try (ContentSession cs = createTestSession2()) {
Root r = cs.getLatestRoot();
CugAccessControlManager m = new CugAccessControlManager(r, NamePathMapper.DEFAULT, getSecurityProvider(), ImmutableSet.copyOf(SUPPORTED_PATHS), getExclude(), getRootProvider());
AccessControlPolicy[] effective = m.getEffectivePolicies("/content/a/b/c");
// [/content/a, /content/a/b/c]
assertEquals(2, effective.length);
}
}
@Test
public void testSetPolicy() throws Exception {
CugPolicy cug = getApplicableCug();
cug.addPrincipals(EveryonePrincipal.getInstance());
cugAccessControlManager.setPolicy(SUPPORTED_PATH, cug);
AccessControlPolicy[] policies = cugAccessControlManager.getPolicies(SUPPORTED_PATH);
assertEquals(1, policies.length);
AccessControlPolicy policy = policies[0];
assertTrue(policy instanceof CugPolicyImpl);
Set<Principal> principals = ((CugPolicy) policy).getPrincipals();
assertEquals(1, principals.size());
assertEquals(EveryonePrincipal.getInstance(), principals.iterator().next());
}
@Test
public void testSetPolicyPersisted() throws Exception {
CugPolicy cug = getApplicableCug();
cug.addPrincipals(EveryonePrincipal.getInstance());
cugAccessControlManager.setPolicy(SUPPORTED_PATH, cug);
root.commit();
Tree tree = root.getTree(SUPPORTED_PATH);
assertTrue(TreeUtil.isNodeType(tree, CugConstants.MIX_REP_CUG_MIXIN, root.getTree(NodeTypeConstants.NODE_TYPES_PATH)));
Tree cugTree = tree.getChild(CugConstants.REP_CUG_POLICY);
assertTrue(cugTree.exists());
assertEquals(CugConstants.NT_REP_CUG_POLICY, TreeUtil.getPrimaryTypeName(cugTree));
PropertyState prop = cugTree.getProperty(CugConstants.REP_PRINCIPAL_NAMES);
assertNotNull(prop);
assertTrue(prop.isArray());
assertEquals(Type.STRINGS, prop.getType());
assertEquals(1, prop.count());
assertEquals(EveryonePrincipal.NAME, prop.getValue(Type.STRING, 0));
}
@Test
public void testSetInvalidPolicy() throws Exception {
List<AccessControlPolicy> invalidPolicies = ImmutableList.of(
new AccessControlPolicy() {},
(NamedAccessControlPolicy) () -> "name",
InvalidCug.INSTANCE
);
for (AccessControlPolicy policy : invalidPolicies) {
try {
cugAccessControlManager.setPolicy(SUPPORTED_PATH, policy);
fail("Invalid cug policy must be detected.");
} catch (AccessControlException e) {
// success
}
}
}
@Test(expected = PathNotFoundException.class)
public void testSetPolicyInvalidPath() throws Exception {
cugAccessControlManager.setPolicy(INVALID_PATH, createCug(INVALID_PATH));
}
@Test(expected = AccessControlException.class)
public void testSetPolicyUnsupportedPath() throws Exception {
cugAccessControlManager.setPolicy(UNSUPPORTED_PATH, createCug(UNSUPPORTED_PATH));
}
@Test(expected = AccessControlException.class)
public void testSetPolicyPathMismatch() throws Exception {
cugAccessControlManager.setPolicy(SUPPORTED_PATH, createCug(SUPPORTED_PATH + "/subtree"));
}
@Test(expected = AccessControlException.class)
public void testSetInvalidCugNode() throws Exception {
Tree supportedTree = root.getTree(SUPPORTED_PATH);
TreeUtil.addChild(supportedTree, REP_CUG_POLICY, NodeTypeConstants.NT_OAK_UNSTRUCTURED);
cugAccessControlManager.setPolicy(SUPPORTED_PATH, new CugPolicyImpl(SUPPORTED_PATH, NamePathMapper.DEFAULT, getPrincipalManager(root), ImportBehavior.BESTEFFORT, getExclude()));
}
@Test
public void testSetPolicyMixinAlreadyPresent() throws Exception {
CugPolicy cug = getApplicableCug();
cug.addPrincipals(EveryonePrincipal.getInstance());
TreeUtil.addMixin(root.getTree(SUPPORTED_PATH), MIX_REP_CUG_MIXIN, root.getTree(NODE_TYPES_PATH), "uid");
cugAccessControlManager.setPolicy(SUPPORTED_PATH, cug);
root.commit();
ReadOnlyNodeTypeManager ntMgr = ReadOnlyNodeTypeManager.getInstance(root, NamePathMapper.DEFAULT);
assertTrue(ntMgr.isNodeType(root.getTree(SUPPORTED_PATH), MIX_REP_CUG_MIXIN));
}
@Test
public void testResetPolicy() throws Exception {
CugPolicy cug = getApplicableCug();
cug.addPrincipals(EveryonePrincipal.getInstance());
cugAccessControlManager.setPolicy(SUPPORTED_PATH, cug);
cug = (CugPolicy) cugAccessControlManager.getPolicies(SUPPORTED_PATH)[0];
assertTrue(cug.removePrincipals(EveryonePrincipal.getInstance()));
assertTrue(cug.getPrincipals().isEmpty());
Principal testprincipal = getTestGroupPrincipal();
cug.addPrincipals(testprincipal);
cugAccessControlManager.setPolicy(SUPPORTED_PATH, cug);
cug = (CugPolicy) cugAccessControlManager.getPolicies(SUPPORTED_PATH)[0];
assertEquals(ImmutableSet.of(testprincipal), cug.getPrincipals());
}
@Test
public void testRemovePolicy() throws Exception {
CugPolicy cug = getApplicableCug();
cugAccessControlManager.setPolicy(SUPPORTED_PATH, cug);
cugAccessControlManager.removePolicy(SUPPORTED_PATH, cugAccessControlManager.getPolicies(SUPPORTED_PATH)[0]);
assertArrayEquals(new AccessControlPolicy[0], cugAccessControlManager.getPolicies(SUPPORTED_PATH));
}
@Test
public void testRemovePolicyPersisted() throws Exception {
CugPolicy cug = getApplicableCug();
cugAccessControlManager.setPolicy(SUPPORTED_PATH, cug);
root.commit();
cugAccessControlManager.removePolicy(SUPPORTED_PATH, cugAccessControlManager.getPolicies(SUPPORTED_PATH)[0]);
root.commit();
Tree tree = root.getTree(SUPPORTED_PATH);
assertFalse(tree.hasChild(CugConstants.REP_CUG_POLICY));
}
@Test
public void testRemovePolicyRemovesMixin() throws Exception {
ReadOnlyNodeTypeManager ntMgr = ReadOnlyNodeTypeManager.getInstance(root, NamePathMapper.DEFAULT);
CugPolicy cug = getApplicableCug();
cugAccessControlManager.setPolicy(SUPPORTED_PATH, cug);
root.commit();
assertTrue(ntMgr.isNodeType(root.getTree(SUPPORTED_PATH), MIX_REP_CUG_MIXIN));
cugAccessControlManager.removePolicy(SUPPORTED_PATH, cugAccessControlManager.getPolicies(SUPPORTED_PATH)[0]);
root.commit();
assertFalse(ntMgr.isNodeType(root.getTree(SUPPORTED_PATH), MIX_REP_CUG_MIXIN));
}
@Test
public void testRemovePolicyMixinAlreadyRemoved() throws Exception {
ReadOnlyNodeTypeManager ntMgr = ReadOnlyNodeTypeManager.getInstance(root, NamePathMapper.DEFAULT);
CugPolicy cug = getApplicableCug();
cugAccessControlManager.setPolicy(SUPPORTED_PATH, cug);
root.commit();
Tree tree = root.getTree(SUPPORTED_PATH);
Set<String> mixins = Sets.newHashSet(TreeUtil.getNames(tree, NodeTypeConstants.JCR_MIXINTYPES));
mixins.remove(MIX_REP_CUG_MIXIN);
tree.setProperty(JcrConstants.JCR_MIXINTYPES, mixins, NAMES);
assertFalse(ntMgr.isNodeType(root.getTree(SUPPORTED_PATH), MIX_REP_CUG_MIXIN));
cugAccessControlManager.removePolicy(SUPPORTED_PATH, cug);
root.commit();
}
@Test
public void testRemoveInvalidPolicy() throws Exception {
List<AccessControlPolicy> invalidPolicies = ImmutableList.of(
new AccessControlPolicy() {},
(NamedAccessControlPolicy) () -> "name",
InvalidCug.INSTANCE
);
for (AccessControlPolicy policy : invalidPolicies) {
try {
cugAccessControlManager.removePolicy(SUPPORTED_PATH, policy);
fail("Invalid cug policy must be detected.");
} catch (AccessControlException e) {
// success
}
}
}
@Test(expected = AccessControlException.class)
public void testRemoveInvalidCugNode() throws Exception {
Tree supportedTree = root.getTree(SUPPORTED_PATH);
TreeUtil.addChild(supportedTree, REP_CUG_POLICY, NodeTypeConstants.NT_OAK_UNSTRUCTURED);
cugAccessControlManager.removePolicy(SUPPORTED_PATH, new CugPolicyImpl(SUPPORTED_PATH, NamePathMapper.DEFAULT, getPrincipalManager(root), ImportBehavior.BESTEFFORT, getExclude()));
}
@Test(expected = PathNotFoundException.class)
public void testRemovePolicyInvalidPath() throws Exception {
cugAccessControlManager.removePolicy(INVALID_PATH, createCug(INVALID_PATH));
}
@Test(expected = AccessControlException.class)
public void testRemovePolicyUnsupportedPath() throws Exception {
cugAccessControlManager.removePolicy(UNSUPPORTED_PATH, createCug(UNSUPPORTED_PATH));
}
@Test(expected = AccessControlException.class)
public void testRemovePolicyPathMismatch() throws Exception {
cugAccessControlManager.removePolicy(SUPPORTED_PATH, createCug(SUPPORTED_PATH + "/subtree"));
}
@Test
public void testGetApplicablePoliciesByPrincipal() {
AccessControlPolicy[] applicable = cugAccessControlManager.getApplicablePolicies(EveryonePrincipal.getInstance());
assertNotNull(applicable);
assertEquals(0, applicable.length);
}
@Test
public void testGetPoliciesByPrincipal() {
AccessControlPolicy[] applicable = cugAccessControlManager.getPolicies(EveryonePrincipal.getInstance());
assertNotNull(applicable);
assertEquals(0, applicable.length);
}
@Test
public void testGetEffectiveByPrincipalNoCugPresent() {
AccessControlPolicy[] effective = cugAccessControlManager.getEffectivePolicies(Collections.singleton(EveryonePrincipal.getInstance()));
assertEquals(0, effective.length);
}
@Test
public void testGetEffectiveByPrincipalTransientChanges() throws Exception {
Principal p = getTestGroupPrincipal();
createCug(SUPPORTED_PATH, p);
createCug(SUPPORTED_PATH + "/subtree", p);
AccessControlPolicy[] effective = cugAccessControlManager.getEffectivePolicies(Collections.singleton(p));
assertEquals(0, effective.length);
}
@Test
public void testGetEffectiveByPrincipal() throws Exception {
Principal p = getTestGroupPrincipal();
createCug(SUPPORTED_PATH, p);
createCug(SUPPORTED_PATH + "/subtree", p);
root.commit();
Principal na = new PrincipalImpl("testNA");
Set<Principal> pp = ImmutableSet.of(p, na);
AccessControlPolicy[] effective = cugAccessControlManager.getEffectivePolicies(pp);
assertEquals(2, effective.length);
AccessControlPolicy policy = effective[0];
assertTrue(policy instanceof CugPolicy);
assertEquals(Collections.singleton(p), ((CugPolicy) policy).getPrincipals());
assertEquals(SUPPORTED_PATH, ((CugPolicy) policy).getPath());
AccessControlPolicy policy2 = effective[1];
assertTrue(policy2 instanceof CugPolicy);
assertEquals(Collections.singleton(p), ((CugPolicy) policy2).getPrincipals());
assertEquals(SUPPORTED_PATH + "/subtree", ((CugPolicy) policy2).getPath());
}
@Test
public void testGetEffectiveByPrincipalNotListed() throws Exception {
createCug(SUPPORTED_PATH + "/subtree", getTestGroupPrincipal());
root.commit();
Principal na = new PrincipalImpl("testNA");
AccessControlPolicy[] effective = cugAccessControlManager.getEffectivePolicies(ImmutableSet.of(na));
assertEquals(0, effective.length);
}
@Test(expected = AccessControlException.class)
public void testGetEffectiveByPrincipalIsImmutable() throws Exception {
Principal p = getTestGroupPrincipal();
createCug(SUPPORTED_PATH, p);
root.commit();
Principal na = new PrincipalImpl("testNA");
Set<Principal> pp = ImmutableSet.of(p, na);
AccessControlPolicy[] effective = cugAccessControlManager.getEffectivePolicies(pp);
assertEquals(1, effective.length);
assertTrue(effective[0] instanceof CugPolicy);
// modifying policy must fail
((CugPolicy) effective[0]).addPrincipals(EveryonePrincipal.getInstance());
}
@Test
public void testGetEffectivePrincipalDistributed() throws Exception {
// [/content/a : testgroup, /content/aa/bb : testgroup, /content/a/b/c : everyone, /content2: everyone]
setupCugsAndAcls();
AccessControlPolicy[] effective = cugAccessControlManager.getEffectivePolicies(ImmutableSet.of(getTestGroupPrincipal(), EveryonePrincipal.getInstance()));
assertEquals(4, effective.length);
AccessControlPolicy[] everyoneEffective = cugAccessControlManager.getEffectivePolicies(ImmutableSet.of(EveryonePrincipal.getInstance()));
assertEquals(2, everyoneEffective.length);
AccessControlPolicy[] testgroupEffective = cugAccessControlManager.getEffectivePolicies(ImmutableSet.of(getTestGroupPrincipal()));
assertEquals(2, testgroupEffective.length);
assertTrue(Sets.intersection(ImmutableSet.copyOf(everyoneEffective), ImmutableSet.copyOf(testgroupEffective)).isEmpty());
}
@Test
public void testGetEffectivePrincipalNoReadAcPermission() throws Exception {
setupCugsAndAcls();
// test-user only has read-access on /content (no read-ac permission)
try (ContentSession cs = createTestSession()) {
Root r = cs.getLatestRoot();
CugAccessControlManager m = new CugAccessControlManager(r, NamePathMapper.DEFAULT, getSecurityProvider(),
ImmutableSet.copyOf(SUPPORTED_PATHS), getExclude(), getRootProvider());
AccessControlPolicy[] effective = m.getEffectivePolicies(ImmutableSet.of(getTestGroupPrincipal(), EveryonePrincipal.getInstance()));
assertEquals(0, effective.length);
}
}
@Test
public void testGetEffectivePrincipalLimitedReadAcPermission() throws Exception {
setupCugsAndAcls();
// test-user3 only has read-ac permission on /content but not on /content2
try (ContentSession cs = createTestSession2()) {
Root r = cs.getLatestRoot();
CugAccessControlManager m = new CugAccessControlManager(r, NamePathMapper.DEFAULT, getSecurityProvider(),
ImmutableSet.copyOf(SUPPORTED_PATHS), getExclude(), getRootProvider());
AccessControlPolicy[] effective = m.getEffectivePolicies(ImmutableSet.of(getTestGroupPrincipal(), EveryonePrincipal.getInstance()));
// [/content/a, /content/a/b/c, /content/aa/bb] but not: /content2
assertEquals(3, effective.length);
}
}
@Test
public void tesetGetEffectiveByPrincipalRootIncludedIsSupportedPath() throws Exception {
setupCugsAndAcls();
CugAccessControlManager acMgr = new CugAccessControlManager(root, NamePathMapper.DEFAULT, getSecurityProvider(), ImmutableSet.of(PathUtils.ROOT_PATH), getExclude(), getRootProvider());
assertEquals(4, acMgr.getEffectivePolicies(ImmutableSet.of(getTestGroupPrincipal(), EveryonePrincipal.getInstance())).length);
}
@Test
public void tesetGetEffectiveByPrincipalNotEnabled() throws Exception {
setupCugsAndAcls();
ConfigurationParameters config = ConfigurationParameters.of(AuthorizationConfiguration.NAME, ConfigurationParameters.of(
CugConstants.PARAM_CUG_SUPPORTED_PATHS, SUPPORTED_PATHS,
CugConstants.PARAM_CUG_ENABLED, false));
CugAccessControlManager acMgr = new CugAccessControlManager(root, NamePathMapper.DEFAULT, CugSecurityProvider.newTestSecurityProvider(config), ImmutableSet.copyOf(SUPPORTED_PATHS), getExclude(), getRootProvider());
assertEquals(0, acMgr.getEffectivePolicies(ImmutableSet.of(getTestGroupPrincipal(), EveryonePrincipal.getInstance())).length);
}
@Test
public void testDefinesPathMismatch() {
assertFalse(cugAccessControlManager.defines(null, createCug(SUPPORTED_PATH)));
assertFalse(cugAccessControlManager.defines(SUPPORTED_PATH2, createCug(SUPPORTED_PATH)));
}
@Test
public void testDefinesUnsupportedPolicy() {
assertFalse(cugAccessControlManager.defines(InvalidCug.INSTANCE.getPath(), InvalidCug.INSTANCE));
}
@Test
public void testDefines() {
CugPolicy cugPolicy = createCug(SUPPORTED_PATH);
assertTrue(cugAccessControlManager.defines(cugPolicy.getPath(), cugPolicy));
}
/**
* An invalid (unsupported) implementation of {@link CugPolicy}.
*/
private static final class InvalidCug implements CugPolicy {
private static final InvalidCug INSTANCE = new InvalidCug();
@NotNull
@Override
public Set<Principal> getPrincipals() {
return Collections.emptySet();
}
@Override
public boolean addPrincipals(@NotNull Principal... principals) {
return false;
}
@Override
public boolean removePrincipals(@NotNull Principal... principals) {
return false;
}
@Override
public String getPath() {
return null;
}
}
}