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/28 06:56:01 UTC
svn commit: r1800129 - in /jackrabbit/oak/trunk:
oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/
oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/composite/
oak-core/src/main/java/org/apache/jackrabbit/oa...
Author: stillalex
Date: Wed Jun 28 06:56:00 2017
New Revision: 1800129
URL: http://svn.apache.org/viewvc?rev=1800129&view=rev
Log:
OAK-3777 Multiplexing support in default PermissionStore implementation
Added:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/composite/MultiplexingPermissionProvider.java (with props)
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/composite/MultiplexingProviderTest.java (with props)
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/composite/MutiplexingProviderRandomTestIT.java (with props)
jackrabbit/oak/trunk/oak-doc/src/site/markdown/security/permission/multiplexing.md (with props)
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/AuthorizationConfigurationImpl.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/AuthorizationInitializer.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/permission/PermissionHook.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/accesscontrol/AccessControlConstants.java
jackrabbit/oak/trunk/oak-doc/src/site/markdown/security/permission.md
jackrabbit/oak/trunk/oak-doc/src/site/markdown/security/permission/default.md
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/AuthorizationConfigurationImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/AuthorizationConfigurationImpl.java?rev=1800129&r1=1800128&r2=1800129&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/AuthorizationConfigurationImpl.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/AuthorizationConfigurationImpl.java Wed Jun 28 06:56:00 2017
@@ -17,19 +17,20 @@
package org.apache.jackrabbit.oak.security.authorization;
import java.security.Principal;
-import java.util.Collections;
+import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
+
import javax.annotation.Nonnull;
import javax.jcr.security.AccessControlManager;
-import com.google.common.collect.ImmutableList;
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Properties;
import org.apache.felix.scr.annotations.Property;
import org.apache.felix.scr.annotations.PropertyOption;
+import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.Service;
import org.apache.jackrabbit.oak.api.Root;
import org.apache.jackrabbit.oak.namepath.NamePathMapper;
@@ -39,6 +40,7 @@ import org.apache.jackrabbit.oak.plugins
import org.apache.jackrabbit.oak.security.authorization.accesscontrol.AccessControlImporter;
import org.apache.jackrabbit.oak.security.authorization.accesscontrol.AccessControlManagerImpl;
import org.apache.jackrabbit.oak.security.authorization.accesscontrol.AccessControlValidatorProvider;
+import org.apache.jackrabbit.oak.security.authorization.composite.MultiplexingPermissionProvider;
import org.apache.jackrabbit.oak.security.authorization.permission.PermissionHook;
import org.apache.jackrabbit.oak.security.authorization.permission.PermissionProviderImpl;
import org.apache.jackrabbit.oak.security.authorization.permission.PermissionStoreValidatorProvider;
@@ -48,6 +50,9 @@ import org.apache.jackrabbit.oak.spi.com
import org.apache.jackrabbit.oak.spi.commit.MoveTracker;
import org.apache.jackrabbit.oak.spi.commit.ValidatorProvider;
import org.apache.jackrabbit.oak.spi.lifecycle.WorkspaceInitializer;
+import org.apache.jackrabbit.oak.spi.mount.Mount;
+import org.apache.jackrabbit.oak.spi.mount.MountInfoProvider;
+import org.apache.jackrabbit.oak.spi.mount.Mounts;
import org.apache.jackrabbit.oak.spi.security.CompositeConfiguration;
import org.apache.jackrabbit.oak.spi.security.ConfigurationBase;
import org.apache.jackrabbit.oak.spi.security.ConfigurationParameters;
@@ -56,6 +61,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.accesscontrol.AccessControlConstants;
+import org.apache.jackrabbit.oak.spi.security.authorization.permission.AggregatedPermissionProvider;
import org.apache.jackrabbit.oak.spi.security.authorization.permission.PermissionConstants;
import org.apache.jackrabbit.oak.spi.security.authorization.permission.PermissionProvider;
import org.apache.jackrabbit.oak.spi.security.authorization.restriction.RestrictionProvider;
@@ -63,6 +69,8 @@ import org.apache.jackrabbit.oak.spi.sec
import org.apache.jackrabbit.oak.spi.xml.ImportBehavior;
import org.apache.jackrabbit.oak.spi.xml.ProtectedItemImporter;
+import com.google.common.collect.ImmutableList;
+
/**
* Default implementation of the {@code AccessControlConfiguration}.
*/
@@ -104,6 +112,9 @@ import org.apache.jackrabbit.oak.spi.xml
})
public class AuthorizationConfigurationImpl extends ConfigurationBase implements AuthorizationConfiguration {
+ @Reference
+ private MountInfoProvider mountInfoProvider;
+
public AuthorizationConfigurationImpl() {
super();
}
@@ -116,6 +127,8 @@ public class AuthorizationConfigurationI
public AuthorizationConfigurationImpl(SecurityProvider securityProvider) {
super(securityProvider, securityProvider.getParameters(NAME));
+ mountInfoProvider = getParameters().getConfigValue(AccessControlConstants.PARAM_MOUNT_PROVIDER,
+ Mounts.defaultMountInfoProvider(), MountInfoProvider.class);
}
//----------------------------------------------< SecurityConfiguration >---
@@ -134,7 +147,7 @@ public class AuthorizationConfigurationI
@Nonnull
@Override
public WorkspaceInitializer getWorkspaceInitializer() {
- return new AuthorizationInitializer();
+ return new AuthorizationInitializer(mountInfoProvider);
}
@Nonnull
@@ -142,7 +155,7 @@ public class AuthorizationConfigurationI
public List<? extends CommitHook> getCommitHooks(@Nonnull String workspaceName) {
return ImmutableList.of(
new VersionablePathHook(workspaceName),
- new PermissionHook(workspaceName, getRestrictionProvider()));
+ new PermissionHook(workspaceName, getRestrictionProvider(), mountInfoProvider));
}
@Nonnull
@@ -157,7 +170,7 @@ public class AuthorizationConfigurationI
@Nonnull
@Override
public List<ProtectedItemImporter> getProtectedItemImporters() {
- return Collections.<ProtectedItemImporter>singletonList(new AccessControlImporter());
+ return ImmutableList.of(new AccessControlImporter());
}
//-----------------------------------------< AccessControlConfiguration >---
@@ -180,8 +193,22 @@ public class AuthorizationConfigurationI
@Nonnull
@Override
- public PermissionProvider getPermissionProvider(@Nonnull Root root, @Nonnull String workspaceName, @Nonnull Set<Principal> principals) {
+ public PermissionProvider getPermissionProvider(@Nonnull Root root, @Nonnull String workspaceName,
+ @Nonnull Set<Principal> principals) {
Context ctx = getSecurityProvider().getConfiguration(AuthorizationConfiguration.class).getContext();
- return new PermissionProviderImpl(root, workspaceName, principals, getRestrictionProvider(), getParameters(), ctx);
+
+ if (mountInfoProvider.hasNonDefaultMounts()) {
+ List<AggregatedPermissionProvider> agg = new ArrayList<>();
+ agg.add(new PermissionProviderImpl(root, workspaceName, principals, getRestrictionProvider(),
+ getParameters(), ctx));
+ for (Mount m : mountInfoProvider.getNonDefaultMounts()) {
+ String ws = MultiplexingPermissionProvider.getWorkspaceName(m, workspaceName);
+ agg.add(new PermissionProviderImpl(root, ws, principals, getRestrictionProvider(), getParameters(),
+ ctx));
+ }
+ return new MultiplexingPermissionProvider(root, agg, ctx);
+ }
+ return new PermissionProviderImpl(root, workspaceName, principals, getRestrictionProvider(), getParameters(),
+ ctx);
}
}
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/AuthorizationInitializer.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/AuthorizationInitializer.java?rev=1800129&r1=1800128&r2=1800129&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/AuthorizationInitializer.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/AuthorizationInitializer.java Wed Jun 28 06:56:00 2017
@@ -20,9 +20,12 @@ import com.google.common.collect.Immutab
import org.apache.jackrabbit.JcrConstants;
import org.apache.jackrabbit.oak.api.Type;
import org.apache.jackrabbit.oak.plugins.index.IndexUtils;
-import org.apache.jackrabbit.oak.spi.security.authorization.permission.PermissionConstants;
+import org.apache.jackrabbit.oak.security.authorization.composite.MultiplexingPermissionProvider;
import org.apache.jackrabbit.oak.spi.lifecycle.WorkspaceInitializer;
+import org.apache.jackrabbit.oak.spi.mount.Mount;
+import org.apache.jackrabbit.oak.spi.mount.MountInfoProvider;
import org.apache.jackrabbit.oak.spi.security.authorization.accesscontrol.AccessControlConstants;
+import org.apache.jackrabbit.oak.spi.security.authorization.permission.PermissionConstants;
import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
import static org.apache.jackrabbit.JcrConstants.JCR_PRIMARYTYPE;
@@ -40,6 +43,12 @@ import static org.apache.jackrabbit.JcrC
*/
class AuthorizationInitializer implements WorkspaceInitializer, AccessControlConstants, PermissionConstants {
+ private final MountInfoProvider mountInfoProvider;
+
+ public AuthorizationInitializer(MountInfoProvider mountInfoProvider) {
+ this.mountInfoProvider = mountInfoProvider;
+ }
+
@Override
public void initialize(NodeBuilder builder, String workspaceName) {
// property index for rep:principalName stored in ACEs
@@ -62,6 +71,12 @@ class AuthorizationInitializer implement
if (!permissionStore.hasChildNode(workspaceName)) {
permissionStore.child(workspaceName).setProperty(JcrConstants.JCR_PRIMARYTYPE, NT_REP_PERMISSION_STORE, Type.NAME);
}
+ for (Mount m : mountInfoProvider.getNonDefaultMounts()) {
+ String ws = MultiplexingPermissionProvider.getWorkspaceName(m, workspaceName);
+ if (!permissionStore.hasChildNode(ws)) {
+ permissionStore.child(ws).setProperty(JcrConstants.JCR_PRIMARYTYPE, NT_REP_PERMISSION_STORE, Type.NAME);
+ }
+ }
}
}
Added: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/composite/MultiplexingPermissionProvider.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/composite/MultiplexingPermissionProvider.java?rev=1800129&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/composite/MultiplexingPermissionProvider.java (added)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/composite/MultiplexingPermissionProvider.java Wed Jun 28 06:56:00 2017
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.oak.security.authorization.composite;
+
+import java.util.List;
+
+import org.apache.jackrabbit.oak.api.Root;
+import org.apache.jackrabbit.oak.security.authorization.composite.CompositeAuthorizationConfiguration.CompositionType;
+import org.apache.jackrabbit.oak.spi.mount.Mount;
+import org.apache.jackrabbit.oak.spi.security.Context;
+import org.apache.jackrabbit.oak.spi.security.authorization.permission.AggregatedPermissionProvider;
+
+public class MultiplexingPermissionProvider extends CompositePermissionProvider {
+
+ public MultiplexingPermissionProvider(Root root, List<AggregatedPermissionProvider> pps, Context acContext) {
+ super(root, pps, acContext, CompositionType.OR);
+ }
+
+ public static String getWorkspaceName(Mount m, String workspace) {
+ return m.getPathFragmentName() + "-" + workspace;
+ }
+
+}
Propchange: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/composite/MultiplexingPermissionProvider.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/permission/PermissionHook.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/permission/PermissionHook.java?rev=1800129&r1=1800128&r2=1800129&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/permission/PermissionHook.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/permission/PermissionHook.java Wed Jun 28 06:56:00 2017
@@ -23,8 +23,11 @@ import javax.annotation.Nonnull;
import org.apache.jackrabbit.oak.api.CommitFailedException;
import org.apache.jackrabbit.oak.plugins.nodetype.TypePredicate;
import org.apache.jackrabbit.oak.plugins.tree.RootFactory;
+import org.apache.jackrabbit.oak.security.authorization.composite.MultiplexingPermissionProvider;
import org.apache.jackrabbit.oak.spi.commit.CommitInfo;
import org.apache.jackrabbit.oak.spi.commit.PostValidationHook;
+import org.apache.jackrabbit.oak.spi.mount.Mount;
+import org.apache.jackrabbit.oak.spi.mount.MountInfoProvider;
import org.apache.jackrabbit.oak.spi.security.authorization.accesscontrol.AccessControlConstants;
import org.apache.jackrabbit.oak.spi.security.authorization.permission.PermissionConstants;
import org.apache.jackrabbit.oak.spi.security.authorization.restriction.RestrictionProvider;
@@ -64,6 +67,7 @@ public class PermissionHook implements P
private final RestrictionProvider restrictionProvider;
private final String workspaceName;
+ private final MountInfoProvider mountInfoProvider;
private NodeBuilder permissionRoot;
private PrivilegeBitsProvider bitsProvider;
@@ -75,9 +79,10 @@ public class PermissionHook implements P
private Map<String, PermissionStoreEditor> modified = new HashMap<String, PermissionStoreEditor>();
private Map<String, PermissionStoreEditor> deleted = new HashMap<String, PermissionStoreEditor>();
- public PermissionHook(String workspaceName, RestrictionProvider restrictionProvider) {
+ public PermissionHook(String workspaceName, RestrictionProvider restrictionProvider, MountInfoProvider mountInfoProvider) {
this.workspaceName = workspaceName;
this.restrictionProvider = restrictionProvider;
+ this.mountInfoProvider = mountInfoProvider;
}
//---------------------------------------------------------< CommitHook >---
@@ -121,9 +126,19 @@ public class PermissionHook implements P
}
@Nonnull
- private NodeBuilder getPermissionRoot(NodeBuilder rootBuilder) {
+ private static NodeBuilder getPermissionRoot(NodeBuilder rootBuilder) {
// permission root has been created during workspace initialization
- return rootBuilder.getChildNode(JCR_SYSTEM).getChildNode(REP_PERMISSION_STORE).getChildNode(workspaceName);
+ return rootBuilder.getChildNode(JCR_SYSTEM).getChildNode(REP_PERMISSION_STORE);
+ }
+
+ @Nonnull
+ private NodeBuilder getPermissionRoot(String path) {
+ Mount m = mountInfoProvider.getMountByPath(path);
+ String ws = workspaceName;
+ if (!m.isDefault()) {
+ ws = MultiplexingPermissionProvider.getWorkspaceName(m, ws);
+ }
+ return permissionRoot.getChildNode(ws);
}
private final class Diff extends DefaultNodeStateDiff {
@@ -199,7 +214,7 @@ public class PermissionHook implements P
}
private PermissionStoreEditor createPermissionStoreEditor(@Nonnull String nodeName, @Nonnull NodeState nodeState) {
- return new PermissionStoreEditor(parentPath, nodeName, nodeState, permissionRoot, isACE, isGrantACE, bitsProvider, restrictionProvider);
+ return new PermissionStoreEditor(parentPath, nodeName, nodeState, getPermissionRoot(parentPath), isACE, isGrantACE, bitsProvider, restrictionProvider);
}
}
}
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/accesscontrol/AccessControlConstants.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/accesscontrol/AccessControlConstants.java?rev=1800129&r1=1800128&r2=1800129&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/accesscontrol/AccessControlConstants.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/accesscontrol/AccessControlConstants.java Wed Jun 28 06:56:00 2017
@@ -82,4 +82,6 @@ public interface AccessControlConstants
Collection<String> AC_NODETYPE_NAMES = ImmutableSet.of(NT_REP_POLICY, NT_REP_ACL, NT_REP_ACE, NT_REP_DENY_ACE, NT_REP_GRANT_ACE, NT_REP_RESTRICTIONS);
String PARAM_RESTRICTION_PROVIDER = "restrictionProvider";
+
+ String PARAM_MOUNT_PROVIDER = "mountInfoProvider";
}
Added: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/composite/MultiplexingProviderTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/composite/MultiplexingProviderTest.java?rev=1800129&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/composite/MultiplexingProviderTest.java (added)
+++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/composite/MultiplexingProviderTest.java Wed Jun 28 06:56:00 2017
@@ -0,0 +1,132 @@
+/*
+ * 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.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import java.security.Principal;
+import java.util.Collections;
+
+import javax.jcr.security.AccessControlManager;
+
+import org.apache.jackrabbit.JcrConstants;
+import org.apache.jackrabbit.api.security.JackrabbitAccessControlList;
+import org.apache.jackrabbit.commons.jackrabbit.authorization.AccessControlUtils;
+import org.apache.jackrabbit.oak.AbstractSecurityTest;
+import org.apache.jackrabbit.oak.api.ContentSession;
+import org.apache.jackrabbit.oak.api.Root;
+import org.apache.jackrabbit.oak.api.Tree;
+import org.apache.jackrabbit.oak.plugins.tree.TreeUtil;
+import org.apache.jackrabbit.oak.spi.mount.Mount;
+import org.apache.jackrabbit.oak.spi.mount.MountInfoProvider;
+import org.apache.jackrabbit.oak.spi.mount.Mounts;
+import org.apache.jackrabbit.oak.spi.security.ConfigurationParameters;
+import org.apache.jackrabbit.oak.spi.security.authorization.AuthorizationConfiguration;
+import org.apache.jackrabbit.oak.spi.security.authorization.accesscontrol.AccessControlConstants;
+import org.apache.jackrabbit.oak.spi.security.authorization.permission.PermissionConstants;
+import org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableMap;
+
+public class MultiplexingProviderTest extends AbstractSecurityTest
+ implements AccessControlConstants, PrivilegeConstants, PermissionConstants {
+
+ private MountInfoProvider mountInfoProvider;
+ private String testNode = "MultiplexingProviderTest";
+ private String testPath = "/" + testNode;
+
+ @Override
+ @Before
+ public void before() throws Exception {
+ mountInfoProvider = Mounts.newBuilder().mount("testMount", testPath).build();
+ super.before();
+ }
+
+ @Override
+ @After
+ public void after() throws Exception {
+ try {
+ root.refresh();
+ Tree test = root.getTree(testPath);
+ if (test.exists()) {
+ test.remove();
+ }
+ root.commit();
+ } finally {
+ super.after();
+ }
+ }
+
+ @Override
+ protected ConfigurationParameters getSecurityConfigParameters() {
+ ConfigurationParameters authConfig = ConfigurationParameters.of(Collections.singletonMap(
+ AccessControlConstants.PARAM_MOUNT_PROVIDER, Preconditions.checkNotNull(mountInfoProvider)));
+ return ConfigurationParameters.of(ImmutableMap.of(AuthorizationConfiguration.NAME, authConfig));
+ }
+
+ @Test
+ public void multiplexingProvider() throws Exception {
+
+ // check init
+ Tree permStore = root.getTree(PERMISSIONS_STORE_PATH);
+ String wsName = adminSession.getWorkspaceName();
+ assertTrue(permStore.hasChild(wsName));
+ for (Mount m : mountInfoProvider.getNonDefaultMounts()) {
+ assertTrue(permStore.hasChild(MultiplexingPermissionProvider.getWorkspaceName(m, wsName)));
+ }
+
+ Tree rootNode = root.getTree("/");
+ Tree test = TreeUtil.addChild(rootNode, testNode, JcrConstants.NT_UNSTRUCTURED);
+ Tree content = TreeUtil.addChild(test, "content", JcrConstants.NT_UNSTRUCTURED);
+ root.commit();
+
+ Principal p = getTestUser().getPrincipal();
+ setPrivileges(p, test.getPath(), true, JCR_READ);
+ setPrivileges(p, content.getPath(), false, JCR_READ);
+
+ permStore = root.getTree(PERMISSIONS_STORE_PATH);
+ // no entries in the default store
+ assertFalse(permStore.getChild(wsName).hasChild(p.getName()));
+ for (Mount m : mountInfoProvider.getNonDefaultMounts()) {
+ Tree mps = permStore.getChild(MultiplexingPermissionProvider.getWorkspaceName(m, wsName));
+ assertTrue(mps.hasChild(p.getName()));
+ }
+
+ ContentSession testSession = createTestSession();
+ try {
+ Root r = testSession.getLatestRoot();
+ assertFalse(r.getTree("/").exists());
+ assertTrue(r.getTree(test.getPath()).exists());
+ assertFalse(r.getTree(content.getPath()).exists());
+ } finally {
+ testSession.close();
+ }
+ }
+
+ private void setPrivileges(Principal principal, String path, boolean allow, String... privileges) throws Exception {
+ AccessControlManager acm = getAccessControlManager(root);
+ JackrabbitAccessControlList acl = AccessControlUtils.getAccessControlList(acm, path);
+ acl.addEntry(principal, privilegesFromNames(privileges), allow);
+ acm.setPolicy(path, acl);
+ root.commit();
+ }
+}
Propchange: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/composite/MultiplexingProviderTest.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/composite/MutiplexingProviderRandomTestIT.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/composite/MutiplexingProviderRandomTestIT.java?rev=1800129&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/composite/MutiplexingProviderRandomTestIT.java (added)
+++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/composite/MutiplexingProviderRandomTestIT.java Wed Jun 28 06:56:00 2017
@@ -0,0 +1,66 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.oak.security.authorization.composite;
+
+import java.security.Principal;
+import java.util.Collections;
+import java.util.Set;
+
+import javax.annotation.Nonnull;
+
+import org.apache.jackrabbit.oak.api.Root;
+import org.apache.jackrabbit.oak.security.SecurityProviderImpl;
+import org.apache.jackrabbit.oak.security.authorization.permission.AbstractPermissionRandomTestIT;
+import org.apache.jackrabbit.oak.spi.mount.MountInfoProvider;
+import org.apache.jackrabbit.oak.spi.mount.Mounts;
+import org.apache.jackrabbit.oak.spi.security.ConfigurationParameters;
+import org.apache.jackrabbit.oak.spi.security.authorization.AuthorizationConfiguration;
+import org.apache.jackrabbit.oak.spi.security.authorization.accesscontrol.AccessControlConstants;
+import org.apache.jackrabbit.oak.spi.security.authorization.permission.PermissionProvider;
+
+import com.google.common.base.Preconditions;
+import com.google.common.collect.Iterators;
+
+public class MutiplexingProviderRandomTestIT extends AbstractPermissionRandomTestIT {
+
+ private MountInfoProvider mountInfoProvider;
+
+ @Override
+ public void before() throws Exception {
+ super.before();
+
+ String[] mpxs = new String[] { Iterators.get(allowU.iterator(), allowU.size() / 2) };
+ Mounts.Builder builder = Mounts.newBuilder();
+ int i = 0;
+ for (String p : mpxs) {
+ builder.mount("m" + i, p);
+ i++;
+ }
+ mountInfoProvider = builder.build();
+ }
+
+ @Override
+ protected PermissionProvider candidatePermissionProvider(@Nonnull Root root, @Nonnull String workspaceName,
+ @Nonnull Set<Principal> principals) {
+ ConfigurationParameters authConfig = ConfigurationParameters.of(Collections.singletonMap(
+ AccessControlConstants.PARAM_MOUNT_PROVIDER, Preconditions.checkNotNull(mountInfoProvider)));
+ SecurityProviderImpl sp = new SecurityProviderImpl(authConfig);
+ AuthorizationConfiguration acConfig = sp.getConfiguration(AuthorizationConfiguration.class);
+ return acConfig.getPermissionProvider(root, workspaceName, principals);
+ }
+
+}
\ No newline at end of file
Propchange: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/composite/MutiplexingProviderRandomTestIT.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: jackrabbit/oak/trunk/oak-doc/src/site/markdown/security/permission.md
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-doc/src/site/markdown/security/permission.md?rev=1800129&r1=1800128&r2=1800129&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-doc/src/site/markdown/security/permission.md (original)
+++ jackrabbit/oak/trunk/oak-doc/src/site/markdown/security/permission.md Wed Jun 28 06:56:00 2017
@@ -371,6 +371,7 @@ The supported configuration options of t
- [Differences wrt Jackrabbit 2.x](permission/differences.html)
- [Permissions : The Default Implementation](permission/default.html)
- [Permission Evaluation in Detail](permission/evaluation.html)
+- [Multiplexed PermissionStore](permission/multiplexing.html)
- [Restriction Management](authorization/restriction.html)
<!-- references -->
Modified: jackrabbit/oak/trunk/oak-doc/src/site/markdown/security/permission/default.md
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-doc/src/site/markdown/security/permission/default.md?rev=1800129&r1=1800128&r2=1800129&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-doc/src/site/markdown/security/permission/default.md (original)
+++ jackrabbit/oak/trunk/oak-doc/src/site/markdown/security/permission/default.md Wed Jun 28 06:56:00 2017
@@ -61,6 +61,10 @@ on the Oak API) irrespective of the acce
evaluation and is currently not reflected in other security models nor methods
that deal with the administrator (i.e. `User#isAdmin`).
+#### Permission Evaluation in Multiplexed Stores
+
+See section [Multiplexing support in the PermissionStore](multiplexing.html).
+
<a name="representation"/>
### Representation in the Repository
Added: jackrabbit/oak/trunk/oak-doc/src/site/markdown/security/permission/multiplexing.md
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-doc/src/site/markdown/security/permission/multiplexing.md?rev=1800129&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-doc/src/site/markdown/security/permission/multiplexing.md (added)
+++ jackrabbit/oak/trunk/oak-doc/src/site/markdown/security/permission/multiplexing.md Wed Jun 28 06:56:00 2017
@@ -0,0 +1,59 @@
+<!--
+ 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.
+-->
+
+Multiplexing support in the PermissionStore
+--------------------------------------------------------------------------------
+
+### General Notes
+
+Multiplexing support is implemented as a composite `PermissionProvider` made of
+the default workspace provider and the existing mounts.
+This is available since Oak 1.7.3 [OAK-3777](https://issues.apache.org/jira/browse/OAK-3777).
+
+### PermissionStore Evaluation (reading)
+
+Given the following mount setup
+
+ private
+ - /libs
+ - /apps
+ default
+ - /
+
+In above setup nodes under /apps and /libs (include apps and libs) are part of "private" mount (mount name is "private") and all other paths are part of default mount.
+A dedicated PermissionStore will be created under `oak:mount-private-default` that contains information relevant to this specific mount.
+
+ /jcr:system/rep:permissionStore
+ + oak:mount-private-default
+ + editor //principal name
+ + 1345610890 (rep:PermissionStore) //path hash
+ - rep:accessControlledPath = /libs
+ + 0
+ - rep:isAllow = false
+ - rep:privileges = [1279]
+ + default //workspace name
+ + editor //principal name
+ + 1227964008 (rep:PermissionStore) //path hash
+ - rep:accessControlledPath = /content
+ + 0
+ - rep:isAllow = true
+ - rep:privileges = [1279]
+
+### PermissionStore updates (writing)
+
+The `PermissionHook` is now mount-aware and will delegate changes to specific path to their designated components based on path.
+
Propchange: jackrabbit/oak/trunk/oak-doc/src/site/markdown/security/permission/multiplexing.md
------------------------------------------------------------------------------
svn:eol-style = native