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 2014/04/09 15:15:41 UTC
svn commit: r1585963 - in /jackrabbit/oak/trunk/oak-core/src:
main/java/org/apache/jackrabbit/oak/security/authorization/permission/
main/java/org/apache/jackrabbit/oak/security/authorization/restriction/
main/java/org/apache/jackrabbit/oak/spi/securit...
Author: angela
Date: Wed Apr 9 13:15:40 2014
New Revision: 1585963
URL: http://svn.apache.org/r1585963
Log:
OAK-1707 : RestrictionProviderImpl returns empty pattern if all supported restrictions are set
OAK-1706 : Add RestrictionProvider#getPattern(String,Set<Restriction>)
Added:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/permission/PermissionStoreEditor.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/permission/PermissionHook.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/restriction/PrincipalRestrictionProvider.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/restriction/CompositePattern.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/restriction/CompositeRestrictionProvider.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/restriction/RestrictionProvider.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/whiteboard/WhiteboardRestrictionProvider.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-core/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/restriction/TestProvider.java
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=1585963&r1=1585962&r2=1585963&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 Wed Apr 9 13:15:40 2014
@@ -16,7 +16,6 @@
*/
package org.apache.jackrabbit.oak.security.authorization.permission;
-import java.util.Set;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
@@ -26,15 +25,11 @@ import org.apache.jackrabbit.oak.api.Tre
import org.apache.jackrabbit.oak.api.Type;
import org.apache.jackrabbit.oak.commons.PathUtils;
import org.apache.jackrabbit.oak.spi.security.authorization.permission.PermissionConstants;
-import org.apache.jackrabbit.oak.spi.security.authorization.restriction.Restriction;
import org.apache.jackrabbit.oak.spi.security.authorization.restriction.RestrictionPattern;
import org.apache.jackrabbit.oak.spi.security.authorization.restriction.RestrictionProvider;
import org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeBits;
-import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
import org.apache.jackrabbit.util.Text;
-import static org.apache.jackrabbit.JcrConstants.JCR_PRIMARYTYPE;
-
final class PermissionEntry implements Comparable<PermissionEntry>, PermissionConstants {
/**
@@ -62,22 +57,19 @@ final class PermissionEntry implements C
*/
final RestrictionPattern restriction;
- PermissionEntry(String path, Tree entryTree, RestrictionProvider restrictionsProvider) {
- this.path = path;
- isAllow = entryTree.getProperty(REP_IS_ALLOW).getValue(Type.BOOLEAN);
- index = Integer.parseInt(entryTree.getName());
- privilegeBits = PrivilegeBits.getInstance(entryTree.getProperty(REP_PRIVILEGE_BITS));
- restriction = restrictionsProvider.getPattern(path, entryTree);
+ PermissionEntry(@Nonnull String path, @Nonnull Tree entryTree, @Nonnull RestrictionProvider restrictionsProvider) {
+ this(path, entryTree.getProperty(REP_IS_ALLOW).getValue(Type.BOOLEAN),
+ Integer.parseInt(entryTree.getName()),
+ PrivilegeBits.getInstance(entryTree.getProperty(REP_PRIVILEGE_BITS)),
+ restrictionsProvider.getPattern(path, entryTree));
}
- static void write(NodeBuilder parent, boolean isAllow, int index, PrivilegeBits privilegeBits, Set<Restriction> restrictions) {
- NodeBuilder n = parent.child(String.valueOf(index))
- .setProperty(JCR_PRIMARYTYPE, NT_REP_PERMISSIONS, Type.NAME)
- .setProperty(REP_IS_ALLOW, isAllow)
- .setProperty(privilegeBits.asPropertyState(REP_PRIVILEGE_BITS));
- for (Restriction restriction : restrictions) {
- n.setProperty(restriction.getProperty());
- }
+ PermissionEntry(@Nonnull String path, boolean isAllow, int index, @Nonnull PrivilegeBits privilegeBits, @Nonnull RestrictionPattern restriction) {
+ this.path = path;
+ this.isAllow = isAllow;
+ this.index = index;
+ this.privilegeBits = privilegeBits;
+ this.restriction = restriction;
}
public boolean matches(@Nonnull Tree tree, @Nullable PropertyState property) {
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=1585963&r1=1585962&r2=1585963&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 Apr 9 13:15:40 2014
@@ -16,44 +16,28 @@
*/
package org.apache.jackrabbit.oak.security.authorization.permission;
-import java.util.ArrayList;
import java.util.HashMap;
-import java.util.List;
import java.util.Map;
-import java.util.Set;
-
import javax.annotation.Nonnull;
import org.apache.jackrabbit.oak.api.CommitFailedException;
-import org.apache.jackrabbit.oak.api.Type;
import org.apache.jackrabbit.oak.core.ImmutableRoot;
import org.apache.jackrabbit.oak.plugins.nodetype.TypePredicate;
-import org.apache.jackrabbit.oak.plugins.tree.ImmutableTree;
import org.apache.jackrabbit.oak.spi.commit.CommitInfo;
import org.apache.jackrabbit.oak.spi.commit.PostValidationHook;
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.Restriction;
import org.apache.jackrabbit.oak.spi.security.authorization.restriction.RestrictionProvider;
-import org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeBits;
import org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeBitsProvider;
import org.apache.jackrabbit.oak.spi.state.DefaultNodeStateDiff;
import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
import org.apache.jackrabbit.oak.spi.state.NodeState;
import org.apache.jackrabbit.oak.spi.state.NodeStateUtils;
-import org.apache.jackrabbit.util.Text;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import com.google.common.base.Objects;
-import com.google.common.base.Strings;
-
-import static com.google.common.collect.Iterables.addAll;
-import static com.google.common.collect.Sets.newLinkedHashSet;
-import static org.apache.jackrabbit.JcrConstants.JCR_PRIMARYTYPE;
import static org.apache.jackrabbit.JcrConstants.JCR_SYSTEM;
import static org.apache.jackrabbit.oak.plugins.memory.EmptyNodeState.EMPTY_NODE;
-import static org.apache.jackrabbit.oak.plugins.tree.TreeConstants.OAK_CHILD_ORDER;
/**
* {@code CommitHook} implementation that processes any modification made to
@@ -92,8 +76,8 @@ public class PermissionHook implements P
private TypePredicate isACE;
private TypePredicate isGrantACE;
- private Map<String, Acl> modified = new HashMap<String, Acl>();
- private Map<String, Acl> deleted = new HashMap<String, Acl>();
+ private Map<String, PermissionStoreEditor> modified = new HashMap<String, PermissionStoreEditor>();
+ private Map<String, PermissionStoreEditor> deleted = new HashMap<String, PermissionStoreEditor>();
public PermissionHook(String workspaceName, RestrictionProvider restrictionProvider) {
this.workspaceName = workspaceName;
@@ -121,11 +105,11 @@ public class PermissionHook implements P
}
private void apply() {
- for (Map.Entry<String, Acl> entry : deleted.entrySet()) {
- entry.getValue().remove();
+ for (Map.Entry<String, PermissionStoreEditor> entry : deleted.entrySet()) {
+ entry.getValue().removePermissionEntries();
}
- for (Map.Entry<String, Acl> entry : modified.entrySet()) {
- entry.getValue().update();
+ for (Map.Entry<String, PermissionStoreEditor> entry : modified.entrySet()) {
+ entry.getValue().updatePermissionEntries();
}
}
@@ -151,8 +135,8 @@ public class PermissionHook implements P
}
String path = parentPath + '/' + name;
if (isACL.apply(after)) {
- Acl acl = new Acl(parentPath, name, after);
- modified.put(acl.accessControlledPath, acl);
+ PermissionStoreEditor psEditor = createPermissionStoreEditor(name, after);
+ modified.put(psEditor.accessControlledPath, psEditor);
} else {
after.compareAgainstBaseState(EMPTY_NODE, new Diff(path));
}
@@ -168,23 +152,23 @@ public class PermissionHook implements P
String path = parentPath + '/' + name;
if (isACL.apply(before)) {
if (isACL.apply(after)) {
- Acl acl = new Acl(parentPath, name, after);
- modified.put(acl.accessControlledPath, acl);
+ PermissionStoreEditor psEditor = createPermissionStoreEditor(name, after);
+ modified.put(psEditor.accessControlledPath, psEditor);
// also consider to remove the ACL from removed entries of other principals
- Acl beforeAcl = new Acl(parentPath, name, before);
- beforeAcl.entries.keySet().removeAll(acl.entries.keySet());
- if (!beforeAcl.entries.isEmpty()) {
- deleted.put(parentPath, beforeAcl);
+ PermissionStoreEditor beforeEditor = createPermissionStoreEditor(name, before);
+ beforeEditor.entries.keySet().removeAll(psEditor.entries.keySet());
+ if (!beforeEditor.entries.isEmpty()) {
+ deleted.put(parentPath, beforeEditor);
}
} else {
- Acl acl = new Acl(parentPath, name, before);
- deleted.put(acl.accessControlledPath, acl);
+ PermissionStoreEditor psEditor = createPermissionStoreEditor(name, before);
+ deleted.put(psEditor.accessControlledPath, psEditor);
}
} else if (isACL.apply(after)) {
- Acl acl = new Acl(parentPath, name, after);
- modified.put(acl.accessControlledPath, acl);
+ PermissionStoreEditor psEditor = createPermissionStoreEditor(name, after);
+ modified.put(psEditor.accessControlledPath, psEditor);
} else {
after.compareAgainstBaseState(before, new Diff(path));
}
@@ -199,218 +183,16 @@ public class PermissionHook implements P
}
String path = parentPath + '/' + name;
if (isACL.apply(before)) {
- Acl acl = new Acl(parentPath, name, before);
- deleted.put(acl.accessControlledPath, acl);
+ PermissionStoreEditor psEditor = createPermissionStoreEditor(name, before);
+ deleted.put(psEditor.accessControlledPath, psEditor);
} else {
EMPTY_NODE.compareAgainstBaseState(before, new Diff(path));
}
return true;
}
- }
-
- private final class Acl {
-
- private final String accessControlledPath;
-
- private final String nodeName;
-
- private final Map<String, List<AcEntry>> entries = new HashMap<String, List<AcEntry>>();
-
- private Acl(String aclPath, String name, @Nonnull NodeState node) {
- if (name.equals(REP_REPO_POLICY)) {
- this.accessControlledPath = "";
- } else {
- this.accessControlledPath = aclPath.length() == 0 ? "/" : aclPath;
- }
- nodeName = PermissionUtil.getEntryName(accessControlledPath);
-
- Set<String> orderedChildNames =
- newLinkedHashSet(node.getNames(OAK_CHILD_ORDER));
- long n = orderedChildNames.size();
- if (node.getChildNodeCount(n + 1) > n) {
- addAll(orderedChildNames, node.getChildNodeNames());
- }
-
- int index = 0;
- for (String childName : orderedChildNames) {
- NodeState ace = node.getChildNode(childName);
- if (isACE.apply(ace)) {
- AcEntry entry = new AcEntry(ace, accessControlledPath, index);
- List<AcEntry> list = entries.get(entry.principalName);
- if (list == null) {
- list = new ArrayList<AcEntry>();
- entries.put(entry.principalName, list);
- }
- list.add(entry);
- index++;
- }
- }
- }
-
- private void remove() {
- for (String principalName: entries.keySet()) {
- if (permissionRoot.hasChildNode(principalName)) {
- NodeBuilder principalRoot = permissionRoot.getChildNode(principalName);
-
- // find the ACL node that for this path and principal
- NodeBuilder parent = principalRoot.getChildNode(nodeName);
- if (!parent.exists()) {
- continue;
- }
-
- // check if the node is the correct one
- if (PermissionUtil.checkACLPath(parent, accessControlledPath)) {
- // remove and reconnect child nodes
- NodeBuilder newParent = null;
- for (String childName : parent.getChildNodeNames()) {
- if (childName.charAt(0) != 'c') {
- continue;
- }
- NodeBuilder child = parent.getChildNode(childName);
- if (newParent == null) {
- newParent = child;
- } else {
- newParent.setChildNode(childName, child.getNodeState());
- child.remove();
- }
- }
- parent.remove();
- if (newParent != null) {
- principalRoot.setChildNode(nodeName, newParent.getNodeState());
- }
- } else {
- // check if any of the child nodes match
- for (String childName : parent.getChildNodeNames()) {
- if (childName.charAt(0) != 'c') {
- continue;
- }
- NodeBuilder child = parent.getChildNode(childName);
- if (PermissionUtil.checkACLPath(child, accessControlledPath)) {
- child.remove();
- }
- }
- }
- } else {
- log.error("Unable to remove permission entry {}: Principal root missing.", this);
- }
- }
- }
-
- private void update() {
- for (String principalName: entries.keySet()) {
- NodeBuilder principalRoot = permissionRoot.child(principalName);
- if (!principalRoot.hasProperty(JCR_PRIMARYTYPE)) {
- principalRoot.setProperty(JCR_PRIMARYTYPE, NT_REP_PERMISSION_STORE, Type.NAME);
- }
- NodeBuilder parent = principalRoot.child(nodeName);
- if (!parent.hasProperty(JCR_PRIMARYTYPE)) {
- parent.setProperty(JCR_PRIMARYTYPE, NT_REP_PERMISSION_STORE, Type.NAME);
- }
-
- // check if current parent already has the correct path
- if (parent.hasProperty(REP_ACCESS_CONTROLLED_PATH)) {
- if (!PermissionUtil.checkACLPath(parent, accessControlledPath)) {
- // hash collision, find a new child
- NodeBuilder child = null;
- int idx = 0;
- for (String childName : parent.getChildNodeNames()) {
- if (childName.charAt(0) != 'c') {
- continue;
- }
- child = parent.getChildNode(childName);
- if (PermissionUtil.checkACLPath(child, accessControlledPath)) {
- break;
- }
- child = null;
- idx++;
- }
- while (child == null) {
- String name = 'c' + String.valueOf(idx++);
- child = parent.getChildNode(name);
- if (child.exists()) {
- child = null;
- } else {
- child = parent.child(name);
- child.setProperty(JCR_PRIMARYTYPE, NT_REP_PERMISSION_STORE, Type.NAME);
- }
- }
- parent = child;
- parent.setProperty(REP_ACCESS_CONTROLLED_PATH, accessControlledPath);
- }
- } else {
- // new parent
- parent.setProperty(REP_ACCESS_CONTROLLED_PATH, accessControlledPath);
- }
- updateEntries(parent, entries.get(principalName));
- }
- }
-
- private void updateEntries(NodeBuilder parent, List<AcEntry> list) {
- // remove old entries
- for (String childName : parent.getChildNodeNames()) {
- if (childName.charAt(0) != 'c') {
- parent.getChildNode(childName).remove();
- }
- }
- for (AcEntry ace: list) {
- PermissionEntry.write(parent, ace.isAllow, ace.index, ace.privilegeBits, ace.restrictions);
- }
- }
- }
-
- private final class AcEntry {
- private final String accessControlledPath;
- private final String principalName;
- private final PrivilegeBits privilegeBits;
- private final boolean isAllow;
- private final Set<Restriction> restrictions;
- private final int index;
- private int hashCode = -1;
-
- private AcEntry(@Nonnull NodeState node, @Nonnull String accessControlledPath, int index) {
- this.accessControlledPath = accessControlledPath;
- this.index = index;
-
- principalName = Text.escapeIllegalJcrChars(node.getString(REP_PRINCIPAL_NAME));
- privilegeBits = bitsProvider.getBits(node.getNames(REP_PRIVILEGES));
- isAllow = isGrantACE.apply(node);
- restrictions = restrictionProvider.readRestrictions(Strings.emptyToNull(accessControlledPath), new ImmutableTree(node));
- }
-
- @Override
- public int hashCode() {
- if (hashCode == -1) {
- hashCode = Objects.hashCode(accessControlledPath, principalName, privilegeBits, isAllow, restrictions);
- }
- return hashCode;
- }
-
- @Override
- public boolean equals(Object o) {
- if (o == this) {
- return true;
- }
- if (o instanceof AcEntry) {
- AcEntry other = (AcEntry) o;
- return isAllow == other.isAllow
- && privilegeBits.equals(other.privilegeBits)
- && principalName.equals(other.principalName)
- && accessControlledPath.equals(other.accessControlledPath)
- && restrictions.equals(other.restrictions);
- }
- return false;
- }
-
- @Override
- public String toString() {
- StringBuilder sb = new StringBuilder();
- sb.append(accessControlledPath);
- sb.append(';').append(principalName);
- sb.append(';').append(isAllow ? "allow" : "deny");
- sb.append(';').append(bitsProvider.getPrivilegeNames(privilegeBits));
- sb.append(';').append(restrictions);
- return sb.toString();
+ private PermissionStoreEditor createPermissionStoreEditor(@Nonnull String nodeName, @Nonnull NodeState nodeState) {
+ return new PermissionStoreEditor(parentPath, nodeName, nodeState, permissionRoot, isACE, isGrantACE, bitsProvider, restrictionProvider);
}
}
}
Added: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/permission/PermissionStoreEditor.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/permission/PermissionStoreEditor.java?rev=1585963&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/permission/PermissionStoreEditor.java (added)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/permission/PermissionStoreEditor.java Wed Apr 9 13:15:40 2014
@@ -0,0 +1,332 @@
+/*
+ * 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.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import javax.annotation.Nonnull;
+
+import com.google.common.base.Objects;
+import com.google.common.base.Strings;
+import com.google.common.collect.Maps;
+import org.apache.jackrabbit.oak.api.Type;
+import org.apache.jackrabbit.oak.plugins.nodetype.TypePredicate;
+import org.apache.jackrabbit.oak.plugins.tree.ImmutableTree;
+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.Restriction;
+import org.apache.jackrabbit.oak.spi.security.authorization.restriction.RestrictionProvider;
+import org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeBits;
+import org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeBitsProvider;
+import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
+import org.apache.jackrabbit.oak.spi.state.NodeState;
+import org.apache.jackrabbit.util.Text;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import static com.google.common.collect.Iterables.addAll;
+import static com.google.common.collect.Sets.newLinkedHashSet;
+import static org.apache.jackrabbit.JcrConstants.JCR_PRIMARYTYPE;
+import static org.apache.jackrabbit.oak.plugins.tree.TreeConstants.OAK_CHILD_ORDER;
+
+final class PermissionStoreEditor implements AccessControlConstants, PermissionConstants {
+
+ private static final Logger log = LoggerFactory.getLogger(PermissionStoreEditor.class);
+
+ final String accessControlledPath;
+ final String nodeName;
+ final Map<String, List<AcEntry>> entries = Maps.<String, List<AcEntry>>newHashMap();
+
+ private final NodeBuilder permissionRoot;
+ private final TypePredicate isACE;
+ private final RestrictionProvider restrictionProvider;
+
+ PermissionStoreEditor(@Nonnull String aclPath, @Nonnull String name,
+ @Nonnull NodeState node, @Nonnull NodeBuilder permissionRoot,
+ @Nonnull TypePredicate isACE, @Nonnull TypePredicate isGrantACE,
+ @Nonnull PrivilegeBitsProvider bitsProvider,
+ @Nonnull RestrictionProvider restrictionProvider) {
+ this.permissionRoot = permissionRoot;
+ this.isACE = isACE;
+ this.restrictionProvider = restrictionProvider;
+
+ if (name.equals(REP_REPO_POLICY)) {
+ accessControlledPath = "";
+ } else {
+ accessControlledPath = aclPath.length() == 0 ? "/" : aclPath;
+ }
+ nodeName = PermissionUtil.getEntryName(accessControlledPath);
+
+ Set<String> orderedChildNames = newLinkedHashSet(node.getNames(OAK_CHILD_ORDER));
+ long n = orderedChildNames.size();
+ if (node.getChildNodeCount(n + 1) > n) {
+ addAll(orderedChildNames, node.getChildNodeNames());
+ }
+
+ int index = 0;
+ for (String childName : orderedChildNames) {
+ NodeState ace = node.getChildNode(childName);
+ if (isACE.apply(ace)) {
+ boolean isAllow = isGrantACE.apply(ace);
+ PrivilegeBits privilegeBits = bitsProvider.getBits(ace.getNames(REP_PRIVILEGES));
+ Set<Restriction> restrictions = restrictionProvider.readRestrictions(Strings.emptyToNull(accessControlledPath), new ImmutableTree(ace));
+
+
+ AcEntry entry = new AcEntry(ace, accessControlledPath, index, isAllow, privilegeBits, restrictions);
+ List<AcEntry> list = entries.get(entry.principalName);
+ if (list == null) {
+ list = new ArrayList<AcEntry>();
+ entries.put(entry.principalName, list);
+ }
+ list.add(entry);
+ index++;
+ }
+ }
+ }
+
+ void removePermissionEntry(@Nonnull String principalName, @Nonnull PermissionEntry permissionEntry) {
+ if (permissionRoot.hasChildNode(principalName)) {
+ NodeBuilder principalRoot = permissionRoot.getChildNode(principalName);
+
+ // find the ACL node that for this path and principal
+ NodeBuilder parent = principalRoot.getChildNode(nodeName);
+ if (!parent.exists()) {
+ log.error("Unable to remove permission entry {}: Parent for node " + nodeName + " missing.", this);
+ return;
+ }
+
+ // check if the node is the correct one
+ if (!PermissionUtil.checkACLPath(parent, accessControlledPath)) {
+ parent = null;
+ // find the right collision node
+ for (String childName : parent.getChildNodeNames()) {
+ if (childName.charAt(0) != 'c') {
+ continue;
+ }
+ NodeBuilder child = parent.getChildNode(childName);
+ if (PermissionUtil.checkACLPath(child, accessControlledPath)) {
+ parent = child;
+ break;
+ }
+ }
+ if (parent == null) {
+ log.error("Unable to remove permission entry {}: Parent for node " + nodeName + " missing.", this);
+ return;
+ }
+ }
+
+ for (String childName : parent.getChildNodeNames()) {
+ if (childName.charAt(0) == 'c') {
+ continue;
+ }
+
+ NodeBuilder entryNode = parent.getChildNode(childName);
+ if (permissionEntry.equals(new PermissionEntry(accessControlledPath, new ImmutableTree(entryNode.getNodeState()), restrictionProvider))) {
+ entryNode.remove();
+ }
+ }
+ } else {
+ log.error("Unable to remove permission entry {}: Principal root missing.", this);
+ }
+ }
+
+ void removePermissionEntries() {
+ for (String principalName : entries.keySet()) {
+ if (permissionRoot.hasChildNode(principalName)) {
+ NodeBuilder principalRoot = permissionRoot.getChildNode(principalName);
+
+ // find the ACL node that for this path and principal
+ NodeBuilder parent = principalRoot.getChildNode(nodeName);
+ if (!parent.exists()) {
+ continue;
+ }
+
+ // check if the node is the correct one
+ if (PermissionUtil.checkACLPath(parent, accessControlledPath)) {
+ // remove and reconnect child nodes
+ NodeBuilder newParent = null;
+ for (String childName : parent.getChildNodeNames()) {
+ if (childName.charAt(0) != 'c') {
+ continue;
+ }
+ NodeBuilder child = parent.getChildNode(childName);
+ if (newParent == null) {
+ newParent = child;
+ } else {
+ newParent.setChildNode(childName, child.getNodeState());
+ child.remove();
+ }
+ }
+ parent.remove();
+ if (newParent != null) {
+ principalRoot.setChildNode(nodeName, newParent.getNodeState());
+ }
+ } else {
+ // check if any of the child nodes match
+ for (String childName : parent.getChildNodeNames()) {
+ if (childName.charAt(0) != 'c') {
+ continue;
+ }
+ NodeBuilder child = parent.getChildNode(childName);
+ if (PermissionUtil.checkACLPath(child, accessControlledPath)) {
+ child.remove();
+ }
+ }
+ }
+ } else {
+ log.error("Unable to remove permission entry {}: Principal root missing.", this);
+ }
+ }
+ }
+
+ void updatePermissionEntries() {
+ for (String principalName: entries.keySet()) {
+ NodeBuilder principalRoot = permissionRoot.child(principalName);
+ if (!principalRoot.hasProperty(JCR_PRIMARYTYPE)) {
+ principalRoot.setProperty(JCR_PRIMARYTYPE, NT_REP_PERMISSION_STORE, Type.NAME);
+ }
+ NodeBuilder parent = principalRoot.child(nodeName);
+ if (!parent.hasProperty(JCR_PRIMARYTYPE)) {
+ parent.setProperty(JCR_PRIMARYTYPE, NT_REP_PERMISSION_STORE, Type.NAME);
+ }
+
+ // check if current parent already has the correct path
+ if (parent.hasProperty(REP_ACCESS_CONTROLLED_PATH)) {
+ if (!PermissionUtil.checkACLPath(parent, accessControlledPath)) {
+ // hash collision, find a new child
+ NodeBuilder child = null;
+ int idx = 0;
+ for (String childName : parent.getChildNodeNames()) {
+ if (childName.charAt(0) != 'c') {
+ continue;
+ }
+ child = parent.getChildNode(childName);
+ if (PermissionUtil.checkACLPath(child, accessControlledPath)) {
+ break;
+ }
+ child = null;
+ idx++;
+ }
+ while (child == null) {
+ String name = 'c' + String.valueOf(idx++);
+ child = parent.getChildNode(name);
+ if (child.exists()) {
+ child = null;
+ } else {
+ child = parent.child(name);
+ child.setProperty(JCR_PRIMARYTYPE, NT_REP_PERMISSION_STORE, Type.NAME);
+ }
+ }
+ parent = child;
+ parent.setProperty(REP_ACCESS_CONTROLLED_PATH, accessControlledPath);
+ }
+ } else {
+ // new parent
+ parent.setProperty(REP_ACCESS_CONTROLLED_PATH, accessControlledPath);
+ }
+ updateEntries(parent, entries.get(principalName));
+ }
+ }
+
+ private void updateEntries(NodeBuilder parent, List<AcEntry> list) {
+ // remove old entries
+ for (String childName : parent.getChildNodeNames()) {
+ if (childName.charAt(0) != 'c') {
+ parent.getChildNode(childName).remove();
+ }
+ }
+ for (AcEntry ace: list) {
+ ace.writeToPermissionStore(parent);
+ }
+ }
+
+ final class AcEntry {
+
+ final String accessControlledPath;
+ final String principalName;
+ final PrivilegeBits privilegeBits;
+ final boolean isAllow;
+ final Set<Restriction> restrictions;
+ final int index;
+ int hashCode = -1;
+
+ private TypePredicate isACE;
+
+ AcEntry(@Nonnull NodeState node, @Nonnull String accessControlledPath, int index,
+ boolean isAllow, PrivilegeBits privilegeBits, Set<Restriction> restrictions) {
+ this.accessControlledPath = accessControlledPath;
+ this.index = index;
+
+ this.principalName = Text.escapeIllegalJcrChars(node.getString(REP_PRINCIPAL_NAME));
+ this.privilegeBits = privilegeBits;
+ this.isAllow = isAllow;
+ this.restrictions = restrictions;
+ }
+
+ PermissionEntry asPermissionEntry() {
+ return new PermissionEntry(accessControlledPath, isAllow, index, privilegeBits, restrictionProvider.getPattern(accessControlledPath, restrictions));
+ }
+
+ void writeToPermissionStore(NodeBuilder parent) {
+ NodeBuilder n = parent.child(String.valueOf(index))
+ .setProperty(JCR_PRIMARYTYPE, NT_REP_PERMISSIONS, Type.NAME)
+ .setProperty(REP_IS_ALLOW, isAllow)
+ .setProperty(privilegeBits.asPropertyState(REP_PRIVILEGE_BITS));
+ for (Restriction restriction : restrictions) {
+ n.setProperty(restriction.getProperty());
+ }
+ }
+
+ //-------------------------------------------------------------< Object >---
+ @Override
+ public int hashCode() {
+ if (hashCode == -1) {
+ hashCode = Objects.hashCode(accessControlledPath, principalName, privilegeBits, isAllow, restrictions);
+ }
+ return hashCode;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (o == this) {
+ return true;
+ }
+ if (o instanceof AcEntry) {
+ AcEntry other = (AcEntry) o;
+ return isAllow == other.isAllow
+ && privilegeBits.equals(other.privilegeBits)
+ && principalName.equals(other.principalName)
+ && accessControlledPath.equals(other.accessControlledPath)
+ && restrictions.equals(other.restrictions);
+ }
+ return false;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ sb.append(accessControlledPath);
+ sb.append(';').append(principalName);
+ sb.append(';').append(isAllow ? "allow" : "deny");
+ sb.append(';').append(privilegeBits);
+ sb.append(';').append(restrictions);
+ return sb.toString();
+ }
+ }
+}
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/restriction/PrincipalRestrictionProvider.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/restriction/PrincipalRestrictionProvider.java?rev=1585963&r1=1585962&r2=1585963&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/restriction/PrincipalRestrictionProvider.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/restriction/PrincipalRestrictionProvider.java Wed Apr 9 13:15:40 2014
@@ -108,4 +108,10 @@ public class PrincipalRestrictionProvide
public RestrictionPattern getPattern(@Nullable String oakPath, @Nonnull Tree tree) {
return base.getPattern(oakPath, tree);
}
+
+ @Nonnull
+ @Override
+ public RestrictionPattern getPattern(@Nullable String oakPath, @Nonnull Set<Restriction> restrictions) {
+ return base.getPattern(oakPath, restrictions);
+ }
}
\ 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=1585963&r1=1585962&r2=1585963&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 Wed Apr 9 13:15:40 2014
@@ -19,6 +19,9 @@ package org.apache.jackrabbit.oak.securi
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
+import java.util.Set;
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
import javax.jcr.security.AccessControlException;
import com.google.common.collect.ImmutableMap;
@@ -29,10 +32,13 @@ import org.apache.jackrabbit.oak.api.Tre
import org.apache.jackrabbit.oak.api.Type;
import org.apache.jackrabbit.oak.spi.security.authorization.restriction.AbstractRestrictionProvider;
import org.apache.jackrabbit.oak.spi.security.authorization.restriction.CompositePattern;
+import org.apache.jackrabbit.oak.spi.security.authorization.restriction.Restriction;
import org.apache.jackrabbit.oak.spi.security.authorization.restriction.RestrictionDefinition;
import org.apache.jackrabbit.oak.spi.security.authorization.restriction.RestrictionDefinitionImpl;
import org.apache.jackrabbit.oak.spi.security.authorization.restriction.RestrictionPattern;
import org.apache.jackrabbit.oak.spi.security.authorization.restriction.RestrictionProvider;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
/**
* Default restriction provider implementation that supports the following
@@ -51,6 +57,8 @@ import org.apache.jackrabbit.oak.spi.sec
@Service(RestrictionProvider.class)
public class RestrictionProviderImpl extends AbstractRestrictionProvider {
+ private static final Logger log = LoggerFactory.getLogger(RestrictionProviderImpl.class);
+
public RestrictionProviderImpl() {
super(supportedRestrictions());
}
@@ -69,9 +77,8 @@ public class RestrictionProviderImpl ext
if (oakPath == null) {
return RestrictionPattern.EMPTY;
} else {
+ List<RestrictionPattern> patterns = new ArrayList<RestrictionPattern>(3);
PropertyState glob = tree.getProperty(REP_GLOB);
-
- List<RestrictionPattern> patterns = new ArrayList<RestrictionPattern>(2);
if (glob != null) {
patterns.add(GlobPattern.create(oakPath, glob.getValue(Type.STRING)));
}
@@ -79,17 +86,34 @@ public class RestrictionProviderImpl ext
if (ntNames != null) {
patterns.add(new NodeTypePattern(ntNames.getValue(Type.NAMES)));
}
-
PropertyState prefixes = tree.getProperty(REP_PREFIXES);
if (prefixes != null) {
patterns.add(new PrefixPattern(prefixes.getValue(Type.STRINGS)));
}
+ return CompositePattern.create(patterns);
+ }
+ }
- switch (patterns.size()) {
- case 1 : return patterns.get(0);
- case 2 : return new CompositePattern(patterns);
- default : return RestrictionPattern.EMPTY;
+ @Nonnull
+ @Override
+ public RestrictionPattern getPattern(@Nullable String oakPath, @Nonnull Set<Restriction> restrictions) {
+ if (oakPath == null || restrictions.isEmpty()) {
+ return RestrictionPattern.EMPTY;
+ } else {
+ List<RestrictionPattern> patterns = new ArrayList<RestrictionPattern>(3);
+ for (Restriction r : restrictions) {
+ String name = r.getDefinition().getName();
+ if (REP_GLOB.equals(name)) {
+ patterns.add(GlobPattern.create(oakPath, r.getProperty().getValue(Type.STRING)));
+ } else if (REP_NT_NAMES.equals(name)) {
+ 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 {
+ log.debug("Ignoring unsupported restriction " + name);
+ }
}
+ return CompositePattern.create(patterns);
}
}
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/restriction/CompositePattern.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/restriction/CompositePattern.java?rev=1585963&r1=1585962&r2=1585963&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/restriction/CompositePattern.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/restriction/CompositePattern.java Wed Apr 9 13:15:40 2014
@@ -37,6 +37,14 @@ public final class CompositePattern impl
this.patterns = patterns;
}
+ public static RestrictionPattern create(@Nonnull List<RestrictionPattern> patterns) {
+ switch (patterns.size()) {
+ case 0 : return RestrictionPattern.EMPTY;
+ case 1 : return patterns.get(0);
+ default : return new CompositePattern(patterns);
+ }
+ }
+
@Override
public boolean matches(@Nonnull Tree tree, @Nullable PropertyState property) {
for (RestrictionPattern pattern : patterns) {
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/restriction/CompositeRestrictionProvider.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/restriction/CompositeRestrictionProvider.java?rev=1585963&r1=1585962&r2=1585963&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/restriction/CompositeRestrictionProvider.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/restriction/CompositeRestrictionProvider.java Wed Apr 9 13:15:40 2014
@@ -128,18 +128,20 @@ public class CompositeRestrictionProvide
@Nonnull
@Override
public RestrictionPattern getPattern(@Nullable String oakPath, @Nonnull Tree tree) {
+ return getPattern(oakPath, readRestrictions(oakPath, tree));
+ }
+
+ @Nonnull
+ @Override
+ public RestrictionPattern getPattern(@Nullable String oakPath, @Nonnull Set<Restriction> restrictions) {
List<RestrictionPattern> patterns = new ArrayList<RestrictionPattern>();
for (RestrictionProvider rp : providers) {
- RestrictionPattern pattern = rp.getPattern(oakPath, tree);
+ RestrictionPattern pattern = rp.getPattern(oakPath, restrictions);
if (pattern != RestrictionPattern.EMPTY) {
patterns.add(pattern);
}
}
- switch (patterns.size()) {
- case 0 : return RestrictionPattern.EMPTY;
- case 1 : return patterns.iterator().next();
- default : return new CompositePattern(patterns);
- }
+ return CompositePattern.create(patterns);
}
//------------------------------------------------------------< private >---
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/restriction/RestrictionProvider.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/restriction/RestrictionProvider.java?rev=1585963&r1=1585962&r2=1585963&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/restriction/RestrictionProvider.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/restriction/RestrictionProvider.java Wed Apr 9 13:15:40 2014
@@ -134,6 +134,20 @@ public interface RestrictionProvider {
RestrictionPattern getPattern(@Nullable String oakPath, @Nonnull Tree tree);
/**
+ * Creates the {@link RestrictionPattern} for the specified restrictions.
+ * The implementation should ignore all restrictions present in the specified
+ * set that it doesn't support.
+ *
+ * @param oakPath The path of the access controlled tree or {@code null} if
+ * the target policies applies to the repository level.
+ * @param restrictions the restrictions.
+ * @return A new {@link RestrictionPattern} representing those restrictions
+ * of the specified set that are supported by this implementation.
+ */
+ @Nonnull
+ RestrictionPattern getPattern(@Nullable String oakPath, @Nonnull Set<Restriction> restrictions);
+
+ /**
* Empty restriction provider implementation that doesn't support any
* restrictions.
*/
@@ -178,5 +192,11 @@ public interface RestrictionProvider {
public RestrictionPattern getPattern(@Nullable String oakPath, @Nonnull Tree tree) {
return RestrictionPattern.EMPTY;
}
+
+ @Nonnull
+ @Override
+ public RestrictionPattern getPattern(@Nullable String oakPath, @Nonnull Set<Restriction> restrictions) {
+ return RestrictionPattern.EMPTY;
+ }
};
}
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/whiteboard/WhiteboardRestrictionProvider.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/whiteboard/WhiteboardRestrictionProvider.java?rev=1585963&r1=1585962&r2=1585963&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/whiteboard/WhiteboardRestrictionProvider.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/whiteboard/WhiteboardRestrictionProvider.java Wed Apr 9 13:15:40 2014
@@ -83,6 +83,12 @@ public class WhiteboardRestrictionProvid
return getProvider().getPattern(oakPath, tree);
}
+ @Nonnull
+ @Override
+ public RestrictionPattern getPattern(@Nullable String oakPath, @Nonnull Set<Restriction> restrictions) {
+ return getProvider().getPattern(oakPath, restrictions);
+ }
+
//------------------------------------------------------------< private >---
private RestrictionProvider getProvider() {
return CompositeRestrictionProvider.newInstance(getServices());
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=1585963&r1=1585962&r2=1585963&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 Wed Apr 9 13:15:40 2014
@@ -800,5 +800,11 @@ public class ACLTest extends AbstractAcc
public RestrictionPattern getPattern(@Nullable String oakPath, @Nonnull Tree tree) {
throw new UnsupportedOperationException();
}
+
+ @Nonnull
+ @Override
+ public RestrictionPattern getPattern(@Nullable String oakPath, @Nonnull Set<Restriction> restrictions) {
+ throw new UnsupportedOperationException();
+ }
}
}
\ 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=1585963&r1=1585962&r2=1585963&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 Wed Apr 9 13:15:40 2014
@@ -94,7 +94,7 @@ public class RestrictionProviderImplTest
map.put(PropertyStates.createProperty(REP_NT_NAMES, ntNames, Type.NAMES), new NodeTypePattern(ntNames));
NodeUtil tree = new NodeUtil(root.getTree("/")).getOrAddTree("testPath", JcrConstants.NT_UNSTRUCTURED);
- Tree restrictions = tree.addChild("restrictions", NT_REP_RESTRICTIONS).getTree();
+ Tree restrictions = tree.addChild(REP_RESTRICTIONS, NT_REP_RESTRICTIONS).getTree();
// test restrictions individually
for (Map.Entry<PropertyState, RestrictionPattern> entry : map.entrySet()) {
@@ -115,6 +115,54 @@ public class RestrictionProviderImplTest
}
@Test
+ public void testGetPatternForAllSupported() 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));
+
+ NodeUtil tree = new NodeUtil(root.getTree("/")).getOrAddTree("testPath", JcrConstants.NT_UNSTRUCTURED);
+ Tree restrictions = tree.addChild(REP_RESTRICTIONS, NT_REP_RESTRICTIONS).getTree();
+ for (Map.Entry<PropertyState, RestrictionPattern> entry : map.entrySet()) {
+ restrictions.setProperty(entry.getKey());
+ }
+
+ RestrictionPattern pattern = provider.getPattern("/testPath", restrictions);
+ assertTrue(pattern instanceof CompositePattern);
+ }
+
+ @Test
+ 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));
+
+ NodeUtil tree = new NodeUtil(root.getTree("/")).getOrAddTree("testPath", JcrConstants.NT_UNSTRUCTURED);
+ Tree restrictions = tree.addChild(REP_RESTRICTIONS, NT_REP_RESTRICTIONS).getTree();
+
+ // test restrictions individually
+ for (Map.Entry<PropertyState, RestrictionPattern> entry : map.entrySet()) {
+ restrictions.setProperty(entry.getKey());
+
+ RestrictionPattern pattern = provider.getPattern("/testPath", provider.readRestrictions("/testPath", tree.getTree()));
+ assertEquals(entry.getValue(), pattern);
+ restrictions.removeProperty(entry.getKey().getName());
+ }
+
+ // test combination on multiple restrictions
+ for (Map.Entry<PropertyState, RestrictionPattern> entry : map.entrySet()) {
+ restrictions.setProperty(entry.getKey());
+ }
+ RestrictionPattern pattern = provider.getPattern("/testPath", provider.readRestrictions("/testPath", tree.getTree()));
+ assertTrue(pattern instanceof CompositePattern);
+ }
+
+ @Test
public void testValidateGlobRestriction() throws Exception {
Tree t = new NodeUtil(root.getTree("/")).addChild("testTree", "nt:unstructured").getTree();
String path = t.getPath();
Modified: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/restriction/TestProvider.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/restriction/TestProvider.java?rev=1585963&r1=1585962&r2=1585963&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/restriction/TestProvider.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/restriction/TestProvider.java Wed Apr 9 13:15:40 2014
@@ -17,6 +17,7 @@
package org.apache.jackrabbit.oak.spi.security.authorization.restriction;
import java.util.Map;
+import java.util.Set;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
@@ -45,6 +46,17 @@ final class TestProvider extends Abstrac
return (hasRestriction) ? new MatchingPattern() : RestrictionPattern.EMPTY;
}
+ @Nonnull
+ @Override
+ public RestrictionPattern getPattern(@Nullable String oakPath, @Nonnull Set<Restriction> restrictions) {
+ for (Restriction r : restrictions) {
+ if (getSupportedRestrictions(oakPath).contains(r.getDefinition())) {
+ return new MatchingPattern();
+ }
+ }
+ return RestrictionPattern.EMPTY;
+ }
+
private static final class MatchingPattern implements RestrictionPattern {
@Override