You are viewing a plain text version of this content. The canonical link for it is here.
Posted to oak-commits@jackrabbit.apache.org by an...@apache.org on 2015/09/29 14:04:45 UTC
svn commit: r1705841 - in /jackrabbit/oak/trunk:
oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/permission/
oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/restriction/
oak-core/src/main/java/org/apache/...
Author: angela
Date: Tue Sep 29 12:04:44 2015
New Revision: 1705841
URL: http://svn.apache.org/viewvc?rev=1705841&view=rev
Log:
OAK-3457 : Multivalued restriction to limit effect of ACE to items with a given name
Added:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/restriction/ItemNamePattern.java
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/restriction/ItemNamePatternTest.java
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/restriction/ItemNameRestrictionTest.java
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/permission/PermissionEntry.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/restriction/RestrictionProviderImpl.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/accesscontrol/AccessControlConstants.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/accesscontrol/package-info.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/restriction/package-info.java
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/accesscontrol/ACLTest.java
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/restriction/RestrictionProviderImplTest.java
jackrabbit/oak/trunk/oak-doc/src/site/markdown/security/accesscontrol/restriction.md
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/permission/PermissionEntry.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/permission/PermissionEntry.java?rev=1705841&r1=1705840&r2=1705841&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/permission/PermissionEntry.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/permission/PermissionEntry.java Tue Sep 29 12:04:44 2015
@@ -122,16 +122,4 @@ final class PermissionEntry implements C
public int hashCode() {
return Objects.hashCode(privilegeBits, index, path, isAllow, restriction);
}
-
- @Override
- public String toString() {
- final StringBuilder sb = new StringBuilder("PermissionEntry{");
- sb.append("isAllow=").append(isAllow);
- sb.append(", privilegeBits=").append(privilegeBits);
- sb.append(", index=").append(index);
- sb.append(", path='").append(path).append('\'');
- sb.append(", restriction=").append(restriction);
- sb.append('}');
- return sb.toString();
- }
}
\ No newline at end of file
Added: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/restriction/ItemNamePattern.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/restriction/ItemNamePattern.java?rev=1705841&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/restriction/ItemNamePattern.java (added)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/restriction/ItemNamePattern.java Tue Sep 29 12:04:44 2015
@@ -0,0 +1,95 @@
+/*
+ * 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.restriction;
+
+import java.util.Set;
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import com.google.common.collect.ImmutableSet;
+import org.apache.jackrabbit.oak.api.PropertyState;
+import org.apache.jackrabbit.oak.api.Tree;
+import org.apache.jackrabbit.oak.commons.PathUtils;
+import org.apache.jackrabbit.oak.spi.security.authorization.restriction.RestrictionPattern;
+
+/**
+ * Implementation of the {@link RestrictionPattern} interface that returns
+ * {@code true} if the name of the target item (property or node) is contained
+ * in the configured set of names. This allows to limit certain operations (e.g.
+ * reading or modifying properties) to a subset of items in the tree defined
+ * by the associated policy.
+ */
+class ItemNamePattern implements RestrictionPattern {
+
+ private final Set<String> names;
+
+ ItemNamePattern(Iterable<String> names) {
+ this.names = ImmutableSet.copyOf(names);
+ }
+
+ @Override
+ public boolean matches(@Nonnull Tree tree, @Nullable PropertyState property) {
+ if (property != null) {
+ return names.contains(property.getName());
+ } else {
+ return names.contains(tree.getName());
+ }
+ }
+
+ @Override
+ public boolean matches(@Nonnull String path) {
+ return (PathUtils.denotesRoot(path) ? false : names.contains(PathUtils.getName(path)));
+ }
+
+ @Override
+ public boolean matches() {
+ // name pattern never matches for repository level permissions
+ return false;
+ }
+
+ //-------------------------------------------------------------< Object >---
+ /**
+ * @see Object#hashCode()
+ */
+ @Override
+ public int hashCode() {
+ return names.hashCode();
+ }
+
+ /**
+ * @see Object#toString()
+ */
+ @Override
+ public String toString() {
+ return names.toString();
+ }
+
+ /**
+ * @see Object#equals(Object)
+ */
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == this) {
+ return true;
+ }
+ if (obj instanceof ItemNamePattern) {
+ ItemNamePattern other = (ItemNamePattern) obj;
+ return names.equals(other.names);
+ }
+ return false;
+ }
+}
\ No newline at end of file
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/restriction/RestrictionProviderImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/restriction/RestrictionProviderImpl.java?rev=1705841&r1=1705840&r2=1705841&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/restriction/RestrictionProviderImpl.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/restriction/RestrictionProviderImpl.java Tue Sep 29 12:04:44 2015
@@ -72,7 +72,8 @@ public class RestrictionProviderImpl ext
RestrictionDefinition glob = new RestrictionDefinitionImpl(REP_GLOB, Type.STRING, false);
RestrictionDefinition nts = new RestrictionDefinitionImpl(REP_NT_NAMES, Type.NAMES, false);
RestrictionDefinition pfxs = new RestrictionDefinitionImpl(REP_PREFIXES, Type.STRINGS, false);
- return ImmutableMap.of(glob.getName(), glob, nts.getName(), nts, pfxs.getName(), pfxs);
+ RestrictionDefinition names = new RestrictionDefinitionImpl(REP_ITEM_NAMES, Type.NAMES, false);
+ return ImmutableMap.of(glob.getName(), glob, nts.getName(), nts, pfxs.getName(), pfxs, names.getName(), names);
}
//------------------------------------------------< RestrictionProvider >---
@@ -96,6 +97,11 @@ public class RestrictionProviderImpl ext
if (prefixes != null) {
patterns.add(new PrefixPattern(prefixes.getValue(Type.STRINGS)));
}
+ PropertyState itemNames = tree.getProperty(REP_ITEM_NAMES);
+ if (itemNames != null) {
+ patterns.add(new ItemNamePattern(itemNames.getValue(Type.NAMES)));
+ }
+
return CompositePattern.create(patterns);
}
}
@@ -115,6 +121,8 @@ public class RestrictionProviderImpl ext
patterns.add(new NodeTypePattern(r.getProperty().getValue(Type.NAMES)));
} else if (REP_PREFIXES.equals(name)) {
patterns.add(new PrefixPattern(r.getProperty().getValue(Type.STRINGS)));
+ } else if (REP_ITEM_NAMES.equals(name)) {
+ patterns.add(new ItemNamePattern(r.getProperty().getValue(Type.NAMES)));
} else {
log.debug("Ignoring unsupported restriction " + name);
}
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=1705841&r1=1705840&r2=1705841&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 Tue Sep 29 12:04:44 2015
@@ -50,6 +50,14 @@ public interface AccessControlConstants
String REP_PREFIXES = "rep:prefixes";
/**
+ * Name of the optional multivalued access control restriction by item name.
+ * The corresponding restriction type is {@link org.apache.jackrabbit.oak.api.Type#NAMES}.
+ *
+ * @since OAK 1.3.8
+ */
+ String REP_ITEM_NAMES = "rep:itemNames";
+
+ /**
* @since OAK 1.0
*/
String REP_RESTRICTIONS = "rep:restrictions";
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/accesscontrol/package-info.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/accesscontrol/package-info.java?rev=1705841&r1=1705840&r2=1705841&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/accesscontrol/package-info.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/accesscontrol/package-info.java Tue Sep 29 12:04:44 2015
@@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-@Version("1.3.1")
+@Version("1.4.0")
@Export(optional = "provide:=true")
package org.apache.jackrabbit.oak.spi.security.authorization.accesscontrol;
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/restriction/package-info.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/restriction/package-info.java?rev=1705841&r1=1705840&r2=1705841&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/restriction/package-info.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/restriction/package-info.java Tue Sep 29 12:04:44 2015
@@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-@Version("1.0")
+@Version("1.1")
@Export(optional = "provide:=true")
package org.apache.jackrabbit.oak.spi.security.authorization.restriction;
Modified: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/accesscontrol/ACLTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/accesscontrol/ACLTest.java?rev=1705841&r1=1705840&r2=1705841&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/accesscontrol/ACLTest.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/accesscontrol/ACLTest.java Tue Sep 29 12:04:44 2015
@@ -648,11 +648,12 @@ public class ACLTest extends AbstractAcc
public void testRestrictions() throws Exception {
String[] names = acl.getRestrictionNames();
assertNotNull(names);
- assertEquals(3, names.length);
- assertArrayEquals(new String[] {REP_GLOB, REP_NT_NAMES, REP_PREFIXES}, names);
+ assertEquals(4, names.length);
+ assertArrayEquals(new String[] {REP_GLOB, REP_NT_NAMES, REP_PREFIXES, REP_ITEM_NAMES}, names);
assertEquals(PropertyType.STRING, acl.getRestrictionType(names[0]));
assertEquals(PropertyType.NAME, acl.getRestrictionType(names[1]));
assertEquals(PropertyType.STRING, acl.getRestrictionType(names[2]));
+ assertEquals(PropertyType.NAME, acl.getRestrictionType(names[3]));
Privilege[] writePriv = privilegesFromNames(JCR_WRITE);
Added: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/restriction/ItemNamePatternTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/restriction/ItemNamePatternTest.java?rev=1705841&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/restriction/ItemNamePatternTest.java (added)
+++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/restriction/ItemNamePatternTest.java Tue Sep 29 12:04:44 2015
@@ -0,0 +1,77 @@
+/*
+ * 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.restriction;
+
+import java.util.List;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+import org.apache.jackrabbit.oak.AbstractSecurityTest;
+import org.apache.jackrabbit.oak.api.Tree;
+import org.apache.jackrabbit.oak.plugins.memory.PropertyStates;
+import org.apache.jackrabbit.oak.plugins.nodetype.NodeTypeConstants;
+import org.apache.jackrabbit.oak.util.NodeUtil;
+import org.junit.Test;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+public class ItemNamePatternTest extends AbstractSecurityTest {
+
+ private ItemNamePattern pattern = new ItemNamePattern(ImmutableSet.of("a", "b", "c"));
+
+ @Test
+ public void testMatchesItem() throws Exception {
+
+ NodeUtil rootTree = new NodeUtil(root.getTree("/"));
+ List<String> matching = ImmutableList.of("a", "b", "c", "d/e/a", "a/b/c/d/b", "test/c");
+ for (String relPath : matching) {
+ Tree testTree = rootTree.getOrAddTree(relPath, NodeTypeConstants.NT_OAK_UNSTRUCTURED).getTree();
+
+ assertTrue(pattern.matches(testTree, null));
+ assertTrue(pattern.matches(testTree, PropertyStates.createProperty("a", Boolean.FALSE)));
+ assertFalse(pattern.matches(testTree, PropertyStates.createProperty("f", "anyval")));
+ }
+
+ List<String> notMatching = ImmutableList.of("d", "b/d", "d/e/f", "c/b/abc");
+ for (String relPath : notMatching) {
+ Tree testTree = rootTree.getOrAddTree(relPath, NodeTypeConstants.NT_OAK_UNSTRUCTURED).getTree();
+
+ assertFalse(pattern.matches(testTree, null));
+ assertTrue(pattern.matches(testTree, PropertyStates.createProperty("a", Boolean.FALSE)));
+ assertFalse(pattern.matches(testTree, PropertyStates.createProperty("f", "anyval")));
+ }
+ }
+
+ @Test
+ public void testMatchesPath() {
+ List<String> matching = ImmutableList.of("/a", "/b", "/c", "/d/e/a", "/a/b/c/d/b", "/test/c");
+ for (String p : matching) {
+ assertTrue(pattern.matches(p));
+ }
+
+ List<String> notMatching = ImmutableList.of("/", "/d", "/b/d", "/d/e/f", "/c/b/abc");
+ for (String p : notMatching) {
+ assertFalse(pattern.matches(p));
+ }
+ }
+
+ @Test
+ public void testMatchesNull() {
+ assertFalse(pattern.matches());
+ }
+}
\ No newline at end of file
Added: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/restriction/ItemNameRestrictionTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/restriction/ItemNameRestrictionTest.java?rev=1705841&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/restriction/ItemNameRestrictionTest.java (added)
+++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/restriction/ItemNameRestrictionTest.java Tue Sep 29 12:04:44 2015
@@ -0,0 +1,283 @@
+/*
+ * 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.restriction;
+
+import java.security.Principal;
+import java.util.Collections;
+import java.util.List;
+import java.util.UUID;
+import javax.jcr.PropertyType;
+import javax.jcr.Value;
+import javax.jcr.ValueFactory;
+import javax.jcr.security.AccessControlManager;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import org.apache.jackrabbit.JcrConstants;
+import org.apache.jackrabbit.api.security.JackrabbitAccessControlList;
+import org.apache.jackrabbit.api.security.user.Group;
+import org.apache.jackrabbit.api.security.user.User;
+import org.apache.jackrabbit.api.security.user.UserManager;
+import org.apache.jackrabbit.commons.jackrabbit.authorization.AccessControlUtils;
+import org.apache.jackrabbit.oak.AbstractSecurityTest;
+import org.apache.jackrabbit.oak.api.CommitFailedException;
+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.commons.PathUtils;
+import org.apache.jackrabbit.oak.namepath.NamePathMapper;
+import org.apache.jackrabbit.oak.plugins.nodetype.NodeTypeConstants;
+import org.apache.jackrabbit.oak.plugins.value.ValueFactoryImpl;
+import org.apache.jackrabbit.oak.spi.security.authorization.accesscontrol.AccessControlConstants;
+import org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants;
+import org.apache.jackrabbit.oak.spi.security.user.UserConstants;
+import org.apache.jackrabbit.oak.util.NodeUtil;
+import org.junit.Test;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+public class ItemNameRestrictionTest extends AbstractSecurityTest {
+
+ private ValueFactory vf;
+ private ContentSession testSession;
+
+ private Principal testPrincipal;
+ private Group testGroup;
+
+ @Override
+ public void before() throws Exception {
+ super.before();
+
+ Tree rootTree = root.getTree("/");
+ NodeUtil f = new NodeUtil(rootTree).getOrAddTree("a/d/b/e/c/f", NodeTypeConstants.NT_OAK_UNSTRUCTURED);
+ NodeUtil c = f.getParent();
+ c.setString("prop", "value");
+ c.setString("a", "value");
+
+ testPrincipal = getTestUser().getPrincipal();
+
+ AccessControlManager acMgr = getAccessControlManager(root);
+ JackrabbitAccessControlList acl = AccessControlUtils.getAccessControlList(acMgr, "/a");
+
+ vf = new ValueFactoryImpl(root, NamePathMapper.DEFAULT);
+ acl.addEntry(testPrincipal,
+ privilegesFromNames(
+ PrivilegeConstants.JCR_READ,
+ PrivilegeConstants.REP_ADD_PROPERTIES,
+ PrivilegeConstants.JCR_ADD_CHILD_NODES,
+ PrivilegeConstants.JCR_REMOVE_NODE), true,
+ Collections.<String, Value>emptyMap(),
+ ImmutableMap.of(AccessControlConstants.REP_ITEM_NAMES, new Value[] {
+ vf.createValue("a", PropertyType.NAME),
+ vf.createValue("b", PropertyType.NAME),
+ vf.createValue("c", PropertyType.NAME)}));
+ acMgr.setPolicy(acl.getPath(), acl);
+
+ UserManager uMgr = getUserManager(root);
+ testGroup = uMgr.createGroup("testGroup" + UUID.randomUUID());
+
+ root.commit();
+ testSession = createTestSession();
+ }
+
+ @Override
+ public void after() throws Exception {
+ try {
+ testSession.close();
+ root.refresh();
+ Tree a = root.getTree("/a");
+ if (a.exists()) {
+ a.remove();
+ root.commit();
+ }
+ } finally {
+ super.after();
+ }
+ }
+
+ @Test
+ public void testRead() {
+ Root testRoot = testSession.getLatestRoot();
+
+ List<String> visible = ImmutableList.of("/a", "/a/d/b", "/a/d/b/e/c");
+ for (String p : visible) {
+ assertTrue(testRoot.getTree(p).exists());
+ }
+
+ List<String> invisible = ImmutableList.of("/", "/a/d", "/a/d/b/e", "/a/d/b/e/c/f");
+ for (String p : invisible) {
+ assertFalse(testRoot.getTree(p).exists());
+ }
+
+ Tree c = testRoot.getTree("/a/d/b/e/c");
+ assertNull(c.getProperty(JcrConstants.JCR_PRIMARYTYPE));
+ assertNull(c.getProperty("prop"));
+ assertNotNull(c.getProperty("a"));
+ }
+
+ @Test
+ public void testAddProperty() throws Exception {
+ Root testRoot = testSession.getLatestRoot();
+
+ List<String> paths = ImmutableList.of("/a", "/a/d/b", "/a/d/b/e/c");
+ for (String p : paths) {
+ Tree t = testRoot.getTree(p);
+ t.setProperty("b", "anyvalue");
+ testRoot.commit();
+ }
+
+ for (String p : paths) {
+ Tree t = testRoot.getTree(p);
+ try {
+ t.setProperty("notAllowed", "anyvalue");
+ testRoot.commit();
+ fail();
+ } catch (CommitFailedException e) {
+ // success
+ assertTrue(e.isAccessViolation());
+ } finally {
+ testRoot.refresh();
+ }
+ }
+ }
+
+ @Test
+ public void testModifyProperty() throws Exception {
+ Root testRoot = testSession.getLatestRoot();
+ Tree c = testRoot.getTree("/a/d/b/e/c");
+
+ try {
+ c.setProperty("a", "anyvalue");
+ testRoot.commit();
+ fail();
+ } catch (CommitFailedException e) {
+ // success
+ assertTrue(e.isAccessViolation());
+ } finally {
+ testRoot.refresh();
+ }
+ }
+
+ @Test
+ public void testAddChild() throws Exception {
+ Root testRoot = testSession.getLatestRoot();
+
+ List<String> paths = ImmutableList.of("/a", "/a/d/b", "/a/d/b/e/c");
+ for (String p : paths) {
+ NodeUtil t = new NodeUtil(testRoot.getTree(p));
+ t.addChild("c", NodeTypeConstants.NT_OAK_UNSTRUCTURED);
+ testRoot.commit();
+ }
+ }
+
+ @Test
+ public void testRemoveTree() throws Exception {
+ Root testRoot = testSession.getLatestRoot();
+ List<String> paths = ImmutableList.of("/a/d/b/e/c", "/a/d/b", "/a");
+ for (String p : paths) {
+ try {
+ testRoot.getTree(p).remove();
+ testRoot.commit();
+ fail();
+ } catch (CommitFailedException e) {
+ // success
+ assertTrue(e.isAccessViolation());
+ } finally {
+ testRoot.refresh();
+ }
+ }
+ }
+
+ @Test
+ public void testRemoveTree2() throws Exception {
+ AccessControlManager acMgr = getAccessControlManager(root);
+ JackrabbitAccessControlList acl = AccessControlUtils.getAccessControlList(acMgr, "/a");
+
+ acl.addEntry(testPrincipal,
+ privilegesFromNames(PrivilegeConstants.JCR_READ, PrivilegeConstants.JCR_REMOVE_CHILD_NODES), true);
+ acMgr.setPolicy(acl.getPath(), acl);
+ root.commit();
+
+ Root testRoot = testSession.getLatestRoot();
+ List<String> paths = ImmutableList.of("/a/d/b/e/c", "/a/d/b");
+ for (String p : paths) {
+ testRoot.getTree(p).remove();
+ testRoot.commit();
+ }
+
+ try {
+ testRoot.getTree("/a").remove();
+ testRoot.commit();
+ fail();
+ } catch (CommitFailedException e) {
+ // success
+ assertTrue(e.isAccessViolation());
+ } finally {
+ testRoot.refresh();
+ }
+ }
+
+ @Test
+ public void testModifyMembersOnly() throws Exception {
+ AccessControlManager acMgr = getAccessControlManager(root);
+ String path = PathUtils.getAncestorPath(UserConstants.DEFAULT_USER_PATH, 1);
+ try {
+ JackrabbitAccessControlList acl = AccessControlUtils.getAccessControlList(acMgr, path);
+ acl.addEntry(testPrincipal, privilegesFromNames(PrivilegeConstants.JCR_READ), true);
+ acl.addEntry(testPrincipal, privilegesFromNames(PrivilegeConstants.REP_USER_MANAGEMENT), true,
+ Collections.<String,Value>emptyMap(),
+ ImmutableMap.<String,Value[]>of (AccessControlConstants.REP_ITEM_NAMES, new Value[] {
+ vf.createValue(UserConstants.REP_MEMBERS, PropertyType.NAME)}));
+ acMgr.setPolicy(acl.getPath(), acl);
+ root.commit();
+
+ Root testRoot = testSession.getLatestRoot();
+
+ UserManager uMgr = getUserManager(testRoot);
+
+ // adding a group member must succeed
+ Group gr = uMgr.getAuthorizable(testGroup.getID(), Group.class);
+ User u = uMgr.getAuthorizable(getTestUser().getID(), User.class);
+ gr.addMember(u);
+ testRoot.commit();
+
+ // changing the pw property of the test user must fail
+ try {
+ u.changePassword("blub");
+ testRoot.commit();
+ fail();
+ } catch (CommitFailedException e) {
+ // success
+ assertTrue(e.isAccessViolation());
+ } finally {
+ testRoot.refresh();
+ }
+ } catch (CommitFailedException e) {
+ // success
+ assertTrue(e.isAccessViolation());
+ } finally {
+ JackrabbitAccessControlList acl = AccessControlUtils.getAccessControlList(acMgr, path);
+ if (acl != null) {
+ acMgr.removePolicy(acl.getPath(), acl);
+ root.commit();
+ }
+ }
+ }
+}
\ No newline at end of file
Modified: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/restriction/RestrictionProviderImplTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/restriction/RestrictionProviderImplTest.java?rev=1705841&r1=1705840&r2=1705841&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/restriction/RestrictionProviderImplTest.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/restriction/RestrictionProviderImplTest.java Tue Sep 29 12:04:44 2015
@@ -68,7 +68,7 @@ public class RestrictionProviderImplTest
Set<RestrictionDefinition> defs = provider.getSupportedRestrictions("/testPath");
assertNotNull(defs);
- assertEquals(3, defs.size());
+ assertEquals(4, defs.size());
for (RestrictionDefinition def : defs) {
if (REP_GLOB.equals(def.getName())) {
@@ -80,6 +80,9 @@ public class RestrictionProviderImplTest
} else if (REP_PREFIXES.equals(def.getName())) {
assertEquals(Type.STRINGS, def.getRequiredType());
assertFalse(def.isMandatory());
+ } else if (REP_ITEM_NAMES.equals(def.getName())) {
+ assertEquals(Type.NAMES, def.getRequiredType());
+ assertFalse(def.isMandatory());
} else {
fail("unexpected restriction " + def.getName());
}
@@ -122,6 +125,8 @@ public class RestrictionProviderImplTest
map.put(PropertyStates.createProperty(REP_NT_NAMES, ntNames, Type.NAMES), new NodeTypePattern(ntNames));
List<String> prefixes = ImmutableList.of("rep", "jcr");
map.put(PropertyStates.createProperty(REP_PREFIXES, prefixes, Type.STRINGS), new PrefixPattern(prefixes));
+ List<String> itemNames = ImmutableList.of("abc", "jcr:primaryType");
+ map.put(PropertyStates.createProperty(REP_ITEM_NAMES, prefixes, Type.NAMES), new ItemNamePattern(itemNames));
NodeUtil tree = new NodeUtil(root.getTree("/")).getOrAddTree("testPath", JcrConstants.NT_UNSTRUCTURED);
Tree restrictions = tree.addChild(REP_RESTRICTIONS, NT_REP_RESTRICTIONS).getTree();
@@ -137,11 +142,16 @@ public class RestrictionProviderImplTest
public void testGetPatternFromRestrictions() throws Exception {
Map<PropertyState, RestrictionPattern> map = newHashMap();
map.put(PropertyStates.createProperty(REP_GLOB, "/*/jcr:content"), GlobPattern.create("/testPath", "/*/jcr:content"));
+
List<String> ntNames = ImmutableList.of(JcrConstants.NT_FOLDER, JcrConstants.NT_LINKEDFILE);
map.put(PropertyStates.createProperty(REP_NT_NAMES, ntNames, Type.NAMES), new NodeTypePattern(ntNames));
+
List<String> prefixes = ImmutableList.of("rep", "jcr");
map.put(PropertyStates.createProperty(REP_PREFIXES, prefixes, Type.STRINGS), new PrefixPattern(prefixes));
+ List<String> itemNames = ImmutableList.of("abc", "jcr:primaryType");
+ map.put(PropertyStates.createProperty(REP_ITEM_NAMES, itemNames, Type.NAMES), new ItemNamePattern(itemNames));
+
NodeUtil tree = new NodeUtil(root.getTree("/")).getOrAddTree("testPath", JcrConstants.NT_UNSTRUCTURED);
Tree restrictions = tree.addChild(REP_RESTRICTIONS, NT_REP_RESTRICTIONS).getTree();
Modified: jackrabbit/oak/trunk/oak-doc/src/site/markdown/security/accesscontrol/restriction.md
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-doc/src/site/markdown/security/accesscontrol/restriction.md?rev=1705841&r1=1705840&r2=1705841&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-doc/src/site/markdown/security/accesscontrol/restriction.md (original)
+++ jackrabbit/oak/trunk/oak-doc/src/site/markdown/security/accesscontrol/restriction.md Tue Sep 29 12:04:44 2015
@@ -95,7 +95,7 @@ as follows:
- supports multi-valued restrictions
- validation of the restrictions is delegated to a dedicated commit hook
- restriction `rep:glob` limits the number of wildcard characters to 20
-- new restrictions `rep:ntNames` and `rep:prefixes`
+- new restrictions `rep:ntNames`, `rep:prefixes` and `rep:itemNames`
#### Built-in Restrictions
@@ -105,6 +105,7 @@ Oak 1.0 access control management:
* `rep:glob`: single name or path pattern with '*' wildcard(s).
* `rep:ntNames`: multivalued restriction for primary node type names (no inheritence, since Oak 1.0)
* `rep:prefixes`: multivalued restriction for namespace prefixes (session level remapping not respected, since Oak 1.0)
+* `rep:itemNames`: multivalued restriction for property or node names (since Oak 1.3.8)
### Pluggability