blob: 179a21f5c38c06ffc342cdd4b5981e754370a9dc [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.security.authorization.composite;
import java.util.Set;
import javax.jcr.Session;
import org.apache.jackrabbit.JcrConstants;
import org.apache.jackrabbit.api.JackrabbitSession;
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.commons.PathUtils;
import org.apache.jackrabbit.oak.plugins.tree.TreeLocation;
import org.apache.jackrabbit.oak.spi.security.authorization.permission.AggregatedPermissionProvider;
import org.apache.jackrabbit.oak.spi.security.authorization.permission.EmptyPermissionProvider;
import org.apache.jackrabbit.oak.spi.security.authorization.permission.PermissionProvider;
import org.apache.jackrabbit.oak.spi.security.authorization.permission.Permissions;
import org.apache.jackrabbit.oak.spi.security.authorization.permission.RepositoryPermission;
import org.apache.jackrabbit.oak.spi.security.authorization.permission.TreePermission;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.junit.Test;
import com.google.common.collect.ImmutableSet;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
/**
* Test the effect of the 'AND' combination of
*
* - default permission provider, which always grants full access to an administrative session.
* - custom provider that prevents all access but supports all permissions and
* thus is always called during composite evaluation.
*
* The tests are executed with the set of principals associated with the admin session,
* which in the default permission provider is granted full access.
*
* The expected outcome is that despite the default provider granting full access,
* the combination effectively prevents any access.
* <p>
* Test the effect of the 'OR' combination of
*
* - default permission provider, which always grants full access to an administrative session.
* - custom provider that prevents all access but supports all permissions and
* thus is always called during composite evaluation.
*
* The tests are executed with the set of principals associated with the admin session,
* which in the default permission provider is granted full access.
*
* The expected outcome is that the combination effectively allows any access.
*/
public class CompositeProviderEmptyTest extends AbstractCompositeProviderTest {
private CompositePermissionProvider cpp;
private CompositePermissionProvider cppO;
@Override
public void before() throws Exception {
super.before();
cpp = createPermissionProvider(root.getContentSession().getAuthInfo().getPrincipals());
cppO = createPermissionProviderOR(root.getContentSession().getAuthInfo().getPrincipals());
}
@Override
protected AggregatedPermissionProvider getTestPermissionProvider() {
return new EmptyAggregatedProvider(root);
}
@Test
public void testGetPrivileges() throws Exception {
for (String p : NODE_PATHS) {
assertTrue(cpp.getPrivileges(readOnlyRoot.getTree(p)).isEmpty());
assertEquals(ImmutableSet.of(JCR_ALL), cppO.getPrivileges(readOnlyRoot.getTree(p)));
}
}
@Test
public void testGetPrivilegesOnRepo() throws Exception {
assertTrue(cpp.getPrivileges(null).isEmpty());
assertEquals(ImmutableSet.of(JCR_ALL), cppO.getPrivileges(null));
}
@Test
public void testHasPrivileges() throws Exception {
for (String p : NODE_PATHS) {
Tree tree = readOnlyRoot.getTree(p);
assertFalse(cpp.hasPrivileges(tree, JCR_READ));
assertFalse(cpp.hasPrivileges(tree, JCR_WRITE));
assertFalse(cpp.hasPrivileges(tree, REP_READ_NODES));
}
}
@Test
public void testHasPrivilegesOnRepo() throws Exception {
assertFalse(cpp.hasPrivileges(null, JCR_NAMESPACE_MANAGEMENT, JCR_NODE_TYPE_DEFINITION_MANAGEMENT));
assertTrue(cppO.hasPrivileges(null, JCR_NAMESPACE_MANAGEMENT, JCR_NODE_TYPE_DEFINITION_MANAGEMENT));
}
@Test
public void testIsGranted() throws Exception {
for (String p : NODE_PATHS) {
Tree tree = readOnlyRoot.getTree(p);
assertFalse(cpp.isGranted(tree, null, Permissions.READ_NODE));
assertFalse(cpp.isGranted(tree, null, Permissions.READ_NODE | Permissions.MODIFY_CHILD_NODE_COLLECTION));
assertFalse(cpp.isGranted(tree, null, Permissions.READ_ACCESS_CONTROL | Permissions.MODIFY_ACCESS_CONTROL));
assertTrue(cppO.isGranted(tree, null, Permissions.READ_NODE));
assertTrue(cppO.isGranted(tree, null, Permissions.READ_NODE | Permissions.MODIFY_CHILD_NODE_COLLECTION));
assertTrue(cppO.isGranted(tree, null, Permissions.READ_ACCESS_CONTROL | Permissions.MODIFY_ACCESS_CONTROL));
}
}
@Test
public void testIsGrantedProperty() throws Exception {
for (String p : NODE_PATHS) {
Tree tree = readOnlyRoot.getTree(p);
assertFalse(cpp.isGranted(tree, PROPERTY_STATE, Permissions.READ_PROPERTY));
assertFalse(cpp.isGranted(tree, PROPERTY_STATE, Permissions.MODIFY_PROPERTY));
assertFalse(cpp.isGranted(tree, PROPERTY_STATE, Permissions.ADD_PROPERTY));
assertFalse(cpp.isGranted(tree, PROPERTY_STATE, Permissions.REMOVE_PROPERTY));
assertFalse(cpp.isGranted(tree, PROPERTY_STATE, Permissions.READ_ACCESS_CONTROL | Permissions.MODIFY_ACCESS_CONTROL));
assertTrue(cppO.isGranted(tree, PROPERTY_STATE, Permissions.READ_PROPERTY));
assertTrue(cppO.isGranted(tree, PROPERTY_STATE, Permissions.MODIFY_PROPERTY));
assertTrue(cppO.isGranted(tree, PROPERTY_STATE, Permissions.ADD_PROPERTY));
assertTrue(cppO.isGranted(tree, PROPERTY_STATE, Permissions.REMOVE_PROPERTY));
assertTrue(cppO.isGranted(tree, PROPERTY_STATE, Permissions.READ_ACCESS_CONTROL | Permissions.MODIFY_ACCESS_CONTROL));
}
}
@Test
public void testIsGrantedAction() throws Exception {
for (String nodePath : NODE_PATHS) {
String propPath = PathUtils.concat(nodePath, JcrConstants.JCR_PRIMARYTYPE);
String nonExisting = PathUtils.concat(nodePath, "nonExisting");
assertFalse(cpp.isGranted(nodePath, Session.ACTION_REMOVE));
assertFalse(cpp.isGranted(propPath, JackrabbitSession.ACTION_MODIFY_PROPERTY));
assertFalse(cpp.isGranted(nodePath, getActionString(JackrabbitSession.ACTION_MODIFY_ACCESS_CONTROL, JackrabbitSession.ACTION_READ_ACCESS_CONTROL)));
assertFalse(cpp.isGranted(nonExisting, JackrabbitSession.ACTION_ADD_PROPERTY));
assertFalse(cpp.isGranted(nonExisting, Session.ACTION_ADD_NODE));
assertTrue(cppO.isGranted(nodePath, Session.ACTION_REMOVE));
assertTrue(cppO.isGranted(propPath, JackrabbitSession.ACTION_MODIFY_PROPERTY));
assertTrue(cppO.isGranted(nodePath, getActionString(JackrabbitSession.ACTION_MODIFY_ACCESS_CONTROL, JackrabbitSession.ACTION_READ_ACCESS_CONTROL)));
assertTrue(cppO.isGranted(nonExisting, JackrabbitSession.ACTION_ADD_PROPERTY));
assertTrue(cppO.isGranted(nonExisting, Session.ACTION_ADD_NODE));
}
}
@Test
public void testRepositoryPermissionsIsGranted() throws Exception {
RepositoryPermission rp = cpp.getRepositoryPermission();
assertFalse(rp.isGranted(Permissions.NAMESPACE_MANAGEMENT));
assertFalse(rp.isGranted(Permissions.NODE_TYPE_DEFINITION_MANAGEMENT));
RepositoryPermission rpO = cppO.getRepositoryPermission();
assertTrue(rpO.isGranted(Permissions.NAMESPACE_MANAGEMENT));
assertTrue(rpO.isGranted(Permissions.NODE_TYPE_DEFINITION_MANAGEMENT));
}
@Test
public void testTreePermissionIsGranted() throws Exception {
TreePermission parentPermission = TreePermission.EMPTY;
for (String path : TP_PATHS) {
TreePermission tp = cpp.getTreePermission(readOnlyRoot.getTree(path), parentPermission);
assertFalse(tp.isGranted(Permissions.READ_NODE));
assertFalse(tp.isGranted(Permissions.REMOVE_NODE));
assertFalse(tp.isGranted(Permissions.ALL));
parentPermission = tp;
}
}
@Test
public void testTreePermissionIsGrantedOR() throws Exception {
TreePermission parentPermission = TreePermission.EMPTY;
for (String path : TP_PATHS) {
TreePermission tp = cppO.getTreePermission(readOnlyRoot.getTree(path), parentPermission);
assertTrue(tp.isGranted(Permissions.READ_NODE));
assertTrue(tp.isGranted(Permissions.REMOVE_NODE));
assertTrue(tp.isGranted(Permissions.ALL));
parentPermission = tp;
}
}
@Test
public void testTreePermissionIsGrantedProperty() throws Exception {
TreePermission parentPermission = TreePermission.EMPTY;
for (String path : TP_PATHS) {
TreePermission tp = cpp.getTreePermission(readOnlyRoot.getTree(path), parentPermission);
assertFalse(tp.isGranted(Permissions.READ_PROPERTY, PROPERTY_STATE));
assertFalse(tp.isGranted(Permissions.REMOVE_PROPERTY, PROPERTY_STATE));
parentPermission = tp;
}
}
@Test
public void testTreePermissionIsGrantedPropertyOR() throws Exception {
TreePermission parentPermission = TreePermission.EMPTY;
for (String path : TP_PATHS) {
TreePermission tp = cppO.getTreePermission(readOnlyRoot.getTree(path), parentPermission);
assertTrue(tp.isGranted(Permissions.READ_PROPERTY, PROPERTY_STATE));
assertTrue(tp.isGranted(Permissions.REMOVE_PROPERTY, PROPERTY_STATE));
parentPermission = tp;
}
}
@Test
public void testTreePermissionCanRead() throws Exception {
TreePermission parentPermission = TreePermission.EMPTY;
for (String path : TP_PATHS) {
Tree t = readOnlyRoot.getTree(path);
TreePermission tp = cpp.getTreePermission(t, parentPermission);
assertFalse(tp.canRead());
parentPermission = tp;
}
}
@Test
public void testTreePermissionCanReadOR() throws Exception {
TreePermission parentPermission = TreePermission.EMPTY;
for (String path : TP_PATHS) {
Tree t = readOnlyRoot.getTree(path);
TreePermission tp = cppO.getTreePermission(t, parentPermission);
assertTrue(tp.canRead());
parentPermission = tp;
}
}
@Test
public void testTreePermissionCanReadProperty() throws Exception {
TreePermission parentPermission = TreePermission.EMPTY;
for (String path : TP_PATHS) {
Tree t = readOnlyRoot.getTree(path);
TreePermission tp = cpp.getTreePermission(t, parentPermission);
assertFalse(tp.canRead(PROPERTY_STATE));
parentPermission = tp;
}
}
@Test
public void testTreePermissionCanReadPropertyOR() throws Exception {
TreePermission parentPermission = TreePermission.EMPTY;
for (String path : TP_PATHS) {
Tree t = readOnlyRoot.getTree(path);
TreePermission tp = cppO.getTreePermission(t, parentPermission);
assertTrue(tp.canRead(PROPERTY_STATE));
parentPermission = tp;
}
}
/**
* {@code AggregatedPermissionProvider} that doesn't grant any access.
*/
static class EmptyAggregatedProvider extends AbstractAggrProvider {
private static final PermissionProvider BASE = EmptyPermissionProvider.getInstance();
public EmptyAggregatedProvider(@NotNull Root root) {
super(root);
}
//---------------------------------------------< PermissionProvider >---
@NotNull
@Override
public Set<String> getPrivileges(@Nullable Tree tree) {
return BASE.getPrivileges(tree);
}
@Override
public boolean hasPrivileges(@Nullable Tree tree, @NotNull String... privilegeNames) {
return BASE.hasPrivileges(tree, privilegeNames);
}
@NotNull
@Override
public RepositoryPermission getRepositoryPermission() {
return BASE.getRepositoryPermission();
}
@NotNull
@Override
public TreePermission getTreePermission(@NotNull Tree tree, @NotNull TreePermission parentPermission) {
return BASE.getTreePermission(tree, parentPermission);
}
@Override
public boolean isGranted(@NotNull Tree tree, @Nullable PropertyState property, long permissions) {
return BASE.isGranted(tree, property, permissions);
}
@Override
public boolean isGranted(@NotNull String oakPath, @NotNull String jcrActions) {
return BASE.isGranted(oakPath, jcrActions);
}
//-----------------------------------< AggregatedPermissionProvider >---
@Override
public boolean isGranted(@NotNull TreeLocation location, long permissions) {
return false;
}
}
}