You are viewing a plain text version of this content. The canonical link for it is here.
Posted to oak-commits@jackrabbit.apache.org by an...@apache.org on 2015/12/17 18:40:03 UTC
svn commit: r1720618 [1/2] - in /jackrabbit/oak/trunk:
oak-authorization-cug/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/cug/impl/
oak-authorization-cug/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/cug/impl/...
Author: angela
Date: Thu Dec 17 17:40:03 2015
New Revision: 1720618
URL: http://svn.apache.org/viewvc?rev=1720618&view=rev
Log:
OAK-3704 : Keep track of nested CUGs (WIP)
Added:
jackrabbit/oak/trunk/oak-authorization-cug/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/cug/impl/NestedCugHook.java
jackrabbit/oak/trunk/oak-authorization-cug/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/cug/impl/TopLevelPaths.java
jackrabbit/oak/trunk/oak-authorization-cug/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/cug/impl/NestedCugHookRootSupportedTest.java
jackrabbit/oak/trunk/oak-authorization-cug/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/cug/impl/NestedCugHookTest.java
jackrabbit/oak/trunk/oak-authorization-cug/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/cug/impl/NoCugTest.java
jackrabbit/oak/trunk/oak-authorization-cug/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/cug/impl/TopLevelPathTest.java
Modified:
jackrabbit/oak/trunk/oak-authorization-cug/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/cug/impl/CugConfiguration.java
jackrabbit/oak/trunk/oak-authorization-cug/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/cug/impl/CugConstants.java
jackrabbit/oak/trunk/oak-authorization-cug/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/cug/impl/CugPermissionProvider.java
jackrabbit/oak/trunk/oak-authorization-cug/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/cug/impl/CugTreePermission.java
jackrabbit/oak/trunk/oak-authorization-cug/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/cug/impl/CugUtil.java
jackrabbit/oak/trunk/oak-authorization-cug/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/cug/impl/AbstractCugTest.java
jackrabbit/oak/trunk/oak-authorization-cug/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/cug/impl/AccessControlTest.java
jackrabbit/oak/trunk/oak-authorization-cug/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/cug/impl/CugAccessControlManagerTest.java
jackrabbit/oak/trunk/oak-authorization-cug/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/cug/impl/CugEvaluationTest.java
jackrabbit/oak/trunk/oak-authorization-cug/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/cug/impl/CugPermissionProviderTest.java
jackrabbit/oak/trunk/oak-authorization-cug/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/cug/impl/CugTreePermissionTest.java
jackrabbit/oak/trunk/oak-authorization-cug/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/cug/impl/CugUtilTest.java
jackrabbit/oak/trunk/oak-authorization-cug/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/cug/impl/EmptyCugTreePermissionTest.java
jackrabbit/oak/trunk/oak-authorization-cug/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/cug/impl/VersionTest.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/memory/PropertyBuilder.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/memory/package-info.java
Modified: jackrabbit/oak/trunk/oak-authorization-cug/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/cug/impl/CugConfiguration.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-authorization-cug/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/cug/impl/CugConfiguration.java?rev=1720618&r1=1720617&r2=1720618&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-authorization-cug/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/cug/impl/CugConfiguration.java (original)
+++ jackrabbit/oak/trunk/oak-authorization-cug/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/cug/impl/CugConfiguration.java Thu Dec 17 17:40:03 2015
@@ -17,6 +17,7 @@
package org.apache.jackrabbit.oak.spi.security.authorization.cug.impl;
import java.io.IOException;
+import java.io.InputStream;
import java.security.Principal;
import java.security.PrivilegedActionException;
import java.util.Collections;
@@ -30,6 +31,7 @@ import javax.jcr.security.AccessControlM
import com.google.common.collect.ImmutableList;
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.ConfigurationPolicy;
import org.apache.felix.scr.annotations.Properties;
import org.apache.felix.scr.annotations.Property;
import org.apache.felix.scr.annotations.Reference;
@@ -37,11 +39,16 @@ import org.apache.felix.scr.annotations.
import org.apache.felix.scr.annotations.Service;
import org.apache.jackrabbit.oak.api.CommitFailedException;
import org.apache.jackrabbit.oak.api.Root;
+import org.apache.jackrabbit.oak.api.Tree;
import org.apache.jackrabbit.oak.namepath.NamePathMapper;
import org.apache.jackrabbit.oak.plugins.memory.MemoryNodeStore;
import org.apache.jackrabbit.oak.plugins.name.NamespaceEditorProvider;
+import org.apache.jackrabbit.oak.plugins.nodetype.NodeTypeConstants;
+import org.apache.jackrabbit.oak.plugins.nodetype.ReadOnlyNodeTypeManager;
import org.apache.jackrabbit.oak.plugins.nodetype.TypeEditorProvider;
+import org.apache.jackrabbit.oak.plugins.nodetype.write.NodeTypeRegistry;
import org.apache.jackrabbit.oak.plugins.tree.RootFactory;
+import org.apache.jackrabbit.oak.spi.commit.CommitHook;
import org.apache.jackrabbit.oak.spi.commit.CompositeEditorProvider;
import org.apache.jackrabbit.oak.spi.commit.EditorHook;
import org.apache.jackrabbit.oak.spi.commit.MoveTracker;
@@ -66,7 +73,8 @@ import org.apache.jackrabbit.oak.spi.xml
@Component(metatype = true,
label = "Apache Jackrabbit Oak CUG Configuration",
- description = "Authorization configuration dedicated to setup and evaluate 'Closed User Group' permissions.")
+ description = "Authorization configuration dedicated to setup and evaluate 'Closed User Group' permissions.",
+ policy = ConfigurationPolicy.REQUIRE)
@Service({AuthorizationConfiguration.class, SecurityConfiguration.class})
@Properties({
@Property(name = CugConstants.PARAM_CUG_SUPPORTED_PATHS,
@@ -143,7 +151,7 @@ public class CugConfiguration extends Co
Root root = RootFactory.createSystemRoot(store,
new EditorHook(new CompositeEditorProvider(new NamespaceEditorProvider(), new TypeEditorProvider())),
null, null, null, null);
- if (CugUtil.registerCugNodeTypes(root)) {
+ if (registerCugNodeTypes(root)) {
NodeState target = store.getRoot();
target.compareAgainstBaseState(base, new ApplyDiff(builder));
}
@@ -153,6 +161,12 @@ public class CugConfiguration extends Co
@Nonnull
@Override
+ public List<? extends CommitHook> getCommitHooks(@Nonnull String workspaceName) {
+ return Collections.singletonList(new NestedCugHook());
+ }
+
+ @Nonnull
+ @Override
public List<? extends ValidatorProvider> getValidators(@Nonnull String workspaceName, @Nonnull Set<Principal> principals, @Nonnull MoveTracker moveTracker) {
return ImmutableList.of(new CugValidatorProvider());
}
@@ -181,4 +195,29 @@ public class CugConfiguration extends Co
private CugExclude getExclude() {
return (exclude == null) ? new CugExclude.Default() : exclude;
}
+
+ static boolean registerCugNodeTypes(@Nonnull final Root root) {
+ try {
+ ReadOnlyNodeTypeManager ntMgr = new ReadOnlyNodeTypeManager() {
+ @Override
+ protected Tree getTypes() {
+ return root.getTree(NodeTypeConstants.NODE_TYPES_PATH);
+ }
+ };
+ if (!ntMgr.hasNodeType(NT_REP_CUG_POLICY)) {
+ InputStream stream = CugConfiguration.class.getResourceAsStream("cug_nodetypes.cnd");
+ try {
+ NodeTypeRegistry.register(root, stream, "cug node types");
+ return true;
+ } finally {
+ stream.close();
+ }
+ }
+ } catch (IOException e) {
+ throw new IllegalStateException("Unable to read cug node types", e);
+ } catch (RepositoryException e) {
+ throw new IllegalStateException("Unable to read cug node types", e);
+ }
+ return false;
+ }
}
\ No newline at end of file
Modified: jackrabbit/oak/trunk/oak-authorization-cug/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/cug/impl/CugConstants.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-authorization-cug/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/cug/impl/CugConstants.java?rev=1720618&r1=1720617&r2=1720618&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-authorization-cug/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/cug/impl/CugConstants.java (original)
+++ jackrabbit/oak/trunk/oak-authorization-cug/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/cug/impl/CugConstants.java Thu Dec 17 17:40:03 2015
@@ -37,6 +37,18 @@ interface CugConstants {
String REP_CUG_POLICY = "rep:cugPolicy";
/**
+ * The name of the hidden property that stores information about nested
+ * CUG policy nodes.
+ */
+ String HIDDEN_NESTED_CUGS = ":nestedCugs";
+
+ /**
+ * The name of the hidden property that stores information about the number
+ * of CUG roots located close to the root node.
+ */
+ String HIDDEN_TOP_CUG_CNT = ":topCugCnt";
+
+ /**
* The name of the property that stores the principal names that are allowed
* to access the restricted area defined by the CUG (closed user group).
*/
Modified: jackrabbit/oak/trunk/oak-authorization-cug/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/cug/impl/CugPermissionProvider.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-authorization-cug/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/cug/impl/CugPermissionProvider.java?rev=1720618&r1=1720617&r2=1720618&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-authorization-cug/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/cug/impl/CugPermissionProvider.java (original)
+++ jackrabbit/oak/trunk/oak-authorization-cug/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/cug/impl/CugPermissionProvider.java Thu Dec 17 17:40:03 2015
@@ -67,6 +67,7 @@ class CugPermissionProvider implements A
private Root immutableRoot;
private ReadOnlyVersionManager versionManager;
+ private TopLevelPaths topPaths;
CugPermissionProvider(@Nonnull Root root,
@Nonnull String workspaceName,
@@ -86,6 +87,8 @@ class CugPermissionProvider implements A
this.supportedPaths = new SupportedPaths(supportedPaths);
this.typeProvider = new TreeTypeProvider(ctx);
this.ctx = ctx;
+
+ topPaths = new TopLevelPaths(immutableRoot);
}
@Nonnull
@@ -114,6 +117,7 @@ class CugPermissionProvider implements A
public void refresh() {
immutableRoot = RootFactory.createReadOnlyRoot(root);
versionManager = null;
+ topPaths = new TopLevelPaths(immutableRoot);
}
@Nonnull
@@ -149,7 +153,7 @@ class CugPermissionProvider implements A
@Override
public TreePermission getTreePermission(@Nonnull Tree tree, @Nonnull TreePermission parentPermission) {
if (TreePermission.NO_RECOURSE == parentPermission) {
- throw new IllegalStateException("Attempt to create tree permission for unsupported path.");
+ throw new IllegalStateException("Attempt to create tree permission for path '"+ tree.getPath() +"', which is either not supported or doesn't contain any CUGs.");
}
Tree immutableTree = getImmutableTree(tree);
TreeType type = typeProvider.getType(immutableTree);
@@ -247,7 +251,7 @@ class CugPermissionProvider implements A
@Nonnull
public TreePermission getTreePermission(@Nonnull Tree immutableTree, @Nonnull TreeType type, @Nonnull TreePermission parentPermission) {
- if (!isSupportedType(type)) {
+ if (!isSupportedType(type) || !topPaths.hasAny()) {
return TreePermission.NO_RECOURSE;
}
@@ -260,9 +264,13 @@ class CugPermissionProvider implements A
tp = new CugTreePermission(immutableTree, type, parentPermission, this);
} else {
String path = immutableTree.getPath();
- if (supportedPaths.includes(path)) {
- tp = new CugTreePermission(immutableTree, type, parentPermission, this);
- } else if (supportedPaths.mayContainCug(path) || isJcrSystemPath(immutableTree)) {
+ if (includes(path)) {
+ if (topPaths.contains(path)) {
+ tp = new CugTreePermission(immutableTree, type, parentPermission, this);
+ } else {
+ tp = TreePermission.NO_RECOURSE;
+ }
+ } else if (mayContain(path) || isJcrSystemPath(immutableTree)) {
tp = new EmptyCugTreePermission(immutableTree, type, this);
} else {
tp = TreePermission.NO_RECOURSE;
@@ -273,6 +281,7 @@ class CugPermissionProvider implements A
}
//--------------------------------------------------------------------------
+
private static boolean isJcrSystemPath(@Nonnull Tree tree) {
return JcrConstants.JCR_SYSTEM.equals(tree.getName());
}
@@ -289,13 +298,21 @@ class CugPermissionProvider implements A
if (tree != null) {
Tree immutableTree = getImmutableTree(tree);
TreeType type = typeProvider.getType(immutableTree);
- if (isSupportedType(type)) {
+ if (isSupportedType(type) && topPaths.hasAny()) {
return getCugRoot(immutableTree, type) != null;
}
}
return false;
}
+ private boolean includes(@Nonnull String path) {
+ return supportedPaths.includes(path);
+ }
+
+ private boolean mayContain(@Nonnull String path) {
+ return supportedPaths.mayContainCug(path) && topPaths.contains(path);
+ }
+
/**
* Returns the {@code tree} that holds a CUG policy in the ancestry of the
* given {@code tree} with the specified {@code path} or {@code null} if no
@@ -317,7 +334,7 @@ class CugPermissionProvider implements A
}
p = tree.getPath();
}
- if (!supportedPaths.includes(p)) {
+ if (!includes(p)) {
return null;
}
if (CugUtil.hasCug(tree)) {
@@ -326,7 +343,7 @@ class CugPermissionProvider implements A
String parentPath;
while (!tree.isRoot()) {
parentPath = PathUtils.getParentPath(p);
- if (!supportedPaths.includes(parentPath)) {
+ if (!includes(parentPath)) {
break;
}
tree = tree.getParent();
@@ -340,7 +357,7 @@ class CugPermissionProvider implements A
private boolean canRead(@Nonnull Tree tree) {
Tree immutableTree = getImmutableTree(tree);
TreeType type = typeProvider.getType(immutableTree);
- if (!isSupportedType(type)) {
+ if (!isSupportedType(type) || !topPaths.hasAny()) {
return false;
}
Tree cugRoot = getCugRoot(immutableTree, type);
@@ -393,7 +410,7 @@ class CugPermissionProvider implements A
Tree cug = null;
if (parentIsCugPermission) {
cug = CugUtil.getCug(versionableTree);
- } else if (supportedPaths.includes(path)) {
+ } else if (includes(path)) {
isSupportedPath = true;
// the versionable tree might be included in a cug defined by
// a parent node -> need to search for inherited cugs as well.
@@ -406,13 +423,13 @@ class CugPermissionProvider implements A
TreePermission tp;
if (cug != null) {
// backing versionable tree holds a cug
- tp = new CugTreePermission(tree, type, parent, this, true, isAllow(cug));
+ tp = new CugTreePermission(tree, type, parent, this, true, isAllow(cug), CugUtil.hasNestedCug(cug));
} else if (parentIsCugPermission) {
CugTreePermission ctp = (CugTreePermission) parent;
- tp = new CugTreePermission(tree, type, parent, this, ctp.isInCug(), ctp.isAllow());
+ tp = new CugTreePermission(tree, type, parent, this, ctp.isInCug(), ctp.isAllow(), ctp.hasNestedCug());
} else if (isSupportedPath) {
- tp = new CugTreePermission(tree, type, parent, this, false, false);
- } else if (supportedPaths.mayContainCug(path)) {
+ tp = new CugTreePermission(tree, type, parent, this, false, false, false);
+ } else if (mayContain(path)) {
tp = new EmptyCugTreePermission(tree, type, this);
} else {
tp = TreePermission.NO_RECOURSE;
Modified: jackrabbit/oak/trunk/oak-authorization-cug/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/cug/impl/CugTreePermission.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-authorization-cug/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/cug/impl/CugTreePermission.java?rev=1720618&r1=1720617&r2=1720618&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-authorization-cug/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/cug/impl/CugTreePermission.java (original)
+++ jackrabbit/oak/trunk/oak-authorization-cug/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/cug/impl/CugTreePermission.java Thu Dec 17 17:40:03 2015
@@ -16,6 +16,7 @@
*/
package org.apache.jackrabbit.oak.spi.security.authorization.cug.impl;
+import javax.annotation.CheckForNull;
import javax.annotation.Nonnull;
import org.apache.jackrabbit.oak.api.PropertyState;
@@ -40,10 +41,10 @@ final class CugTreePermission extends Ab
}
CugTreePermission(@Nonnull Tree tree, @Nonnull TreeType type, @Nonnull TreePermission parent,
- @Nonnull CugPermissionProvider permissionProvider, boolean inCug, boolean canRead) {
+ @Nonnull CugPermissionProvider permissionProvider, boolean inCug, boolean canRead, boolean hasNestedCug) {
super(tree, type, permissionProvider);
this.parent = parent;
- status = new Status(inCug, canRead);
+ status = new Status(inCug, canRead, hasNestedCug);
}
boolean isInCug() {
@@ -59,26 +60,46 @@ final class CugTreePermission extends Ab
}
return status.allow;
}
-
+
+ boolean hasNestedCug() {
+ if (status == null) {
+ loadStatus();
+ }
+ return status.hasNested;
+ }
+
private Status getStatus() {
if (status == null) {
loadStatus();
}
return status;
}
-
+
private void loadStatus() {
- Tree cugTree = CugUtil.getCug(tree);
- if (cugTree != null) {
- status = new Status(true, permissionProvider.isAllow(cugTree));
- } else if (parent instanceof CugTreePermission) {
- status = ((CugTreePermission) parent).getStatus();
- ;
+ CugTreePermission parentCugPerm = (parent instanceof CugTreePermission) ? (CugTreePermission) parent : null;
+ if (neverNested(parentCugPerm)) {
+ status = parentCugPerm.getStatus();
} else {
- status = Status.FALSE;
+ // need to load information
+ Tree cugTree = CugUtil.getCug(tree);
+ if (cugTree != null) {
+ status = new Status(true, permissionProvider.isAllow(cugTree), CugUtil.hasNestedCug(cugTree));
+ } else if (parentCugPerm != null) {
+ status = parentCugPerm.getStatus();
+ } else {
+ status = Status.FALSE;
+ }
}
}
+ private static boolean neverNested(@CheckForNull CugTreePermission parentCugPerm) {
+ if (parentCugPerm != null) {
+ Status st = parentCugPerm.status;
+ return st != null && st.inCug && !st.hasNested;
+ }
+ return false;
+ }
+
//-----------------------------------------------------< TreePermission >---
@Override
@@ -114,14 +135,16 @@ final class CugTreePermission extends Ab
//--------------------------------------------------------------------------
private final static class Status {
- private static final Status FALSE = new Status(false, false);
+ private static final Status FALSE = new Status(false, false, false);
private final boolean inCug;
private final boolean allow;
+ private final boolean hasNested;
- private Status(boolean inCug, boolean allow) {
+ private Status(boolean inCug, boolean allow, boolean hasNested) {
this.inCug = inCug;
this.allow = allow;
+ this.hasNested = hasNested;
}
}
}
\ No newline at end of file
Modified: jackrabbit/oak/trunk/oak-authorization-cug/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/cug/impl/CugUtil.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-authorization-cug/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/cug/impl/CugUtil.java?rev=1720618&r1=1720617&r2=1720618&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-authorization-cug/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/cug/impl/CugUtil.java (original)
+++ jackrabbit/oak/trunk/oak-authorization-cug/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/cug/impl/CugUtil.java Thu Dec 17 17:40:03 2015
@@ -16,20 +16,16 @@
*/
package org.apache.jackrabbit.oak.spi.security.authorization.cug.impl;
-import java.io.IOException;
-import java.io.InputStream;
import javax.annotation.CheckForNull;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
-import javax.jcr.RepositoryException;
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.plugins.nodetype.NodeTypeConstants;
-import org.apache.jackrabbit.oak.plugins.nodetype.ReadOnlyNodeTypeManager;
-import org.apache.jackrabbit.oak.plugins.nodetype.write.NodeTypeRegistry;
import org.apache.jackrabbit.oak.spi.security.ConfigurationParameters;
+import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
+import org.apache.jackrabbit.oak.spi.state.NodeState;
+import org.apache.jackrabbit.oak.spi.state.NodeStateUtils;
import org.apache.jackrabbit.oak.spi.xml.ImportBehavior;
import org.apache.jackrabbit.oak.spi.xml.ProtectedItemImporter;
import org.apache.jackrabbit.oak.util.TreeUtil;
@@ -46,6 +42,14 @@ final class CugUtil implements CugConsta
return tree.exists() && tree.hasChild(REP_CUG_POLICY);
}
+ public static boolean hasCug(@CheckForNull NodeState state) {
+ return state != null && state.hasChildNode(REP_CUG_POLICY);
+ }
+
+ public static boolean hasCug(@CheckForNull NodeBuilder builder) {
+ return builder != null && builder.hasChildNode(REP_CUG_POLICY);
+ }
+
@CheckForNull
public static Tree getCug(@Nonnull Tree tree) {
Tree cugTree = (CugUtil.hasCug(tree)) ? tree.getChild(REP_CUG_POLICY) : null;
@@ -60,10 +64,18 @@ final class CugUtil implements CugConsta
return tree.exists() && REP_CUG_POLICY.equals(tree.getName()) && NT_REP_CUG_POLICY.equals(TreeUtil.getPrimaryTypeName(tree));
}
+ public static boolean definesCug(@Nonnull String name, @Nonnull NodeState state) {
+ return REP_CUG_POLICY.equals(name) && NT_REP_CUG_POLICY.equals(NodeStateUtils.getPrimaryTypeName(state));
+ }
+
public static boolean definesCug(@Nonnull Tree tree, @Nonnull PropertyState property) {
return REP_PRINCIPAL_NAMES.equals(property.getName()) && definesCug(tree);
}
+ public static boolean hasNestedCug(@Nonnull Tree cugTree) {
+ return cugTree.hasProperty(CugConstants.HIDDEN_NESTED_CUGS);
+ }
+
public static boolean isSupportedPath(@Nullable String oakPath, @Nonnull ConfigurationParameters config) {
if (oakPath == null) {
return false;
@@ -81,29 +93,4 @@ final class CugUtil implements CugConsta
String importBehaviorStr = config.getConfigValue(ProtectedItemImporter.PARAM_IMPORT_BEHAVIOR, ImportBehavior.NAME_ABORT);
return ImportBehavior.valueFromString(importBehaviorStr);
}
-
- public static boolean registerCugNodeTypes(@Nonnull final Root root) {
- try {
- ReadOnlyNodeTypeManager ntMgr = new ReadOnlyNodeTypeManager() {
- @Override
- protected Tree getTypes() {
- return root.getTree(NodeTypeConstants.NODE_TYPES_PATH);
- }
- };
- if (!ntMgr.hasNodeType(NT_REP_CUG_POLICY)) {
- InputStream stream = CugConfiguration.class.getResourceAsStream("cug_nodetypes.cnd");
- try {
- NodeTypeRegistry.register(root, stream, "cug node types");
- return true;
- } finally {
- stream.close();
- }
- }
- } catch (IOException e) {
- throw new IllegalStateException("Unable to read cug node types", e);
- } catch (RepositoryException e) {
- throw new IllegalStateException("Unable to read cug node types", e);
- }
- return false;
- }
}
\ No newline at end of file
Added: jackrabbit/oak/trunk/oak-authorization-cug/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/cug/impl/NestedCugHook.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-authorization-cug/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/cug/impl/NestedCugHook.java?rev=1720618&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-authorization-cug/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/cug/impl/NestedCugHook.java (added)
+++ jackrabbit/oak/trunk/oak-authorization-cug/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/cug/impl/NestedCugHook.java Thu Dec 17 17:40:03 2015
@@ -0,0 +1,273 @@
+/*
+ * 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.util.List;
+import java.util.Set;
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
+import org.apache.jackrabbit.oak.api.CommitFailedException;
+import org.apache.jackrabbit.oak.api.PropertyState;
+import org.apache.jackrabbit.oak.api.Type;
+import org.apache.jackrabbit.oak.commons.PathUtils;
+import org.apache.jackrabbit.oak.plugins.memory.PropertyBuilder;
+import org.apache.jackrabbit.oak.spi.commit.CommitInfo;
+import org.apache.jackrabbit.oak.spi.commit.PostValidationHook;
+import org.apache.jackrabbit.oak.spi.state.DefaultNodeStateDiff;
+import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
+import org.apache.jackrabbit.oak.spi.state.NodeState;
+import org.apache.jackrabbit.oak.spi.state.NodeStateUtils;
+import org.apache.jackrabbit.util.Text;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import static org.apache.jackrabbit.oak.plugins.memory.EmptyNodeState.EMPTY_NODE;
+
+/**
+ * {@code PostValidationHook} implementation responsible for keeping track of
+ * nested CUGs to simplify evaluation. The information about the nested CUGs is
+ * stored in a hidden property associated with the policy node.
+ *
+ * Note, that this hook does _not_ respect the configured supported paths
+ * and keeps track of all CUG policies irrespective of their validity.
+ * Consequently all optimization considering the nested CUG information must
+ * also verify the supported paths.
+ */
+class NestedCugHook implements PostValidationHook, CugConstants {
+
+ /**
+ * logger instance
+ */
+ private static final Logger log = LoggerFactory.getLogger(NestedCugHook.class);
+
+ private Set<String> deletedCUGs = Sets.newHashSet();
+
+ //-------------------------------------------------< PostValidationHook >---
+ @Nonnull
+ @Override
+ public NodeState processCommit(NodeState before, NodeState after, CommitInfo info) throws CommitFailedException {
+ NodeBuilder builder = after.builder();
+ after.compareAgainstBaseState(before, new Diff(before, builder));
+ deletedCUGs.clear();
+ return builder.getNodeState();
+ }
+
+ //-------------------------------------------------------------< Object >---
+ @Override
+ public String toString() {
+ return "NestedCugHook";
+ }
+
+ //------------------------------------------------------------< private >---
+
+ private static long addNestedCugPath(@Nonnull NodeBuilder parentBuilder, @Nonnull NodeBuilder builder, @Nonnull String pathWithNewCug) {
+ PropertyState ps = parentBuilder.getProperty(HIDDEN_NESTED_CUGS);
+ PropertyBuilder pb = getHiddenPropertyBuilder(ps);
+ if (ps != null) {
+ List<String> moveToNestedCug = Lists.newArrayList();
+ for (String p : ps.getValue(Type.STRINGS)) {
+ if (Text.isDescendant(pathWithNewCug, p)) {
+ pb.removeValue(p);
+ moveToNestedCug.add(p);
+ } else if (p.equals(pathWithNewCug)) {
+ // already present with parent -> remove to avoid duplicate entries
+ log.debug("Path of node holding a new nested CUG is already listed with the parent CUG.");
+ pb.removeValue(p);
+ }
+ }
+ if (!moveToNestedCug.isEmpty()) {
+ PropertyBuilder pb2 = getHiddenPropertyBuilder(builder.getProperty(HIDDEN_NESTED_CUGS));
+ pb2.addValues(moveToNestedCug);
+ builder.setProperty(pb2.getPropertyState());
+ }
+ }
+
+ // update the nested-cug property of the parent
+ pb.addValue(pathWithNewCug);
+ parentBuilder.setProperty(pb.getPropertyState());
+ return pb.count();
+ }
+
+ private static int removeNestedCugPath(@Nonnull NodeBuilder parentBuilder, @Nonnull String toRemove, @Nonnull Iterable<String> toReconnect) {
+ PropertyState ps = parentBuilder.getProperty(HIDDEN_NESTED_CUGS);
+ PropertyBuilder pb = getHiddenPropertyBuilder(ps);
+ if (pb.hasValue(toRemove)) {
+ pb.removeValue(toRemove);
+ pb.addValues(toReconnect);
+ if (pb.isEmpty()) {
+ parentBuilder.removeProperty(HIDDEN_NESTED_CUGS);
+ return 0;
+ } else {
+ parentBuilder.setProperty(pb.getPropertyState());
+ return pb.count();
+ }
+ } else {
+ log.debug("Parent CUG doesn't contain expected entry for removed nested CUG");
+ return -1;
+ }
+ }
+
+ private static PropertyBuilder getHiddenPropertyBuilder(@Nullable PropertyState ps) {
+ return PropertyBuilder.copy(Type.STRING, ps).setName(HIDDEN_NESTED_CUGS).setArray();
+ }
+
+ private final class Diff extends DefaultNodeStateDiff {
+
+ private final Diff parentDiff;
+ private final boolean isRoot;
+
+ private String path;
+ private NodeState beforeState = null;
+
+ private NodeBuilder afterBuilder;
+ private boolean afterHoldsCug;
+
+ private Diff(@Nonnull NodeState rootBefore, @Nonnull NodeBuilder rootAfter) {
+ parentDiff = null;
+ isRoot = true;
+ path = PathUtils.ROOT_PATH;
+
+ beforeState = rootBefore;
+
+ afterBuilder = rootAfter;
+ afterHoldsCug = CugUtil.hasCug(rootAfter);
+ }
+
+ private Diff(@Nonnull Diff parentDiff, @Nonnull String name, @Nullable NodeState before, @Nullable NodeBuilder after) {
+ this.parentDiff = parentDiff;
+ isRoot = false;
+ path = PathUtils.concat(parentDiff.path, name);
+
+ this.beforeState = before;
+
+ afterBuilder = after;
+ afterHoldsCug = CugUtil.hasCug(after);
+ }
+
+ @Override
+ public boolean childNodeAdded(String name, NodeState after) {
+ if (!NodeStateUtils.isHidden(name)) {
+ if (CugUtil.definesCug(name, after)) {
+ if (isRoot) {
+ PropertyState alt = afterBuilder.getProperty(HIDDEN_NESTED_CUGS);
+ if (alt != null) {
+ NodeBuilder cugNode = afterBuilder.getChildNode(REP_CUG_POLICY);
+ cugNode.setProperty(alt);
+ afterBuilder.removeProperty(HIDDEN_NESTED_CUGS);
+ afterBuilder.removeProperty(HIDDEN_TOP_CUG_CNT);
+ }
+ } else {
+ Diff diff = parentDiff;
+ while (diff != null) {
+ if (diff.afterHoldsCug) {
+ NodeBuilder cugNode = diff.afterBuilder.getChildNode(REP_CUG_POLICY);
+ addNestedCugPath(cugNode, afterBuilder.getChildNode(REP_CUG_POLICY), path);
+ break;
+ } else if (diff.isRoot) {
+ long cnt = addNestedCugPath(diff.afterBuilder, afterBuilder.getChildNode(name), path);
+ diff.afterBuilder.setProperty(HIDDEN_TOP_CUG_CNT, cnt, Type.LONG);
+
+ }
+ diff = diff.parentDiff;
+ }
+ }
+ // no need to traverse down the CUG policy node.
+ } else {
+ after.compareAgainstBaseState(EMPTY_NODE, new Diff(this, name, null, afterBuilder.getChildNode(name)));
+ }
+ }
+ return true;
+ }
+
+ @Override
+ public boolean childNodeChanged(String name, NodeState before, NodeState after) {
+ if (!NodeStateUtils.isHidden(name)) {
+ after.compareAgainstBaseState(before, new Diff(this, name, before, afterBuilder.getChildNode(name)));
+ }
+ return true;
+ }
+
+ @Override
+ public boolean childNodeDeleted(String name, NodeState before) {
+ if (!NodeStateUtils.isHidden(name)) {
+ if (CugUtil.definesCug(name, before)) {
+ deletedCUGs.add(path);
+ // reconnect information about nested cugs at a parent if
+ // only the CUG got removed but the whole subtree including CUGs
+ // are still present.
+ Set<String> reconnect = Sets.newHashSet();
+ if (afterBuilder != null) {
+ for (String nestedCug : before.getStrings(HIDDEN_NESTED_CUGS)) {
+ if (!deletedCUGs.contains(nestedCug)) {
+ String relPath = PathUtils.relativize(path, nestedCug);
+ NodeState ns = NodeStateUtils.getNode(afterBuilder.getNodeState(), relPath);
+ if (CugUtil.hasCug(ns)) {
+ reconnect.add(nestedCug);
+ }
+ }
+ }
+ }
+ if (isRoot) {
+ if (!Iterables.isEmpty(reconnect)) {
+ afterBuilder.setProperty(HIDDEN_NESTED_CUGS, reconnect, Type.STRINGS);
+ afterBuilder.setProperty(HIDDEN_TOP_CUG_CNT, reconnect.size());
+ }
+ } else {
+ Diff diff = parentDiff;
+ while (diff != null) {
+ if (diff.afterHoldsCug) {
+ // found an existing parent CUG
+ NodeBuilder cugNode = diff.afterBuilder.getChildNode(REP_CUG_POLICY);
+ if (removeNestedCugPath(cugNode, path, reconnect) > -1) {
+ break;
+ }
+ }
+ if (CugUtil.hasCug(diff.beforeState)) {
+ // parent CUG got removed -> no removal/reconnect required if current path is listed.
+ NodeState cugNode = diff.beforeState.getChildNode(REP_CUG_POLICY);
+ PropertyState ps = cugNode.getProperty(HIDDEN_NESTED_CUGS);
+ if (ps != null && Iterables.contains(ps.getValue(Type.STRINGS), path)) {
+ log.debug("Nested cug property containing " + path + " has also been removed; no reconnect required.");
+ break;
+ }
+ }
+ if (diff.isRoot) {
+ long cnt = removeNestedCugPath(diff.afterBuilder, path, reconnect);
+ if (cnt < 0) {
+ log.warn("Failed to updated nested CUG info for path '" + path + "'.");
+ } else if (cnt == 0) {
+ diff.afterBuilder.removeProperty(HIDDEN_TOP_CUG_CNT);
+ } else {
+ diff.afterBuilder.setProperty(HIDDEN_TOP_CUG_CNT, cnt, Type.LONG);
+ }
+ }
+ diff = diff.parentDiff;
+ }
+ }
+ // no need to traverse down the CUG policy node
+ } else {
+ EMPTY_NODE.compareAgainstBaseState(before, new Diff(this, name, before, null));
+ }
+ }
+ return true;
+ }
+ }
+}
\ No newline at end of file
Added: jackrabbit/oak/trunk/oak-authorization-cug/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/cug/impl/TopLevelPaths.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-authorization-cug/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/cug/impl/TopLevelPaths.java?rev=1720618&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-authorization-cug/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/cug/impl/TopLevelPaths.java (added)
+++ jackrabbit/oak/trunk/oak-authorization-cug/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/cug/impl/TopLevelPaths.java Thu Dec 17 17:40:03 2015
@@ -0,0 +1,93 @@
+/*
+ * 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 javax.annotation.Nonnull;
+
+import com.google.common.collect.Iterables;
+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.util.Text;
+
+/**
+ * Utility class to determine the top-level CUG paths as recorded on the root
+ * node.
+ */
+class TopLevelPaths implements CugConstants {
+
+ static final long NONE = -1;
+ static final long MAX_CNT = 10;
+
+ private final Root root;
+
+ private Boolean hasAny;
+ private Long cnt;
+ private String[] paths;
+
+ TopLevelPaths(Root root) {
+ this.root = root;
+ }
+
+ boolean hasAny() {
+ if (hasAny == null) {
+ Tree rootTree = root.getTree(PathUtils.ROOT_PATH);
+ hasAny = rootTree.hasProperty(HIDDEN_TOP_CUG_CNT) || CugUtil.hasCug(rootTree);
+ }
+ return hasAny;
+ }
+
+ boolean contains(@Nonnull String path) {
+ if (!hasAny()) {
+ return false;
+ }
+ if (PathUtils.denotesRoot(path)) {
+ return true;
+ }
+
+ if (cnt == null) {
+ Tree rootTree = root.getTree(PathUtils.ROOT_PATH);
+ PropertyState hiddenTopCnt = rootTree.getProperty(HIDDEN_TOP_CUG_CNT);
+ if (hiddenTopCnt != null) {
+ cnt = hiddenTopCnt.getValue(Type.LONG);
+ if (cnt <= MAX_CNT) {
+ PropertyState hidden = root.getTree(PathUtils.ROOT_PATH).getProperty(HIDDEN_NESTED_CUGS);
+ paths = (hidden == null) ? new String[0] : Iterables.toArray(hidden.getValue(Type.STRINGS), String.class);
+ } else {
+ paths = null;
+ }
+ } else {
+ cnt = NONE;
+ }
+ }
+
+ if (cnt == NONE) {
+ return false;
+ } if (cnt > MAX_CNT) {
+ return true;
+ } else if (paths != null) {
+ for (String p : paths) {
+ if (Text.isDescendantOrEqual(path, p)) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+}
\ No newline at end of file
Modified: jackrabbit/oak/trunk/oak-authorization-cug/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/cug/impl/AbstractCugTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-authorization-cug/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/cug/impl/AbstractCugTest.java?rev=1720618&r1=1720617&r2=1720618&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-authorization-cug/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/cug/impl/AbstractCugTest.java (original)
+++ jackrabbit/oak/trunk/oak-authorization-cug/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/cug/impl/AbstractCugTest.java Thu Dec 17 17:40:03 2015
@@ -27,6 +27,7 @@ import javax.jcr.security.AccessControlM
import javax.jcr.security.AccessControlPolicy;
import javax.jcr.security.AccessControlPolicyIterator;
+import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableSet;
import org.apache.jackrabbit.api.security.user.Authorizable;
import org.apache.jackrabbit.api.security.user.Group;
@@ -48,6 +49,8 @@ import org.apache.jackrabbit.oak.spi.sec
import org.apache.jackrabbit.oak.spi.security.principal.EveryonePrincipal;
import org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants;
import org.apache.jackrabbit.oak.util.NodeUtil;
+import org.apache.jackrabbit.oak.util.TreeUtil;
+import org.apache.jackrabbit.util.Text;
import static org.junit.Assert.assertTrue;
@@ -60,11 +63,14 @@ public class AbstractCugTest extends Abs
static final String SUPPORTED_PATH = "/content";
static final String SUPPORTED_PATH2 = "/content2";
+ static final String SUPPORTED_PATH3 = "/some/content/tree";
static final String UNSUPPORTED_PATH = "/testNode";
static final String INVALID_PATH = "/path/to/non/existing/tree";
+ static final String[] SUPPORTED_PATHS = {SUPPORTED_PATH, SUPPORTED_PATH2, SUPPORTED_PATH3};
+
static final ConfigurationParameters CUG_CONFIG = ConfigurationParameters.of(
- CugConstants.PARAM_CUG_SUPPORTED_PATHS, new String[] {SUPPORTED_PATH, SUPPORTED_PATH2},
+ CugConstants.PARAM_CUG_SUPPORTED_PATHS, SUPPORTED_PATHS,
CugConstants.PARAM_CUG_ENABLED, true);
private static final String TEST_GROUP_ID = "testGroup" + UUID.randomUUID();
@@ -74,10 +80,28 @@ public class AbstractCugTest extends Abs
public void before() throws Exception {
super.before();
+ /**
+ * Create tree structure:
+ *
+ * + root
+ * + content
+ * + subtree
+ * + content2
+ * + some
+ * + content
+ * + tree
+ * + testNode
+ * + child
+ */
NodeUtil rootNode = new NodeUtil(root.getTree("/"));
+
NodeUtil content = rootNode.addChild("content", NodeTypeConstants.NT_OAK_UNSTRUCTURED);
content.addChild("subtree", NodeTypeConstants.NT_OAK_UNSTRUCTURED);
+
rootNode.addChild("content2", NodeTypeConstants.NT_OAK_UNSTRUCTURED);
+
+ rootNode.addChild("some", NodeTypeConstants.NT_OAK_UNSTRUCTURED).addChild("content", NodeTypeConstants.NT_OAK_UNSTRUCTURED).addChild("tree", NodeTypeConstants.NT_OAK_UNSTRUCTURED);
+
NodeUtil testNode = rootNode.addChild("testNode", NodeTypeConstants.NT_OAK_UNSTRUCTURED);
testNode.addChild("child", NodeTypeConstants.NT_OAK_UNSTRUCTURED);
root.commit();
@@ -98,9 +122,12 @@ public class AbstractCugTest extends Abs
if (testUser2 != null) {
testUser2.remove();
}
- root.getTree(SUPPORTED_PATH).remove();
- root.getTree(SUPPORTED_PATH2).remove();
- root.getTree(UNSUPPORTED_PATH).remove();
+ for (String p : new String[] {SUPPORTED_PATH, SUPPORTED_PATH2, Text.getAbsoluteParent(SUPPORTED_PATH3, 0), UNSUPPORTED_PATH}) {
+ Tree t = root.getTree(p);
+ if (t.exists()) {
+ t.remove();
+ }
+ }
root.commit();
} finally {
super.after();
@@ -132,6 +159,8 @@ public class AbstractCugTest extends Abs
((Group) uMgr.getAuthorizable(testGroupPrincipal)).addMember(testUser2);
root.commit();
+ User testUser = getTestUser();
+
// add more child nodes
NodeUtil n = new NodeUtil(root.getTree(SUPPORTED_PATH));
n.addChild("a", NT_OAK_UNSTRUCTURED).addChild("b", NT_OAK_UNSTRUCTURED).addChild("c", NT_OAK_UNSTRUCTURED);
@@ -152,7 +181,7 @@ public class AbstractCugTest extends Abs
// - testGroup ; allow ; jcr:read, jcr:write, jcr:readAccessControl
AccessControlManager acMgr = getAccessControlManager(root);
AccessControlList acl = AccessControlUtils.getAccessControlList(acMgr, "/content");
- acl.addAccessControlEntry(getTestUser().getPrincipal(), privilegesFromNames(
+ acl.addAccessControlEntry(testUser.getPrincipal(), privilegesFromNames(
PrivilegeConstants.JCR_READ));
acl.addAccessControlEntry(testGroupPrincipal, privilegesFromNames(
PrivilegeConstants.JCR_READ, PrivilegeConstants.REP_WRITE, PrivilegeConstants.JCR_READ_ACCESS_CONTROL)
@@ -175,6 +204,14 @@ public class AbstractCugTest extends Abs
throw new IllegalStateException("Unable to create CUG at " + absPath);
}
+ static void createCug(@Nonnull Root root, @Nonnull String path, @Nonnull String principalName) throws RepositoryException {
+ Tree tree = root.getTree(path);
+ Preconditions.checkState(tree.exists());
+
+ TreeUtil.addMixin(tree, MIX_REP_CUG_MIXIN, root.getTree(NODE_TYPES_PATH), null);
+ new NodeUtil(tree).addChild(REP_CUG_POLICY, NT_REP_CUG_POLICY).setStrings(REP_PRINCIPAL_NAMES, principalName);
+ }
+
Principal getTestGroupPrincipal() throws Exception {
UserManager uMgr = getUserManager(root);
Group g = uMgr.getAuthorizable(TEST_GROUP_ID, Group.class);
Modified: jackrabbit/oak/trunk/oak-authorization-cug/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/cug/impl/AccessControlTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-authorization-cug/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/cug/impl/AccessControlTest.java?rev=1720618&r1=1720617&r2=1720618&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-authorization-cug/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/cug/impl/AccessControlTest.java (original)
+++ jackrabbit/oak/trunk/oak-authorization-cug/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/cug/impl/AccessControlTest.java Thu Dec 17 17:40:03 2015
@@ -82,7 +82,7 @@ public class AccessControlTest extends A
"/content2/rep:cugPolicy"
);
- pp = createCugPermissionProvider(ImmutableSet.of("/"), EveryonePrincipal.getInstance(), getTestGroupPrincipal(), getTestUser().getPrincipal());
+ pp = createCugPermissionProvider(ImmutableSet.of(PathUtils.ROOT_PATH), EveryonePrincipal.getInstance(), getTestGroupPrincipal(), getTestUser().getPrincipal());
}
@Test
Modified: jackrabbit/oak/trunk/oak-authorization-cug/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/cug/impl/CugAccessControlManagerTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-authorization-cug/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/cug/impl/CugAccessControlManagerTest.java?rev=1720618&r1=1720617&r2=1720618&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-authorization-cug/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/cug/impl/CugAccessControlManagerTest.java (original)
+++ jackrabbit/oak/trunk/oak-authorization-cug/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/cug/impl/CugAccessControlManagerTest.java Thu Dec 17 17:40:03 2015
@@ -221,7 +221,7 @@ public class CugAccessControlManagerTest
root.commit();
ConfigurationParameters config = ConfigurationParameters.of(AuthorizationConfiguration.NAME, ConfigurationParameters.of(
- CugConstants.PARAM_CUG_SUPPORTED_PATHS, new String[] {SUPPORTED_PATH, SUPPORTED_PATH2},
+ CugConstants.PARAM_CUG_SUPPORTED_PATHS, SUPPORTED_PATHS,
CugConstants.PARAM_CUG_ENABLED, false));
CugAccessControlManager acMgr = new CugAccessControlManager(root, NamePathMapper.DEFAULT, new CugSecurityProvider(config));
AccessControlPolicy[] policies = acMgr.getEffectivePolicies(SUPPORTED_PATH);
Modified: jackrabbit/oak/trunk/oak-authorization-cug/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/cug/impl/CugEvaluationTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-authorization-cug/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/cug/impl/CugEvaluationTest.java?rev=1720618&r1=1720617&r2=1720618&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-authorization-cug/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/cug/impl/CugEvaluationTest.java (original)
+++ jackrabbit/oak/trunk/oak-authorization-cug/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/cug/impl/CugEvaluationTest.java Thu Dec 17 17:40:03 2015
@@ -62,6 +62,15 @@ public class CugEvaluationTest extends A
public void before() throws Exception {
super.before();
+ // create cugs
+ // - /content/a : allow testGroup, deny everyone
+ // - /content/aa/bb : allow testGroup, deny everyone
+ // - /content/a/b/c : allow everyone, deny testGroup (isolated)
+ // - /content2 : allow everyone, deny testGroup (isolated)
+
+ // regular acl:
+ // - /content : allow testUser, jcr:read
+ // - /content : allow testGroup, jcr:read, jcr:write, jcr:readAccessControl
setupCugsAndAcls();
testGroupPrincipal = getTestGroupPrincipal();
Modified: jackrabbit/oak/trunk/oak-authorization-cug/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/cug/impl/CugPermissionProviderTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-authorization-cug/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/cug/impl/CugPermissionProviderTest.java?rev=1720618&r1=1720617&r2=1720618&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-authorization-cug/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/cug/impl/CugPermissionProviderTest.java (original)
+++ jackrabbit/oak/trunk/oak-authorization-cug/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/cug/impl/CugPermissionProviderTest.java Thu Dec 17 17:40:03 2015
@@ -64,6 +64,13 @@ public class CugPermissionProviderTest e
PATH_INCUG_MAP.put("/content/a/b/c/jcr:primaryType", true);
PATH_INCUG_MAP.put("/content/aa", false);
PATH_INCUG_MAP.put("/content/aa/bb/cc", true);
+
+ // path below supported-path but which never contains a cug
+ PATH_INCUG_MAP.put("/content/no", false);
+ PATH_INCUG_MAP.put("/content/no/cug", false);
+ PATH_INCUG_MAP.put("/content/no/cug/in", false);
+ PATH_INCUG_MAP.put("/content/no/cug/in/subtree", false);
+
// paths that may not contain cugs anyway
PATH_INCUG_MAP.put(NODE_TYPES_PATH, false);
PATH_INCUG_MAP.put("/", false);
@@ -86,7 +93,8 @@ public class CugPermissionProviderTest e
"/content/aa", "/content/aa/jcr:primaryType",
"/content/bb", "/content/bb/jcr:primaryType",
"/content/aa/bb/rep:cugPolicy", "/content/aa/bb/rep:cugPolicy/jcr:primaryType", "/content/aa/bb/rep:cugPolicy/rep:principalNames",
- "/content/nonExisting", "/content/nonExisting/jcr:primaryType");
+ "/content/nonExisting", "/content/nonExisting/jcr:primaryType",
+ "/content/no","/content/no/cug","/content/no/cug/in","/content/no/cug/in/subtree");
private Principal testGroupPrincipal;
private CugPermissionProvider cugPermProvider;
@@ -102,6 +110,7 @@ public class CugPermissionProviderTest e
NodeUtil n = new NodeUtil(root.getTree(SUPPORTED_PATH));
n.addChild("a", NT_OAK_UNSTRUCTURED).addChild("b", NT_OAK_UNSTRUCTURED).addChild("c", NT_OAK_UNSTRUCTURED);
n.addChild("aa", NT_OAK_UNSTRUCTURED).addChild("bb", NT_OAK_UNSTRUCTURED).addChild("cc", NT_OAK_UNSTRUCTURED);
+ n.addChild("no", NT_OAK_UNSTRUCTURED).addChild("cug", NT_OAK_UNSTRUCTURED).addChild("in", NT_OAK_UNSTRUCTURED).addChild("subtree", NT_OAK_UNSTRUCTURED);
createCug("/content/a", testGroupPrincipal);
createCug("/content/a/b/c", EveryonePrincipal.getInstance());
Modified: jackrabbit/oak/trunk/oak-authorization-cug/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/cug/impl/CugTreePermissionTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-authorization-cug/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/cug/impl/CugTreePermissionTest.java?rev=1720618&r1=1720617&r2=1720618&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-authorization-cug/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/cug/impl/CugTreePermissionTest.java (original)
+++ jackrabbit/oak/trunk/oak-authorization-cug/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/cug/impl/CugTreePermissionTest.java Thu Dec 17 17:40:03 2015
@@ -21,12 +21,15 @@ import javax.annotation.Nonnull;
import com.google.common.collect.ImmutableSet;
import org.apache.jackrabbit.oak.api.PropertyState;
+import org.apache.jackrabbit.oak.api.Tree;
+import org.apache.jackrabbit.oak.commons.PathUtils;
import org.apache.jackrabbit.oak.plugins.memory.PropertyStates;
import org.apache.jackrabbit.oak.plugins.tree.impl.AbstractTree;
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.principal.EveryonePrincipal;
import org.apache.jackrabbit.oak.spi.state.NodeState;
+import org.apache.jackrabbit.oak.util.NodeUtil;
import org.junit.Test;
import static org.junit.Assert.assertFalse;
@@ -54,7 +57,7 @@ public class CugTreePermissionTest exten
}
private CugTreePermission getCugTreePermission(@Nonnull String path, @Nonnull Principal... principals) {
- CugPermissionProvider pp = createCugPermissionProvider(ImmutableSet.of(SUPPORTED_PATH, SUPPORTED_PATH2), principals);
+ CugPermissionProvider pp = createCugPermissionProvider(ImmutableSet.copyOf(SUPPORTED_PATHS), principals);
TreePermission targetTp = getTreePermission(root, path, pp);
assertTrue(targetTp instanceof CugTreePermission);
return (CugTreePermission) targetTp;
@@ -69,7 +72,7 @@ public class CugTreePermissionTest exten
child = deniedTp.getChildPermission("subtree", ns);
assertTrue(child instanceof CugTreePermission);
- NodeState cugNs = ((AbstractTree) root.getTree(SUPPORTED_PATH + "/" + REP_CUG_POLICY)).getNodeState();
+ NodeState cugNs = ((AbstractTree) root.getTree(PathUtils.concat(SUPPORTED_PATH, REP_CUG_POLICY))).getNodeState();
TreePermission cugChild = allowedTp.getChildPermission(REP_CUG_POLICY, cugNs);
assertSame(TreePermission.NO_RECOURSE, cugChild);
}
@@ -78,20 +81,97 @@ public class CugTreePermissionTest exten
public void testIsAllow() throws Exception {
assertTrue(allowedTp.isAllow());
assertFalse(deniedTp.isAllow());
+ }
+
+ @Test
+ public void testIsAllowNestedCug() throws Exception {
+ String childPath = SUPPORTED_PATH + "/subtree";
- CugTreePermission tp = getCugTreePermission(SUPPORTED_PATH2);
+ // before creating nested CUG
+ CugTreePermission tp = getCugTreePermission(childPath);
assertFalse(tp.isAllow());
- tp = getCugTreePermission(SUPPORTED_PATH2, getTestUser().getPrincipal(), EveryonePrincipal.getInstance());
+ tp = getCugTreePermission(childPath, getTestUser().getPrincipal(), EveryonePrincipal.getInstance());
+ assertTrue(tp.isAllow());
+
+ // create nested CUG for same principal
+ createCug(childPath, EveryonePrincipal.getInstance());
+ root.commit();
+
+ tp = getCugTreePermission(childPath);
assertFalse(tp.isAllow());
+
+ tp = getCugTreePermission(childPath, getTestUser().getPrincipal(), EveryonePrincipal.getInstance());
+ assertTrue(tp.isAllow());
}
@Test
public void testIsInCug() {
assertTrue(allowedTp.isInCug());
assertTrue(deniedTp.isInCug());
+ }
+
+ @Test
+ public void testIsInCugChild() throws Exception {
+ String childPath = SUPPORTED_PATH + "/subtree";
+
+ CugTreePermission tp = getCugTreePermission(childPath);
+ assertTrue(tp.isInCug());
+
+ tp = getCugTreePermission(childPath, getTestUser().getPrincipal(), EveryonePrincipal.getInstance());
+ assertTrue(tp.isInCug());
+ }
+
+ @Test
+ public void testIsInCugNestedCug() throws Exception {
+ String childPath = SUPPORTED_PATH + "/subtree";
+
+ // create nested CUG for same principal
+ createCug(childPath, EveryonePrincipal.getInstance());
+ root.commit();
+
+ CugTreePermission tp = getCugTreePermission(childPath);
+ assertTrue(tp.isInCug());
+
+ tp = getCugTreePermission(childPath, getTestUser().getPrincipal(), EveryonePrincipal.getInstance());
+ assertTrue(tp.isInCug());
+ }
+
+ @Test
+ public void testIsInCugSupportedPathWithoutCug() throws Exception {
+ NodeUtil node = new NodeUtil(root.getTree(SUPPORTED_PATH2));
+ Tree c1 = node.addChild("c1", NT_OAK_UNSTRUCTURED).getTree();
+ Tree c2 = node.addChild("c2", NT_OAK_UNSTRUCTURED).getTree();
+
+ String cugPath = c2.getPath();
+ createCug(cugPath, getTestGroupPrincipal());
+ root.commit();
+
+ assertTrue(getCugTreePermission(cugPath).isInCug());
+ assertFalse(getCugTreePermission(c1.getPath()).isInCug());
+ }
+
+ @Test
+ public void testHasNested() {
+ CugTreePermission tp = getCugTreePermission(SUPPORTED_PATH);
+ assertFalse(tp.hasNestedCug());
+
+ String childPath = SUPPORTED_PATH + "/subtree";
+ tp = getCugTreePermission(childPath);
+ assertFalse(tp.hasNestedCug());
+ }
+
+ @Test
+ public void testHasNestedWithNestedCug() throws Exception {
+ // create nested CUG for same principal
+ String childPath = SUPPORTED_PATH + "/subtree";
+ createCug(childPath, EveryonePrincipal.getInstance());
+ root.commit();
+
+ CugTreePermission tp = getCugTreePermission(SUPPORTED_PATH);
+ assertTrue(tp.hasNestedCug());
- CugTreePermission tp = getCugTreePermission(SUPPORTED_PATH2);
- assertFalse(tp.isInCug());
+ tp = getCugTreePermission(childPath);
+ assertFalse(tp.hasNestedCug());
}
@Test
Modified: jackrabbit/oak/trunk/oak-authorization-cug/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/cug/impl/CugUtilTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-authorization-cug/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/cug/impl/CugUtilTest.java?rev=1720618&r1=1720617&r2=1720618&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-authorization-cug/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/cug/impl/CugUtilTest.java (original)
+++ jackrabbit/oak/trunk/oak-authorization-cug/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/cug/impl/CugUtilTest.java Thu Dec 17 17:40:03 2015
@@ -16,11 +16,16 @@
*/
package org.apache.jackrabbit.oak.spi.security.authorization.cug.impl;
+import javax.annotation.Nonnull;
+
import org.apache.jackrabbit.oak.api.Tree;
import org.apache.jackrabbit.oak.commons.PathUtils;
import org.apache.jackrabbit.oak.plugins.nodetype.NodeTypeConstants;
+import org.apache.jackrabbit.oak.plugins.tree.impl.AbstractTree;
import org.apache.jackrabbit.oak.spi.security.ConfigurationParameters;
import org.apache.jackrabbit.oak.spi.security.principal.EveryonePrincipal;
+import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
+import org.apache.jackrabbit.oak.spi.state.NodeState;
import org.apache.jackrabbit.oak.spi.xml.ImportBehavior;
import org.apache.jackrabbit.oak.util.NodeUtil;
import org.junit.Test;
@@ -49,32 +54,60 @@ public class CugUtilTest extends Abstrac
}
}
+ @Nonnull
+ private static NodeState getNodeState(@Nonnull Tree tree) {
+ return ((AbstractTree) tree).getNodeState();
+ }
+
@Test
public void testHasCug() throws Exception {
- assertFalse(CugUtil.hasCug(root.getTree("/")));
- assertFalse(CugUtil.hasCug(root.getTree(INVALID_PATH)));
- assertFalse(CugUtil.hasCug(root.getTree(UNSUPPORTED_PATH)));
- assertFalse(CugUtil.hasCug(root.getTree(SUPPORTED_PATH + "/subtree")));
- assertFalse(CugUtil.hasCug(root.getTree(SUPPORTED_PATH2)));
-
assertTrue(CugUtil.hasCug(root.getTree(SUPPORTED_PATH)));
+ for (String path : new String[] {PathUtils.ROOT_PATH, INVALID_PATH, UNSUPPORTED_PATH, SUPPORTED_PATH + "/subtree", SUPPORTED_PATH2, SUPPORTED_PATH3}) {
+ assertFalse(CugUtil.hasCug(root.getTree(path)));
+ }
+
new NodeUtil(root.getTree(SUPPORTED_PATH2)).addChild(REP_CUG_POLICY, NodeTypeConstants.NT_OAK_UNSTRUCTURED).getTree();
assertTrue(CugUtil.hasCug(root.getTree(SUPPORTED_PATH2)));
}
@Test
- public void testGetCug() throws Exception {
- assertNull(CugUtil.getCug(root.getTree("/")));
- assertNull(CugUtil.getCug(root.getTree(INVALID_PATH)));
- assertNull(CugUtil.getCug(root.getTree(UNSUPPORTED_PATH)));
- assertNull(CugUtil.getCug(root.getTree(SUPPORTED_PATH + "/subtree")));
- assertNull(CugUtil.getCug(root.getTree(SUPPORTED_PATH2)));
+ public void testHasCugNodeState() throws Exception {
+ assertTrue(CugUtil.hasCug(getNodeState(root.getTree(SUPPORTED_PATH))));
+
+ assertFalse(CugUtil.hasCug((NodeState) null));
+
+ for (String path : new String[] {PathUtils.ROOT_PATH, INVALID_PATH, UNSUPPORTED_PATH, SUPPORTED_PATH + "/subtree", SUPPORTED_PATH2, SUPPORTED_PATH3}) {
+ assertFalse(CugUtil.hasCug(getNodeState(root.getTree(path))));
+ }
+
+ new NodeUtil(root.getTree(SUPPORTED_PATH2)).addChild(REP_CUG_POLICY, NodeTypeConstants.NT_OAK_UNSTRUCTURED);
+ assertTrue(CugUtil.hasCug(getNodeState(root.getTree(SUPPORTED_PATH2))));
+ }
+
+ @Test
+ public void testHasCugNodeBuilder() throws Exception {
+ assertTrue(CugUtil.hasCug(getNodeState(root.getTree(SUPPORTED_PATH)).builder()));
+
+ assertFalse(CugUtil.hasCug((NodeBuilder) null));
+ for (String path : new String[] {PathUtils.ROOT_PATH, INVALID_PATH, UNSUPPORTED_PATH, SUPPORTED_PATH + "/subtree", SUPPORTED_PATH2, SUPPORTED_PATH3}) {
+ assertFalse(CugUtil.hasCug(getNodeState(root.getTree(path)).builder()));
+ }
+
+ new NodeUtil(root.getTree(SUPPORTED_PATH2)).addChild(REP_CUG_POLICY, NodeTypeConstants.NT_OAK_UNSTRUCTURED);
+ assertTrue(CugUtil.hasCug(getNodeState(root.getTree(SUPPORTED_PATH2)).builder()));
+ }
+ @Test
+ public void testGetCug() throws Exception {
assertNotNull(CugUtil.getCug(root.getTree(SUPPORTED_PATH)));
- Tree invalid = new NodeUtil(root.getTree(SUPPORTED_PATH2)).addChild(REP_CUG_POLICY, NodeTypeConstants.NT_OAK_UNSTRUCTURED).getTree();
- assertNull(CugUtil.getCug(invalid));
+ for (String path : new String[] {PathUtils.ROOT_PATH, INVALID_PATH, UNSUPPORTED_PATH, SUPPORTED_PATH + "/subtree", SUPPORTED_PATH2, SUPPORTED_PATH3}) {
+ assertNull(CugUtil.getCug(root.getTree(path)));
+ }
+
+ new NodeUtil(root.getTree(SUPPORTED_PATH2)).addChild(REP_CUG_POLICY, NodeTypeConstants.NT_OAK_UNSTRUCTURED);
+ assertNull(CugUtil.getCug(root.getTree(SUPPORTED_PATH2)));
}
@Test
Modified: jackrabbit/oak/trunk/oak-authorization-cug/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/cug/impl/EmptyCugTreePermissionTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-authorization-cug/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/cug/impl/EmptyCugTreePermissionTest.java?rev=1720618&r1=1720617&r2=1720618&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-authorization-cug/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/cug/impl/EmptyCugTreePermissionTest.java (original)
+++ jackrabbit/oak/trunk/oak-authorization-cug/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/cug/impl/EmptyCugTreePermissionTest.java Thu Dec 17 17:40:03 2015
@@ -90,8 +90,7 @@ public class EmptyCugTreePermissionTest
String name = Text.getName(SUPPORTED_PATH2);
NodeState ns = rootState.getChildNode(name);
TreePermission child = tp.getChildPermission(name, ns);
- assertCugPermission(child, true);
- assertFalse(((CugTreePermission) child).isInCug());
+ assertSame(TreePermission.NO_RECOURSE, child);
name = Text.getName(SUPPORTED_PATH);
ns = rootState.getChildNode(name);
Added: jackrabbit/oak/trunk/oak-authorization-cug/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/cug/impl/NestedCugHookRootSupportedTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-authorization-cug/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/cug/impl/NestedCugHookRootSupportedTest.java?rev=1720618&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-authorization-cug/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/cug/impl/NestedCugHookRootSupportedTest.java (added)
+++ jackrabbit/oak/trunk/oak-authorization-cug/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/cug/impl/NestedCugHookRootSupportedTest.java Thu Dec 17 17:40:03 2015
@@ -0,0 +1,144 @@
+/*
+ * 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 org.apache.jackrabbit.oak.commons.PathUtils;
+import org.apache.jackrabbit.oak.spi.security.ConfigurationParameters;
+import org.apache.jackrabbit.oak.spi.security.authorization.AuthorizationConfiguration;
+import org.apache.jackrabbit.oak.spi.security.principal.EveryonePrincipal;
+import org.junit.Test;
+
+import static org.apache.jackrabbit.oak.commons.PathUtils.ROOT_PATH;
+import static org.junit.Assert.assertTrue;
+
+public class NestedCugHookRootSupportedTest extends NestedCugHookTest {
+
+ @Override
+ protected ConfigurationParameters getSecurityConfigParameters() {
+ return ConfigurationParameters.of(AuthorizationConfiguration.NAME, ConfigurationParameters.of(
+ CugConstants.PARAM_CUG_SUPPORTED_PATHS, new String[] {PathUtils.ROOT_PATH},
+ CugConstants.PARAM_CUG_ENABLED, true));
+ }
+
+ @Test
+ public void testAddAtRoot() throws Exception {
+ createCug(ROOT_PATH, EveryonePrincipal.getInstance());
+ root.commit();
+ assertTrue(root.getTree("/").hasChild(REP_CUG_POLICY));
+
+ createCug("/content", getTestGroupPrincipal());
+ createCug("/content2", EveryonePrincipal.getInstance());
+ root.commit();
+
+ assertNestedCugs(root, ROOT_PATH, true, "/content", "/content2");
+ }
+
+ @Test
+ public void testAddAtRoot2() throws Exception {
+ createCug("/content", getTestGroupPrincipal());
+ createCug("/content2", EveryonePrincipal.getInstance());
+ root.commit();
+
+ assertNestedCugs(root, ROOT_PATH, false, "/content", "/content2");
+
+ createCug(ROOT_PATH, EveryonePrincipal.getInstance());
+ root.commit();
+
+ assertNestedCugs(root, ROOT_PATH, false);
+ assertNestedCugs(root, ROOT_PATH, true, "/content", "/content2");
+ }
+
+ @Test
+ public void testAddAtRoot3() throws Exception {
+ createCug(ROOT_PATH, EveryonePrincipal.getInstance());
+ createCug("/content", getTestGroupPrincipal());
+ createCug("/content2", EveryonePrincipal.getInstance());
+ root.commit();
+
+ assertNestedCugs(root, ROOT_PATH, true, "/content", "/content2");
+ }
+
+ @Test
+ public void testRemoveRootCug() throws Exception {
+ // add cug at /
+ createCug(ROOT_PATH, EveryonePrincipal.getInstance());
+ createCug("/content", getTestGroupPrincipal());
+ createCug("/content2", EveryonePrincipal.getInstance());
+ root.commit();
+
+ assertTrue(removeCug(ROOT_PATH, true));
+ assertNestedCugs(root, ROOT_PATH, false, "/content", "/content2");
+
+ assertTrue(removeCug("/content", true));
+ assertNestedCugs(root, ROOT_PATH, false, "/content2");
+
+ assertTrue(removeCug("/content2", true));
+ assertNestedCugs(root, ROOT_PATH, false);
+ }
+
+ @Test
+ public void testRemoveRootCug2() throws Exception {
+ // add cug at /
+ createCug(ROOT_PATH, EveryonePrincipal.getInstance());
+ createCug("/content", getTestGroupPrincipal());
+ createCug("/content2", EveryonePrincipal.getInstance());
+ root.commit();
+
+ removeCug("/content", true);
+ assertNestedCugs(root, ROOT_PATH, true, "/content2");
+
+ removeCug("/", true);
+ assertNestedCugs(root, ROOT_PATH, false, "/content2");
+
+ removeCug("/content2", true);
+ assertNestedCugs(root, ROOT_PATH, false);
+ }
+
+ @Test
+ public void testRemoveRootCug3() throws Exception {
+ // add cug at /
+ createCug(ROOT_PATH, EveryonePrincipal.getInstance());
+ createCug("/content", getTestGroupPrincipal());
+ createCug("/content2", EveryonePrincipal.getInstance());
+ root.commit();
+
+ assertTrue(removeCug("/content", true));
+ assertNestedCugs(root, ROOT_PATH, true, "/content2");
+
+ assertTrue(removeCug("/content2", true));
+ assertNestedCugs(root, ROOT_PATH, true);
+
+ assertTrue(removeCug(ROOT_PATH, true));
+ assertNestedCugs(root, ROOT_PATH, false);
+ }
+
+ @Test
+ public void testRemoveRootCug4() throws Exception {
+ // add cug at /
+ createCug("/", EveryonePrincipal.getInstance());
+ createCug("/content", getTestGroupPrincipal());
+ createCug("/content2", EveryonePrincipal.getInstance());
+ root.commit();
+
+ assertTrue(removeCug("/content", false));
+ assertTrue(removeCug("/content2", false));
+ assertTrue(removeCug("/", false));
+ root.commit();
+
+ assertNestedCugs(root, "/", false);
+ }
+}
\ No newline at end of file