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 2019/06/06 16:01:15 UTC
svn commit: r1860721 - 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/oak/sec...
Author: angela
Date: Thu Jun 6 16:01:14 2019
New Revision: 1860721
URL: http://svn.apache.org/viewvc?rev=1860721&view=rev
Log:
OAK-8155 : CompositePermissionProvider: add possibility to abort evaluation
Added:
jackrabbit/oak/trunk/oak-security-spi/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/permission/AggregationFilter.java (with props)
jackrabbit/oak/trunk/oak-security-spi/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/permission/AggregationFilterDefaultTest.java (with props)
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/composite/CompositeAccessControlManager.java
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/internal/SecurityProviderRegistration.java
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/composite/CompositeAccessControlManagerTest.java
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/composite/CompositeAuthorizationConfigurationTest.java
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/internal/SecurityProviderRegistrationTest.java
jackrabbit/oak/trunk/oak-security-spi/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/permission/package-info.java
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/composite/CompositeAccessControlManager.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/composite/CompositeAccessControlManager.java?rev=1860721&r1=1860720&r2=1860721&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/composite/CompositeAccessControlManager.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/composite/CompositeAccessControlManager.java Thu Jun 6 16:01:14 2019
@@ -38,6 +38,7 @@ import org.apache.jackrabbit.oak.namepat
import org.apache.jackrabbit.oak.spi.security.SecurityProvider;
import org.apache.jackrabbit.oak.spi.security.authorization.accesscontrol.AbstractAccessControlManager;
import org.apache.jackrabbit.oak.spi.security.authorization.accesscontrol.PolicyOwner;
+import org.apache.jackrabbit.oak.spi.security.authorization.permission.AggregationFilter;
import org.jetbrains.annotations.NotNull;
/**
@@ -50,13 +51,16 @@ import org.jetbrains.annotations.NotNull
class CompositeAccessControlManager extends AbstractAccessControlManager {
private final List<AccessControlManager> acMgrs;
+ private final AggregationFilter aggregationFilter;
public CompositeAccessControlManager(@NotNull Root root,
@NotNull NamePathMapper namePathMapper,
@NotNull SecurityProvider securityProvider,
- @NotNull List<AccessControlManager> acMgrs) {
+ @NotNull List<AccessControlManager> acMgrs,
+ @NotNull AggregationFilter aggregationFilter) {
super(root, namePathMapper, securityProvider);
this.acMgrs = acMgrs;
+ this.aggregationFilter = aggregationFilter;
}
//-----------------------------------------------< AccessControlManager >---
@@ -86,6 +90,9 @@ class CompositeAccessControlManager exte
ImmutableList.Builder<AccessControlPolicy> policies = ImmutableList.builder();
for (AccessControlManager acMgr : acMgrs) {
policies.add(acMgr.getEffectivePolicies(absPath));
+ if (aggregationFilter.stop(acMgr, absPath)) {
+ break;
+ }
}
List<AccessControlPolicy> l = policies.build();
return l.toArray(new AccessControlPolicy[0]);
@@ -154,7 +161,11 @@ class CompositeAccessControlManager exte
ImmutableList.Builder<AccessControlPolicy> policies = ImmutableList.builder();
for (AccessControlManager acMgr : acMgrs) {
if (acMgr instanceof JackrabbitAccessControlManager) {
- policies.add(((JackrabbitAccessControlManager) acMgr).getEffectivePolicies(principals));
+ JackrabbitAccessControlManager jAcMgr = (JackrabbitAccessControlManager) acMgr;
+ policies.add(jAcMgr.getEffectivePolicies(principals));
+ if (aggregationFilter.stop(jAcMgr, principals)) {
+ break;
+ }
}
}
List<AccessControlPolicy> l = policies.build();
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=1860721&r1=1860720&r2=1860721&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 Thu Jun 6 16:01:14 2019
@@ -30,6 +30,7 @@ import org.apache.jackrabbit.oak.spi.sec
import org.apache.jackrabbit.oak.spi.security.SecurityProvider;
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.AggregationFilter;
import org.apache.jackrabbit.oak.spi.security.authorization.permission.EmptyPermissionProvider;
import org.apache.jackrabbit.oak.spi.security.authorization.permission.PermissionProvider;
import org.apache.jackrabbit.oak.spi.security.authorization.restriction.CompositeRestrictionProvider;
@@ -112,6 +113,8 @@ public class CompositeAuthorizationConfi
private CompositionType compositionType = CompositionType.AND;
+ private AggregationFilter aggregationFilter = AggregationFilter.DEFAULT;
+
public CompositeAuthorizationConfiguration() {
super(AuthorizationConfiguration.NAME);
}
@@ -124,6 +127,10 @@ public class CompositeAuthorizationConfi
this.compositionType = CompositionType.fromString(ct);
}
+ public void withAggregationFilter(@NotNull AggregationFilter aggregationFilter) {
+ this.aggregationFilter = aggregationFilter;
+ }
+
@NotNull
@Override
public AccessControlManager getAccessControlManager(@NotNull final Root root,
@@ -134,8 +141,7 @@ public class CompositeAuthorizationConfi
case 1: return configurations.get(0).getAccessControlManager(root, namePathMapper);
default:
List<AccessControlManager> mgrs = Lists.transform(configurations, authorizationConfiguration -> authorizationConfiguration.getAccessControlManager(root, namePathMapper));
- return new CompositeAccessControlManager(root, namePathMapper, getSecurityProvider(), mgrs);
-
+ return new CompositeAccessControlManager(root, namePathMapper, getSecurityProvider(), mgrs, aggregationFilter);
}
}
@@ -172,7 +178,11 @@ public class CompositeAuthorizationConfi
for (AuthorizationConfiguration conf : configurations) {
PermissionProvider pProvider = conf.getPermissionProvider(root, workspaceName, principals);
if (pProvider instanceof AggregatedPermissionProvider) {
- aggrPermissionProviders.add((AggregatedPermissionProvider) pProvider);
+ AggregatedPermissionProvider aggrProvider = (AggregatedPermissionProvider) pProvider;
+ aggrPermissionProviders.add(aggrProvider);
+ if (aggregationFilter.stop(aggrProvider, principals)) {
+ break;
+ }
} else {
log.debug("Ignoring permission provider of '{}': Not an AggregatedPermissionProvider", conf.getClass().getName());
}
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=1860721&r1=1860720&r2=1860721&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 Thu Jun 6 16:01:14 2019
@@ -17,15 +17,18 @@
package org.apache.jackrabbit.oak.security.internal;
import java.io.Closeable;
+import java.security.Principal;
import java.util.Collection;
import java.util.Collections;
import java.util.Dictionary;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;
+import java.util.Set;
import java.util.SortedMap;
import java.util.TreeMap;
+import org.apache.jackrabbit.api.security.JackrabbitAccessControlManager;
import org.apache.jackrabbit.oak.commons.PropertiesUtil;
import org.apache.jackrabbit.oak.osgi.OsgiWhiteboard;
import org.apache.jackrabbit.oak.plugins.tree.RootProvider;
@@ -49,6 +52,8 @@ import org.apache.jackrabbit.oak.spi.sec
import org.apache.jackrabbit.oak.spi.security.authentication.token.TokenConfiguration;
import org.apache.jackrabbit.oak.spi.security.authorization.AuthorizationConfiguration;
import org.apache.jackrabbit.oak.spi.security.authorization.accesscontrol.AccessControlConstants;
+import org.apache.jackrabbit.oak.spi.security.authorization.permission.AggregatedPermissionProvider;
+import org.apache.jackrabbit.oak.spi.security.authorization.permission.AggregationFilter;
import org.apache.jackrabbit.oak.spi.security.authorization.restriction.RestrictionProvider;
import org.apache.jackrabbit.oak.spi.security.principal.CompositePrincipalConfiguration;
import org.apache.jackrabbit.oak.spi.security.principal.PrincipalConfiguration;
@@ -62,6 +67,7 @@ import org.apache.jackrabbit.oak.spi.whi
import org.apache.jackrabbit.oak.spi.whiteboard.Whiteboard;
import org.apache.jackrabbit.oak.stats.StatisticsProvider;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
import org.osgi.framework.BundleContext;
import org.osgi.framework.Constants;
import org.osgi.framework.ServiceReference;
@@ -82,6 +88,8 @@ import org.slf4j.LoggerFactory;
import com.google.common.io.Closer;
+import javax.jcr.security.AccessControlManager;
+
import static com.google.common.collect.Lists.newArrayList;
import static org.apache.jackrabbit.oak.spi.security.RegistrationConstants.OAK_SECURITY_NAME;
import static org.apache.jackrabbit.oak.commons.IOUtils.closeQuietly;
@@ -156,6 +164,7 @@ public class SecurityProviderRegistratio
private final SortedMap<ServiceReference, AuthorizableActionProvider> authorizableActionProviders = Collections.synchronizedSortedMap(new TreeMap<>());
private final SortedMap<ServiceReference, RestrictionProvider> restrictionProviders = Collections.synchronizedSortedMap(new TreeMap<>());
private final SortedMap<ServiceReference, UserAuthenticationFactory> userAuthenticationFactories = Collections.synchronizedSortedMap(new TreeMap<>());
+ private final SortedMap<ServiceReference, AggregationFilter> aggregationFilters = Collections.synchronizedSortedMap(new TreeMap<>());
private RootProvider rootProvider;
private TreeProvider treeProvider;
@@ -424,6 +433,26 @@ public class SecurityProviderRegistratio
maybeUnregister();
}
+ @Reference(
+ name = "aggregationFilters", service = AggregationFilter.class,
+ cardinality = ReferenceCardinality.MULTIPLE,
+ policy = ReferencePolicy.DYNAMIC)
+ public void bindAggregationFilter(@NotNull ServiceReference serviceReference, @NotNull AggregationFilter aggregationFilter) {
+ synchronized (this) {
+ aggregationFilters.put(serviceReference, aggregationFilter);
+ addCandidate(serviceReference);
+ }
+ maybeRegister();
+ }
+
+ public void unbindAggregationFilter(@NotNull ServiceReference serviceReference, @NotNull AggregationFilter aggregationFilter) {
+ synchronized (this) {
+ aggregationFilters.remove(serviceReference);
+ removeCandidate(serviceReference);
+ }
+ maybeUnregister();
+ }
+
private void maybeRegister() {
BundleContext context;
@@ -557,6 +586,7 @@ public class SecurityProviderRegistratio
ConfigurationParameters authorizationParams = ConfigurationParameters
.of(AccessControlConstants.PARAM_RESTRICTION_PROVIDER, createWhiteboardRestrictionProvider());
+ authorizationConfiguration.withAggregationFilter(createAggregationFilter());
return SecurityProviderBuilder.newBuilder().withRootProvider(rootProvider).withTreeProvider(treeProvider)
.with(authenticationConfiguration, EMPTY, privilegeConfiguration, EMPTY, userConfiguration, userParams,
@@ -621,6 +651,49 @@ public class SecurityProviderRegistratio
};
}
+ private AggregationFilter createAggregationFilter() {
+ List<AggregationFilter> filters;
+ synchronized (aggregationFilters) {
+ filters = newArrayList(aggregationFilters.values());
+ }
+ switch (filters.size()) {
+ case 0: return AggregationFilter.DEFAULT;
+ case 1: return filters.get(0);
+ default:
+ return new AggregationFilter() {
+ @Override
+ public boolean stop(@NotNull AggregatedPermissionProvider permissionProvider, @NotNull Set<Principal> principals) {
+ for (AggregationFilter f : filters) {
+ if (f.stop(permissionProvider, principals)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public boolean stop(@NotNull JackrabbitAccessControlManager accessControlManager, @NotNull Set<Principal> principals) {
+ for (AggregationFilter f : filters) {
+ if (f.stop(accessControlManager, principals)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public boolean stop(@NotNull AccessControlManager accessControlManager, @Nullable String absPath) {
+ for (AggregationFilter f : filters) {
+ if (f.stop(accessControlManager, absPath)) {
+ return true;
+ }
+ }
+ return false;
+ }
+ };
+ }
+ }
+
private void addCandidate(Map<String, Object> properties) {
String pidOrName = getServicePidOrComponentName(properties);
Modified: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/composite/CompositeAccessControlManagerTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/composite/CompositeAccessControlManagerTest.java?rev=1860721&r1=1860720&r2=1860721&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/composite/CompositeAccessControlManagerTest.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/composite/CompositeAccessControlManagerTest.java Thu Jun 6 16:01:14 2019
@@ -26,12 +26,13 @@ import org.apache.jackrabbit.api.securit
import org.apache.jackrabbit.commons.iterator.AccessControlPolicyIteratorAdapter;
import org.apache.jackrabbit.oak.AbstractSecurityTest;
import org.apache.jackrabbit.oak.api.Tree;
-import org.apache.jackrabbit.oak.commons.PathUtils;
import org.apache.jackrabbit.oak.namepath.NamePathMapper;
import org.apache.jackrabbit.oak.plugins.tree.TreeUtil;
import org.apache.jackrabbit.oak.spi.nodetype.NodeTypeConstants;
import org.apache.jackrabbit.oak.spi.security.authorization.accesscontrol.PolicyOwner;
+import org.apache.jackrabbit.oak.spi.security.authorization.permission.AggregationFilter;
import org.apache.jackrabbit.oak.spi.security.principal.EveryonePrincipal;
+import org.apache.jackrabbit.oak.spi.security.principal.PrincipalImpl;
import org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants;
import org.jetbrains.annotations.NotNull;
import org.junit.Test;
@@ -46,6 +47,7 @@ import java.security.Principal;
import java.util.Collections;
import java.util.Set;
+import static org.apache.jackrabbit.oak.commons.PathUtils.ROOT_PATH;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
@@ -74,7 +76,7 @@ public class CompositeAccessControlManag
acMgr = createComposite(getAccessControlManager(root), new TestAcMgr());
- Tree tree = root.getTree(PathUtils.ROOT_PATH);
+ Tree tree = root.getTree(ROOT_PATH);
TreeUtil.addChild(tree,"test", NodeTypeConstants.NT_OAK_UNSTRUCTURED);
root.commit();
@@ -93,7 +95,12 @@ public class CompositeAccessControlManag
@NotNull
private CompositeAccessControlManager createComposite(@NotNull AccessControlManager... acMgrs) {
- return new CompositeAccessControlManager(root, NamePathMapper.DEFAULT, getSecurityProvider(), ImmutableList.copyOf(acMgrs));
+ return createComposite(AggregationFilter.DEFAULT, acMgrs);
+ }
+
+ @NotNull
+ private CompositeAccessControlManager createComposite(@NotNull AggregationFilter aggregationFilter, @NotNull AccessControlManager... acMgrs) {
+ return new CompositeAccessControlManager(root, NamePathMapper.DEFAULT, getSecurityProvider(), ImmutableList.copyOf(acMgrs), aggregationFilter);
}
@Test
@@ -127,10 +134,10 @@ public class CompositeAccessControlManag
AccessControlManager mgr = when(mock(AccessControlManager.class).getApplicablePolicies(anyString())).thenReturn(new AccessControlPolicyIteratorAdapter(ImmutableSet.of(policy))).getMock();
CompositeAccessControlManager composite = createComposite(mgr);
- AccessControlPolicyIterator it = composite.getApplicablePolicies(PathUtils.ROOT_PATH);
+ AccessControlPolicyIterator it = composite.getApplicablePolicies(ROOT_PATH);
assertFalse(it.hasNext());
- verify(mgr, never()).getApplicablePolicies(PathUtils.ROOT_PATH);
+ verify(mgr, never()).getApplicablePolicies(ROOT_PATH);
}
@Test
@@ -218,9 +225,9 @@ public class CompositeAccessControlManag
try {
CompositeAccessControlManager composite = createComposite(mgr);
- composite.setPolicy(PathUtils.ROOT_PATH, policy);
+ composite.setPolicy(ROOT_PATH, policy);
} finally {
- verify(mgr, never()).setPolicy(PathUtils.ROOT_PATH, policy);
+ verify(mgr, never()).setPolicy(ROOT_PATH, policy);
}
}
@@ -233,10 +240,10 @@ public class CompositeAccessControlManag
try {
CompositeAccessControlManager composite = createComposite(mgr);
- composite.setPolicy(PathUtils.ROOT_PATH, policy);
+ composite.setPolicy(ROOT_PATH, policy);
} finally {
- verify(mgr, never()).setPolicy(PathUtils.ROOT_PATH, policy);
- verify(((PolicyOwner) mgr), times(1)).defines(PathUtils.ROOT_PATH, policy);
+ verify(mgr, never()).setPolicy(ROOT_PATH, policy);
+ verify(((PolicyOwner) mgr), times(1)).defines(ROOT_PATH, policy);
}
}
@@ -267,9 +274,9 @@ public class CompositeAccessControlManag
try {
CompositeAccessControlManager composite = createComposite(mgr);
- composite.removePolicy(PathUtils.ROOT_PATH, policy);
+ composite.removePolicy(ROOT_PATH, policy);
} finally {
- verify(mgr, never()).removePolicy(PathUtils.ROOT_PATH, policy);
+ verify(mgr, never()).removePolicy(ROOT_PATH, policy);
}
}
@@ -282,10 +289,10 @@ public class CompositeAccessControlManag
try {
CompositeAccessControlManager composite = createComposite(mgr);
- composite.removePolicy(PathUtils.ROOT_PATH, policy);
+ composite.removePolicy(ROOT_PATH, policy);
} finally {
- verify(mgr, never()).removePolicy(PathUtils.ROOT_PATH, policy);
- verify(((PolicyOwner) mgr), times(1)).defines(PathUtils.ROOT_PATH, policy);
+ verify(mgr, never()).removePolicy(ROOT_PATH, policy);
+ verify(((PolicyOwner) mgr), times(1)).defines(ROOT_PATH, policy);
}
}
@@ -384,6 +391,78 @@ public class CompositeAccessControlManag
verify(mgr, times(1)).getEffectivePolicies(principalSet);
}
+ @Test
+ public void testAggregationFilterByPath() throws Exception {
+ String matchingPath = TEST_PATH;
+
+ JackrabbitAccessControlManager acMgr1 = mock(JackrabbitAccessControlManager.class, withSettings().extraInterfaces(PolicyOwner.class));
+ JackrabbitAccessControlManager acMgr2 = mock(JackrabbitAccessControlManager.class, withSettings().extraInterfaces(PolicyOwner.class));
+ for (JackrabbitAccessControlManager acMgr : new JackrabbitAccessControlManager[] {acMgr1, acMgr2}) {
+ when(acMgr.getApplicablePolicies(anyString())).thenReturn(AccessControlPolicyIteratorAdapter.EMPTY);
+ when(acMgr.getPolicies(anyString())).thenReturn(new AccessControlPolicy[0]);
+ when(acMgr.getEffectivePolicies(anyString())).thenReturn(new AccessControlPolicy[0]);
+ }
+
+ AggregationFilter aggregationFilter = mock(AggregationFilter.class);
+ when(aggregationFilter.stop(acMgr1, matchingPath)).thenReturn(true);
+
+ CompositeAccessControlManager composite = createComposite(aggregationFilter, acMgr1, acMgr2);
+ composite.getApplicablePolicies(TEST_PATH); // must not call AggregationFilter
+ composite.getPolicies(TEST_PATH); // must not call AggregationFilter
+ composite.getEffectivePolicies(TEST_PATH); // must call AggregationFilter
+
+ verify(aggregationFilter, times(1)).stop(acMgr1, TEST_PATH);
+ verify(aggregationFilter, never()).stop(acMgr2, TEST_PATH);
+
+ verify(acMgr1, times(1)).getEffectivePolicies(TEST_PATH);
+ verify(acMgr2, never()).getEffectivePolicies(TEST_PATH);
+
+ composite.getEffectivePolicies(ROOT_PATH); // must call AggregationFilter but not trigger stop
+
+ verify(aggregationFilter, times(1)).stop(acMgr1, ROOT_PATH);
+ verify(aggregationFilter, times(1)).stop(acMgr2, ROOT_PATH);
+
+ verify(acMgr1, times(1)).getEffectivePolicies(ROOT_PATH);
+ verify(acMgr2, times(1)).getEffectivePolicies(ROOT_PATH);
+ }
+
+ @Test
+ public void testAggregationFilterByPrincipals() throws Exception {
+ Principal principal = new PrincipalImpl("matchingPrincipal");
+ Set<Principal> matchingSet = ImmutableSet.of(principal);
+ Set<Principal> notMatching = ImmutableSet.of(EveryonePrincipal.getInstance());
+
+ JackrabbitAccessControlManager acMgr1 = mock(JackrabbitAccessControlManager.class, withSettings().extraInterfaces(PolicyOwner.class));
+ JackrabbitAccessControlManager acMgr2 = mock(JackrabbitAccessControlManager.class, withSettings().extraInterfaces(PolicyOwner.class));
+ for (JackrabbitAccessControlManager acMgr : new JackrabbitAccessControlManager[] {acMgr1, acMgr2}) {
+ when(acMgr.getApplicablePolicies(any(Principal.class))).thenReturn(new JackrabbitAccessControlPolicy[0]);
+ when(acMgr.getPolicies(any(Principal.class))).thenReturn(new JackrabbitAccessControlPolicy[0]);
+ when(acMgr.getEffectivePolicies(any(Set.class))).thenReturn(new JackrabbitAccessControlPolicy[0]);
+ }
+
+ AggregationFilter aggregationFilter = mock(AggregationFilter.class);
+ when(aggregationFilter.stop(acMgr1, matchingSet)).thenReturn(true);
+
+ CompositeAccessControlManager composite = createComposite(aggregationFilter, acMgr1, acMgr2);
+ composite.getApplicablePolicies(principal); // must not call AggregationFilter
+ composite.getPolicies(principal); // must not call AggregationFilter
+ composite.getEffectivePolicies(matchingSet); // must call AggregationFilter
+
+ verify(aggregationFilter, times(1)).stop(acMgr1, matchingSet);
+ verify(aggregationFilter, never()).stop(acMgr2, matchingSet);
+
+ verify(acMgr1, times(1)).getEffectivePolicies(matchingSet);
+ verify(acMgr2, never()).getEffectivePolicies(matchingSet);
+
+ composite.getEffectivePolicies(notMatching); // must call AggregationFilter but not trigger stop
+
+ verify(aggregationFilter, times(1)).stop(acMgr1, notMatching);
+ verify(aggregationFilter, times(1)).stop(acMgr2, notMatching);
+
+ verify(acMgr1, times(1)).getEffectivePolicies(notMatching);
+ verify(acMgr2, times(1)).getEffectivePolicies(notMatching);
+ }
+
private final static class TestAcMgr implements AccessControlManager, PolicyOwner {
private boolean hasPolicy = false;
Modified: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/composite/CompositeAuthorizationConfigurationTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/composite/CompositeAuthorizationConfigurationTest.java?rev=1860721&r1=1860720&r2=1860721&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/composite/CompositeAuthorizationConfigurationTest.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/composite/CompositeAuthorizationConfigurationTest.java Thu Jun 6 16:01:14 2019
@@ -16,31 +16,42 @@
*/
package org.apache.jackrabbit.oak.security.authorization.composite;
-import java.security.Principal;
-import java.util.Collections;
-
-import javax.jcr.RepositoryException;
-import javax.jcr.security.AccessControlManager;
-
+import com.google.common.collect.ImmutableSet;
import org.apache.jackrabbit.oak.AbstractSecurityTest;
+import org.apache.jackrabbit.oak.api.Root;
import org.apache.jackrabbit.oak.namepath.NamePathMapper;
import org.apache.jackrabbit.oak.security.authorization.AuthorizationConfigurationImpl;
import org.apache.jackrabbit.oak.spi.security.ConfigurationParameters;
+import org.apache.jackrabbit.oak.spi.security.Context;
import org.apache.jackrabbit.oak.spi.security.authorization.AuthorizationConfiguration;
import org.apache.jackrabbit.oak.spi.security.authorization.OpenAuthorizationConfiguration;
+import org.apache.jackrabbit.oak.spi.security.authorization.permission.AggregatedPermissionProvider;
+import org.apache.jackrabbit.oak.spi.security.authorization.permission.AggregationFilter;
import org.apache.jackrabbit.oak.spi.security.authorization.permission.EmptyPermissionProvider;
import org.apache.jackrabbit.oak.spi.security.authorization.permission.PermissionProvider;
import org.apache.jackrabbit.oak.spi.security.authorization.restriction.CompositeRestrictionProvider;
import org.apache.jackrabbit.oak.spi.security.authorization.restriction.RestrictionProvider;
+import org.apache.jackrabbit.oak.spi.security.principal.EveryonePrincipal;
import org.jetbrains.annotations.NotNull;
import org.junit.Test;
-import org.mockito.Mockito;
+
+import javax.jcr.RepositoryException;
+import javax.jcr.security.AccessControlManager;
+import java.security.Principal;
+import java.util.Collections;
+import java.util.Set;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotSame;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+import static org.mockito.Mockito.withSettings;
public class CompositeAuthorizationConfigurationTest extends AbstractSecurityTest {
@@ -146,8 +157,8 @@ public class CompositeAuthorizationConfi
public void testMultipleRestrictionProvider() {
// 2 authorization configuration with different RestrictionProvider
AuthorizationConfiguration ac = createAuthorizationConfigurationImpl();
- AuthorizationConfiguration ac2 = Mockito.mock(AuthorizationConfiguration.class);
- when(ac2.getRestrictionProvider()).thenReturn(Mockito.mock(RestrictionProvider.class));
+ AuthorizationConfiguration ac2 = mock(AuthorizationConfiguration.class);
+ when(ac2.getRestrictionProvider()).thenReturn(mock(RestrictionProvider.class));
when(ac2.getParameters()).thenReturn(ConfigurationParameters.EMPTY);
CompositeAuthorizationConfiguration cc = getCompositeConfiguration(ac, ac2);
@@ -160,7 +171,7 @@ public class CompositeAuthorizationConfi
public void testRedundantRestrictionProvider() {
// 2 authorization configuration sharing the same RestrictionProvider
AuthorizationConfiguration ac = createAuthorizationConfigurationImpl();
- AuthorizationConfiguration ac2 = Mockito.mock(AuthorizationConfiguration.class);
+ AuthorizationConfiguration ac2 = mock(AuthorizationConfiguration.class);
when(ac2.getRestrictionProvider()).thenReturn(ac.getRestrictionProvider());
when(ac2.getParameters()).thenReturn(ConfigurationParameters.EMPTY);
@@ -204,4 +215,47 @@ public class CompositeAuthorizationConfi
assertFalse(rp instanceof CompositeRestrictionProvider);
assertSame(RestrictionProvider.EMPTY, rp);
}
+
+ @Test
+ public void testDefaultEvaluationFilter() {
+ PermissionProvider pp = mock(PermissionProvider.class, withSettings().extraInterfaces(AggregatedPermissionProvider.class));
+ AuthorizationConfiguration ac1 = mock(AuthorizationConfiguration.class);
+ AuthorizationConfiguration ac2 = mock(AuthorizationConfiguration.class);
+ for (AuthorizationConfiguration ac : new AuthorizationConfiguration[] {ac1, ac2}) {
+ when(ac.getPermissionProvider(any(Root.class), anyString(), any(Set.class))).thenReturn(pp);
+ when(ac.getParameters()).thenReturn(ConfigurationParameters.EMPTY);
+ when(ac.getContext()).thenReturn(Context.DEFAULT);
+ }
+ CompositeAuthorizationConfiguration cc = getCompositeConfiguration(ac1, ac2);
+ PermissionProvider permissionProvider = cc.getPermissionProvider(root, adminSession.getWorkspaceName(), ImmutableSet.of(EveryonePrincipal.getInstance()));
+ permissionProvider.refresh();
+
+ verify(pp, times(2)).refresh();
+ }
+
+ @Test
+ public void testAbortingEvaluationFilter() {
+ Set<Principal> principalSet = ImmutableSet.of(EveryonePrincipal.getInstance());
+ AggregatedPermissionProvider pp = mock(AggregatedPermissionProvider.class);
+ AggregationFilter filter = when(mock(AggregationFilter.class).stop(pp, principalSet)).thenReturn(true).getMock();
+
+ AuthorizationConfiguration ac1 = mock(AuthorizationConfiguration.class);
+ AuthorizationConfiguration ac2 = mock(AuthorizationConfiguration.class);
+ for (AuthorizationConfiguration ac : new AuthorizationConfiguration[] {ac1, ac2}) {
+ when(ac.getPermissionProvider(any(Root.class), anyString(), any(Set.class))).thenReturn(pp);
+ when(ac.getParameters()).thenReturn(ConfigurationParameters.EMPTY);
+ when(ac.getContext()).thenReturn(Context.DEFAULT);
+ }
+ CompositeAuthorizationConfiguration cc = getCompositeConfiguration(ac1, ac2);
+ cc.withAggregationFilter(filter);
+
+ PermissionProvider permissionProvider = cc.getPermissionProvider(root, adminSession.getWorkspaceName(), principalSet);
+ permissionProvider.refresh();
+
+ Set<Principal> nonMatchingSet = adminSession.getAuthInfo().getPrincipals();
+ permissionProvider = cc.getPermissionProvider(root, adminSession.getWorkspaceName(), nonMatchingSet);
+ permissionProvider.refresh();
+
+ verify(pp, times(3)).refresh();
+ }
}
Modified: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/internal/SecurityProviderRegistrationTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/internal/SecurityProviderRegistrationTest.java?rev=1860721&r1=1860720&r2=1860721&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/internal/SecurityProviderRegistrationTest.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/internal/SecurityProviderRegistrationTest.java Thu Jun 6 16:01:14 2019
@@ -19,9 +19,14 @@ package org.apache.jackrabbit.oak.securi
import com.google.common.base.Predicates;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
+import org.apache.jackrabbit.api.security.JackrabbitAccessControlManager;
import org.apache.jackrabbit.oak.AbstractSecurityTest;
+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.namepath.NamePathMapper;
import org.apache.jackrabbit.oak.plugins.memory.PropertyStates;
import org.apache.jackrabbit.oak.plugins.tree.RootProvider;
import org.apache.jackrabbit.oak.plugins.tree.TreeLocation;
@@ -48,8 +53,12 @@ import org.apache.jackrabbit.oak.spi.sec
import org.apache.jackrabbit.oak.spi.security.authentication.token.CompositeTokenConfiguration;
import org.apache.jackrabbit.oak.spi.security.authentication.token.TokenConfiguration;
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.AggregationFilter;
+import org.apache.jackrabbit.oak.spi.security.authorization.permission.PermissionProvider;
import org.apache.jackrabbit.oak.spi.security.authorization.restriction.RestrictionProvider;
import org.apache.jackrabbit.oak.spi.security.principal.CompositePrincipalConfiguration;
+import org.apache.jackrabbit.oak.spi.security.principal.EveryonePrincipal;
import org.apache.jackrabbit.oak.spi.security.principal.PrincipalConfiguration;
import org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConfiguration;
import org.apache.jackrabbit.oak.spi.security.user.AuthorizableNodeName;
@@ -66,12 +75,14 @@ import org.osgi.framework.Constants;
import org.osgi.framework.ServiceReference;
import org.osgi.framework.ServiceRegistration;
+import javax.jcr.security.AccessControlPolicy;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.util.Collection;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;
+import java.util.Set;
import java.util.SortedMap;
import static org.apache.jackrabbit.oak.spi.security.RegistrationConstants.OAK_SECURITY_NAME;
@@ -82,12 +93,15 @@ import static org.junit.Assert.assertNul
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.mockito.Mockito.withSettings;
import static org.osgi.framework.Constants.SERVICE_PID;
+import static org.osgi.framework.Constants.SERVICE_RANKING;
public class SecurityProviderRegistrationTest extends AbstractSecurityTest {
@@ -850,4 +864,181 @@ public class SecurityProviderRegistratio
registration.unbindTreeProvider(tp);
assertNull(f.get(registration));
}
+
+ @Test
+ public void testBindAggregationFilter() throws Exception {
+ registration.activate(context.bundleContext(), configWithRequiredServiceIds("filterId", "a1", "a2"));
+
+ AggregationFilter filter = mock(AggregationFilter.class, withSettings().defaultAnswer(invocationOnMock -> Boolean.TRUE));
+ ServiceRegistration sr = context.bundleContext().registerService(AggregationFilter.class.getName(), filter, new Hashtable(ImmutableMap.of(SERVICE_PID, "filterId")));
+ registration.bindAggregationFilter(sr.getReference(), filter);
+
+ AggregatedPermissionProvider pp = mock(AggregatedPermissionProvider.class);
+ JackrabbitAccessControlManager acMgr = mock(JackrabbitAccessControlManager.class);
+ AccessControlPolicy policy = mock(AccessControlPolicy.class);
+ when(acMgr.getEffectivePolicies(anyString())).thenReturn(new AccessControlPolicy[] {policy});
+ when(acMgr.getEffectivePolicies(any(Set.class))).thenReturn(new AccessControlPolicy[] {policy});
+
+ AuthorizationConfiguration ac1 = mock(AuthorizationConfiguration.class);
+ AuthorizationConfiguration ac2 = mock(AuthorizationConfiguration.class);
+ for (AuthorizationConfiguration ac : new AuthorizationConfiguration[]{ac1, ac2}) {
+ when(ac.getPermissionProvider(any(Root.class), anyString(), any(Set.class))).thenReturn(pp);
+ when(ac.getAccessControlManager(any(Root.class), any(NamePathMapper.class))).thenReturn(acMgr);
+ when(ac.getParameters()).thenReturn(ConfigurationParameters.EMPTY);
+ when(ac.getContext()).thenReturn(Context.DEFAULT);
+ }
+
+ registration.bindAuthorizationConfiguration(ac1, new Hashtable(ImmutableMap.of(SERVICE_PID, "a1")));
+ registration.bindAuthorizationConfiguration(ac2, new Hashtable(ImmutableMap.of(SERVICE_PID, "a2")));
+
+ SecurityProvider service = context.getService(SecurityProvider.class);
+
+ AuthorizationConfiguration ac = service.getConfiguration(AuthorizationConfiguration.class);
+ assertTrue(ac instanceof CompositeAuthorizationConfiguration);
+
+ PermissionProvider permissionProvider = ac.getPermissionProvider(root, adminSession.getWorkspaceName(), ImmutableSet.of());
+ assertSame(pp, permissionProvider);
+ verify(filter, times(1)).stop(pp, ImmutableSet.of());
+
+ JackrabbitAccessControlManager am = (JackrabbitAccessControlManager) ac.getAccessControlManager(root, getNamePathMapper());
+
+ assertEquals(1, am.getEffectivePolicies(PathUtils.ROOT_PATH).length);
+ verify(filter, times(1)).stop(acMgr, PathUtils.ROOT_PATH);
+
+ assertEquals(1, am.getEffectivePolicies(ImmutableSet.of(EveryonePrincipal.getInstance())).length);
+ verify(filter, times(1)).stop(acMgr, ImmutableSet.of(EveryonePrincipal.getInstance()));
+ }
+
+ @Test
+ public void testUnbindAggregationFilter() {
+ registration.activate(context.bundleContext(), configWithRequiredServiceIds("a1", "a2", "f1"));
+
+ AggregationFilter filter = mock(AggregationFilter.class, withSettings().defaultAnswer(invocationOnMock -> Boolean.TRUE));
+ ServiceRegistration sr = context.bundleContext().registerService(AggregationFilter.class.getName(), filter, new Hashtable(ImmutableMap.of(SERVICE_PID, "f1")));
+ registration.bindAggregationFilter(sr.getReference(), filter);
+
+ AggregatedPermissionProvider pp = mock(AggregatedPermissionProvider.class);
+ AuthorizationConfiguration ac1 = mock(AuthorizationConfiguration.class);
+ AuthorizationConfiguration ac2 = mock(AuthorizationConfiguration.class);
+ for (AuthorizationConfiguration ac : new AuthorizationConfiguration[]{ac1, ac2}) {
+ when(ac.getPermissionProvider(any(Root.class), anyString(), any(Set.class))).thenReturn(pp);
+ when(ac.getParameters()).thenReturn(ConfigurationParameters.EMPTY);
+ when(ac.getContext()).thenReturn(Context.DEFAULT);
+ }
+
+ registration.bindAuthorizationConfiguration(ac1, new Hashtable(ImmutableMap.of(SERVICE_PID, "a1")));
+ registration.bindAuthorizationConfiguration(ac2, new Hashtable(ImmutableMap.of(SERVICE_PID, "a2")));
+
+ AuthorizationConfiguration ac = context.getService(SecurityProvider.class).getConfiguration(AuthorizationConfiguration.class);
+ assertTrue(ac instanceof CompositeAuthorizationConfiguration);
+
+ PermissionProvider permissionProvider = ac.getPermissionProvider(root, adminSession.getWorkspaceName(), ImmutableSet.of());
+ assertSame(pp, permissionProvider);
+ verify(filter, times(1)).stop(pp, ImmutableSet.of());
+
+ registration.unbindAggregationFilter(sr.getReference(), filter);
+ assertNull(context.getService(SecurityProvider.class));
+
+ registration.modified(configWithRequiredServiceIds("a1", "a2"));
+
+ context.getService(SecurityProvider.class).getConfiguration(AuthorizationConfiguration.class).getPermissionProvider(root, adminSession.getWorkspaceName(), ImmutableSet.of());
+ // since unbind was called on filter -> no additional calls
+ verify(filter, times(1)).stop(pp, ImmutableSet.of());
+ }
+
+ @Test
+ public void testMultipleEvaluationFilterFalse() throws Exception {
+ registration.activate(context.bundleContext(), configWithRequiredServiceIds("f1", "f2", "ac1", "ac2"));
+
+ AggregationFilter filter1 = mock(AggregationFilter.class, withSettings().defaultAnswer(invocationOnMock -> Boolean.FALSE));
+ ServiceRegistration sr1 = context.bundleContext().registerService(AggregationFilter.class.getName(), filter1, new Hashtable(ImmutableMap.of(SERVICE_PID, "f1", SERVICE_RANKING, 100)));
+ registration.bindAggregationFilter(sr1.getReference(), filter1);
+
+ AggregationFilter filter2 = mock(AggregationFilter.class, withSettings().defaultAnswer(invocationOnMock -> Boolean.FALSE));
+ ServiceRegistration sr2 = context.bundleContext().registerService(AggregationFilter.class.getName(), filter2, new Hashtable(ImmutableMap.of(SERVICE_PID, "f2", SERVICE_RANKING, 200)));
+ registration.bindAggregationFilter(sr2.getReference(), filter2);
+
+ AggregatedPermissionProvider pp = mock(AggregatedPermissionProvider.class);
+ JackrabbitAccessControlManager acMgr = mock(JackrabbitAccessControlManager.class);
+ AccessControlPolicy policy = mock(AccessControlPolicy.class);
+ when(acMgr.getEffectivePolicies(anyString())).thenReturn(new AccessControlPolicy[] {policy});
+ when(acMgr.getEffectivePolicies(any(Set.class))).thenReturn(new AccessControlPolicy[] {policy});
+
+ AuthorizationConfiguration ac1 = mock(AuthorizationConfiguration.class);
+ AuthorizationConfiguration ac2 = mock(AuthorizationConfiguration.class);
+ for (AuthorizationConfiguration ac : new AuthorizationConfiguration[]{ac1, ac2}) {
+ when(ac.getPermissionProvider(any(Root.class), anyString(), any(Set.class))).thenReturn(pp);
+ when(ac.getAccessControlManager(any(Root.class), any(NamePathMapper.class))).thenReturn(acMgr);
+ when(ac.getParameters()).thenReturn(ConfigurationParameters.EMPTY);
+ when(ac.getContext()).thenReturn(Context.DEFAULT);
+ }
+
+ registration.bindAuthorizationConfiguration(ac1, new Hashtable(ImmutableMap.of(SERVICE_PID, "ac1")));
+ registration.bindAuthorizationConfiguration(ac2, new Hashtable(ImmutableMap.of(SERVICE_PID, "ac2")));
+
+ AuthorizationConfiguration config = context.getService(SecurityProvider.class).getConfiguration(AuthorizationConfiguration.class);
+ PermissionProvider permissionProvider = config.getPermissionProvider(root, adminSession.getWorkspaceName(), ImmutableSet.of());
+
+ verify(filter1, times(2)).stop(pp, ImmutableSet.of());
+ verify(filter2, times(2)).stop(pp, ImmutableSet.of());
+
+
+ JackrabbitAccessControlManager am = (JackrabbitAccessControlManager) config.getAccessControlManager(root, getNamePathMapper());
+
+ assertEquals(2, am.getEffectivePolicies(PathUtils.ROOT_PATH).length);
+ verify(filter1, times(2)).stop(acMgr, PathUtils.ROOT_PATH);
+ verify(filter2, times(2)).stop(acMgr, PathUtils.ROOT_PATH);
+
+ assertEquals(2, am.getEffectivePolicies(ImmutableSet.of(EveryonePrincipal.getInstance())).length);
+ verify(filter1, times(2)).stop(acMgr, ImmutableSet.of(EveryonePrincipal.getInstance()));
+ verify(filter2, times(2)).stop(acMgr, ImmutableSet.of(EveryonePrincipal.getInstance()));
+ }
+
+ @Test
+ public void testMultipleEvaluationFilterTrue() throws Exception {
+ registration.activate(context.bundleContext(), configWithRequiredServiceIds("f1", "f2", "ac1", "ac2"));
+
+ AggregationFilter filter1 = mock(AggregationFilter.class, withSettings().defaultAnswer(invocationOnMock -> Boolean.TRUE));
+ ServiceRegistration sr1 = context.bundleContext().registerService(AggregationFilter.class.getName(), filter1, new Hashtable(ImmutableMap.of(SERVICE_PID, "f1", SERVICE_RANKING, 200)));
+ registration.bindAggregationFilter(sr1.getReference(), filter1);
+
+ AggregationFilter filter2 = mock(AggregationFilter.class, withSettings().defaultAnswer(invocationOnMock -> Boolean.TRUE));
+ ServiceRegistration sr2 = context.bundleContext().registerService(AggregationFilter.class.getName(), filter2, new Hashtable(ImmutableMap.of(SERVICE_PID, "f2", SERVICE_RANKING, 100)));
+ registration.bindAggregationFilter(sr2.getReference(), filter2);
+
+ AggregatedPermissionProvider pp = mock(AggregatedPermissionProvider.class);
+ JackrabbitAccessControlManager acMgr = mock(JackrabbitAccessControlManager.class);
+ AccessControlPolicy policy = mock(AccessControlPolicy.class);
+ when(acMgr.getEffectivePolicies(anyString())).thenReturn(new AccessControlPolicy[] {policy});
+ when(acMgr.getEffectivePolicies(any(Set.class))).thenReturn(new AccessControlPolicy[] {policy});
+
+ AuthorizationConfiguration ac1 = mock(AuthorizationConfiguration.class);
+ AuthorizationConfiguration ac2 = mock(AuthorizationConfiguration.class);
+ for (AuthorizationConfiguration ac : new AuthorizationConfiguration[]{ac1, ac2}) {
+ when(ac.getPermissionProvider(any(Root.class), anyString(), any(Set.class))).thenReturn(pp);
+ when(ac.getAccessControlManager(any(Root.class), any(NamePathMapper.class))).thenReturn(acMgr);
+ when(ac.getParameters()).thenReturn(ConfigurationParameters.EMPTY);
+ when(ac.getContext()).thenReturn(Context.DEFAULT);
+ }
+
+ registration.bindAuthorizationConfiguration(ac1, new Hashtable(ImmutableMap.of(SERVICE_PID, "ac1")));
+ registration.bindAuthorizationConfiguration(ac2, new Hashtable(ImmutableMap.of(SERVICE_PID, "ac2")));
+
+ AuthorizationConfiguration config = context.getService(SecurityProvider.class).getConfiguration(AuthorizationConfiguration.class);
+ PermissionProvider permissionProvider = config.getPermissionProvider(root, adminSession.getWorkspaceName(), ImmutableSet.of());
+
+ verify(filter1, never()).stop(pp, ImmutableSet.of());
+ verify(filter2, times(1)).stop(pp, ImmutableSet.of());
+
+ JackrabbitAccessControlManager am = (JackrabbitAccessControlManager) config.getAccessControlManager(root, getNamePathMapper());
+
+ assertEquals(1, am.getEffectivePolicies(PathUtils.ROOT_PATH).length);
+ verify(filter1, never()).stop(acMgr, PathUtils.ROOT_PATH);
+ verify(filter2, times(1)).stop(acMgr, PathUtils.ROOT_PATH);
+
+ assertEquals(1, am.getEffectivePolicies(ImmutableSet.of(EveryonePrincipal.getInstance())).length);
+ verify(filter1, never()).stop(acMgr, ImmutableSet.of(EveryonePrincipal.getInstance()));
+ verify(filter2, times(1)).stop(acMgr, ImmutableSet.of(EveryonePrincipal.getInstance()));
+
+ }
}
Added: jackrabbit/oak/trunk/oak-security-spi/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/permission/AggregationFilter.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-security-spi/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/permission/AggregationFilter.java?rev=1860721&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-security-spi/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/permission/AggregationFilter.java (added)
+++ jackrabbit/oak/trunk/oak-security-spi/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/permission/AggregationFilter.java Thu Jun 6 16:01:14 2019
@@ -0,0 +1,78 @@
+/*
+ * 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.permission;
+
+import org.apache.jackrabbit.api.security.JackrabbitAccessControlManager;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import javax.jcr.security.AccessControlManager;
+import java.security.Principal;
+import java.util.Set;
+
+public interface AggregationFilter {
+
+ /**
+ *
+ * @param permissionProvider
+ * @param principals
+ * @return {@code true} if aggregation of permission providers should be stopped after the given {@code permissionProvider}
+ * created for the given set of {@code principals}.
+ */
+ boolean stop(@NotNull AggregatedPermissionProvider permissionProvider, @NotNull Set<Principal> principals);
+
+ /**
+ *
+ * @param accessControlManager
+ * @param principals
+ * @return {@code true} if aggregation of effective policies for the specified principals should be stopped after
+ * the given {@code accessControlManager}.
+ * @see AccessControlManager#getEffectivePolicies(String)
+ */
+ boolean stop(@NotNull JackrabbitAccessControlManager accessControlManager, @NotNull Set<Principal> principals);
+
+ /**
+ *
+ * @param accessControlManager
+ * @param absPath
+ * @return {@code true} if aggregation of effective policies for the specified effective path should be stopped after
+ * the given {@code accessControlManager}.
+ * @see JackrabbitAccessControlManager#getEffectivePolicies(Set)
+ */
+ boolean stop(@NotNull AccessControlManager accessControlManager, @Nullable String absPath);
+
+ /**
+ * Default implementation of the {@code AggregationFilter} interface that handles all combinations of permission
+ * providers and principals and never aborts the evaluation.
+ */
+ AggregationFilter DEFAULT = new AggregationFilter() {
+ @Override
+ public boolean stop(@NotNull AggregatedPermissionProvider permissionProvider, @NotNull Set<Principal> principals) {
+ return false;
+ }
+
+ @Override
+ public boolean stop(@NotNull JackrabbitAccessControlManager accessControlManager, @NotNull Set<Principal> principals) {
+ return false;
+ }
+
+ @Override
+ public boolean stop(@NotNull AccessControlManager accessControlManager, @Nullable String absPath) {
+ return false;
+ }
+ };
+}
\ No newline at end of file
Propchange: jackrabbit/oak/trunk/oak-security-spi/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/permission/AggregationFilter.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: jackrabbit/oak/trunk/oak-security-spi/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/permission/package-info.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-security-spi/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/permission/package-info.java?rev=1860721&r1=1860720&r2=1860721&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-security-spi/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/permission/package-info.java (original)
+++ jackrabbit/oak/trunk/oak-security-spi/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/permission/package-info.java Thu Jun 6 16:01:14 2019
@@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-@Version("4.1.0")
+@Version("4.2.0")
package org.apache.jackrabbit.oak.spi.security.authorization.permission;
import org.osgi.annotation.versioning.Version;
Added: jackrabbit/oak/trunk/oak-security-spi/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/permission/AggregationFilterDefaultTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-security-spi/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/permission/AggregationFilterDefaultTest.java?rev=1860721&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-security-spi/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/permission/AggregationFilterDefaultTest.java (added)
+++ jackrabbit/oak/trunk/oak-security-spi/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/permission/AggregationFilterDefaultTest.java Thu Jun 6 16:01:14 2019
@@ -0,0 +1,46 @@
+/*
+ * 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.permission;
+
+import org.apache.jackrabbit.api.security.JackrabbitAccessControlManager;
+import org.apache.jackrabbit.oak.commons.PathUtils;
+import org.junit.Test;
+
+import javax.jcr.security.AccessControlManager;
+import java.util.Collections;
+
+import static org.junit.Assert.assertFalse;
+import static org.mockito.Mockito.mock;
+
+public class AggregationFilterDefaultTest {
+
+ @Test
+ public void testStopPermissionProvider() {
+ assertFalse(AggregationFilter.DEFAULT.stop(mock(AggregatedPermissionProvider.class), Collections.EMPTY_SET));
+ }
+
+ @Test
+ public void testStopEffectivePoliciesByPath() {
+ assertFalse(AggregationFilter.DEFAULT.stop(mock(AccessControlManager.class), null));
+ assertFalse(AggregationFilter.DEFAULT.stop(mock(AccessControlManager.class), PathUtils.ROOT_PATH));
+ }
+
+ @Test
+ public void testStopEffectivePoliciesByPrincipals() {
+ assertFalse(AggregationFilter.DEFAULT.stop(mock(JackrabbitAccessControlManager.class), Collections.EMPTY_SET));
+ }
+}
\ No newline at end of file
Propchange: jackrabbit/oak/trunk/oak-security-spi/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/permission/AggregationFilterDefaultTest.java
------------------------------------------------------------------------------
svn:eol-style = native