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 2013/03/28 11:07:56 UTC
svn commit: r1462015 - in /jackrabbit/oak/trunk/oak-core/src:
main/java/org/apache/jackrabbit/oak/security/authorization/permission/
test/java/org/apache/jackrabbit/oak/security/authorization/permission/
Author: angela
Date: Thu Mar 28 10:07:56 2013
New Revision: 1462015
URL: http://svn.apache.org/r1462015
Log:
OAK-527: permissions (wip)
Added:
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/permission/CompiledPermissionImplTest.java
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/permission/CompiledPermissionImpl.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/permission/PermissionProviderImpl.java
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/permission/CompiledPermissionImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/permission/CompiledPermissionImpl.java?rev=1462015&r1=1462014&r2=1462015&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/permission/CompiledPermissionImpl.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/permission/CompiledPermissionImpl.java Thu Mar 28 10:07:56 2013
@@ -59,8 +59,7 @@ class CompiledPermissionImpl implements
private PrivilegeBitsProvider bitsProvider;
private Map<Key, PermissionEntry> repoEntries;
- private Map<Key, PermissionEntry> userEntries;
- private Map<Key, PermissionEntry> groupEntries;
+ private Map<Key, PermissionEntry> entries;
CompiledPermissionImpl(@Nonnull Set<Principal> principals,
@Nonnull ImmutableTree permissionsTree,
@@ -107,11 +106,12 @@ class CompiledPermissionImpl implements
//------------------------------------------------< CompiledPermissions >---
@Override
public ReadStatus getReadStatus(@Nonnull Tree tree, @Nullable PropertyState property) {
- // FIXME
long permission = (property == null) ? Permissions.READ_NODE : Permissions.READ_PROPERTY;
for (PermissionEntry entry : filterEntries(tree, property)) {
- if (entry.privilegeBits.includesRead(permission)) {
- return ReadStatus.ALLOW_THIS;
+ if (entry.readStatus != null) {
+ return entry.readStatus;
+ } else if (entry.privilegeBits.includesRead(permission)) {
+ return (entry.isAllow) ? ReadStatus.ALLOW_THIS : ReadStatus.DENY_THIS;
}
}
return ReadStatus.DENY_THIS;
@@ -152,8 +152,7 @@ class CompiledPermissionImpl implements
private void buildEntries(@Nullable ImmutableTree permissionsTree) {
if (permissionsTree == null) {
repoEntries = Collections.emptyMap();
- userEntries = Collections.emptyMap();
- groupEntries = Collections.emptyMap();
+ entries = Collections.emptyMap();
} else {
EntriesBuilder builder = new EntriesBuilder();
for (Principal principal : principals) {
@@ -164,15 +163,18 @@ class CompiledPermissionImpl implements
}
}
repoEntries = builder.repoEntries.build();
- userEntries = builder.userEntries.build();
- groupEntries = builder.groupEntries.build();
+ entries = builder.entries.build();
+ buildReadStatus();
}
}
+ private void buildReadStatus() {
+ // TODO
+ }
+
private Iterable<PermissionEntry> filterEntries(final @Nonnull Tree tree,
final @Nullable PropertyState property) {
- return Iterables.filter(
- Iterables.concat(userEntries.values(), groupEntries.values()),
+ return Iterables.filter(entries.values(),
new Predicate<PermissionEntry>() {
@Override
public boolean apply(@Nullable PermissionEntry entry) {
@@ -199,36 +201,41 @@ class CompiledPermissionImpl implements
private final String path;
private final int depth;
private final long index;
+ private boolean isGroupEntry;
- private Key(Tree tree) {
+ private Key(Tree tree, boolean isGroupEntry) {
path = Strings.emptyToNull(TreeUtil.getString(tree, REP_ACCESS_CONTROLLED_PATH));
depth = (path == null) ? 0 : PathUtils.getDepth(path);
index = checkNotNull(tree.getProperty(REP_INDEX).getValue(Type.LONG)).longValue();
+ this.isGroupEntry = isGroupEntry;
}
@Override
public int compareTo(Key key) {
checkNotNull(key);
+ if (isGroupEntry != key.isGroupEntry) {
+ return (isGroupEntry) ? 1 : -1;
+ }
if (Objects.equal(path, key.path)) {
if (index == key.index) {
return 0;
- } else if (index < key.index) {
- return -1;
- } else {
+ } else if (index < key.index) {
return 1;
+ } else {
+ return -1;
}
} else {
if (depth == key.depth) {
return path.compareTo(key.path);
} else {
- return (depth < key.depth) ? -1 : 1;
+ return (depth < key.depth) ? 1 : -1;
}
}
}
@Override
public int hashCode() {
- return Objects.hashCode(path, index);
+ return Objects.hashCode(path, index, isGroupEntry);
}
@Override
@@ -238,7 +245,9 @@ class CompiledPermissionImpl implements
}
if (o instanceof Key) {
Key other = (Key) o;
- return index == other.index && Objects.equal(path, other.path);
+ return index == other.index
+ && isGroupEntry == other.isGroupEntry
+ && Objects.equal(path, other.path);
}
return false;
}
@@ -251,10 +260,12 @@ class CompiledPermissionImpl implements
private final String path;
private final RestrictionPattern restriction;
+ private ReadStatus readStatus;
+
private PermissionEntry(String accessControlledPath, Tree entryTree, RestrictionProvider restrictionsProvider) {
isAllow = (PREFIX_ALLOW == entryTree.getName().charAt(0));
privilegeBits = PrivilegeBits.getInstance(entryTree.getProperty(REP_PRIVILEGE_BITS));
- this.path = accessControlledPath;
+ path = accessControlledPath;
restriction = restrictionsProvider.getPattern(accessControlledPath, entryTree);
}
@@ -275,24 +286,20 @@ class CompiledPermissionImpl implements
private static final class EntriesBuilder {
private ImmutableSortedMap.Builder<Key, PermissionEntry> repoEntries = ImmutableSortedMap.naturalOrder();
- private ImmutableSortedMap.Builder<Key, PermissionEntry> userEntries = ImmutableSortedMap.naturalOrder();
- private ImmutableSortedMap.Builder<Key, PermissionEntry> groupEntries = ImmutableSortedMap.naturalOrder();
+ private ImmutableSortedMap.Builder<Key, PermissionEntry> entries = ImmutableSortedMap.naturalOrder();
private void addEntries(@Nonnull Principal principal,
@Nonnull Tree principalRoot,
@Nonnull RestrictionProvider restrictionProvider) {
+ boolean isGroupEntry = (principal instanceof Group);
for (Tree entryTree : principalRoot.getChildren()) {
- Key key = new Key(entryTree);
+ Key key = new Key(entryTree, isGroupEntry);
PermissionEntry entry = new PermissionEntry(key.path, entryTree, restrictionProvider);
if (!entry.privilegeBits.isEmpty()) {
if (key.path == null) {
repoEntries.put(key, entry);
} else {
- if (principal instanceof Group) {
- groupEntries.put(key, entry);
- } else {
- userEntries.put(key, entry);
- }
+ entries.put(key, entry);
}
}
}
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/permission/PermissionProviderImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/permission/PermissionProviderImpl.java?rev=1462015&r1=1462014&r2=1462015&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/permission/PermissionProviderImpl.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/permission/PermissionProviderImpl.java Thu Mar 28 10:07:56 2013
@@ -22,7 +22,6 @@ import javax.annotation.CheckForNull;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
-import com.google.common.base.Strings;
import org.apache.jackrabbit.JcrConstants;
import org.apache.jackrabbit.oak.api.PropertyState;
import org.apache.jackrabbit.oak.api.Root;
@@ -110,8 +109,8 @@ public class PermissionProviderImpl impl
} else if (isAccessControlContent(tree) && canReadAccessControlContent(tree, property)) {
// TODO: review if read-ac permission is never fine-granular
return ReadStatus.ALLOW_ALL;
- } else if (isVersionContent(tree) && canReadVersionContent(tree, property)) {
- return ReadStatus.ALLOW_THIS;
+ } else if (isVersionContent(tree)) {
+ return getVersionContentReadStatus(tree, property);
} else {
return compiledPermissions.getReadStatus(tree, property);
}
@@ -125,8 +124,16 @@ public class PermissionProviderImpl impl
@Override
public boolean isGranted(@Nonnull Tree tree, @Nullable PropertyState property, long permissions) {
if (isVersionContent(tree)) {
- String path = getVersionablePath(tree, property);
- return path != null && compiledPermissions.isGranted(path, permissions);
+ TreeLocation location = getVersionableLocation(tree, property);
+ if (location == null) {
+ return false;
+ }
+ Tree versionableTree = (property == null) ? location.getTree() : location.getParent().getTree();
+ if (versionableTree != null) {
+ return compiledPermissions.isGranted(versionableTree, property, permissions);
+ } else {
+ return compiledPermissions.isGranted(location.getPath(), permissions);
+ }
} else {
return compiledPermissions.isGranted(tree, property, permissions);
}
@@ -199,18 +206,29 @@ public class PermissionProviderImpl impl
return ImmutableTree.TypeProvider.TYPE_VERSION == ImmutableTree.getType(tree);
}
- private boolean canReadVersionContent(@Nonnull Tree versionStoreTree, @Nullable PropertyState property) {
- String versionablePath = getVersionablePath(versionStoreTree, property);
- if (versionablePath != null) {
- long permission = (property == null) ? Permissions.READ_NODE : Permissions.READ_PROPERTY;
- return compiledPermissions.isGranted(versionablePath, permission);
+ private ReadStatus getVersionContentReadStatus(@Nonnull Tree versionStoreTree, @Nullable PropertyState property) {
+ TreeLocation location = getVersionableLocation(versionStoreTree, property);
+ ReadStatus status;
+ if (location != null) {
+ Tree tree = (property == null) ? location.getTree() : location.getParent().getTree();
+ if (tree == null) {
+ long permission = (property == null) ? Permissions.READ_NODE : Permissions.READ_PROPERTY;
+ if (compiledPermissions.isGranted(location.getPath(), permission)) {
+ status = ReadStatus.ALLOW_THIS;
+ } else {
+ status = ReadStatus.DENY_THIS;
+ }
+ } else {
+ status = compiledPermissions.getReadStatus(tree, property);
+ }
} else {
- return false;
+ status = ReadStatus.DENY_THIS;
}
+ return status;
}
@CheckForNull
- private String getVersionablePath(@Nonnull Tree versionStoreTree, @Nullable PropertyState property) {
+ private TreeLocation getVersionableLocation(@Nonnull Tree versionStoreTree, @Nullable PropertyState property) {
String relPath = "";
String propName = (property == null) ? "" : property.getName();
String versionablePath = null;
@@ -232,7 +250,9 @@ public class PermissionProviderImpl impl
if (versionablePath == null || versionablePath.length() == 0) {
log.warn("Unable to determine path of the version controlled node.");
+ return null;
+ } else {
+ return getImmutableRoot().getLocation(versionablePath);
}
- return Strings.emptyToNull(versionablePath);
}
}
Added: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/permission/CompiledPermissionImplTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/permission/CompiledPermissionImplTest.java?rev=1462015&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/permission/CompiledPermissionImplTest.java (added)
+++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/permission/CompiledPermissionImplTest.java Thu Mar 28 10:07:56 2013
@@ -0,0 +1,350 @@
+/*
+ * 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.permission;
+
+import java.security.Principal;
+import java.security.acl.Group;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.List;
+import java.util.Set;
+import javax.annotation.Nonnull;
+
+import com.google.common.base.Objects;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+import org.apache.jackrabbit.oak.AbstractSecurityTest;
+import org.apache.jackrabbit.oak.api.CommitFailedException;
+import org.apache.jackrabbit.oak.api.Tree;
+import org.apache.jackrabbit.oak.core.ImmutableRoot;
+import org.apache.jackrabbit.oak.core.ImmutableTree;
+import org.apache.jackrabbit.oak.namepath.NamePathMapper;
+import org.apache.jackrabbit.oak.security.SecurityProviderImpl;
+import org.apache.jackrabbit.oak.security.authorization.restriction.RestrictionProviderImpl;
+import org.apache.jackrabbit.oak.security.principal.PrincipalImpl;
+import org.apache.jackrabbit.oak.security.privilege.PrivilegeBits;
+import org.apache.jackrabbit.oak.security.privilege.PrivilegeBitsProvider;
+import org.apache.jackrabbit.oak.security.privilege.PrivilegeConstants;
+import org.apache.jackrabbit.oak.spi.security.SecurityProvider;
+import org.apache.jackrabbit.oak.spi.security.authorization.AccessControlConfiguration;
+import org.apache.jackrabbit.oak.spi.security.authorization.OpenAccessControlConfiguration;
+import org.apache.jackrabbit.oak.spi.security.authorization.permission.ReadStatus;
+import org.apache.jackrabbit.oak.spi.security.authorization.restriction.Restriction;
+import org.apache.jackrabbit.oak.spi.security.authorization.restriction.RestrictionProvider;
+import org.apache.jackrabbit.oak.spi.security.principal.EveryonePrincipal;
+import org.apache.jackrabbit.oak.spi.security.user.UserConstants;
+import org.apache.jackrabbit.oak.util.NodeUtil;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+
+import static org.apache.jackrabbit.JcrConstants.JCR_PRIMARYTYPE;
+import static org.apache.jackrabbit.JcrConstants.NT_UNSTRUCTURED;
+import static org.junit.Assert.assertSame;
+
+/**
+ * CompiledPermissionImplTest... TODO
+ */
+@Ignore("work in progress")
+public class CompiledPermissionImplTest extends AbstractSecurityTest implements PermissionConstants {
+
+ private Principal userPrincipal;
+ private Principal group1;
+ private Principal group2;
+ private Principal group3;
+
+ private PrivilegeBitsProvider pbp;
+ private RestrictionProvider rp;
+
+ private String node1Path = "/nodeName1";
+ private String node2Path = node1Path + "/nodeName2";
+
+ private List<String> allPaths;
+ private List<String> rootAndUsers;
+ private List<String> nodePaths;
+
+ @Before
+ @Override
+ public void before() throws Exception {
+ super.before();
+
+ userPrincipal = new PrincipalImpl("test");
+ group1 = EveryonePrincipal.getInstance();
+ group2 = new GroupImpl("group2");
+ group3 = new GroupImpl("group3");
+
+ pbp = new PrivilegeBitsProvider(root);
+ rp = new RestrictionProviderImpl(NamePathMapper.DEFAULT);
+
+ NodeUtil rootNode = new NodeUtil(root.getTree("/"));
+ NodeUtil system = rootNode.getChild("jcr:system");
+ NodeUtil perms = system.addChild(REP_PERMISSION_STORE, NT_REP_PERMISSION_STORE);
+ perms.addChild(userPrincipal.getName(), NT_REP_PERMISSION_STORE);
+ perms.addChild(group1.getName(), NT_REP_PERMISSION_STORE);
+ perms.addChild(group2.getName(), NT_REP_PERMISSION_STORE);
+ perms.addChild(group3.getName(), NT_REP_PERMISSION_STORE);
+ NodeUtil testNode = rootNode.addChild("nodeName1", NT_UNSTRUCTURED);
+ testNode.setString("propName1", "strValue");
+ NodeUtil testNode2 = testNode.addChild("nodeName2", NT_UNSTRUCTURED);
+ testNode2.setString("propName2", "strValue");
+ root.commit();
+
+ allPaths = ImmutableList.of("/").of(UserConstants.DEFAULT_USER_PATH).of(node1Path).of(node2Path);
+ rootAndUsers = ImmutableList.of("/").of(UserConstants.DEFAULT_USER_PATH);
+ nodePaths = ImmutableList.of(node1Path).of(node2Path);
+ }
+
+ @Override
+ public void after() throws Exception {
+ root.getTree(PERMISSIONS_STORE_PATH).remove();
+ root.commit();
+
+ super.after();
+ }
+
+ @Override
+ protected SecurityProvider getSecurityProvider() {
+ return new SecurityProviderImpl() {
+ @Nonnull
+ @Override
+ public AccessControlConfiguration getAccessControlConfiguration() {
+ return new OpenAccessControlConfiguration();
+ }
+ };
+ }
+
+ @Test
+ public void testGetReadStatus() throws Exception {
+ setupPermission(userPrincipal, "/", true, 0, pbp.getBits(PrivilegeConstants.JCR_READ), Collections.<Restriction>emptySet());
+
+ CompiledPermissionImpl cp = createPermissions(ImmutableSet.of(userPrincipal));
+ assertReadStatus(ReadStatus.ALLOW_ALL, cp, allPaths);
+ }
+
+ @Test
+ public void testGetReadStatus1() throws Exception {
+ setupPermission(group1, node2Path, true, 0, pbp.getBits(PrivilegeConstants.JCR_READ), Collections.<Restriction>emptySet());
+
+ CompiledPermissionImpl cp = createPermissions(ImmutableSet.of(userPrincipal));
+
+ assertReadStatus(ReadStatus.DENY_THIS, cp, Collections.singletonList("/"));
+
+
+ List<String> treePaths = ImmutableList.of(node1Path).of(node1Path).of(UserConstants.DEFAULT_USER_PATH);
+ assertReadStatus(ReadStatus.ALLOW_ALL, cp, treePaths);
+ }
+
+ @Test
+ public void testGetReadStatus2() throws Exception {
+ setupPermission(userPrincipal, "/", true, 0, pbp.getBits(PrivilegeConstants.JCR_READ), Collections.<Restriction>emptySet());
+ setupPermission(group1, "/", false, 0, pbp.getBits(PrivilegeConstants.JCR_READ), Collections.<Restriction>emptySet());
+
+ CompiledPermissionImpl cp = createPermissions(ImmutableSet.of(userPrincipal));
+ assertReadStatus(ReadStatus.ALLOW_ALL, cp, allPaths);
+ }
+
+ @Test
+ public void testGetReadStatus3() throws Exception {
+ setupPermission(group1, "/", true, 0, pbp.getBits(PrivilegeConstants.JCR_READ), Collections.<Restriction>emptySet());
+ setupPermission(group2, "/", false, 1, pbp.getBits(PrivilegeConstants.JCR_READ), Collections.<Restriction>emptySet());
+
+ CompiledPermissionImpl cp = createPermissions(ImmutableSet.of(group1, group2));
+ assertReadStatus(ReadStatus.DENY_ALL, cp, allPaths);
+ }
+
+ @Test
+ public void testGetReadStatus4() throws Exception {
+ setupPermission(group1, "/", true, 0, pbp.getBits(PrivilegeConstants.JCR_READ), Collections.<Restriction>emptySet());
+ setupPermission(group2, node2Path, true, 1, pbp.getBits(PrivilegeConstants.JCR_READ), Collections.<Restriction>emptySet());
+
+ CompiledPermissionImpl cp = createPermissions(ImmutableSet.of(group1, group2));
+ assertReadStatus(ReadStatus.ALLOW_ALL, cp, allPaths);
+ }
+
+ @Test
+ public void testGetReadStatus5() throws Exception {
+ setupPermission(userPrincipal, "/", true, 0, pbp.getBits(PrivilegeConstants.JCR_READ), Collections.<Restriction>emptySet());
+ setupPermission(group2, node1Path, false, 1, pbp.getBits(PrivilegeConstants.JCR_READ), Collections.<Restriction>emptySet());
+
+ CompiledPermissionImpl cp = createPermissions(ImmutableSet.of(userPrincipal, group2));
+ assertReadStatus(ReadStatus.ALLOW_ALL, cp, allPaths);
+ }
+
+ @Test
+ public void testGetReadStatus6() throws Exception {
+ setupPermission(group2, "/", true, 0, pbp.getBits(PrivilegeConstants.JCR_READ), Collections.<Restriction>emptySet());
+ setupPermission(userPrincipal, node1Path, false, 0, pbp.getBits(PrivilegeConstants.JCR_READ), Collections.<Restriction>emptySet());
+
+ CompiledPermissionImpl cp = createPermissions(ImmutableSet.of(userPrincipal, group2));
+
+ assertReadStatus(ReadStatus.ALLOW_THIS, cp, rootAndUsers);
+ assertReadStatus(ReadStatus.DENY_ALL, cp, nodePaths);
+ }
+
+ @Test
+ public void testGetReadStatus7() throws Exception {
+ setupPermission(group2, "/", true, 0, pbp.getBits(PrivilegeConstants.REP_READ_PROPERTIES), Collections.<Restriction>emptySet());
+ setupPermission(userPrincipal, node1Path, true, 0, pbp.getBits(PrivilegeConstants.REP_READ_NODES), Collections.<Restriction>emptySet());
+
+ CompiledPermissionImpl cp = createPermissions(ImmutableSet.of(userPrincipal, group2));
+
+ assertReadStatus(ReadStatus.ALLOW_PROPERTIES, cp, rootAndUsers);
+ assertReadStatus(ReadStatus.ALLOW_ALL, cp, nodePaths);
+ }
+
+ @Test
+ public void testGetReadStatus8() throws Exception {
+ setupPermission(userPrincipal, "/", true, 0, pbp.getBits(PrivilegeConstants.REP_READ_PROPERTIES), Collections.<Restriction>emptySet());
+ setupPermission(group2, node1Path, true, 0, pbp.getBits(PrivilegeConstants.REP_READ_NODES), Collections.<Restriction>emptySet());
+
+ CompiledPermissionImpl cp = createPermissions(ImmutableSet.of(userPrincipal, group2));
+
+ assertReadStatus(ReadStatus.DENY_THIS, ReadStatus.ALLOW_PROPERTIES, cp, rootAndUsers); // TODO
+ assertReadStatus(ReadStatus.ALLOW_ALL, cp, nodePaths); // TODO
+ }
+
+ @Test
+ public void testGetReadStatus9() throws Exception {
+ setupPermission(group2, "/", true, 0, pbp.getBits(PrivilegeConstants.REP_READ_PROPERTIES), Collections.<Restriction>emptySet());
+ setupPermission(group1, node1Path, true, 0, pbp.getBits(PrivilegeConstants.REP_READ_NODES), Collections.<Restriction>emptySet());
+
+ CompiledPermissionImpl cp = createPermissions(ImmutableSet.of(group1, group2));
+
+ assertReadStatus(ReadStatus.ALLOW_PROPERTIES, cp, rootAndUsers);
+ assertReadStatus(ReadStatus.ALLOW_ALL, cp, nodePaths);
+ }
+
+ @Test
+ public void testGetReadStatus10() throws Exception {
+ setupPermission(group2, "/", false, 0, pbp.getBits(PrivilegeConstants.JCR_READ), Collections.<Restriction>emptySet());
+ setupPermission(group1, node1Path, true, 0, pbp.getBits(PrivilegeConstants.REP_READ_NODES), Collections.<Restriction>emptySet());
+
+ CompiledPermissionImpl cp = createPermissions(ImmutableSet.of(group1, group2));
+
+ assertReadStatus(ReadStatus.DENY_THIS, cp, rootAndUsers);
+ assertReadStatus(ReadStatus.ALLOW_NODES, cp, nodePaths);
+ }
+
+ @Test
+ public void testGetReadStatus11() throws Exception {
+ setupPermission(group2, "/", false, 0, pbp.getBits(PrivilegeConstants.JCR_READ), Collections.<Restriction>emptySet());
+ setupPermission(group2, node1Path, false, 0, pbp.getBits(PrivilegeConstants.JCR_READ), Collections.<Restriction>emptySet());
+ setupPermission(group1, node2Path, true, 0, pbp.getBits(PrivilegeConstants.REP_READ_NODES), Collections.<Restriction>emptySet());
+
+ CompiledPermissionImpl cp = createPermissions(ImmutableSet.of(group1, group2));
+
+ List<String> treePaths = ImmutableList.of("/").of(UserConstants.DEFAULT_USER_PATH).of(node1Path);
+ assertReadStatus(ReadStatus.DENY_THIS, cp, treePaths);
+ assertReadStatus(ReadStatus.ALLOW_NODES, cp, Collections.singletonList(node2Path));
+ }
+
+ @Test
+ public void testGetReadStatus12() throws Exception {
+ setupPermission(group1, "/", true, 0, pbp.getBits(PrivilegeConstants.JCR_READ), Collections.<Restriction>emptySet());
+ setupPermission(group1, node1Path, false, 0, pbp.getBits(PrivilegeConstants.REP_READ_PROPERTIES), Collections.<Restriction>emptySet());
+ setupPermission(group1, node2Path, true, 0, pbp.getBits(PrivilegeConstants.REP_READ_NODES), Collections.<Restriction>emptySet());
+
+ CompiledPermissionImpl cp = createPermissions(ImmutableSet.of(group1));
+
+ assertReadStatus(ReadStatus.ALLOW_THIS, cp, rootAndUsers);
+ assertReadStatus(ReadStatus.ALLOW_NODES, cp, nodePaths);
+ }
+
+ @Test
+ public void testGetReadStatus13() throws Exception {
+ setupPermission(group1, "/", true, 0, pbp.getBits(PrivilegeConstants.JCR_READ), Collections.<Restriction>emptySet());
+ setupPermission(group1, node1Path, false, 0, pbp.getBits(PrivilegeConstants.REP_READ_PROPERTIES), Collections.<Restriction>emptySet());
+ setupPermission(group1, node2Path, true, 0, pbp.getBits(PrivilegeConstants.JCR_READ), Collections.<Restriction>emptySet());
+
+ CompiledPermissionImpl cp = createPermissions(ImmutableSet.of(group1));
+
+ assertReadStatus(ReadStatus.ALLOW_THIS, cp, rootAndUsers);
+ assertReadStatus(ReadStatus.ALLOW_NODES, cp, Collections.singletonList(node1Path));
+ assertReadStatus(ReadStatus.ALLOW_ALL, cp, nodePaths);
+ }
+
+ private CompiledPermissionImpl createPermissions(Set<Principal> principals) {
+ ImmutableTree permissionsTree = new ImmutableRoot(root, ImmutableTree.TypeProvider.EMPTY).getTree(PERMISSIONS_STORE_PATH);
+ return new CompiledPermissionImpl(principals, permissionsTree, pbp, rp);
+ }
+
+ private void setupPermission(Principal principal, String path, boolean isAllow,
+ int index, PrivilegeBits pb, Set<Restriction> restrictions) throws CommitFailedException {
+ String name = ((isAllow) ? PREFIX_ALLOW : PREFIX_DENY) + "-" + Objects.hashCode(path, principal, index, pb, isAllow, restrictions);
+ Tree principalRoot = root.getTree(PERMISSIONS_STORE_PATH + '/' + principal.getName());
+ Tree entry = principalRoot.addChild(name);
+ entry.setProperty(JCR_PRIMARYTYPE, NT_REP_PERMISSIONS);
+ entry.setProperty(REP_ACCESS_CONTROLLED_PATH, path);
+ entry.setProperty(REP_INDEX, index);
+ entry.setProperty(pb.asPropertyState(REP_PRIVILEGE_BITS));
+ for (Restriction restriction : restrictions) {
+ entry.setProperty(restriction.getProperty());
+ }
+ root.commit();
+ }
+
+ private void assertReadStatus(ReadStatus expectedTrees,
+ CompiledPermissions cp,
+ List<String> treePaths) {
+ assertReadStatus(expectedTrees, expectedTrees, cp, treePaths);
+ }
+
+ private void assertReadStatus(ReadStatus expectedTrees,
+ ReadStatus expectedProperties,
+ CompiledPermissions cp,
+ List<String> treePaths) {
+ for (String path : treePaths) {
+ Tree node = root.getTree(path);
+ assertSame(expectedTrees, cp.getReadStatus(node, null));
+ assertSame(expectedProperties, cp.getReadStatus(node, node.getProperty(JCR_PRIMARYTYPE)));
+ }
+ }
+
+ private class GroupImpl implements Group {
+
+ private final String name;
+
+ private GroupImpl(String name) {
+ this.name = name;
+ }
+
+ @Override
+ public boolean addMember(Principal principal) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean removeMember(Principal principal) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean isMember(Principal principal) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Enumeration<? extends Principal> members() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public String getName() {
+ return name;
+ }
+ }
+}
\ No newline at end of file