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 st...@apache.org on 2017/06/27 14:11:33 UTC
svn commit: r1800063 [1/2] - in /jackrabbit/oak/trunk:
oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/composite/
oak-core/src/main/java/org/apache/jackrabbit/oak/security/internal/
oak-core/src/test/java/org/apache/jackrabbit/o...
Author: stillalex
Date: Tue Jun 27 14:11:33 2017
New Revision: 1800063
URL: http://svn.apache.org/viewvc?rev=1800063&view=rev
Log:
OAK-6356 Allow CompositePermissionProvider to OR entries
Added:
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/composite/CompositeProviderCustomMixTest.java (with props)
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/composite/CompositeAuthorizationConfiguration.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/composite/CompositePermissionProvider.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/composite/CompositeTreePermission.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/internal/SecurityProviderRegistration.java
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/composite/AbstractCompositeProviderTest.java
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/composite/CompositeProviderAllTest.java
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/composite/CompositeProviderCoverageTest.java
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/composite/CompositeProviderEmptyTest.java
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/composite/CompositeProviderNoScopeTest.java
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/composite/CompositeTreePermissionTest.java
jackrabbit/oak/trunk/oak-doc/src/site/markdown/security/authorization/composite.md
jackrabbit/oak/trunk/oak-doc/src/site/markdown/security/introduction.md
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/composite/CompositeAuthorizationConfiguration.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/composite/CompositeAuthorizationConfiguration.java?rev=1800063&r1=1800062&r2=1800063&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/composite/CompositeAuthorizationConfiguration.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/composite/CompositeAuthorizationConfiguration.java Tue Jun 27 14:11:33 2017
@@ -21,6 +21,7 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
import javax.jcr.security.AccessControlManager;
import com.google.common.base.Function;
@@ -77,6 +78,40 @@ public class CompositeAuthorizationConfi
private static final Logger log = LoggerFactory.getLogger(CompositeAuthorizationConfiguration.class);
+ public enum CompositionType {
+
+ /**
+ * Break as soon as any one of the aggregated permission providers
+ * denies a privilege (default setup)
+ */
+ AND,
+
+ /**
+ * Check all aggregated permission providers for one that could provide
+ * a privilege (multiplexing setup)
+ */
+ OR;
+
+ /**
+ * Returns the corresponding composition type.
+ * @param type
+ * String representation of the composition type, or
+ * {@code null}
+ * @return corresponding composition type, or {@code AND} if the
+ * provided type is {@code null}
+ */
+ public static CompositionType fromString(@Nullable String type) {
+ String or = OR.name();
+ if (or.equals(type) || or.toLowerCase().equals(type)) {
+ return OR;
+ } else {
+ return AND;
+ }
+ }
+ }
+
+ private CompositionType compositionType = CompositionType.AND;
+
public CompositeAuthorizationConfiguration() {
super(AuthorizationConfiguration.NAME);
}
@@ -85,6 +120,10 @@ public class CompositeAuthorizationConfi
super(AuthorizationConfiguration.NAME, securityProvider);
}
+ public void withCompositionType(@Nullable String ct) {
+ this.compositionType = CompositionType.fromString(ct);
+ }
+
@Nonnull
@Override
public AccessControlManager getAccessControlManager(@Nonnull final Root root,
@@ -134,7 +173,7 @@ public class CompositeAuthorizationConfi
case 0: throw new IllegalStateException();
case 1: return configurations.get(0).getPermissionProvider(root, workspaceName, principals);
default:
- List<AggregatedPermissionProvider> aggrPermissionProviders = new ArrayList(configurations.size());
+ List<AggregatedPermissionProvider> aggrPermissionProviders = new ArrayList<>(configurations.size());
for (AuthorizationConfiguration conf : configurations) {
PermissionProvider pProvider = conf.getPermissionProvider(root, workspaceName, principals);
if (pProvider instanceof AggregatedPermissionProvider) {
@@ -152,7 +191,7 @@ public class CompositeAuthorizationConfi
pp = aggrPermissionProviders.get(0);
break;
default :
- pp = new CompositePermissionProvider(root, aggrPermissionProviders, getContext());
+ pp = new CompositePermissionProvider(root, aggrPermissionProviders, getContext(), compositionType);
}
return pp;
}
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/composite/CompositePermissionProvider.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/composite/CompositePermissionProvider.java?rev=1800063&r1=1800062&r2=1800063&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/composite/CompositePermissionProvider.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/composite/CompositePermissionProvider.java Tue Jun 27 14:11:33 2017
@@ -16,8 +16,11 @@
*/
package org.apache.jackrabbit.oak.security.authorization.composite;
+import static org.apache.jackrabbit.oak.security.authorization.composite.CompositeAuthorizationConfiguration.CompositionType.AND;
+
import java.util.List;
import java.util.Set;
+
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
@@ -28,6 +31,7 @@ import org.apache.jackrabbit.oak.plugins
import org.apache.jackrabbit.oak.plugins.tree.TreeLocation;
import org.apache.jackrabbit.oak.plugins.tree.TreeTypeProvider;
import org.apache.jackrabbit.oak.plugins.tree.impl.ImmutableTree;
+import org.apache.jackrabbit.oak.security.authorization.composite.CompositeAuthorizationConfiguration.CompositionType;
import org.apache.jackrabbit.oak.security.authorization.permission.PermissionUtil;
import org.apache.jackrabbit.oak.spi.security.Context;
import org.apache.jackrabbit.oak.spi.security.authorization.permission.AggregatedPermissionProvider;
@@ -50,6 +54,7 @@ class CompositePermissionProvider implem
private final Root root;
private final AggregatedPermissionProvider[] pps;
private final Context ctx;
+ private final CompositionType compositionType;
private final RepositoryPermission repositoryPermission;
@@ -57,12 +62,14 @@ class CompositePermissionProvider implem
private PrivilegeBitsProvider privilegeBitsProvider;
private TreeTypeProvider typeProvider;
- CompositePermissionProvider(@Nonnull Root root, @Nonnull List<AggregatedPermissionProvider> pps, @Nonnull Context acContext) {
+ CompositePermissionProvider(@Nonnull Root root, @Nonnull List<AggregatedPermissionProvider> pps,
+ @Nonnull Context acContext, @Nonnull CompositionType compositionType) {
this.root = root;
this.pps = pps.toArray(new AggregatedPermissionProvider[pps.size()]);
this.ctx = acContext;
+ this.compositionType = compositionType;
- repositoryPermission = new CompositeRepositoryPermission();
+ repositoryPermission = new CompositeRepositoryPermission(this.pps, this.compositionType);
immutableRoot = RootFactory.createReadOnlyRoot(root);
privilegeBitsProvider = new PrivilegeBitsProvider(immutableRoot);
typeProvider = new TreeTypeProvider(ctx);
@@ -122,11 +129,24 @@ class CompositePermissionProvider implem
PrivilegeBits supported = aggregatedPermissionProvider.supportedPrivileges(immutableTree, privilegeBits);
if (doEvaluate(supported)) {
Set<String> supportedNames = privilegeBitsProvider.getPrivilegeNames(supported);
- hasPrivileges = aggregatedPermissionProvider.hasPrivileges(immutableTree, supportedNames.toArray(new String[supportedNames.size()]));
- coveredPrivs.add(supported);
+ if (compositionType == AND) {
+ hasPrivileges = aggregatedPermissionProvider.hasPrivileges(immutableTree,
+ supportedNames.toArray(new String[supportedNames.size()]));
+ if (!hasPrivileges) {
+ return false;
+ }
+ coveredPrivs.add(supported);
- if (!hasPrivileges) {
- break;
+ } else {
+ // evaluate one by one so we can aggregate fragments of
+ // supported privileges
+ for (String p : supportedNames) {
+ if (aggregatedPermissionProvider.hasPrivileges(immutableTree, p)) {
+ PrivilegeBits granted = privilegeBitsProvider.getBits(p);
+ coveredPrivs.add(granted);
+ hasPrivileges = true;
+ }
+ }
}
}
}
@@ -144,7 +164,7 @@ class CompositePermissionProvider implem
public TreePermission getTreePermission(@Nonnull Tree tree, @Nonnull TreePermission parentPermission) {
ImmutableTree immutableTree = (ImmutableTree) PermissionUtil.getImmutableTree(tree, immutableRoot);
if (tree.isRoot()) {
- return CompositeTreePermission.create(immutableTree, typeProvider, pps);
+ return CompositeTreePermission.create(immutableTree, typeProvider, pps, compositionType);
} else if (parentPermission instanceof CompositeTreePermission) {
return CompositeTreePermission.create(immutableTree, ((CompositeTreePermission) parentPermission));
} else {
@@ -158,15 +178,22 @@ class CompositePermissionProvider implem
boolean isGranted = false;
long coveredPermissions = Permissions.NO_PERMISSION;
-
for (AggregatedPermissionProvider aggregatedPermissionProvider : pps) {
long supportedPermissions = aggregatedPermissionProvider.supportedPermissions(immParent, property, permissions);
if (doEvaluate(supportedPermissions)) {
- isGranted = aggregatedPermissionProvider.isGranted(immParent, property, supportedPermissions);
- coveredPermissions |= supportedPermissions;
-
- if (!isGranted) {
- break;
+ if (compositionType == AND) {
+ isGranted = aggregatedPermissionProvider.isGranted(immParent, property, supportedPermissions);
+ if (!isGranted) {
+ return false;
+ }
+ coveredPermissions |= supportedPermissions;
+ } else {
+ for (long p : Permissions.aggregates(permissions)) {
+ if (aggregatedPermissionProvider.isGranted(immParent, property, p)) {
+ coveredPermissions |= p;
+ isGranted = true;
+ }
+ }
}
}
}
@@ -192,11 +219,19 @@ class CompositePermissionProvider implem
for (AggregatedPermissionProvider aggregatedPermissionProvider : pps) {
long supportedPermissions = aggregatedPermissionProvider.supportedPermissions(location, permissions);
if (doEvaluate(supportedPermissions)) {
- isGranted = aggregatedPermissionProvider.isGranted(location, supportedPermissions);
- coveredPermissions |= supportedPermissions;
-
- if (!isGranted) {
- break;
+ if (compositionType == AND) {
+ isGranted = aggregatedPermissionProvider.isGranted(location, supportedPermissions);
+ if (!isGranted) {
+ return false;
+ }
+ coveredPermissions |= supportedPermissions;
+ } else {
+ for (long p : Permissions.aggregates(permissions)) {
+ if (aggregatedPermissionProvider.isGranted(location, p)) {
+ coveredPermissions |= p;
+ isGranted = true;
+ }
+ }
}
}
}
@@ -218,7 +253,17 @@ class CompositePermissionProvider implem
/**
* {@code RepositoryPermission} implementation that wraps multiple implementations.
*/
- private final class CompositeRepositoryPermission implements RepositoryPermission {
+ private final static class CompositeRepositoryPermission implements RepositoryPermission {
+
+ private final AggregatedPermissionProvider[] pps;
+
+ private final CompositionType compositionType;
+
+ public CompositeRepositoryPermission(@Nonnull AggregatedPermissionProvider[] pps,
+ @Nonnull CompositionType compositionType) {
+ this.pps = pps;
+ this.compositionType = compositionType;
+ }
@Override
public boolean isGranted(long repositoryPermissions) {
@@ -228,10 +273,20 @@ class CompositePermissionProvider implem
for (AggregatedPermissionProvider aggregatedPermissionProvider : pps) {
long supportedPermissions = aggregatedPermissionProvider.supportedPermissions((Tree) null, null, repositoryPermissions);
if (doEvaluate(supportedPermissions)) {
- isGranted = aggregatedPermissionProvider.getRepositoryPermission().isGranted(supportedPermissions);
- coveredPermissions |= supportedPermissions;
- if (!isGranted) {
- break;
+ RepositoryPermission rp = aggregatedPermissionProvider.getRepositoryPermission();
+ if (compositionType == AND) {
+ isGranted = rp.isGranted(supportedPermissions);
+ if (!isGranted) {
+ return false;
+ }
+ coveredPermissions |= supportedPermissions;
+ } else {
+ for (long p : Permissions.aggregates(repositoryPermissions)) {
+ if (rp.isGranted(p)) {
+ coveredPermissions |= p;
+ isGranted = true;
+ }
+ }
}
}
}
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/composite/CompositeTreePermission.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/composite/CompositeTreePermission.java?rev=1800063&r1=1800062&r2=1800063&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/composite/CompositeTreePermission.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/composite/CompositeTreePermission.java Tue Jun 27 14:11:33 2017
@@ -16,6 +16,9 @@
*/
package org.apache.jackrabbit.oak.security.authorization.composite;
+import static org.apache.jackrabbit.oak.security.authorization.composite.CompositeAuthorizationConfiguration.CompositionType.AND;
+import static org.apache.jackrabbit.oak.security.authorization.composite.CompositeAuthorizationConfiguration.CompositionType.OR;
+
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
@@ -24,6 +27,7 @@ import org.apache.jackrabbit.oak.api.Tre
import org.apache.jackrabbit.oak.plugins.tree.TreeType;
import org.apache.jackrabbit.oak.plugins.tree.TreeTypeProvider;
import org.apache.jackrabbit.oak.plugins.tree.impl.ImmutableTree;
+import org.apache.jackrabbit.oak.security.authorization.composite.CompositeAuthorizationConfiguration.CompositionType;
import org.apache.jackrabbit.oak.spi.security.authorization.permission.AggregatedPermissionProvider;
import org.apache.jackrabbit.oak.spi.security.authorization.permission.Permissions;
import org.apache.jackrabbit.oak.spi.security.authorization.permission.TreePermission;
@@ -37,6 +41,7 @@ final class CompositeTreePermission impl
private final ImmutableTree tree;
private final TreeType type;
+ private final CompositionType compositionType;
private final TreeTypeProvider typeProvider;
private final AggregatedPermissionProvider[] providers;
@@ -46,7 +51,9 @@ final class CompositeTreePermission impl
private Boolean canRead;
private Boolean canReadProperties;
- private CompositeTreePermission(@Nonnull ImmutableTree tree, @Nonnull TreeType type, @Nonnull TreeTypeProvider typeProvider, @Nonnull AggregatedPermissionProvider[] providers, @Nonnull TreePermission[] treePermissions, int cnt) {
+ private CompositeTreePermission(@Nonnull ImmutableTree tree, @Nonnull TreeType type,
+ @Nonnull TreeTypeProvider typeProvider, @Nonnull AggregatedPermissionProvider[] providers,
+ @Nonnull TreePermission[] treePermissions, int cnt, @Nonnull CompositionType compositionType) {
this.tree = tree;
this.type = type;
@@ -54,9 +61,11 @@ final class CompositeTreePermission impl
this.providers = providers;
this.treePermissions = treePermissions;
this.childSize = providers.length - cnt;
+ this.compositionType = compositionType;
}
- static TreePermission create(@Nonnull ImmutableTree rootTree, @Nonnull TreeTypeProvider typeProvider, @Nonnull AggregatedPermissionProvider[] providers) {
+ static TreePermission create(@Nonnull ImmutableTree rootTree, @Nonnull TreeTypeProvider typeProvider,
+ @Nonnull AggregatedPermissionProvider[] providers, @Nonnull CompositionType compositionType) {
switch (providers.length) {
case 0 : return TreePermission.EMPTY;
case 1 : return providers[0].getTreePermission(rootTree, TreeType.DEFAULT, TreePermission.EMPTY);
@@ -70,7 +79,8 @@ final class CompositeTreePermission impl
}
treePermissions[i] = tp;
}
- return new CompositeTreePermission(rootTree, TreeType.DEFAULT, typeProvider, providers, treePermissions, cnt);
+ return new CompositeTreePermission(rootTree, TreeType.DEFAULT, typeProvider, providers, treePermissions,
+ cnt, compositionType);
}
}
@@ -115,7 +125,8 @@ final class CompositeTreePermission impl
j++;
}
}
- return new CompositeTreePermission(tree, type, parentPermission.typeProvider, pvds, tps, cnt);
+ return new CompositeTreePermission(tree, type, parentPermission.typeProvider, pvds, tps, cnt,
+ parentPermission.compositionType);
}
}
@@ -158,7 +169,10 @@ final class CompositeTreePermission impl
long supported = providers[i].supportedPermissions(tp, null, Permissions.READ_PROPERTY);
if (doEvaluate(supported)) {
readable = tp.canReadProperties();
- if (!readable) {
+ if (!readable && compositionType == AND) {
+ break;
+ }
+ if (readable && compositionType == OR) {
break;
}
}
@@ -188,11 +202,20 @@ final class CompositeTreePermission impl
TreePermission tp = treePermissions[i];
long supported = providers[i].supportedPermissions(tp, property, permissions);
if (doEvaluate(supported)) {
- isGranted = (property == null) ? tp.isGranted(supported) : tp.isGranted(supported, property);
- coveredPermissions |= supported;
-
- if (!isGranted) {
- return false;
+ if (compositionType == AND) {
+ isGranted = (property == null) ? tp.isGranted(supported) : tp.isGranted(supported, property);
+ if (!isGranted) {
+ return false;
+ }
+ coveredPermissions |= supported;
+ } else {
+ for (long p : Permissions.aggregates(permissions)) {
+ boolean aGrant = (property == null) ? tp.isGranted(p) : tp.isGranted(p, property);
+ if (aGrant) {
+ coveredPermissions |= p;
+ isGranted = true;
+ }
+ }
}
}
}
@@ -209,8 +232,11 @@ final class CompositeTreePermission impl
long supported = providers[i].supportedPermissions(tp, property, (property == null) ? Permissions.READ_NODE : Permissions.READ_PROPERTY);
if (doEvaluate(supported)) {
readable = (property == null) ? tp.canRead() : tp.canRead(property);
- if (!readable) {
- break;
+ if (!readable && compositionType == AND) {
+ return false;
+ }
+ if (readable && compositionType == OR) {
+ return true;
}
}
}
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/internal/SecurityProviderRegistration.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/internal/SecurityProviderRegistration.java?rev=1800063&r1=1800062&r2=1800063&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/internal/SecurityProviderRegistration.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/internal/SecurityProviderRegistration.java Tue Jun 27 14:11:33 2017
@@ -28,6 +28,7 @@ import org.apache.felix.scr.annotations.
import org.apache.felix.scr.annotations.Modified;
import org.apache.felix.scr.annotations.Properties;
import org.apache.felix.scr.annotations.Property;
+import org.apache.felix.scr.annotations.PropertyOption;
import org.apache.felix.scr.annotations.PropertyUnbounded;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.ReferenceCardinality;
@@ -94,6 +95,17 @@ import static com.google.common.collect.
"org.apache.jackrabbit.oak.security.user.UserAuthenticationFactoryImpl"
},
unbounded = PropertyUnbounded.ARRAY
+ ),
+ @Property(
+ name = "authorizationCompositionType",
+ label = "Authorization Composition Type",
+ description = "The Composite Authorization model uses this flag to determine what type of logic "
+ + "to apply to the existing providers (default value is AND).",
+ value = "AND",
+ options = {
+ @PropertyOption(name = "AND", value = "AND"),
+ @PropertyOption(name = "OR", value = "OR")
+ }
)
})
@References({
@@ -184,6 +196,7 @@ public class SecurityProviderRegistratio
this.context = context;
}
+ this.authorizationConfiguration.withCompositionType(getAuthorizationCompositionType(configuration));
maybeRegister();
}
@@ -199,6 +212,7 @@ public class SecurityProviderRegistratio
preconditions.addPrecondition(pid);
}
}
+ this.authorizationConfiguration.withCompositionType(getAuthorizationCompositionType(configuration));
maybeUnregister();
maybeRegister();
@@ -572,12 +586,16 @@ public class SecurityProviderRegistratio
preconditions.removeCandidate(pid);
}
- private String getServicePid(Map<String, Object> properties) {
+ private static String getServicePid(Map<String, Object> properties) {
return PropertiesUtil.toString(properties.get(Constants.SERVICE_PID), null);
}
- private String[] getRequiredServicePids(Map<String, Object> configuration) {
+ private static String[] getRequiredServicePids(Map<String, Object> configuration) {
return PropertiesUtil.toStringArray(configuration.get("requiredServicePids"), new String[]{});
}
+ @Nonnull
+ private static String getAuthorizationCompositionType(Map<String, Object> properties) {
+ return PropertiesUtil.toString(properties.get("authorizationCompositionType"), "AND");
+ }
}
Modified: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/composite/AbstractCompositeProviderTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/composite/AbstractCompositeProviderTest.java?rev=1800063&r1=1800062&r2=1800063&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/composite/AbstractCompositeProviderTest.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/composite/AbstractCompositeProviderTest.java Tue Jun 27 14:11:33 2017
@@ -42,6 +42,7 @@ import org.apache.jackrabbit.oak.plugins
import org.apache.jackrabbit.oak.plugins.tree.RootFactory;
import org.apache.jackrabbit.oak.plugins.tree.TreeUtil;
import org.apache.jackrabbit.oak.plugins.tree.impl.ImmutableTree;
+import org.apache.jackrabbit.oak.security.authorization.composite.CompositeAuthorizationConfiguration.CompositionType;
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.PermissionProvider;
@@ -220,7 +221,7 @@ public abstract class AbstractCompositeP
}
static void assertCompositeTreePermission(@Nonnull TreePermission tp) {
- assertTrue(tp instanceof CompositeTreePermission);
+ assertTrue(tp.getClass()+ "", tp instanceof CompositeTreePermission);
}
static void assertCompositeTreePermission(boolean expected, @Nonnull TreePermission tp) {
@@ -246,7 +247,6 @@ public abstract class AbstractCompositeP
}
}
-
CompositePermissionProvider createPermissionProvider(Principal... principals) {
return createPermissionProvider(ImmutableSet.copyOf(principals));
}
@@ -254,13 +254,25 @@ public abstract class AbstractCompositeP
CompositePermissionProvider createPermissionProvider(Set<Principal> principals) {
String workspaceName = root.getContentSession().getWorkspaceName();
AuthorizationConfiguration config = getConfig(AuthorizationConfiguration.class);
- return new CompositePermissionProvider(root, getAggregatedProviders(workspaceName, config, principals), config.getContext());
+ return new CompositePermissionProvider(root, getAggregatedProviders(workspaceName, config, principals),
+ config.getContext(), CompositionType.AND);
+ }
+
+ CompositePermissionProvider createPermissionProviderOR(Principal... principals) {
+ return createPermissionProviderOR(ImmutableSet.copyOf(principals));
+ }
+
+ CompositePermissionProvider createPermissionProviderOR(Set<Principal> principals) {
+ String workspaceName = root.getContentSession().getWorkspaceName();
+ AuthorizationConfiguration config = getConfig(AuthorizationConfiguration.class);
+ return new CompositePermissionProvider(root, getAggregatedProviders(workspaceName, config, principals),
+ config.getContext(), CompositionType.OR);
}
@Test
public void testRefresh() throws Exception {
- CompositePermissionProvider pp = createPermissionProvider();
- pp.refresh();
+ createPermissionProvider().refresh();
+ createPermissionProviderOR().refresh();
}
@Test
@@ -268,7 +280,15 @@ public abstract class AbstractCompositeP
PermissionProvider pp = createPermissionProvider();
for (String p : NODE_PATHS) {
Tree tree = readOnlyRoot.getTree(p);
+ assertFalse(p, pp.hasPrivileges(tree, JCR_ALL));
+ }
+ }
+ @Test
+ public void testHasPrivilegesJcrAllOR() throws Exception {
+ PermissionProvider pp = createPermissionProviderOR();
+ for (String p : NODE_PATHS) {
+ Tree tree = readOnlyRoot.getTree(p);
assertFalse(p, pp.hasPrivileges(tree, JCR_ALL));
}
}
@@ -276,10 +296,11 @@ public abstract class AbstractCompositeP
@Test
public void testHasPrivilegesNone() throws Exception {
PermissionProvider pp = createPermissionProvider();
+ PermissionProvider ppo = createPermissionProviderOR();
for (String p : NODE_PATHS) {
Tree tree = readOnlyRoot.getTree(p);
-
assertTrue(p, pp.hasPrivileges(tree));
+ assertTrue(p, ppo.hasPrivileges(tree));
}
}
@@ -287,17 +308,22 @@ public abstract class AbstractCompositeP
public void testHasPrivilegesOnRepoJcrAll() throws Exception {
PermissionProvider pp = createPermissionProvider();
assertFalse(pp.hasPrivileges(null, JCR_ALL));
+ PermissionProvider ppo = createPermissionProviderOR();
+ assertFalse(ppo.hasPrivileges(null, JCR_ALL));
}
@Test
public void testHasPrivilegesOnRepoNone() throws Exception {
PermissionProvider pp = createPermissionProvider();
assertTrue(pp.hasPrivileges(null));
+ PermissionProvider ppo = createPermissionProviderOR();
+ assertTrue(ppo.hasPrivileges(null));
}
@Test
public void testIsGrantedAll() throws Exception {
PermissionProvider pp = createPermissionProvider();
+ PermissionProvider ppo = createPermissionProviderOR();
for (String p : NODE_PATHS) {
Tree tree = readOnlyRoot.getTree(p);
@@ -305,12 +331,15 @@ public abstract class AbstractCompositeP
assertFalse(p, pp.isGranted(tree, null, Permissions.ALL));
assertFalse(PathUtils.concat(p, JcrConstants.JCR_PRIMARYTYPE), pp.isGranted(tree, ps, Permissions.ALL));
+ assertFalse(p, ppo.isGranted(tree, null, Permissions.ALL));
+ assertFalse(PathUtils.concat(p, JcrConstants.JCR_PRIMARYTYPE), ppo.isGranted(tree, ps, Permissions.ALL));
}
}
@Test
public void testIsGrantedNone() throws Exception {
PermissionProvider pp = createPermissionProvider();
+ PermissionProvider ppo = createPermissionProviderOR();
for (String p : NODE_PATHS) {
Tree tree = readOnlyRoot.getTree(p);
@@ -318,12 +347,15 @@ public abstract class AbstractCompositeP
assertFalse(p, pp.isGranted(tree, null, Permissions.NO_PERMISSION));
assertFalse(PathUtils.concat(p, JcrConstants.JCR_PRIMARYTYPE), pp.isGranted(tree, ps, Permissions.NO_PERMISSION));
+ assertFalse(p, ppo.isGranted(tree, null, Permissions.NO_PERMISSION));
+ assertFalse(PathUtils.concat(p, JcrConstants.JCR_PRIMARYTYPE), ppo.isGranted(tree, ps, Permissions.NO_PERMISSION));
}
}
@Test
public void testIsNotGranted() throws Exception {
PermissionProvider pp = createPermissionProvider();
+ PermissionProvider ppo = createPermissionProviderOR();
for (String p : NODE_PATHS) {
Tree tree = readOnlyRoot.getTree(p);
@@ -331,39 +363,49 @@ public abstract class AbstractCompositeP
assertFalse(p, pp.isGranted(tree, null, Permissions.MODIFY_ACCESS_CONTROL));
assertFalse(PathUtils.concat(p, JcrConstants.JCR_PRIMARYTYPE), pp.isGranted(tree, ps, Permissions.MODIFY_ACCESS_CONTROL));
+ assertFalse(p, ppo.isGranted(tree, null, Permissions.MODIFY_ACCESS_CONTROL));
+ assertFalse(PathUtils.concat(p, JcrConstants.JCR_PRIMARYTYPE), ppo.isGranted(tree, ps, Permissions.MODIFY_ACCESS_CONTROL));
}
}
@Test
public void testIsGrantedActionNone() throws Exception {
PermissionProvider pp = createPermissionProvider();
+ PermissionProvider ppo = createPermissionProviderOR();
String actions = "";
for (String nodePath : NODE_PATHS) {
assertFalse(nodePath, pp.isGranted(nodePath, actions));
+ assertFalse(nodePath, ppo.isGranted(nodePath, actions));
String propPath = PathUtils.concat(nodePath, JcrConstants.JCR_PRIMARYTYPE);
assertFalse(propPath, pp.isGranted(propPath, actions));
+ assertFalse(propPath, ppo.isGranted(propPath, actions));
String nonExPath = PathUtils.concat(nodePath, "nonExisting");
assertFalse(nonExPath, pp.isGranted(nonExPath, actions));
+ assertFalse(nonExPath, ppo.isGranted(nonExPath, actions));
}
}
@Test
public void testIsNotGrantedAction() throws Exception {
PermissionProvider pp = createPermissionProvider();
+ PermissionProvider ppo = createPermissionProviderOR();
String[] actions = new String[]{JackrabbitSession.ACTION_LOCKING, JackrabbitSession.ACTION_MODIFY_ACCESS_CONTROL};
for (String nodePath : NODE_PATHS) {
String actionStr = getActionString(actions);
assertFalse(nodePath, pp.isGranted(nodePath, actionStr));
+ assertFalse(nodePath, ppo.isGranted(nodePath, actionStr));
String propPath = PathUtils.concat(nodePath, JcrConstants.JCR_PRIMARYTYPE);
assertFalse(propPath, pp.isGranted(propPath, actionStr));
+ assertFalse(propPath, ppo.isGranted(propPath, actionStr));
String nonExPath = PathUtils.concat(nodePath, "nonExisting");
assertFalse(nonExPath, pp.isGranted(nonExPath, actionStr));
+ assertFalse(nonExPath, ppo.isGranted(nonExPath, actionStr));
}
}
@@ -371,12 +413,16 @@ public abstract class AbstractCompositeP
public void testGetTreePermissionAllParent() throws Exception {
TreePermission tp = createPermissionProvider().getTreePermission(readOnlyRoot.getTree(TEST_PATH), TreePermission.ALL);
assertSame(TreePermission.ALL, tp);
+ TreePermission tpo = createPermissionProviderOR().getTreePermission(readOnlyRoot.getTree(TEST_PATH), TreePermission.ALL);
+ assertSame(TreePermission.ALL, tpo);
}
@Test
public void testGetTreePermissionEmptyParent() throws Exception {
TreePermission tp = createPermissionProvider().getTreePermission(readOnlyRoot.getTree(TEST_PATH), TreePermission.EMPTY);
assertSame(TreePermission.EMPTY, tp);
+ TreePermission tpo = createPermissionProviderOR().getTreePermission(readOnlyRoot.getTree(TEST_PATH), TreePermission.EMPTY);
+ assertSame(TreePermission.EMPTY, tpo);
}
@Test
@@ -398,6 +444,24 @@ public abstract class AbstractCompositeP
}
@Test
+ public void testTreePermissionIsGrantedAllOR() throws Exception {
+ PermissionProvider pp = createPermissionProviderOR();
+ TreePermission parentPermission = TreePermission.EMPTY;
+
+ PropertyState ps = PropertyStates.createProperty("propName", "val");
+
+ for (String path : TP_PATHS) {
+ Tree t = readOnlyRoot.getTree(path);
+ TreePermission tp = pp.getTreePermission(t, parentPermission);
+
+ assertFalse(tp.isGranted(Permissions.ALL));
+ assertFalse(tp.isGranted(Permissions.ALL, ps));
+
+ parentPermission = tp;
+ }
+ }
+
+ @Test
public void testTreePermissionIsNotGranted() throws Exception {
PermissionProvider pp = createPermissionProvider();
TreePermission parentPermission = TreePermission.EMPTY;
@@ -418,15 +482,40 @@ public abstract class AbstractCompositeP
}
@Test
+ public void testTreePermissionIsNotGrantedOR() throws Exception {
+ PermissionProvider pp = createPermissionProviderOR();
+ TreePermission parentPermission = TreePermission.EMPTY;
+
+ PropertyState ps = PropertyStates.createProperty("propName", "val");
+
+ for (String path : TP_PATHS) {
+ Tree t = readOnlyRoot.getTree(path);
+ TreePermission tp = pp.getTreePermission(t, parentPermission);
+
+ assertFalse(tp.isGranted(Permissions.NO_PERMISSION));
+ assertFalse(tp.isGranted(Permissions.MODIFY_ACCESS_CONTROL));
+ assertFalse(tp.isGranted(Permissions.NO_PERMISSION, ps));
+ assertFalse(tp.isGranted(Permissions.MODIFY_ACCESS_CONTROL, ps));
+
+ parentPermission = tp;
+ }
+ }
+
+ @Test
public void testTreePermissionCanReadAll() throws Exception {
PermissionProvider pp = createPermissionProvider();
TreePermission parentPermission = TreePermission.EMPTY;
+ PermissionProvider ppO = createPermissionProviderOR();
+ TreePermission parentPermissionO = TreePermission.EMPTY;
for (String path : TP_PATHS) {
TreePermission tp = pp.getTreePermission(readOnlyRoot.getTree(path), parentPermission);
assertFalse(tp.canReadAll());
-
parentPermission = tp;
+
+ TreePermission tpO = ppO.getTreePermission(readOnlyRoot.getTree(path), parentPermissionO);
+ assertFalse(tpO.canReadAll());
+ parentPermissionO = tpO;
}
}
@@ -444,6 +533,19 @@ public abstract class AbstractCompositeP
}
@Test
+ public void testTreePermissionCanReadPropertiesOR() throws Exception {
+ PermissionProvider pp = createPermissionProviderOR();
+ TreePermission parentPermission = TreePermission.EMPTY;
+
+ for (String path : TP_PATHS) {
+ TreePermission tp = pp.getTreePermission(readOnlyRoot.getTree(path), parentPermission);
+ assertFalse(tp.canReadProperties());
+
+ parentPermission = tp;
+ }
+ }
+
+ @Test
public void testGetTreePermissionInstance() throws Exception {
PermissionProvider pp = createPermissionProvider();
TreePermission parentPermission = TreePermission.EMPTY;
@@ -456,6 +558,18 @@ public abstract class AbstractCompositeP
}
@Test
+ public void testGetTreePermissionInstanceOR() throws Exception {
+ PermissionProvider pp = createPermissionProviderOR();
+ TreePermission parentPermission = TreePermission.EMPTY;
+
+ for (String path : TP_PATHS) {
+ TreePermission tp = pp.getTreePermission(readOnlyRoot.getTree(path), parentPermission);
+ assertCompositeTreePermission(tp);
+ parentPermission = tp;
+ }
+ }
+
+ @Test
public void testTreePermissionGetChild() throws Exception {
List<String> childNames = ImmutableList.of("test", "a", "b", "c", "nonexisting");
@@ -471,9 +585,26 @@ public abstract class AbstractCompositeP
}
@Test
+ public void testTreePermissionGetChildOR() throws Exception {
+ List<String> childNames = ImmutableList.of("test", "a", "b", "c", "nonexisting");
+
+ Tree rootTree = readOnlyRoot.getTree(ROOT_PATH);
+ NodeState ns = ((ImmutableTree) rootTree).getNodeState();
+ TreePermission tp = createPermissionProviderOR().getTreePermission(rootTree, TreePermission.EMPTY);
+
+ for (String cName : childNames) {
+ ns = ns.getChildNode(cName);
+ tp = tp.getChildPermission(cName, ns);
+ assertCompositeTreePermission(tp);
+ }
+ }
+
+ @Test
public void testGetRepositoryPermissionInstance() throws Exception {
RepositoryPermission rp = createPermissionProvider().getRepositoryPermission();
assertTrue(rp.getClass().getName().endsWith("CompositeRepositoryPermission"));
+ RepositoryPermission rpO = createPermissionProviderOR().getRepositoryPermission();
+ assertTrue(rpO.getClass().getName().endsWith("CompositeRepositoryPermission"));
}
@Test
@@ -482,6 +613,16 @@ public abstract class AbstractCompositeP
assertFalse(rp.isGranted(Permissions.PRIVILEGE_MANAGEMENT));
assertFalse(rp.isGranted(Permissions.NAMESPACE_MANAGEMENT|Permissions.PRIVILEGE_MANAGEMENT));
assertFalse(rp.isGranted(Permissions.WORKSPACE_MANAGEMENT));
+ assertFalse(rp.isGranted(Permissions.ALL));
+ assertFalse(rp.isGranted(Permissions.NO_PERMISSION));
+ }
+
+ @Test
+ public void testRepositoryPermissionIsNotGrantedOR() throws Exception {
+ RepositoryPermission rp = createPermissionProviderOR().getRepositoryPermission();
+ assertFalse(rp.isGranted(Permissions.PRIVILEGE_MANAGEMENT));
+ assertFalse(rp.isGranted(Permissions.NAMESPACE_MANAGEMENT|Permissions.PRIVILEGE_MANAGEMENT));
+ assertFalse(rp.isGranted(Permissions.WORKSPACE_MANAGEMENT));
assertFalse(rp.isGranted(Permissions.ALL));
assertFalse(rp.isGranted(Permissions.NO_PERMISSION));
}
Modified: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/composite/CompositeProviderAllTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/composite/CompositeProviderAllTest.java?rev=1800063&r1=1800062&r2=1800063&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/composite/CompositeProviderAllTest.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/composite/CompositeProviderAllTest.java Tue Jun 27 14:11:33 2017
@@ -24,11 +24,14 @@ import javax.jcr.Session;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
+
+import org.apache.jackrabbit.JcrConstants;
import org.apache.jackrabbit.api.JackrabbitSession;
import org.apache.jackrabbit.oak.api.PropertyState;
import org.apache.jackrabbit.oak.api.Root;
import org.apache.jackrabbit.oak.api.Tree;
import org.apache.jackrabbit.oak.commons.PathUtils;
+import org.apache.jackrabbit.oak.plugins.memory.PropertyStates;
import org.apache.jackrabbit.oak.plugins.tree.TreeLocation;
import org.apache.jackrabbit.oak.spi.security.authorization.permission.AggregatedPermissionProvider;
import org.apache.jackrabbit.oak.spi.security.authorization.permission.OpenPermissionProvider;
@@ -44,7 +47,7 @@ import static org.junit.Assert.assertFal
import static org.junit.Assert.assertTrue;
/**
- * Test the effect of the combination of
+ * Test the effect of the 'AND' combination of
*
* - default permission provider (which a limited permission setup)
* - custom provider that always grants full access and supports all permissions.
@@ -53,17 +56,28 @@ import static org.junit.Assert.assertTru
*
* The expected result is only the subset of permissions granted by the default
* provider. The test user must never have full access anywhere.
+ * <p>
+ * Test the effect of the 'OR'ed combination of
+ *
+ * - default permission provider (which a limited permission setup)
+ * - custom provider that always grants full access and supports all permissions.
+ *
+ * for the {@link #getTestUser()}.
+ *
+ * The expected result is the test user will have full access anywhere.
+
*/
public class CompositeProviderAllTest extends AbstractCompositeProviderTest {
private CompositePermissionProvider cpp;
-
+ private CompositePermissionProvider cppO;
@Override
public void before() throws Exception {
super.before();
cpp = createPermissionProvider(getTestUser().getPrincipal(), EveryonePrincipal.getInstance());
+ cppO = createPermissionProviderOR(getTestUser().getPrincipal(), EveryonePrincipal.getInstance());
}
@Override
@@ -71,13 +85,153 @@ public class CompositeProviderAllTest ex
return new OpenAggregateProvider(root);
}
+ @Override
+ @Test
+ public void testHasPrivilegesJcrAllOR() throws Exception {
+ PermissionProvider pp = createPermissionProviderOR();
+ for (String p : NODE_PATHS) {
+ Tree tree = readOnlyRoot.getTree(p);
+ assertTrue(p, pp.hasPrivileges(tree, JCR_ALL));
+ }
+ }
+
+ @Override
+ @Test
+ public void testIsGrantedAll() throws Exception {
+ PermissionProvider pp = createPermissionProvider();
+ PermissionProvider ppo = createPermissionProviderOR();
+
+ for (String p : NODE_PATHS) {
+ Tree tree = readOnlyRoot.getTree(p);
+ PropertyState ps = tree.getProperty(JcrConstants.JCR_PRIMARYTYPE);
+
+ assertFalse(p, pp.isGranted(tree, null, Permissions.ALL));
+ assertFalse(PathUtils.concat(p, JcrConstants.JCR_PRIMARYTYPE), pp.isGranted(tree, ps, Permissions.ALL));
+ assertTrue(p, ppo.isGranted(tree, null, Permissions.ALL));
+ assertTrue(PathUtils.concat(p, JcrConstants.JCR_PRIMARYTYPE), ppo.isGranted(tree, ps, Permissions.ALL));
+ }
+ }
+
+ @Override
+ @Test
+ public void testHasPrivilegesOnRepoJcrAll() throws Exception {
+ PermissionProvider pp = createPermissionProvider();
+ assertFalse(pp.hasPrivileges(null, JCR_ALL));
+ PermissionProvider ppo = createPermissionProviderOR();
+ assertTrue(ppo.hasPrivileges(null, JCR_ALL));
+ }
+
+ @Override
+ @Test
+ public void testIsNotGranted() throws Exception {
+ PermissionProvider pp = createPermissionProvider();
+ PermissionProvider ppo = createPermissionProviderOR();
+
+ for (String p : NODE_PATHS) {
+ Tree tree = readOnlyRoot.getTree(p);
+ PropertyState ps = tree.getProperty(JcrConstants.JCR_PRIMARYTYPE);
+
+ assertFalse(p, pp.isGranted(tree, null, Permissions.MODIFY_ACCESS_CONTROL));
+ assertFalse(PathUtils.concat(p, JcrConstants.JCR_PRIMARYTYPE), pp.isGranted(tree, ps, Permissions.MODIFY_ACCESS_CONTROL));
+ assertTrue(p, ppo.isGranted(tree, null, Permissions.MODIFY_ACCESS_CONTROL));
+ assertTrue(PathUtils.concat(p, JcrConstants.JCR_PRIMARYTYPE), ppo.isGranted(tree, ps, Permissions.MODIFY_ACCESS_CONTROL));
+ }
+ }
+
+ @Override
+ @Test
+ public void testIsNotGrantedAction() throws Exception {
+ PermissionProvider pp = createPermissionProvider();
+ PermissionProvider ppo = createPermissionProviderOR();
+ String[] actions = new String[]{JackrabbitSession.ACTION_LOCKING, JackrabbitSession.ACTION_MODIFY_ACCESS_CONTROL};
+
+ for (String nodePath : NODE_PATHS) {
+ String actionStr = getActionString(actions);
+ assertFalse(nodePath, pp.isGranted(nodePath, actionStr));
+ assertTrue(nodePath, ppo.isGranted(nodePath, actionStr));
+
+ String propPath = PathUtils.concat(nodePath, JcrConstants.JCR_PRIMARYTYPE);
+ assertFalse(propPath, pp.isGranted(propPath, actionStr));
+ assertTrue(propPath, ppo.isGranted(propPath, actionStr));
+
+ String nonExPath = PathUtils.concat(nodePath, "nonExisting");
+ assertFalse(nonExPath, pp.isGranted(nonExPath, actionStr));
+ assertTrue(nonExPath, ppo.isGranted(nonExPath, actionStr));
+ }
+ }
+
+ @Override
+ @Test
+ public void testTreePermissionIsGrantedAllOR() throws Exception {
+ PermissionProvider pp = createPermissionProviderOR();
+ TreePermission parentPermission = TreePermission.EMPTY;
+
+ PropertyState ps = PropertyStates.createProperty("propName", "val");
+
+ for (String path : TP_PATHS) {
+ Tree t = readOnlyRoot.getTree(path);
+ TreePermission tp = pp.getTreePermission(t, parentPermission);
+
+ assertTrue(tp.isGranted(Permissions.ALL));
+ assertTrue(tp.isGranted(Permissions.ALL, ps));
+
+ parentPermission = tp;
+ }
+ }
+
+ @Override
+ @Test
+ public void testTreePermissionIsNotGrantedOR() throws Exception {
+ PermissionProvider pp = createPermissionProviderOR();
+ TreePermission parentPermission = TreePermission.EMPTY;
+
+ PropertyState ps = PropertyStates.createProperty("propName", "val");
+
+ for (String path : TP_PATHS) {
+ Tree t = readOnlyRoot.getTree(path);
+ TreePermission tp = pp.getTreePermission(t, parentPermission);
+
+ assertFalse(tp.isGranted(Permissions.NO_PERMISSION));
+ assertTrue(tp.isGranted(Permissions.MODIFY_ACCESS_CONTROL));
+ assertFalse(tp.isGranted(Permissions.NO_PERMISSION, ps));
+ assertTrue(tp.isGranted(Permissions.MODIFY_ACCESS_CONTROL, ps));
+
+ parentPermission = tp;
+ }
+ }
+
+ @Override
+ @Test
+ public void testTreePermissionCanReadPropertiesOR() throws Exception {
+ PermissionProvider pp = createPermissionProviderOR();
+ TreePermission parentPermission = TreePermission.EMPTY;
+
+ for (String path : TP_PATHS) {
+ TreePermission tp = pp.getTreePermission(readOnlyRoot.getTree(path), parentPermission);
+ assertTrue(tp.canReadProperties());
+
+ parentPermission = tp;
+ }
+ }
+
+ @Override
+ @Test
+ public void testRepositoryPermissionIsNotGrantedOR() throws Exception {
+ RepositoryPermission rp = createPermissionProviderOR().getRepositoryPermission();
+ assertTrue(rp.isGranted(Permissions.PRIVILEGE_MANAGEMENT));
+ assertTrue(rp.isGranted(Permissions.NAMESPACE_MANAGEMENT | Permissions.PRIVILEGE_MANAGEMENT));
+ assertTrue(rp.isGranted(Permissions.WORKSPACE_MANAGEMENT));
+ assertTrue(rp.isGranted(Permissions.ALL));
+ assertFalse(rp.isGranted(Permissions.NO_PERMISSION));
+ }
+
@Test
public void testGetPrivileges() throws Exception {
for (String p : defPrivileges.keySet()) {
Set<String> expected = defPrivileges.get(p);
Tree tree = root.getTree(p);
-
assertEquals(p, expected, cpp.getPrivileges(tree));
+ assertEquals(p, expected, cppO.getPrivileges(tree));
}
}
@@ -85,6 +239,8 @@ public class CompositeProviderAllTest ex
public void testGetPrivilegesOnRepo() throws Exception {
Set<String> privilegeNames = cpp.getPrivileges(null);
assertEquals(ImmutableSet.of(JCR_NAMESPACE_MANAGEMENT, JCR_NODE_TYPE_DEFINITION_MANAGEMENT), privilegeNames);
+ Set<String> privilegeNamesO = cppO.getPrivileges(null);
+ assertEquals(ImmutableSet.of(JCR_NAMESPACE_MANAGEMENT, JCR_NODE_TYPE_DEFINITION_MANAGEMENT), privilegeNamesO);
}
@@ -93,18 +249,17 @@ public class CompositeProviderAllTest ex
for (String p : defPrivileges.keySet()) {
Set<String> expected = defPrivileges.get(p);
Tree tree = root.getTree(p);
-
assertTrue(p, cpp.hasPrivileges(tree, expected.toArray(new String[expected.size()])));
+ assertTrue(p, cppO.hasPrivileges(tree, expected.toArray(new String[expected.size()])));
}
}
-
@Test
public void testHasPrivilegesOnRepo() throws Exception {
assertTrue(cpp.hasPrivileges(null, JCR_NAMESPACE_MANAGEMENT, JCR_NODE_TYPE_DEFINITION_MANAGEMENT));
+ assertTrue(cppO.hasPrivileges(null, JCR_NAMESPACE_MANAGEMENT, JCR_NODE_TYPE_DEFINITION_MANAGEMENT));
}
-
@Test
public void testIsGranted() throws Exception {
for (String p : defPermissions.keySet()) {
@@ -112,6 +267,7 @@ public class CompositeProviderAllTest ex
Tree tree = readOnlyRoot.getTree(p);
assertTrue(p, cpp.isGranted(tree, null, expected));
+ assertTrue(p, cppO.isGranted(tree, null, expected));
}
}
@@ -122,6 +278,7 @@ public class CompositeProviderAllTest ex
Tree tree = readOnlyRoot.getTree(p);
assertTrue(p, cpp.isGranted(tree, PROPERTY_STATE, expected));
+ assertTrue(p, cppO.isGranted(tree, PROPERTY_STATE, expected));
}
}
@@ -130,6 +287,7 @@ public class CompositeProviderAllTest ex
for (String p : defActionsGranted.keySet()) {
String actionStr = getActionString(defActionsGranted.get(p));
assertTrue(p + " : " + actionStr, cpp.isGranted(p, actionStr));
+ assertTrue(p + " : " + actionStr, cppO.isGranted(p, actionStr));
}
}
@@ -147,6 +305,7 @@ public class CompositeProviderAllTest ex
for (String p : noAccess.keySet()) {
assertFalse(p, cpp.isGranted(p, getActionString(noAccess.get(p))));
+ assertTrue(p, cppO.isGranted(p, getActionString(noAccess.get(p))));
}
}
@@ -156,6 +315,11 @@ public class CompositeProviderAllTest ex
assertTrue(rp.isGranted(Permissions.NAMESPACE_MANAGEMENT));
assertTrue(rp.isGranted(Permissions.NODE_TYPE_DEFINITION_MANAGEMENT));
assertTrue(rp.isGranted(Permissions.NAMESPACE_MANAGEMENT | Permissions.NODE_TYPE_DEFINITION_MANAGEMENT));
+
+ RepositoryPermission rpO = cpp.getRepositoryPermission();
+ assertTrue(rpO.isGranted(Permissions.NAMESPACE_MANAGEMENT));
+ assertTrue(rpO.isGranted(Permissions.NODE_TYPE_DEFINITION_MANAGEMENT));
+ assertTrue(rpO.isGranted(Permissions.NAMESPACE_MANAGEMENT | Permissions.NODE_TYPE_DEFINITION_MANAGEMENT));
}
@Test
@@ -173,6 +337,20 @@ public class CompositeProviderAllTest ex
}
@Test
+ public void testTreePermissionIsGrantedOR() throws Exception {
+ TreePermission parentPermission = TreePermission.EMPTY;
+
+ for (String path : TP_PATHS) {
+ TreePermission tp = cppO.getTreePermission(root.getTree(path), parentPermission);
+ Long toTest = (defPermissions.containsKey(path)) ? defPermissions.get(path) : defPermissions.get(PathUtils.getAncestorPath(path, 1));
+ if (toTest != null) {
+ assertTrue(tp.isGranted(toTest));
+ }
+ parentPermission = tp;
+ }
+ }
+
+ @Test
public void testTreePermissionIsGrantedProperty() throws Exception {
TreePermission parentPermission = TreePermission.EMPTY;
@@ -187,6 +365,20 @@ public class CompositeProviderAllTest ex
}
@Test
+ public void testTreePermissionIsGrantedPropertyOR() throws Exception {
+ TreePermission parentPermission = TreePermission.EMPTY;
+
+ for (String path : TP_PATHS) {
+ TreePermission tp = cppO.getTreePermission(readOnlyRoot.getTree(path), parentPermission);
+ Long toTest = (defPermissions.containsKey(path)) ? defPermissions.get(path) : defPermissions.get(PathUtils.getAncestorPath(path, 1));
+ if (toTest != null) {
+ assertTrue(tp.isGranted(toTest, PROPERTY_STATE));
+ }
+ parentPermission = tp;
+ }
+ }
+
+ @Test
public void testTreePermissionCanRead() throws Exception {
Map<String, Boolean> readMap = ImmutableMap.<String, Boolean>builder().
put(ROOT_PATH, false).
@@ -210,6 +402,29 @@ public class CompositeProviderAllTest ex
}
@Test
+ public void testTreePermissionCanReadOR() throws Exception {
+ Map<String, Boolean> readMap = ImmutableMap.<String, Boolean>builder().
+ put(ROOT_PATH, true).
+ put(TEST_PATH, true).
+ put(TEST_A_PATH, true).
+ put(TEST_A_B_PATH, true).
+ put(TEST_A_B_C_PATH, true).
+ put(TEST_A_B_C_PATH + "/nonexisting", true).
+ build();
+
+ TreePermission parentPermission = TreePermission.EMPTY;
+ for (String nodePath : readMap.keySet()) {
+ Tree tree = readOnlyRoot.getTree(nodePath);
+ TreePermission tp = cppO.getTreePermission(tree, parentPermission);
+
+ boolean expectedResult = readMap.get(nodePath);
+ assertEquals(nodePath, expectedResult, tp.canRead());
+
+ parentPermission = tp;
+ }
+ }
+
+ @Test
public void testTreePermissionCanReadProperty() throws Exception {
Map<String, Boolean> readMap = ImmutableMap.<String, Boolean>builder().
put(ROOT_PATH, false).
@@ -228,6 +443,30 @@ public class CompositeProviderAllTest ex
boolean expectedResult = readMap.get(nodePath);
assertEquals(nodePath, expectedResult, tp.canRead(PROPERTY_STATE));
+
+ parentPermission = tp;
+ }
+ }
+
+ @Test
+ public void testTreePermissionCanReadPropertyOR() throws Exception {
+ Map<String, Boolean> readMap = ImmutableMap.<String, Boolean>builder().
+ put(ROOT_PATH, true).
+ put(TEST_PATH, true).
+ put(TEST_A_PATH, true).
+ put(TEST_A_B_PATH, true).
+ put(TEST_A_B_C_PATH, true).
+ put(TEST_A_B_C_PATH + "/nonexisting", true).
+ build();
+
+ TreePermission parentPermission = TreePermission.EMPTY;
+ for (String nodePath : readMap.keySet()) {
+ Tree tree = readOnlyRoot.getTree(nodePath);
+
+ TreePermission tp = cppO.getTreePermission(tree, parentPermission);
+
+ boolean expectedResult = readMap.get(nodePath);
+ assertEquals(nodePath, expectedResult, tp.canRead(PROPERTY_STATE));
parentPermission = tp;
}
Modified: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/composite/CompositeProviderCoverageTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/composite/CompositeProviderCoverageTest.java?rev=1800063&r1=1800062&r2=1800063&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/composite/CompositeProviderCoverageTest.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/composite/CompositeProviderCoverageTest.java Tue Jun 27 14:11:33 2017
@@ -64,12 +64,14 @@ import static org.junit.Assert.assertTru
public class CompositeProviderCoverageTest extends AbstractCompositeProviderTest {
private CompositePermissionProvider cpp;
+ private CompositePermissionProvider cppO;
@Override
public void before() throws Exception {
super.before();
cpp = createPermissionProvider();
+ cppO = createPermissionProviderOR();
}
@Override
@@ -95,6 +97,20 @@ public class CompositeProviderCoverageTe
}
}
+ @Override
+ @Test
+ public void testGetTreePermissionInstanceOR() throws Exception {
+ PermissionProvider pp = createPermissionProviderOR(EveryonePrincipal.getInstance());
+ TreePermission parentPermission = TreePermission.EMPTY;
+
+ for (String path : TP_PATHS) {
+ TreePermission tp = pp.getTreePermission(readOnlyRoot.getTree(path), parentPermission);
+ assertTrue(tp instanceof LimitedTreePermission);
+ parentPermission = tp;
+ }
+ }
+
+ @Override
@Test
public void testTreePermissionGetChild() throws Exception {
List<String> childNames = ImmutableList.of("test", "a", "b", "c", "nonexisting");
@@ -110,16 +126,34 @@ public class CompositeProviderCoverageTe
}
}
+ @Override
+ @Test
+ public void testTreePermissionGetChildOR() throws Exception {
+ List<String> childNames = ImmutableList.of("test", "a", "b", "c", "nonexisting");
+
+ Tree rootTree = readOnlyRoot.getTree(ROOT_PATH);
+ NodeState ns = ((ImmutableTree) rootTree).getNodeState();
+ TreePermission tp = createPermissionProviderOR().getTreePermission(rootTree, TreePermission.EMPTY);
+
+ for (String cName : childNames) {
+ ns = ns.getChildNode(cName);
+ tp = tp.getChildPermission(cName, ns);
+ assertTrue(tp instanceof LimitedTreePermission);
+ }
+ }
+
@Test
public void testGetPrivileges() throws Exception {
for (String p : NODE_PATHS) {
assertEquals(ImmutableSet.of(REP_READ_NODES), cpp.getPrivileges(readOnlyRoot.getTree(p)));
+ assertEquals(ImmutableSet.of(REP_READ_NODES), cppO.getPrivileges(readOnlyRoot.getTree(p)));
}
}
@Test
public void testGetPrivilegesOnRepo() throws Exception {
assertEquals(ImmutableSet.of(JCR_NAMESPACE_MANAGEMENT), cpp.getPrivileges(null));
+ assertEquals(ImmutableSet.of(JCR_NAMESPACE_MANAGEMENT), cppO.getPrivileges(null));
}
@Test
@@ -131,6 +165,11 @@ public class CompositeProviderCoverageTe
assertFalse(cpp.hasPrivileges(tree, JCR_READ));
assertFalse(cpp.hasPrivileges(tree, JCR_WRITE));
assertFalse(cpp.hasPrivileges(tree, JCR_ALL));
+
+ assertTrue(cppO.hasPrivileges(tree, REP_READ_NODES));
+ assertFalse(cppO.hasPrivileges(tree, JCR_READ));
+ assertFalse(cppO.hasPrivileges(tree, JCR_WRITE));
+ assertFalse(cppO.hasPrivileges(tree, JCR_ALL));
}
}
@@ -139,6 +178,10 @@ public class CompositeProviderCoverageTe
assertTrue(cpp.hasPrivileges(null, JCR_NAMESPACE_MANAGEMENT));
assertFalse(cpp.hasPrivileges(null, JCR_NODE_TYPE_DEFINITION_MANAGEMENT));
assertFalse(cpp.hasPrivileges(null, JCR_ALL));
+
+ assertTrue(cppO.hasPrivileges(null, JCR_NAMESPACE_MANAGEMENT));
+ assertFalse(cppO.hasPrivileges(null, JCR_NODE_TYPE_DEFINITION_MANAGEMENT));
+ assertFalse(cppO.hasPrivileges(null, JCR_ALL));
}
@@ -151,6 +194,11 @@ public class CompositeProviderCoverageTe
assertFalse(cpp.isGranted(tree, null, Permissions.LOCK_MANAGEMENT));
assertFalse(cpp.isGranted(tree, null, Permissions.ALL));
assertFalse(cpp.isGranted(tree, null, Permissions.READ_NODE | Permissions.LOCK_MANAGEMENT));
+
+ assertTrue(cppO.isGranted(tree, null, Permissions.READ_NODE));
+ assertFalse(cppO.isGranted(tree, null, Permissions.LOCK_MANAGEMENT));
+ assertFalse(cppO.isGranted(tree, null, Permissions.ALL));
+ assertFalse(cppO.isGranted(tree, null, Permissions.READ_NODE | Permissions.LOCK_MANAGEMENT));
}
}
@@ -164,6 +212,12 @@ public class CompositeProviderCoverageTe
assertFalse(cpp.isGranted(tree, PROPERTY_STATE, Permissions.LOCK_MANAGEMENT));
assertFalse(cpp.isGranted(tree, PROPERTY_STATE, Permissions.ALL));
assertFalse(cpp.isGranted(tree, PROPERTY_STATE, Permissions.READ_NODE | Permissions.LOCK_MANAGEMENT));
+
+ assertTrue(cppO.isGranted(tree, PROPERTY_STATE, Permissions.READ_NODE));
+ assertFalse(cppO.isGranted(tree, PROPERTY_STATE, Permissions.READ_PROPERTY));
+ assertFalse(cppO.isGranted(tree, PROPERTY_STATE, Permissions.LOCK_MANAGEMENT));
+ assertFalse(cppO.isGranted(tree, PROPERTY_STATE, Permissions.ALL));
+ assertFalse(cppO.isGranted(tree, PROPERTY_STATE, Permissions.READ_NODE | Permissions.LOCK_MANAGEMENT));
}
}
@@ -174,16 +228,24 @@ public class CompositeProviderCoverageTe
assertTrue(cpp.isGranted(nodePath, Session.ACTION_READ));
assertFalse(cpp.isGranted(propPath, Session.ACTION_READ));
-
assertFalse(cpp.isGranted(nodePath, Session.ACTION_REMOVE));
assertFalse(cpp.isGranted(propPath, JackrabbitSession.ACTION_MODIFY_PROPERTY));
-
assertFalse(cpp.isGranted(nodePath, getActionString(JackrabbitSession.ACTION_MODIFY_ACCESS_CONTROL, JackrabbitSession.ACTION_READ_ACCESS_CONTROL)));
+ assertTrue(cppO.isGranted(nodePath, Session.ACTION_READ));
+ assertFalse(cppO.isGranted(propPath, Session.ACTION_READ));
+ assertFalse(cppO.isGranted(nodePath, Session.ACTION_REMOVE));
+ assertFalse(cppO.isGranted(propPath, JackrabbitSession.ACTION_MODIFY_PROPERTY));
+ assertFalse(cppO.isGranted(nodePath, getActionString(JackrabbitSession.ACTION_MODIFY_ACCESS_CONTROL, JackrabbitSession.ACTION_READ_ACCESS_CONTROL)));
+
String nonExisting = PathUtils.concat(nodePath, "nonExisting");
assertFalse(cpp.isGranted(nonExisting, Session.ACTION_READ));
assertFalse(cpp.isGranted(nonExisting, JackrabbitSession.ACTION_ADD_PROPERTY));
assertFalse(cpp.isGranted(nonExisting, Session.ACTION_ADD_NODE));
+
+ assertFalse(cppO.isGranted(nonExisting, Session.ACTION_READ));
+ assertFalse(cppO.isGranted(nonExisting, JackrabbitSession.ACTION_ADD_PROPERTY));
+ assertFalse(cppO.isGranted(nonExisting, Session.ACTION_ADD_NODE));
}
}
@@ -193,6 +255,11 @@ public class CompositeProviderCoverageTe
assertTrue(rp.isGranted(Permissions.NAMESPACE_MANAGEMENT));
assertFalse(rp.isGranted(Permissions.NODE_TYPE_DEFINITION_MANAGEMENT));
assertFalse(rp.isGranted(Permissions.ALL));
+
+ RepositoryPermission rpO = cppO.getRepositoryPermission();
+ assertTrue(rpO.isGranted(Permissions.NAMESPACE_MANAGEMENT));
+ assertFalse(rpO.isGranted(Permissions.NODE_TYPE_DEFINITION_MANAGEMENT));
+ assertFalse(rpO.isGranted(Permissions.ALL));
}
@Test
@@ -211,6 +278,21 @@ public class CompositeProviderCoverageTe
}
@Test
+ public void testTreePermissionIsGrantedOR() throws Exception {
+ TreePermission parentPermission = TreePermission.EMPTY;
+ for (String path : TP_PATHS) {
+ TreePermission tp = cppO.getTreePermission(readOnlyRoot.getTree(path), parentPermission);
+
+ assertTrue(tp.isGranted(Permissions.READ_NODE));
+ assertFalse(tp.isGranted(Permissions.REMOVE_NODE));
+ assertFalse(tp.isGranted(Permissions.READ));
+ assertFalse(tp.isGranted(Permissions.ALL));
+
+ parentPermission = tp;
+ }
+ }
+
+ @Test
public void testTreePermissionIsGrantedProperty() throws Exception {
TreePermission parentPermission = TreePermission.EMPTY;
@@ -227,6 +309,22 @@ public class CompositeProviderCoverageTe
}
@Test
+ public void testTreePermissionIsGrantedPropertyOR() throws Exception {
+ TreePermission parentPermission = TreePermission.EMPTY;
+
+ for (String path : TP_PATHS) {
+ TreePermission tp = cppO.getTreePermission(readOnlyRoot.getTree(path), parentPermission);
+
+ assertFalse(tp.isGranted(Permissions.READ_PROPERTY, PROPERTY_STATE));
+ assertFalse(tp.isGranted(Permissions.REMOVE_PROPERTY, PROPERTY_STATE));
+ assertFalse(tp.isGranted(Permissions.READ, PROPERTY_STATE));
+ assertFalse(tp.isGranted(Permissions.ALL, PROPERTY_STATE));
+
+ parentPermission = tp;
+ }
+ }
+
+ @Test
public void testTreePermissionCanRead() throws Exception {
TreePermission parentPermission = TreePermission.EMPTY;
@@ -241,6 +339,20 @@ public class CompositeProviderCoverageTe
}
@Test
+ public void testTreePermissionCanReadOR() throws Exception {
+ TreePermission parentPermission = TreePermission.EMPTY;
+
+ for (String path : TP_PATHS) {
+ Tree t = readOnlyRoot.getTree(path);
+ TreePermission tp = cppO.getTreePermission(t, parentPermission);
+
+ assertTrue(tp.canRead());
+
+ parentPermission = tp;
+ }
+ }
+
+ @Test
public void testTreePermissionCanReadProperty() throws Exception {
TreePermission parentPermission = TreePermission.EMPTY;
@@ -250,6 +362,19 @@ public class CompositeProviderCoverageTe
assertFalse(tp.canRead(PROPERTY_STATE));
parentPermission = tp;
+ }
+ }
+
+ @Test
+ public void testTreePermissionCanReadPropertyOR() throws Exception {
+ TreePermission parentPermission = TreePermission.EMPTY;
+
+ for (String path : TP_PATHS) {
+ Tree t = readOnlyRoot.getTree(path);
+ TreePermission tp = cppO.getTreePermission(t, parentPermission);
+ assertFalse(tp.canRead(PROPERTY_STATE));
+
+ parentPermission = tp;
}
}
Added: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/composite/CompositeProviderCustomMixTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/composite/CompositeProviderCustomMixTest.java?rev=1800063&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/composite/CompositeProviderCustomMixTest.java (added)
+++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/composite/CompositeProviderCustomMixTest.java Tue Jun 27 14:11:33 2017
@@ -0,0 +1,407 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.oak.security.authorization.composite;
+
+import static org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants.JCR_NAMESPACE_MANAGEMENT;
+import static org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants.JCR_NODE_TYPE_MANAGEMENT;
+import static org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants.JCR_READ;
+import static org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants.JCR_WRITE;
+import static org.junit.Assert.assertEquals;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.apache.jackrabbit.api.JackrabbitSession;
+import org.apache.jackrabbit.oak.AbstractSecurityTest;
+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.tree.TreeLocation;
+import org.apache.jackrabbit.oak.plugins.tree.TreeType;
+import org.apache.jackrabbit.oak.security.authorization.composite.CompositeAuthorizationConfiguration.CompositionType;
+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.Permissions;
+import org.apache.jackrabbit.oak.spi.security.authorization.permission.RepositoryPermission;
+import org.apache.jackrabbit.oak.spi.security.authorization.permission.TreePermission;
+import org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeBits;
+import org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeBitsProvider;
+import org.apache.jackrabbit.oak.spi.state.NodeState;
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
+
+public class CompositeProviderCustomMixTest extends AbstractSecurityTest {
+
+ @Test
+ public void hasPrivilegesTest() throws Exception {
+ Set<String> supp1 = ImmutableSet.of(JCR_READ, JCR_NAMESPACE_MANAGEMENT);
+ Set<String> supp2 = ImmutableSet.of(JCR_READ, JCR_WRITE);
+ Set<String> all = Sets.union(supp1, supp2);
+
+ // tests all possible 256 shuffles
+ for (CompositionType type : CompositionType.values()) {
+ for (Set<String> granted1 : Sets.powerSet(supp1)) {
+ for (Set<String> granted2 : Sets.powerSet(supp2)) {
+ for (Set<String> ps : Sets.powerSet(all)) {
+ CompositePermissionProvider cpp = buildCpp(supp1, granted1, supp2, granted2, type, null);
+
+ boolean expected = expected(ps, supp1, granted1, supp2, granted2, type, true);
+ boolean result = cpp.hasPrivileges(null, ps.toArray(new String[] {}));
+
+ String err = "Checking " + ps + " in {supported: " + supp1 + ", granted: " + granted1 + "} "
+ + type + " {supported: " + supp2 + ", granted: " + granted2 + "}";
+ assertEquals(err, expected, result);
+ }
+ }
+ }
+ }
+ }
+
+ @Test
+ public void isGrantedTest() throws Exception {
+ Set<String> supp1 = ImmutableSet.of(JCR_READ, JCR_NODE_TYPE_MANAGEMENT);
+ Set<String> supp2 = ImmutableSet.of(JCR_READ, JCR_WRITE);
+ Set<String> all = Sets.union(supp1, supp2);
+
+ Map<String, Long> grantMap = Maps.newHashMap();
+ grantMap.put(JCR_READ, Permissions.READ);
+ grantMap.put(JCR_NODE_TYPE_MANAGEMENT, Permissions.NODE_TYPE_MANAGEMENT);
+ grantMap.put(JCR_WRITE, Permissions.WRITE);
+
+ Map<String, String> actionMap = Maps.newHashMap();
+ actionMap.put(JCR_READ, JackrabbitSession.ACTION_READ);
+ actionMap.put(JCR_NODE_TYPE_MANAGEMENT, JackrabbitSession.ACTION_NODE_TYPE_MANAGEMENT);
+ actionMap.put(JCR_WRITE, JackrabbitSession.ACTION_ADD_NODE);
+
+ // tests all possible 256 shuffles
+ for (CompositionType type : CompositionType.values()) {
+ for (Set<String> granted1 : Sets.powerSet(supp1)) {
+ for (Set<String> granted2 : Sets.powerSet(supp2)) {
+ for (Set<String> ps : Sets.powerSet(all)) {
+ CompositePermissionProvider cpp = buildCpp(supp1, granted1, supp2, granted2, type, grantMap);
+ boolean expected = expected(ps, supp1, granted1, supp2, granted2, type, false);
+
+ boolean result1 = cpp.isGranted(null, null, mapToPermissions(ps, grantMap));
+ String err1 = "[isGranted1] Checking " + ps + " in {supported: " + supp1 + ", granted: "
+ + granted1 + "} " + type + " {supported: " + supp2 + ", granted: " + granted2 + "}";
+ assertEquals(err1, expected, result1);
+
+ // check existing path
+ boolean result2 = cpp.isGranted("/", mapToActions(ps, actionMap));
+ String err2 = "[isGranted2] Checking " + ps + " in {supported: " + supp1 + ", granted: "
+ + granted1 + "} " + type + " {supported: " + supp2 + ", granted: " + granted2 + "}";
+ assertEquals(err2, expected, result2);
+
+ // check non existing path
+ boolean result3 = cpp.isGranted("/doesnotexist", mapToActions(ps, actionMap));
+ String err3 = "[isGranted3] Checking " + ps + " in {supported: " + supp1 + ", granted: "
+ + granted1 + "} " + type + " {supported: " + supp2 + ", granted: " + granted2 + "}";
+ assertEquals(err3, expected, result3);
+ }
+ }
+ }
+ }
+ }
+
+ @Test
+ public void getRepositoryPermissionTest() throws Exception {
+ Set<String> supp1 = ImmutableSet.of(JCR_READ, JCR_NODE_TYPE_MANAGEMENT);
+ Set<String> supp2 = ImmutableSet.of(JCR_READ, JCR_WRITE);
+ Set<String> all = Sets.union(supp1, supp2);
+
+ Map<String, Long> grantMap = Maps.newHashMap();
+ grantMap.put(JCR_READ, Permissions.READ);
+ grantMap.put(JCR_NODE_TYPE_MANAGEMENT, Permissions.NODE_TYPE_MANAGEMENT);
+ grantMap.put(JCR_WRITE, Permissions.WRITE);
+
+ // tests all possible 256 shuffles
+ for (CompositionType type : CompositionType.values()) {
+ for (Set<String> granted1 : Sets.powerSet(supp1)) {
+ for (Set<String> granted2 : Sets.powerSet(supp2)) {
+ for (Set<String> ps : Sets.powerSet(all)) {
+ CompositePermissionProvider cpp = buildCpp(supp1, granted1, supp2, granted2, type, grantMap);
+
+ boolean expected = expected(ps, supp1, granted1, supp2, granted2, type, false);
+ boolean result = cpp.getRepositoryPermission().isGranted(mapToPermissions(ps, grantMap));
+
+ String err = "Checking " + ps + " in {supported: " + supp1 + ", granted: " + granted1 + "} "
+ + type + " {supported: " + supp2 + ", granted: " + granted2 + "}";
+ assertEquals(err, expected, result);
+ }
+ }
+ }
+ }
+ }
+
+ @Test
+ public void getTreePermissionTest() throws Exception {
+ Set<String> supp1 = ImmutableSet.of(JCR_READ, JCR_NODE_TYPE_MANAGEMENT);
+ Set<String> supp2 = ImmutableSet.of(JCR_READ, JCR_WRITE);
+ Set<String> all = Sets.union(supp1, supp2);
+
+ Map<String, Long> grantMap = Maps.newHashMap();
+ grantMap.put(JCR_READ, Permissions.READ);
+ grantMap.put(JCR_NODE_TYPE_MANAGEMENT, Permissions.NODE_TYPE_MANAGEMENT);
+ grantMap.put(JCR_WRITE, Permissions.WRITE);
+
+ // tests all possible 256 shuffles
+ for (CompositionType type : CompositionType.values()) {
+ for (Set<String> granted1 : Sets.powerSet(supp1)) {
+ for (Set<String> granted2 : Sets.powerSet(supp2)) {
+ for (Set<String> ps : Sets.powerSet(all)) {
+ CompositePermissionProvider cpp = buildCpp(supp1, granted1, supp2, granted2, type, grantMap);
+
+ boolean expected = expected(ps, supp1, granted1, supp2, granted2, type, false);
+ boolean result = cpp.getTreePermission(root.getTree("/"), TreePermission.EMPTY)
+ .isGranted(mapToPermissions(ps, grantMap));
+
+ String err = "Checking " + ps + " in {supported: " + supp1 + ", granted: " + granted1 + "} "
+ + type + " {supported: " + supp2 + ", granted: " + granted2 + "}";
+ assertEquals(err, expected, result);
+ }
+ }
+ }
+ }
+ }
+
+ private static long mapToPermissions(Set<String> items, Map<String, Long> grantMap) {
+ long perm = Permissions.NO_PERMISSION;
+ for (String i : items) {
+ perm |= grantMap.get(i);
+ }
+ return perm;
+ }
+
+ private static String mapToActions(Set<String> items, Map<String, String> actionMap) {
+ if (items.isEmpty()) {
+ return "";
+ }
+ String actions = "";
+ for (String i : items) {
+ actions += actionMap.get(i) + ",";
+ }
+ return actions.substring(0, actions.length() - 1);
+ }
+
+ private boolean expected(Set<String> check, Set<String> supported1, Set<String> granted1, Set<String> supported2,
+ Set<String> granted2, CompositionType type, boolean emptyIsTrue) {
+ // Special case handled differently in the composite permissions vs.
+ // actions
+ if (check.isEmpty()) {
+ return emptyIsTrue;
+ }
+
+ if (type == CompositionType.OR) {
+ return Sets.difference(Sets.difference(check, granted1), granted2).isEmpty();
+ } else {
+ Set<String> f1 = Sets.intersection(supported1, check);
+ boolean hasf1 = granted1.containsAll(f1);
+ Set<String> f2 = Sets.intersection(supported2, check);
+ boolean hasf2 = granted2.containsAll(f2);
+ return hasf1 && hasf2;
+ }
+ }
+
+ private CompositePermissionProvider buildCpp(Set<String> supported1, Set<String> granted1, Set<String> supported2,
+ Set<String> granted2, CompositionType type, Map<String, Long> grantMap) {
+ AggregatedPermissionProvider a1 = new CustomProvider(root, supported1, granted1, grantMap);
+ AggregatedPermissionProvider a2 = new CustomProvider(root, supported2, granted2, grantMap);
+
+ AuthorizationConfiguration config = getConfig(AuthorizationConfiguration.class);
+ List<AggregatedPermissionProvider> composite = ImmutableList.of(a1, a2);
+ return new CompositePermissionProvider(root, composite, config.getContext(), type);
+ }
+
+ private static class CustomProvider implements AggregatedPermissionProvider {
+
+ private final PrivilegeBitsProvider pbp;
+
+ private final Set<String> supported;
+ private final Set<String> granted;
+ private final Map<String, Long> grantMap;
+
+ private CustomProvider(@Nonnull Root root, Set<String> supported, Set<String> granted,
+ Map<String, Long> grantMap) {
+ this.pbp = new PrivilegeBitsProvider(root);
+
+ this.supported = supported;
+ this.granted = granted;
+ this.grantMap = grantMap;
+ }
+
+ private static PrivilegeBits toBits(Set<String> supported, PrivilegeBitsProvider pbp) {
+ PrivilegeBits suppBits = PrivilegeBits.getInstance();
+ for (String s : supported) {
+ suppBits.add(pbp.getBits(s));
+ }
+ return suppBits;
+ }
+
+ @Nonnull
+ @Override
+ public PrivilegeBits supportedPrivileges(@Nullable Tree tree, @Nullable PrivilegeBits privilegeBits) {
+ return toBits(supported, pbp).retain(privilegeBits);
+ }
+
+ @Override
+ public boolean hasPrivileges(Tree tree, String... privilegeNames) {
+ Set<String> in = Sets.newHashSet(privilegeNames);
+ return granted.containsAll(in);
+ }
+
+ private long supportedPermissions(long permissions) {
+ long allperms = mapToPermissions(supported, grantMap);
+ long delta = Permissions.diff(permissions, allperms);
+ return Permissions.diff(permissions, delta);
+ }
+
+ @Override
+ public long supportedPermissions(@Nullable Tree tree, @Nullable PropertyState property, long permissions) {
+ return supportedPermissions(permissions);
+ }
+
+ @Override
+ public long supportedPermissions(TreeLocation location, long permissions) {
+ return supportedPermissions(permissions);
+ }
+
+ @Override
+ public long supportedPermissions(TreePermission treePermission, PropertyState property, long permissions) {
+ return supportedPermissions(permissions);
+ }
+
+ @Override
+ public boolean isGranted(@Nonnull Tree tree, @Nullable PropertyState property, long permissions) {
+ long myperms = mapToPermissions(granted, grantMap);
+ return Permissions.includes(myperms, permissions);
+ }
+
+ @Override
+ public boolean isGranted(TreeLocation location, long permissions) {
+ long myperms = mapToPermissions(granted, grantMap);
+ return Permissions.includes(myperms, permissions);
+ }
+
+ @Override
+ public RepositoryPermission getRepositoryPermission() {
+ return new RepositoryPermission() {
+
+ @Override
+ public boolean isGranted(long repositoryPermissions) {
+ long myperms = mapToPermissions(granted, grantMap);
+ return Permissions.includes(myperms, repositoryPermissions);
+ }
+ };
+ }
+
+ @Override
+ public TreePermission getTreePermission(Tree tree, TreeType type, TreePermission parentPermission) {
+ return new CustomTreePermission(granted, grantMap);
+ }
+
+ @Override
+ public void refresh() {
+ Assert.fail("method should not be called");
+ }
+
+ @Override
+ public Set<String> getPrivileges(Tree tree) {
+ Assert.fail("method should not be called");
+ return null;
+ }
+
+ @Override
+ public TreePermission getTreePermission(Tree tree, TreePermission parentPermission) {
+ Assert.fail("method should not be called");
+ return null;
+ }
+
+ @Override
+ public boolean isGranted(String oakPath, String jcrActions) {
+ Assert.fail("method should not be called");
+ return false;
+ }
+
+ @Override
+ public String toString() {
+ return "CustomProvider [supported=" + supported + ", granted=" + granted + "]";
+ }
+ }
+
+ private static class CustomTreePermission implements TreePermission {
+
+ private final Set<String> granted;
+ private final Map<String, Long> grantMap;
+
+ public CustomTreePermission(Set<String> granted, Map<String, Long> grantMap) {
+ this.granted = granted;
+ this.grantMap = grantMap;
+ }
+
+ @Override
+ public TreePermission getChildPermission(String childName, NodeState childState) {
+ Assert.fail("method should not be called");
+ return null;
+ }
+
+ @Override
+ public boolean canRead() {
+ Assert.fail("method should not be called");
+ return false;
+ }
+
+ @Override
+ public boolean canRead(PropertyState property) {
+ Assert.fail("method should not be called");
+ return false;
+ }
+
+ @Override
+ public boolean canReadAll() {
+ Assert.fail("method should not be called");
+ return false;
+ }
+
+ @Override
+ public boolean canReadProperties() {
+ Assert.fail("method should not be called");
+ return false;
+ }
+
+ @Override
+ public boolean isGranted(long permissions) {
+ long myperms = mapToPermissions(granted, grantMap);
+ return Permissions.includes(myperms, permissions);
+ }
+
+ @Override
+ public boolean isGranted(long permissions, PropertyState property) {
+ Assert.fail("method should not be called");
+ return false;
+ }
+
+ }
+}
Propchange: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/composite/CompositeProviderCustomMixTest.java
------------------------------------------------------------------------------
svn:eol-style = native