Author: angela
Date: Fri Oct 11 16:07:11 2019
New Revision: 1868297
URL: http://svn.apache.org/viewvc?rev=1868297&view=rev
Log:
OAK-8671 : respect PARAM_READ_PATHS configuration option
Added:
jackrabbit/oak/trunk/oak-authorization-principalbased/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/ReadablePathsAccessControlTest.java
(with props)
jackrabbit/oak/trunk/oak-authorization-principalbased/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/ReadablePathsPermissionTest.java
(with props)
Modified:
jackrabbit/oak/trunk/oak-authorization-principalbased/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/PrincipalBasedAccessControlManager.java
jackrabbit/oak/trunk/oak-authorization-principalbased/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/PrincipalBasedPermissionProvider.java
jackrabbit/oak/trunk/oak-authorization-principalbased/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/AbstractPrincipalBasedTest.java
Modified:
jackrabbit/oak/trunk/oak-authorization-principalbased/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/PrincipalBasedAccessControlManager.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-authorization-principalbased/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/PrincipalBasedAccessControlManager.java?rev=1868297&r1=1868296&r2=1868297&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-authorization-principalbased/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/PrincipalBasedAccessControlManager.java
(original)
+++
jackrabbit/oak/trunk/oak-authorization-principalbased/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/PrincipalBasedAccessControlManager.java
Fri Oct 11 16:07:11 2019
@@ -36,9 +36,12 @@ import org.apache.jackrabbit.oak.namepat
import org.apache.jackrabbit.oak.plugins.tree.TreeUtil;
import org.apache.jackrabbit.oak.spi.nodetype.NodeTypeConstants;
import org.apache.jackrabbit.oak.spi.query.QueryConstants;
+import org.apache.jackrabbit.oak.spi.security.ConfigurationParameters;
import
org.apache.jackrabbit.oak.spi.security.authorization.accesscontrol.AbstractAccessControlManager;
import
org.apache.jackrabbit.oak.spi.security.authorization.accesscontrol.AccessControlConstants;
import
org.apache.jackrabbit.oak.spi.security.authorization.accesscontrol.PolicyOwner;
+import
org.apache.jackrabbit.oak.spi.security.authorization.accesscontrol.ReadPolicy;
+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.principalbased.Filter;
import
org.apache.jackrabbit.oak.spi.security.authorization.principalbased.FilterProvider;
@@ -49,6 +52,7 @@ import org.apache.jackrabbit.oak.spi.sec
import org.apache.jackrabbit.oak.spi.xml.ImportBehavior;
import org.apache.jackrabbit.oak.spi.xml.ProtectedItemImporter;
import org.apache.jackrabbit.util.ISO9075;
+import org.apache.jackrabbit.util.Text;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
@@ -81,6 +85,7 @@ class PrincipalBasedAccessControlManager
private final MgrProvider mgrProvider;
private final int importBehavior;
+ private final Set<String> readPaths;
private final PrincipalManager principalManager;
private final PrivilegeBitsProvider privilegeBitsProvider;
@@ -94,7 +99,9 @@ class PrincipalBasedAccessControlManager
this.mgrProvider = mgrProvider;
- importBehavior =
ImportBehavior.valueFromString(getConfig().getParameters().getConfigValue(ProtectedItemImporter.PARAM_IMPORT_BEHAVIOR,
ImportBehavior.NAME_ABORT));
+ ConfigurationParameters configParams = getConfig().getParameters();
+ importBehavior =
ImportBehavior.valueFromString(configParams.getConfigValue(ProtectedItemImporter.PARAM_IMPORT_BEHAVIOR,
ImportBehavior.NAME_ABORT));
+ readPaths =
configParams.getConfigValue(PermissionConstants.PARAM_READ_PATHS,
PermissionConstants.DEFAULT_READ_PATHS);
principalManager = mgrProvider.getPrincipalManager();
privilegeBitsProvider = mgrProvider.getPrivilegeBitsProvider();
@@ -173,7 +180,6 @@ class PrincipalBasedAccessControlManager
stmt.append("='").append(QueryUtils.escapeForQuery(effectivePath));
stmt.append("'");
cond = " or ";
-
}
stmt.append("] order by jcr:path option (traversal ok)");
@@ -192,7 +198,13 @@ class PrincipalBasedAccessControlManager
}
}
Iterable<PrincipalAccessControlList> acls =
Iterables.transform(m.entrySet(), entry -> new
ImmutablePrincipalPolicy(entry.getKey(), filter.getOakPath(entry.getKey()),
entry.getValue(), mgrProvider.getRestrictionProvider(), getNamePathMapper()));
- return Iterables.toArray(acls, PrincipalAccessControlList.class);
+
+ if (isReadablePath(oakPath)) {
+ Iterable iterable = Iterables.concat(acls,
Collections.singleton(ReadPolicy.INSTANCE));
+ return Iterables.toArray(iterable, AccessControlPolicy.class);
+ } else {
+ return Iterables.toArray(acls,
PrincipalAccessControlList.class);
+ }
} catch (ParseException e) {
String msg = "Error while collecting effective policies at "
+absPath;
log.error(msg, e);
@@ -394,4 +406,19 @@ class PrincipalBasedAccessControlManager
}
};
}
+
+ private boolean isReadablePath(@Nullable String oakPath) {
+ if (oakPath == null) {
+ return false;
+ }
+ if (readPaths.contains(oakPath)) {
+ return true;
+ }
+ for (String rp : readPaths) {
+ if (Text.isDescendant(rp, oakPath)) {
+ return true;
+ }
+ }
+ return false;
+ }
}
Modified:
jackrabbit/oak/trunk/oak-authorization-principalbased/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/PrincipalBasedPermissionProvider.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-authorization-principalbased/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/PrincipalBasedPermissionProvider.java?rev=1868297&r1=1868296&r2=1868297&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-authorization-principalbased/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/PrincipalBasedPermissionProvider.java
(original)
+++
jackrabbit/oak/trunk/oak-authorization-principalbased/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/PrincipalBasedPermissionProvider.java
Fri Oct 11 16:07:11 2019
@@ -28,7 +28,9 @@ import org.apache.jackrabbit.oak.plugins
import org.apache.jackrabbit.oak.plugins.tree.TreeType;
import org.apache.jackrabbit.oak.plugins.tree.TreeTypeProvider;
import org.apache.jackrabbit.oak.plugins.version.ReadOnlyVersionManager;
+import
org.apache.jackrabbit.oak.spi.security.authorization.AuthorizationConfiguration;
import
org.apache.jackrabbit.oak.spi.security.authorization.permission.AggregatedPermissionProvider;
+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.RepositoryPermission;
import
org.apache.jackrabbit.oak.spi.security.authorization.permission.TreePermission;
@@ -65,6 +67,8 @@ class PrincipalBasedPermissionProvider i
private RepositoryPermissionImpl repositoryPermission;
private EntryCache entryCache;
+ private ReadablePaths readablePaths;
+
PrincipalBasedPermissionProvider(@NotNull Root root,
@NotNull String workspaceName,
@NotNull Iterable<String> principalPaths,
@@ -79,6 +83,7 @@ class PrincipalBasedPermissionProvider i
modAcBits =
mgrProvider.getPrivilegeBitsProvider().getBits(PrivilegeConstants.JCR_MODIFY_ACCESS_CONTROL);
entryCache = new EntryCache(immutableRoot, principalPaths,
mgrProvider.getRestrictionProvider());
+ readablePaths = new ReadablePaths(mgrProvider);
}
//-------------------------------------------------< PermissionProvider
>---
@@ -92,6 +97,7 @@ class PrincipalBasedPermissionProvider i
if (repositoryPermission != null) {
repositoryPermission.refresh();
}
+ readablePaths = new ReadablePaths(mgrProvider);
}
@NotNull
@@ -252,6 +258,13 @@ class PrincipalBasedPermissionProvider i
private boolean isGranted(@NotNull String path, @NotNull
Predicate<PermissionEntry> predicate,
@NotNull Predicate<PermissionEntry>
parentPredicate, long permissions) {
long allows = Permissions.NO_PERMISSION;
+ if (readablePaths.isReadable(path)) {
+ allows = Permissions.READ;
+ if (isGranted(allows, permissions)) {
+ return true;
+ }
+ }
+
PrivilegeBits bits = PrivilegeBits.getInstance();
PrivilegeBits parentBits = PrivilegeBits.getInstance();
@@ -266,13 +279,17 @@ class PrincipalBasedPermissionProvider i
bits.add(entryBits);
}
allows |= PrivilegeBits.calculatePermissions(bits, parentBits,
true);
- if ((allows | ~permissions) == -1) {
+ if (isGranted(allows, permissions)) {
return true;
}
}
return false;
}
+ private static boolean isGranted(long allows, long permissions) {
+ return ((allows | ~permissions) == -1);
+ }
+
private boolean isGrantedOnEffective(@NotNull Tree tree, long permission) {
long toTest = permission & Permissions.MODIFY_ACCESS_CONTROL;
if (Permissions.NO_PERMISSION == toTest) {
@@ -360,6 +377,9 @@ class PrincipalBasedPermissionProvider i
while (entries.hasNext()) {
pb.add(entries.next().getPrivilegeBits());
}
+ if (!pb.includes(readablePaths.readBits) &&
readablePaths.isReadable(oakPath)) {
+ pb.add(readablePaths.readBits);
+ }
return pb;
}
@@ -463,4 +483,35 @@ class PrincipalBasedPermissionProvider i
return new VersionTreePermission(childVersionTree,
childVersionableTree);
}
}
+
+ private static final class ReadablePaths {
+
+ private final String[] paths;
+ private final String[] substrPaths;
+ private final PrivilegeBits readBits;
+
+ private ReadablePaths(@NotNull MgrProvider mgrProvider) {
+ paths =
mgrProvider.getSecurityProvider().getParameters(AuthorizationConfiguration.NAME).getConfigValue(PermissionConstants.PARAM_READ_PATHS,
PermissionConstants.DEFAULT_READ_PATHS).toArray(new String[0]);
+ substrPaths = new String[paths.length];
+ int i = 0;
+ for (String p : this.paths) {
+ substrPaths[i++] = p + '/';
+ }
+ this.readBits =
mgrProvider.getPrivilegeBitsProvider().getBits(PrivilegeConstants.JCR_READ);
+ }
+
+ public boolean isReadable(@NotNull String treePath) {
+ for (String path : paths) {
+ if (treePath.equals(path)) {
+ return true;
+ }
+ }
+ for (String path : substrPaths) {
+ if (treePath.startsWith(path)) {
+ return true;
+ }
+ }
+ return false;
+ }
+ }
}
Modified:
jackrabbit/oak/trunk/oak-authorization-principalbased/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/AbstractPrincipalBasedTest.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/AbstractPrincipalBasedTest.java?rev=1868297&r1=1868296&r2=1868297&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-authorization-principalbased/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/AbstractPrincipalBasedTest.java
(original)
+++
jackrabbit/oak/trunk/oak-authorization-principalbased/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/AbstractPrincipalBasedTest.java
Fri Oct 11 16:07:11 2019
@@ -71,7 +71,6 @@ public class AbstractPrincipalBasedTest
);
private User testSystemUser;
- private MgrProvider mgrProvider;
private PrincipalBasedAuthorizationConfiguration
principalBasedAuthorizationConfiguration;
String testJcrPath;
@@ -213,11 +212,8 @@ public class AbstractPrincipalBasedTest
}
@NotNull
- MgrProvider getMgrProvider(Root root) {
- if (mgrProvider == null) {
- mgrProvider = new
MgrProviderImpl(principalBasedAuthorizationConfiguration, root,
getNamePathMapper());
- }
- return mgrProvider;
+ MgrProvider getMgrProvider(Root r) {
+ return new MgrProviderImpl(principalBasedAuthorizationConfiguration,
r, getNamePathMapper());
}
@NotNull
Added:
jackrabbit/oak/trunk/oak-authorization-principalbased/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/ReadablePathsAccessControlTest.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/ReadablePathsAccessControlTest.java?rev=1868297&view=auto
==============================================================================
---
jackrabbit/oak/trunk/oak-authorization-principalbased/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/ReadablePathsAccessControlTest.java
(added)
+++
jackrabbit/oak/trunk/oak-authorization-principalbased/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/ReadablePathsAccessControlTest.java
Fri Oct 11 16:07:11 2019
@@ -0,0 +1,238 @@
+/*
+ * 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.base.Function;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Iterators;
+import com.google.common.collect.Sets;
+import org.apache.jackrabbit.JcrConstants;
+import org.apache.jackrabbit.api.security.JackrabbitAccessControlManager;
+import org.apache.jackrabbit.oak.api.ContentSession;
+import org.apache.jackrabbit.oak.commons.PathUtils;
+import
org.apache.jackrabbit.oak.spi.security.authorization.AuthorizationConfiguration;
+import
org.apache.jackrabbit.oak.spi.security.authorization.accesscontrol.ReadPolicy;
+import
org.apache.jackrabbit.oak.spi.security.authorization.permission.PermissionConstants;
+import org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants;
+import org.junit.Before;
+import org.junit.Test;
+
+import javax.jcr.AccessDeniedException;
+import javax.jcr.PathNotFoundException;
+import javax.jcr.security.AccessControlPolicy;
+import javax.jcr.security.Privilege;
+import javax.security.auth.Subject;
+import java.security.Principal;
+import java.security.PrivilegedExceptionAction;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.Set;
+
+import static org.apache.jackrabbit.oak.commons.PathUtils.ROOT_PATH;
+import static
org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants.JCR_READ;
+import static
org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants.REP_READ_NODES;
+import static
org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants.REP_READ_PROPERTIES;
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+public class ReadablePathsAccessControlTest extends AbstractPrincipalBasedTest
{
+
+ private Principal testPrincipal;
+ private Iterator<String> readablePaths;
+ private Iterator<String> readableChildPaths;
+
+ private JackrabbitAccessControlManager acMgr;
+
+ @Before
+ public void before() throws Exception {
+ super.before();
+
+ acMgr = new PrincipalBasedAccessControlManager(getMgrProvider(root),
getFilterProvider());
+
+ testPrincipal = getTestSystemUser().getPrincipal();
+ Set<String> paths =
getConfig(AuthorizationConfiguration.class).getParameters().getConfigValue(PermissionConstants.PARAM_READ_PATHS,
PermissionConstants.DEFAULT_READ_PATHS);
+ assertFalse(paths.isEmpty());
+
+ readablePaths = Iterators.cycle(Iterables.transform(paths,
(Function<String, String>) f -> getNamePathMapper().getJcrPath(f)));
+ Set<String> childPaths = Sets.newHashSet();
+ for (String path : paths) {
+ Iterables.addAll(childPaths,
Iterables.transform(root.getTree(path).getChildren(), tree ->
getNamePathMapper().getJcrPath(tree.getPath())));
+ }
+ readableChildPaths = Iterators.cycle(childPaths);
+ }
+
+ private Subject getTestSubject() {
+ return new Subject(true, Collections.singleton(testPrincipal),
ImmutableSet.of(), ImmutableSet.of());
+ }
+
+ @Test
+ public void testHasPrivilege() throws Exception {
+ try (ContentSession cs = Subject.doAsPrivileged(getTestSubject(),
(PrivilegedExceptionAction<ContentSession>) () ->
getContentRepository().login(null, null), null)) {
+ PrincipalBasedAccessControlManager testAcMgr = new
PrincipalBasedAccessControlManager(getMgrProvider(cs.getLatestRoot()),
getFilterProvider());
+
+ Set<Principal> principals = Collections.singleton(testPrincipal);
+
+ assertTrue(testAcMgr.hasPrivileges(readablePaths.next(),
principals, privilegesFromNames(JCR_READ)));
+ assertTrue(testAcMgr.hasPrivileges(readablePaths.next(),
principals, privilegesFromNames(REP_READ_PROPERTIES)));
+
+ assertTrue(testAcMgr.hasPrivileges(readableChildPaths.next(),
principals, privilegesFromNames(REP_READ_NODES)));
+ assertTrue(testAcMgr.hasPrivileges(readableChildPaths.next(),
principals, privilegesFromNames(REP_READ_NODES, REP_READ_PROPERTIES)));
+ }
+ }
+
+ @Test
+ public void testNotHasPrivilege() throws Exception {
+ try (ContentSession cs = Subject.doAsPrivileged(getTestSubject(),
(PrivilegedExceptionAction<ContentSession>) () ->
getContentRepository().login(null, null), null)) {
+ PrincipalBasedAccessControlManager testAcMgr = new
PrincipalBasedAccessControlManager(getMgrProvider(cs.getLatestRoot()),
getFilterProvider());
+
+ Set<Principal> principals = Collections.singleton(testPrincipal);
+
+ assertFalse(testAcMgr.hasPrivileges(readablePaths.next(),
principals, privilegesFromNames(JCR_READ,
PrivilegeConstants.JCR_READ_ACCESS_CONTROL)));
+ assertFalse(testAcMgr.hasPrivileges(readablePaths.next(),
principals, privilegesFromNames(PrivilegeConstants.JCR_ALL)));
+
+ assertFalse(testAcMgr.hasPrivileges(readableChildPaths.next(),
principals, privilegesFromNames(REP_READ_NODES,
PrivilegeConstants.JCR_MODIFY_PROPERTIES)));
+ assertFalse(testAcMgr.hasPrivileges(readableChildPaths.next(),
principals, privilegesFromNames(REP_READ_NODES, REP_READ_PROPERTIES,
PrivilegeConstants.JCR_NAMESPACE_MANAGEMENT)));
+ }
+ }
+
+ @Test
+ public void testHasPrivilegePrincipal() throws Exception {
+ Set<Principal> principals = Collections.singleton(testPrincipal);
+
+ assertTrue(acMgr.hasPrivileges(readablePaths.next(), principals,
privilegesFromNames(JCR_READ)));
+ assertTrue(acMgr.hasPrivileges(readablePaths.next(), principals,
privilegesFromNames(REP_READ_PROPERTIES)));
+
+ assertTrue(acMgr.hasPrivileges(readableChildPaths.next(), principals,
privilegesFromNames(REP_READ_NODES)));
+ assertTrue(acMgr.hasPrivileges(readableChildPaths.next(), principals,
privilegesFromNames(REP_READ_NODES, REP_READ_PROPERTIES)));
+ }
+
+ @Test
+ public void testNotHasPrivilegePrincipal() throws Exception {
+ Set<Principal> principals = Collections.singleton(testPrincipal);
+
+ assertFalse(acMgr.hasPrivileges(readablePaths.next(), principals,
privilegesFromNames(JCR_READ, PrivilegeConstants.JCR_MODIFY_PROPERTIES)));
+ assertFalse(acMgr.hasPrivileges(readablePaths.next(), principals,
privilegesFromNames(PrivilegeConstants.JCR_ALL)));
+
+ assertFalse(acMgr.hasPrivileges(readableChildPaths.next(), principals,
privilegesFromNames(REP_READ_NODES,
PrivilegeConstants.JCR_READ_ACCESS_CONTROL)));
+ assertFalse(acMgr.hasPrivileges(readableChildPaths.next(), principals,
privilegesFromNames(PrivilegeConstants.JCR_VERSION_MANAGEMENT,
REP_READ_PROPERTIES)));
+
+ assertFalse(acMgr.hasPrivileges(ROOT_PATH, principals,
privilegesFromNames(JCR_READ)));
+ String systemPath =
getNamePathMapper().getJcrPath(PathUtils.concat(ROOT_PATH,
JcrConstants.JCR_SYSTEM));
+ assertFalse(acMgr.hasPrivileges(systemPath, principals,
privilegesFromNames(REP_READ_PROPERTIES)));
+ }
+
+ @Test
+ public void testGetPrivileges() throws Exception {
+ try (ContentSession cs = Subject.doAsPrivileged(getTestSubject(),
(PrivilegedExceptionAction<ContentSession>) () ->
getContentRepository().login(null, null), null)) {
+ PrincipalBasedAccessControlManager testAcMgr = new
PrincipalBasedAccessControlManager(getMgrProvider(cs.getLatestRoot()),
getFilterProvider());
+
+ Privilege[] expected = privilegesFromNames(JCR_READ);
+
+ assertArrayEquals(expected,
testAcMgr.getPrivileges(readablePaths.next()));
+ assertArrayEquals(expected,
testAcMgr.getPrivileges(readableChildPaths.next()));
+ }
+ }
+
+ @Test(expected = PathNotFoundException.class)
+ public void testGetPrivilegesAtRoot() throws Exception {
+ try (ContentSession cs = Subject.doAsPrivileged(getTestSubject(),
(PrivilegedExceptionAction<ContentSession>) () ->
getContentRepository().login(null, null), null)) {
+ PrincipalBasedAccessControlManager testAcMgr = new
PrincipalBasedAccessControlManager(getMgrProvider(cs.getLatestRoot()),
getFilterProvider());
+ testAcMgr.getPrivileges(ROOT_PATH);
+ }
+ }
+
+ @Test
+ public void testGetPrivilegesByPrincipal() throws Exception {
+ Privilege[] expected = privilegesFromNames(JCR_READ);
+ Set<Principal> principals = Collections.singleton(testPrincipal);
+
+ assertArrayEquals(expected, acMgr.getPrivileges(readablePaths.next(),
principals));
+ assertArrayEquals(expected,
acMgr.getPrivileges(readableChildPaths.next(), principals));
+
+ assertEquals(0, acMgr.getPrivileges(ROOT_PATH, principals).length);
+ assertEquals(0, acMgr.getPrivileges(PathUtils.concat(ROOT_PATH,
getNamePathMapper().getJcrName(JcrConstants.JCR_SYSTEM)), principals).length);
+
+ }
+
+ @Test
+ public void testGetEffectivePolicies() throws Exception {
+ AccessControlPolicy[] expected = new AccessControlPolicy[]
{ReadPolicy.INSTANCE};
+
+ assertArrayEquals(expected,
acMgr.getEffectivePolicies(readablePaths.next()));
+ assertArrayEquals(expected,
acMgr.getEffectivePolicies(readableChildPaths.next()));
+ }
+
+ @Test
+ public void testGetEffectivePoliciesNullPath() throws Exception {
+ assertEquals(0, acMgr.getEffectivePolicies((String) null).length);
+ }
+
+ @Test(expected = AccessDeniedException.class)
+ public void testGetEffectivePoliciesLimitedAccess() throws Exception {
+ try (ContentSession cs = Subject.doAsPrivileged(getTestSubject(),
(PrivilegedExceptionAction<ContentSession>) () ->
getContentRepository().login(null, null), null)) {
+ PrincipalBasedAccessControlManager testAcMgr = new
PrincipalBasedAccessControlManager(getMgrProvider(cs.getLatestRoot()),
getFilterProvider());
+ testAcMgr.getEffectivePolicies(readablePaths.next());
+ }
+ }
+
+ @Test
+ public void testGetEffectivePoliciesLimitedAccess2() throws Exception {
+ String path = readablePaths.next();
+ setupPrincipalBasedAccessControl(testPrincipal, path,
PrivilegeConstants.JCR_READ_ACCESS_CONTROL);
+ // default: grant read-ac at root node as nodetype/namespace roots
cannot have their mixin changed
+ addDefaultEntry(PathUtils.ROOT_PATH, testPrincipal,
PrivilegeConstants.JCR_READ_ACCESS_CONTROL);
+ root.commit();
+
+ // test-session can read-ac at readable path but cannot access
principal-based policy
+ try (ContentSession cs = Subject.doAsPrivileged(getTestSubject(),
(PrivilegedExceptionAction<ContentSession>) () ->
getContentRepository().login(null, null), null)) {
+ PrincipalBasedAccessControlManager testAcMgr = new
PrincipalBasedAccessControlManager(getMgrProvider(cs.getLatestRoot()),
getFilterProvider());
+ Set<AccessControlPolicy> effective =
ImmutableSet.copyOf(testAcMgr.getEffectivePolicies(path));
+
+ assertEquals(1, effective.size());
+ assertTrue(effective.contains(ReadPolicy.INSTANCE));
+ }
+ }
+
+ @Test
+ public void testGetEffectivePoliciesLimitedAccess3() throws Exception {
+ String path = readablePaths.next();
+ setupPrincipalBasedAccessControl(testPrincipal, path,
PrivilegeConstants.JCR_READ_ACCESS_CONTROL);
+ setupPrincipalBasedAccessControl(testPrincipal,
getTestSystemUser().getPath(), PrivilegeConstants.JCR_READ,
PrivilegeConstants.JCR_READ_ACCESS_CONTROL);
+ // default: grant read and read-ac at root node to make sure both
policies are accessible
+ addDefaultEntry(PathUtils.ROOT_PATH, testPrincipal,
PrivilegeConstants.JCR_READ_ACCESS_CONTROL, PrivilegeConstants.JCR_READ);
+ root.commit();
+
+ // test-session can read-ac at readable path and at principal-based
policy
+ try (ContentSession cs = Subject.doAsPrivileged(getTestSubject(),
(PrivilegedExceptionAction<ContentSession>) () ->
getContentRepository().login(null, null), null)) {
+ PrincipalBasedAccessControlManager testAcMgr = new
PrincipalBasedAccessControlManager(getMgrProvider(cs.getLatestRoot()),
getFilterProvider());
+ Set<AccessControlPolicy> effective =
Sets.newHashSet(testAcMgr.getEffectivePolicies(path));
+
+ assertEquals(2, effective.size());
+ assertTrue(effective.remove(ReadPolicy.INSTANCE));
+ assertTrue(effective.iterator().next() instanceof
ImmutablePrincipalPolicy);
+ }
+ }
+
+ @Test
+ public void testGetEffectivePoliciesByPrincipal() throws Exception {
+ // NOTE: lookup by principal currently doesn't include READ_POLICY in
accordance to default ac implementation
+ assertEquals(0,
acMgr.getEffectivePolicies(Collections.singleton(testPrincipal)).length);
+ }
+}
\ 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/ReadablePathsAccessControlTest.java
------------------------------------------------------------------------------
svn:eol-style = native
Added:
jackrabbit/oak/trunk/oak-authorization-principalbased/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/ReadablePathsPermissionTest.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/ReadablePathsPermissionTest.java?rev=1868297&view=auto
==============================================================================
---
jackrabbit/oak/trunk/oak-authorization-principalbased/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/ReadablePathsPermissionTest.java
(added)
+++
jackrabbit/oak/trunk/oak-authorization-principalbased/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/ReadablePathsPermissionTest.java
Fri Oct 11 16:07:11 2019
@@ -0,0 +1,221 @@
+/*
+ * 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.Iterables;
+import com.google.common.collect.Iterators;
+import com.google.common.collect.Sets;
+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.namespace.NamespaceConstants;
+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.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.jetbrains.annotations.NotNull;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.Set;
+
+import static org.apache.jackrabbit.JcrConstants.JCR_PRIMARYTYPE;
+import static org.apache.jackrabbit.JcrConstants.JCR_SYSTEM;
+import static org.apache.jackrabbit.oak.commons.PathUtils.ROOT_PATH;
+import static
org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants.JCR_READ;
+import static
org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants.REP_READ_NODES;
+import static
org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants.REP_READ_PROPERTIES;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+public class ReadablePathsPermissionTest extends AbstractPrincipalBasedTest {
+
+ private Iterator<String> readablePaths;
+ private Iterator<String> readableChildPaths;
+
+ private PrincipalBasedPermissionProvider permissionProvider;
+
+ @Before
+ public void before() throws Exception {
+ super.before();
+
+ Set<String> paths =
getConfig(AuthorizationConfiguration.class).getParameters().getConfigValue(PermissionConstants.PARAM_READ_PATHS,
PermissionConstants.DEFAULT_READ_PATHS);
+ assertFalse(paths.isEmpty());
+
+ readablePaths = Iterators.cycle(paths);
+ Set<String> childPaths = Sets.newHashSet();
+ for (String path : paths) {
+ Iterables.addAll(childPaths,
Iterables.transform(root.getTree(path).getChildren(), tree -> tree.getPath()));
+ }
+ readableChildPaths = Iterators.cycle(childPaths);
+
+ permissionProvider = new PrincipalBasedPermissionProvider(root,
root.getContentSession().getWorkspaceName(),
Collections.singleton(getTestSystemUser().getPath()),
getPrincipalBasedAuthorizationConfiguration());
+ }
+
+ @Override
+ protected ConfigurationParameters getSecurityConfigParameters() {
+ return ConfigurationParameters.of(AuthorizationConfiguration.NAME,
+
ConfigurationParameters.of(PermissionConstants.PARAM_READ_PATHS, new String[]{
+ NamespaceConstants.NAMESPACES_PATH,
+ PrivilegeConstants.PRIVILEGES_PATH
+ }));
+ }
+
+ @NotNull
+ private Tree getTree(@NotNull String path) {
+ return root.getTree(path);
+ }
+
+ @Test
+ public void testHasPrivileges() throws Exception {
+
assertTrue(permissionProvider.hasPrivileges(getTree(readablePaths.next()),
JCR_READ));
+
assertTrue(permissionProvider.hasPrivileges(getTree(readablePaths.next()),
REP_READ_PROPERTIES));
+
assertTrue(permissionProvider.hasPrivileges(getTree(readableChildPaths.next()),
REP_READ_NODES));
+
assertTrue(permissionProvider.hasPrivileges(getTree(readableChildPaths.next()),
REP_READ_NODES, REP_READ_PROPERTIES));
+ }
+
+ @Test
+ public void testNotHasPrivileges() throws Exception {
+
assertFalse(permissionProvider.hasPrivileges(getTree(readablePaths.next()),
JCR_READ, PrivilegeConstants.JCR_READ_ACCESS_CONTROL));
+
assertFalse(permissionProvider.hasPrivileges(getTree(readablePaths.next()),
PrivilegeConstants.JCR_WRITE));
+
assertFalse(permissionProvider.hasPrivileges(getTree(readableChildPaths.next()),
PrivilegeConstants.JCR_MODIFY_ACCESS_CONTROL, REP_READ_PROPERTIES));
+
assertFalse(permissionProvider.hasPrivileges(getTree(readableChildPaths.next()),
REP_READ_NODES, PrivilegeConstants.JCR_REMOVE_NODE));
+
+ assertFalse(permissionProvider.hasPrivileges(getTree(ROOT_PATH),
JCR_READ));
+ String systemPath = PathUtils.concat(ROOT_PATH, JCR_SYSTEM);
+ assertFalse(permissionProvider.hasPrivileges(getTree(systemPath),
REP_READ_NODES));
+ }
+
+ @Test
+ public void testGetPrivileges() throws Exception {
+ Set<String> expected = Collections.singleton(JCR_READ);
+
+ assertEquals(expected,
permissionProvider.getPrivileges(getTree(readablePaths.next())));
+ assertEquals(expected,
permissionProvider.getPrivileges(getTree(readableChildPaths.next())));
+
+
assertTrue(permissionProvider.getPrivileges(getTree(ROOT_PATH)).isEmpty());
+ String systemPath = PathUtils.concat(ROOT_PATH, JCR_SYSTEM);
+
assertTrue(permissionProvider.getPrivileges(getTree(systemPath)).isEmpty());
+ }
+
+ @Test
+ public void testIsGrantedPath() throws Exception {
+ assertTrue(permissionProvider.isGranted(readablePaths.next(),
Permissions.getString(Permissions.READ)));
+ assertTrue(permissionProvider.isGranted(readablePaths.next(),
Permissions.getString(Permissions.READ_NODE|Permissions.READ_PROPERTY)));
+ assertTrue(permissionProvider.isGranted(readableChildPaths.next(),
Permissions.getString(Permissions.READ_NODE)));
+
assertTrue(permissionProvider.isGranted(PathUtils.concat(readableChildPaths.next(),
JCR_PRIMARYTYPE), Permissions.getString(Permissions.READ_PROPERTY)));
+
assertTrue(permissionProvider.isGranted(PathUtils.concat(readableChildPaths.next(),
"nonExisting"), Permissions.getString(Permissions.READ)));
+ }
+
+ @Test
+ public void testNotIsGrantedPath() throws Exception {
+ assertFalse(permissionProvider.isGranted(readablePaths.next(),
Permissions.getString(Permissions.READ|Permissions.VERSION_MANAGEMENT)));
+ assertFalse(permissionProvider.isGranted(readablePaths.next(),
Permissions.getString(Permissions.READ_ACCESS_CONTROL|Permissions.READ_NODE)));
+ assertFalse(permissionProvider.isGranted(readableChildPaths.next(),
Permissions.getString(Permissions.READ_PROPERTY|Permissions.ALL)));
+
+ assertFalse(permissionProvider.isGranted(ROOT_PATH,
Permissions.getString(Permissions.READ)));
+ assertFalse(permissionProvider.isGranted(PathUtils.concat(ROOT_PATH,
JCR_SYSTEM), Permissions.getString(Permissions.READ_NODE)));
+ assertFalse(permissionProvider.isGranted("/nonExistingContent",
Permissions.getString(Permissions.READ_PROPERTY)));
+ }
+
+ @Test
+ public void testIsGrantedTree() throws Exception {
+ assertTrue(permissionProvider.isGranted(getTree(readablePaths.next()),
null, Permissions.READ));
+ assertTrue(permissionProvider.isGranted(getTree(readablePaths.next()),
null, Permissions.READ_NODE));
+ Tree t = getTree(readablePaths.next());
+ assertTrue(permissionProvider.isGranted(t,
t.getProperty(JCR_PRIMARYTYPE), Permissions.READ_PROPERTY));
+
+
assertTrue(permissionProvider.isGranted(getTree(readableChildPaths.next()),
null, Permissions.READ));
+
assertTrue(permissionProvider.isGranted(getTree(readableChildPaths.next()),
null, Permissions.READ_NODE));
+ t = getTree(readableChildPaths.next());
+ assertTrue(permissionProvider.isGranted(t,
t.getProperty(JCR_PRIMARYTYPE), Permissions.READ_PROPERTY));
+ }
+
+ @Test
+ public void testNotIsGrantedTree() throws Exception {
+
assertFalse(permissionProvider.isGranted(getTree(readablePaths.next()), null,
Permissions.READ_ACCESS_CONTROL|Permissions.READ));
+
assertFalse(permissionProvider.isGranted(getTree(readablePaths.next()), null,
Permissions.ADD_NODE));
+ Tree t = getTree(readableChildPaths.next());
+ assertFalse(permissionProvider.isGranted(t,
t.getProperty(JCR_PRIMARYTYPE),
Permissions.MODIFY_PROPERTY|Permissions.READ_PROPERTY));
+
+ t = getTree(PathUtils.ROOT_PATH);
+ assertFalse(permissionProvider.isGranted(t, null, Permissions.READ));
+ assertFalse(permissionProvider.isGranted(t,
t.getProperty(JCR_PRIMARYTYPE), Permissions.READ_PROPERTY));
+
assertFalse(permissionProvider.isGranted(t.getChildren().iterator().next(),
null, Permissions.READ_NODE));
+ }
+
+ @Test
+ public void testIsGrantedLocation() throws Exception {
+ assertTrue(permissionProvider.isGranted(TreeLocation.create(root,
readablePaths.next()), Permissions.READ));
+ assertTrue(permissionProvider.isGranted(TreeLocation.create(root,
readableChildPaths.next()), Permissions.READ_NODE));
+ assertTrue(permissionProvider.isGranted(TreeLocation.create(root,
readableChildPaths.next()).getChild(JCR_PRIMARYTYPE),
Permissions.READ_PROPERTY));
+ }
+
+ @Test
+ public void testNotIsGrantedLocation() throws Exception {
+ assertFalse(permissionProvider.isGranted(TreeLocation.create(root,
readablePaths.next()), Permissions.READ|Permissions.WRITE));
+ assertFalse(permissionProvider.isGranted(TreeLocation.create(root,
readableChildPaths.next()), Permissions.ALL));
+ assertFalse(permissionProvider.isGranted(TreeLocation.create(root,
readableChildPaths.next()).getChild(JCR_PRIMARYTYPE),
Permissions.READ_PROPERTY|Permissions.MODIFY_PROPERTY));
+
+ TreeLocation location = TreeLocation.create(root);
+ assertFalse(permissionProvider.isGranted(location, Permissions.READ));
+
assertFalse(permissionProvider.isGranted(location.getChild(JCR_SYSTEM),
Permissions.READ_NODE));
+
assertFalse(permissionProvider.isGranted(location.getChild(JCR_PRIMARYTYPE),
Permissions.READ_PROPERTY));
+ }
+
+ @Test
+ public void testTreePermission() throws Exception {
+ Tree t = getTree(ROOT_PATH);
+ TreePermission tp = permissionProvider.getTreePermission(t,
TreePermission.EMPTY);
+ assertFalse(tp.isGranted(Permissions.READ));
+ assertFalse(tp.canRead());
+ assertFalse(tp.canRead(t.getProperty(JCR_PRIMARYTYPE)));
+
+ tp = permissionProvider.getTreePermission(t.getChild(JCR_SYSTEM), tp);
+ assertFalse(tp.isGranted(Permissions.READ_NODE));
+ assertFalse(tp.canReadProperties());
+ assertFalse(tp.canReadAll());
+
+ // readable paths
+ t = root.getTree(readablePaths.next());
+ tp = permissionProvider.getTreePermission(t, tp);
+ assertTrue(tp.isGranted(Permissions.READ));
+ assertFalse(tp.isGranted(Permissions.READ_ACCESS_CONTROL));
+
+ assertTrue(tp.canRead());
+ assertTrue(tp.canRead(t.getProperty(JCR_PRIMARYTYPE)));
+ assertFalse(tp.canReadProperties());
+
+ t = t.getChildren().iterator().next();
+ tp = permissionProvider.getTreePermission(t, tp);
+ assertTrue(tp.isGranted(Permissions.READ_NODE));
+ assertTrue(tp.isGranted(Permissions.READ_PROPERTY,
t.getProperty(JCR_PRIMARYTYPE)));
+
assertFalse(tp.isGranted(Permissions.READ_PROPERTY|Permissions.MODIFY_PROPERTY,
t.getProperty(JCR_PRIMARYTYPE)));
+ assertTrue(tp.canRead());
+ assertFalse(tp.canReadAll());
+ }
+
+ @Test
+ public void testRepositoryPermission() throws Exception {
+
assertFalse(permissionProvider.getRepositoryPermission().isGranted(Permissions.READ));
+ }
+}
\ 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/ReadablePathsPermissionTest.java
------------------------------------------------------------------------------
svn:eol-style = native