jackrabbit-oak-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ang...@apache.org
Subject svn commit: r1468819 - in /jackrabbit/oak/trunk/oak-core/src: main/java/org/apache/jackrabbit/oak/core/ main/java/org/apache/jackrabbit/oak/security/authorization/ main/java/org/apache/jackrabbit/oak/security/authorization/permission/ main/java/org/apa...
Date Wed, 17 Apr 2013 10:04:17 GMT
Author: angela
Date: Wed Apr 17 10:04:17 2013
New Revision: 1468819

URL: http://svn.apache.org/r1468819
Log:
OAK-527: permissions (wip)

Modified:
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/core/RootImpl.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/core/SecureNodeState.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/core/SecurityContext.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/AccessControlContext.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/permission/PermissionConstants.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/privilege/PrivilegeConstants.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/privilege/PrivilegeContext.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/UserContext.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/Context.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/SecurityConfiguration.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/permission/ReadStatus.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/user/UserConstants.java
    jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/permission/ReadStatusTest.java

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/core/RootImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/core/RootImpl.java?rev=1468819&r1=1468818&r2=1468819&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/core/RootImpl.java
(original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/core/RootImpl.java
Wed Apr 17 10:04:17 2013
@@ -18,19 +18,12 @@
  */
 package org.apache.jackrabbit.oak.core;
 
-import static com.google.common.base.Preconditions.checkArgument;
-import static com.google.common.base.Preconditions.checkNotNull;
-import static org.apache.jackrabbit.oak.commons.PathUtils.elements;
-import static org.apache.jackrabbit.oak.commons.PathUtils.getName;
-import static org.apache.jackrabbit.oak.commons.PathUtils.getParentPath;
-
 import java.io.IOException;
 import java.io.InputStream;
 import java.security.PrivilegedAction;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
-
 import javax.annotation.Nonnull;
 import javax.security.auth.Subject;
 
@@ -57,6 +50,7 @@ import org.apache.jackrabbit.oak.spi.com
 import org.apache.jackrabbit.oak.spi.observation.ChangeExtractor;
 import org.apache.jackrabbit.oak.spi.query.CompositeQueryIndexProvider;
 import org.apache.jackrabbit.oak.spi.query.QueryIndexProvider;
+import org.apache.jackrabbit.oak.spi.security.Context;
 import org.apache.jackrabbit.oak.spi.security.OpenSecurityProvider;
 import org.apache.jackrabbit.oak.spi.security.SecurityConfiguration;
 import org.apache.jackrabbit.oak.spi.security.SecurityProvider;
@@ -67,6 +61,12 @@ import org.apache.jackrabbit.oak.spi.sta
 import org.apache.jackrabbit.oak.spi.state.NodeStore;
 import org.apache.jackrabbit.oak.spi.state.NodeStoreBranch;
 
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
+import static org.apache.jackrabbit.oak.commons.PathUtils.elements;
+import static org.apache.jackrabbit.oak.commons.PathUtils.getName;
+import static org.apache.jackrabbit.oak.commons.PathUtils.getParentPath;
+
 public class RootImpl implements Root {
 
     /**
@@ -426,9 +426,7 @@ public class RootImpl implements Root {
 
     @Nonnull
     private SecurityContext getRootContext(NodeState root) {
-        TreeTypeProvider typeProvider = new TreeTypeProviderImpl(
-                securityProvider.getAccessControlConfiguration().getContext());
-        return new SecurityContext(root, getPermissionProvider(), typeProvider);
+        return new SecurityContext(root, getPermissionProvider(), getAcContext());
     }
 
     @Nonnull
@@ -461,6 +459,11 @@ public class RootImpl implements Root {
         return securityProvider.getAccessControlConfiguration().getPermissionProvider(this,
subject.getPrincipals());
     }
 
+    @Nonnull
+    private Context getAcContext() {
+        return securityProvider.getAccessControlConfiguration().getContext();
+    }
+
     //---------------------------------------------------------< MoveRecord >---
 
     /**

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/core/SecureNodeState.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/core/SecureNodeState.java?rev=1468819&r1=1468818&r2=1468819&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/core/SecureNodeState.java
(original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/core/SecureNodeState.java
Wed Apr 17 10:04:17 2013
@@ -16,7 +16,6 @@
  */
 package org.apache.jackrabbit.oak.core;
 
-import java.util.Collections;
 import javax.annotation.CheckForNull;
 import javax.annotation.Nonnull;
 
@@ -58,23 +57,13 @@ class SecureNodeState extends AbstractNo
     /**
      * Predicate for testing whether a given property is readable.
      */
-    private final Predicate<PropertyState> isPropertyReadable = new Predicate<PropertyState>()
{
-        @Override
-        public boolean apply(@Nonnull PropertyState property) {
-            return context.canReadProperty(property);
-        }
-    };
+    private final Predicate<PropertyState> isPropertyReadable = new ReadablePropertyPredicate();
 
     /**
      * Predicate for testing whether the node state in a child node entry
      * is iterable.
      */
-    private final Predicate<ChildNodeEntry> isIterableNode = new Predicate<ChildNodeEntry>()
{
-        @Override
-        public boolean apply(@Nonnull ChildNodeEntry input) {
-            return input.getNodeState().exists();
-        }
-    };
+    private final Predicate<ChildNodeEntry> isIterableNode = new IterableNodePredicate();
 
    /**
     * Function that that adds a security wrapper to node states from
@@ -85,30 +74,7 @@ class SecureNodeState extends AbstractNo
     * or any of its descendants has read access restrictions. Otherwise
     * we can optimize access by skipping the security wrapper entirely.
     */
-    private final Function<ChildNodeEntry, ChildNodeEntry> wrapChildNodeEntry = new
Function<ChildNodeEntry, ChildNodeEntry>() {
-        @Override @Nonnull
-        public ChildNodeEntry apply(@Nonnull ChildNodeEntry input) {
-            String name = input.getName();
-            NodeState child = input.getNodeState();
-            SecurityContext childContext = context.getChildContext(name, child);
-            SecureNodeState secureChild =
-                    new SecureNodeState(child, childContext);
-            if (child.getChildNodeCount() == 0
-                    && secureChild.context.canReadThisNode()
-                    && secureChild.context.canReadAllProperties()) {
-                // Since this is an accessible leaf node whose all properties
-                // are readable, we don't need the SecureNodeState wrapper
-                // TODO: A further optimization would be to return the raw
-                // underlying node state even for non-leaf nodes if we can
-                // tell in advance that the full subtree is readable. Then
-                // we also wouldn't need the above getChildNodeCount() call
-                // that's somewhat expensive on the MongoMK.
-                return input;
-            } else {
-                return new MemoryChildNodeEntry(name, secureChild);
-            }
-        }
-    };
+    private final WrapChildEntryFunction wrapChildNodeEntry = new WrapChildEntryFunction();
 
     private long childNodeCount = -1;
 
@@ -138,13 +104,10 @@ class SecureNodeState extends AbstractNo
     @Override
     public synchronized long getPropertyCount() {
         if (propertyCount == -1) {
-            if (context.canReadAllProperties()) {
+            if (context.canReadAll()) {
                 propertyCount = state.getPropertyCount();
-            } else if (context.canReadThisNode()) {
-                propertyCount = count(
-                        filter(state.getProperties(), isPropertyReadable));
             } else {
-                propertyCount = 0;
+                propertyCount = count(filter(state.getProperties(), isPropertyReadable));
             }
         }
         return propertyCount;
@@ -152,19 +115,17 @@ class SecureNodeState extends AbstractNo
 
     @Override @Nonnull
     public Iterable<? extends PropertyState> getProperties() {
-        if (context.canReadAllProperties()) {
+        if (context.canReadAll()) {
             return state.getProperties();
-        } else if (context.canReadThisNode()) {
-            return filter(state.getProperties(), isPropertyReadable);
         } else {
-            return Collections.emptySet();
+            return filter(state.getProperties(), isPropertyReadable);
         }
     }
 
     @Override
     public NodeState getChildNode(@Nonnull String name) {
         NodeState child = state.getChildNode(checkNotNull(name));
-        if (child.exists()) {
+        if (child.exists() && !context.canReadAll()) {
             ChildNodeEntry entry = new MemoryChildNodeEntry(name, child);
             return wrapChildNodeEntry.apply(entry).getNodeState();
         } else {
@@ -175,20 +136,22 @@ class SecureNodeState extends AbstractNo
     @Override
     public synchronized long getChildNodeCount() {
         if (childNodeCount == -1) {
-            childNodeCount = super.getChildNodeCount();
+            if (context.canReadAll()) {
+                childNodeCount = state.getChildNodeCount();
+            } else {
+                childNodeCount = super.getChildNodeCount();
+            }
         }
         return childNodeCount;
     }
 
     @Override @Nonnull
     public Iterable<? extends ChildNodeEntry> getChildNodeEntries() {
-        if (context.canNotReadChildNodes()) {
-            return Collections.emptySet();
+        if (context.canReadAll()) {
+            // everything is readable including ac-content -> no secure wrapper needed
+            return state.getChildNodeEntries();
         } else {
-            // TODO: review if ALLOW_CHILDREN could be used as well although we
-            // don't know the type of all child-nodes where ac node would need special treatment
-            Iterable<ChildNodeEntry> readable =
-                    transform(state.getChildNodeEntries(), wrapChildNodeEntry);
+            Iterable<ChildNodeEntry> readable = transform(state.getChildNodeEntries(),
wrapChildNodeEntry);
             return filter(readable, isIterableNode);
         }
     }
@@ -224,4 +187,59 @@ class SecureNodeState extends AbstractNo
         return super.equals(object);
     }
 
+
+    //------------------------------------------------------< inner classes >---
+    /**
+     * Predicate for testing whether a given property is readable.
+     */
+    private class ReadablePropertyPredicate implements Predicate<PropertyState> {
+        @Override
+        public boolean apply(@Nonnull PropertyState property) {
+            return context.canReadProperty(property);
+        }
+    }
+
+    /**
+     * Predicate for testing whether the node state in a child node entry is iterable.
+     */
+    private class IterableNodePredicate implements Predicate<ChildNodeEntry> {
+        @Override
+        public boolean apply(@Nonnull ChildNodeEntry input) {
+            return input.getNodeState().exists();
+        }
+    }
+
+    /**
+    * Function that that adds a security wrapper to node states from
+    * in child node entries. The {@link IterableNodePredicate} predicate should be
+    * used on the result to filter out non-existing/iterable child nodes.
+    * <p>
+    * Note that the SecureNodeState wrapper is needed only when the child
+    * or any of its descendants has read access restrictions. Otherwise
+    * we can optimize access by skipping the security wrapper entirely.
+    */
+    private class WrapChildEntryFunction implements Function<ChildNodeEntry, ChildNodeEntry>
{
+        @Nonnull
+        @Override
+        public ChildNodeEntry apply(@Nonnull ChildNodeEntry input) {
+            String name = input.getName();
+            NodeState child = input.getNodeState();
+            SecurityContext childContext = context.getChildContext(name, child);
+            SecureNodeState secureChild = new SecureNodeState(child, childContext);
+            if (child.getChildNodeCount() == 0
+                    && secureChild.context.canReadThisNode()
+                    && secureChild.context.canReadAllProperties()) {
+                // Since this is an accessible leaf node whose all properties
+                // are readable, we don't need the SecureNodeState wrapper
+                // TODO: A further optimization would be to return the raw
+                // underlying node state even for non-leaf nodes if we can
+                // tell in advance that the full subtree is readable. Then
+                // we also wouldn't need the above getChildNodeCount() call
+                // that's somewhat expensive on the MongoMK.
+                return input;
+            } else {
+                return new MemoryChildNodeEntry(name, secureChild);
+            }
+        }
+    }
 }

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/core/SecurityContext.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/core/SecurityContext.java?rev=1468819&r1=1468818&r2=1468819&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/core/SecurityContext.java
(original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/core/SecurityContext.java
Wed Apr 17 10:04:17 2013
@@ -19,6 +19,7 @@ package org.apache.jackrabbit.oak.core;
 import javax.annotation.Nonnull;
 
 import org.apache.jackrabbit.oak.api.PropertyState;
+import org.apache.jackrabbit.oak.spi.security.Context;
 import org.apache.jackrabbit.oak.spi.security.authorization.permission.PermissionProvider;
 import org.apache.jackrabbit.oak.spi.security.authorization.permission.ReadStatus;
 import org.apache.jackrabbit.oak.spi.state.NodeState;
@@ -44,15 +45,18 @@ class SecurityContext {
 
     private final PermissionProvider permissionProvider;
 
+    private final Context acContext;
+
     private ReadStatus readStatus;
 
     SecurityContext(
             @Nonnull NodeState rootState,
             @Nonnull PermissionProvider permissionProvider,
-            @Nonnull TreeTypeProvider typeProvider) {
+            @Nonnull Context acContext) {
         this.root = checkNotNull(rootState);
-        this.base = new ImmutableTree(rootState, typeProvider);
+        this.base = new ImmutableTree(rootState, new TreeTypeProviderImpl(acContext));
         this.permissionProvider = permissionProvider;
+        this.acContext = acContext;
         // calculate the readstatus for the root
         this.readStatus = permissionProvider.getReadStatus(base, null);
     }
@@ -63,8 +67,9 @@ class SecurityContext {
         this.root = checkNotNull(parent).root;
         this.base = new ImmutableTree(parent.base, name, nodeState);
         this.permissionProvider = parent.permissionProvider;
+        this.acContext = parent.acContext;
         if (base.getType() == parent.base.getType()) {
-            readStatus = ReadStatus.getChildStatus(parent.readStatus);
+            readStatus = ReadStatus.getChildStatus(parent.readStatus, acContext.hasChildItems(parent.base));
         } else {
             readStatus = null;
         }
@@ -98,9 +103,8 @@ class SecurityContext {
         }
     }
 
-    boolean canNotReadChildNodes() {
-        ReadStatus rs = getReadStatus();
-        return rs.includes(ReadStatus.DENY_CHILDREN);
+    boolean canReadAll() {
+        return readStatus != null && readStatus.includes(ReadStatus.ALLOW_ALL);
     }
 
     SecurityContext getChildContext(String name, NodeState state) {

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/AccessControlContext.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/AccessControlContext.java?rev=1468819&r1=1468818&r2=1468819&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/AccessControlContext.java
(original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/AccessControlContext.java
Wed Apr 17 10:04:17 2013
@@ -62,4 +62,15 @@ final class AccessControlContext impleme
             return POLICY_NODE_NAMES.contains(name) || ACE_PROPERTY_NAMES.contains(name)
|| path.startsWith(PERMISSIONS_STORE_PATH);
         }
     }
+
+    @Override
+    public boolean hasChildItems(Tree parent) {
+        for (String name : POLICY_NODE_NAMES) {
+            if (parent.hasChild(name)) {
+                return true;
+            }
+        }
+        String ntName = TreeUtil.getPrimaryTypeName(parent);
+        return AC_NODETYPE_NAMES.contains(ntName) || PERMISSION_NODETYPE_NAMES.contains(ntName);
+    }
 }

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/permission/PermissionConstants.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/permission/PermissionConstants.java?rev=1468819&r1=1468818&r2=1468819&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/permission/PermissionConstants.java
(original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/permission/PermissionConstants.java
Wed Apr 17 10:04:17 2013
@@ -36,8 +36,11 @@ public interface PermissionConstants {
     String REP_ACCESS_CONTROLLED_PATH = "rep:accessControlledPath";
     String REP_PRIVILEGE_BITS = "rep:privileges";
     String REP_INDEX = "rep:index";
+
     char PREFIX_ALLOW = 'a';
     char PREFIX_DENY = 'd';
 
     Set<String> PERMISSION_NODETYPE_NAMES = ImmutableSet.of(NT_REP_PERMISSIONS, NT_REP_PERMISSION_STORE);
+    Set<String> PERMISSION_NODE_NAMES = ImmutableSet.of(REP_PERMISSION_STORE);
+    Set<String> PERMISSION_PROPERTY_NAMES = ImmutableSet.of(REP_ACCESS_CONTROLLED_PATH,
REP_PRIVILEGE_BITS, REP_INDEX);
 }
\ No newline at end of file

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/privilege/PrivilegeConstants.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/privilege/PrivilegeConstants.java?rev=1468819&r1=1468818&r2=1468819&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/privilege/PrivilegeConstants.java
(original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/privilege/PrivilegeConstants.java
Wed Apr 17 10:04:17 2013
@@ -32,34 +32,40 @@ public interface PrivilegeConstants {
     String REP_PRIVILEGES = "rep:privileges";
 
     /**
-     * Internal (oak) path for the privilege store.
+     * Name of the property that defines if the privilege is abstract.
      */
-    String PRIVILEGES_PATH = '/' + JcrConstants.JCR_SYSTEM + '/' + REP_PRIVILEGES;
+    String REP_IS_ABSTRACT = "rep:isAbstract";
 
     /**
-     * Node type name of the root node of the privilege store
+     * Name of the privilege definition property that stores the aggregate privilege names.
      */
-    String NT_REP_PRIVILEGES = "rep:Privileges";
+    String REP_AGGREGATES = "rep:aggregates";
 
     /**
-     * Node type name of the privilege definition nodes
+     * Name of the property storing the value of the next available privilege bits.
      */
-    String NT_REP_PRIVILEGE = "rep:Privilege";
+    String REP_NEXT = "rep:next";
 
     /**
-     * Name of the property that defines if the privilege is abstract.
+     * The internal names of all property definitions that are associated with
+     * the {@link #NT_REP_PRIVILEGE rep:Privilege} node type
      */
-    String REP_IS_ABSTRACT = "rep:isAbstract";
+    Set<String> PRIVILEGE_PROPERTY_NAMES = ImmutableSet.of(REP_IS_ABSTRACT, REP_AGGREGATES,
REP_NEXT);
 
     /**
-     * Name of the privilege definition property that stores the aggregate privilege names.
+     * Internal (oak) path for the privilege store.
      */
-    String REP_AGGREGATES = "rep:aggregates";
+    String PRIVILEGES_PATH = '/' + JcrConstants.JCR_SYSTEM + '/' + REP_PRIVILEGES;
 
     /**
-     * Name of the property storing the value of the next available privilege bits.
+     * Node type name of the root node of the privilege store
      */
-    String REP_NEXT = "rep:next";
+    String NT_REP_PRIVILEGES = "rep:Privileges";
+
+    /**
+     * Node type name of the privilege definition nodes
+     */
+    String NT_REP_PRIVILEGE = "rep:Privilege";
 
     /**
      * Name of the privilege definition property that stores the internal representation
@@ -192,10 +198,4 @@ public interface PrivilegeConstants {
      * Internal (oak) name of the rep:removeProperties privilege
      */
     String REP_REMOVE_PROPERTIES = "rep:removeProperties";
-
-    /**
-     * The internal names of all property definitions that are associated with
-     * the {@link #NT_REP_PRIVILEGE rep:Privilege} node type
-     */
-    Set<String> PRIVILEGE_PROPERTY_NAMES = ImmutableSet.of(REP_IS_ABSTRACT, REP_AGGREGATES);
 }

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/privilege/PrivilegeContext.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/privilege/PrivilegeContext.java?rev=1468819&r1=1468818&r2=1468819&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/privilege/PrivilegeContext.java
(original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/privilege/PrivilegeContext.java
Wed Apr 17 10:04:17 2013
@@ -25,7 +25,7 @@ import org.apache.jackrabbit.oak.util.Tr
 /**
  * PrivilegeContext... TODO
  */
-final class PrivilegeContext implements Context {
+final class PrivilegeContext implements Context, PrivilegeConstants {
 
     private static final Context INSTANCE = new PrivilegeContext();
 
@@ -39,16 +39,23 @@ final class PrivilegeContext implements 
     //------------------------------------------------------------< Context >---
     @Override
     public boolean definesProperty(Tree parent, PropertyState property) {
-        return definesTree(parent) && PrivilegeConstants.PRIVILEGE_PROPERTY_NAMES.contains(property.getName());
+        return definesTree(parent) && PRIVILEGE_PROPERTY_NAMES.contains(property.getName());
     }
 
     @Override
     public boolean definesTree(Tree tree) {
-        return PrivilegeConstants.NT_REP_PRIVILEGE.equals(TreeUtil.getPrimaryTypeName(tree));
+        return NT_REP_PRIVILEGE.equals(TreeUtil.getPrimaryTypeName(tree));
     }
 
     @Override
     public boolean definesLocation(TreeLocation location) {
-        return location.getPath().startsWith(PrivilegeConstants.PRIVILEGES_PATH);
+        return location.getPath().startsWith(PRIVILEGES_PATH);
+    }
+
+    @Override
+    public boolean hasChildItems(Tree parent) {
+        return parent.hasChild(REP_PRIVILEGES)
+                || NT_REP_PRIVILEGES.equals(TreeUtil.getPrimaryTypeName(parent))
+                || NT_REP_PRIVILEGE.equals(TreeUtil.getPrimaryTypeName(parent));
     }
 }

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/UserContext.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/UserContext.java?rev=1468819&r1=1468818&r2=1468819&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/UserContext.java
(original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/UserContext.java
Wed Apr 17 10:04:17 2013
@@ -22,6 +22,7 @@ import org.apache.jackrabbit.oak.api.Tre
 import org.apache.jackrabbit.oak.spi.security.Context;
 import org.apache.jackrabbit.oak.spi.security.user.UserConstants;
 import org.apache.jackrabbit.oak.util.TreeUtil;
+import org.apache.jackrabbit.util.Text;
 
 /**
  * UserContext... TODO
@@ -64,8 +65,31 @@ final class UserContext implements Conte
             PropertyState p = location.getProperty();
             return (p == null) ? definesTree(tree) : definesProperty(tree, p);
         } else {
-            // FIXME
-            return false;
+            String path = location.getPath();
+            String name = Text.getName(path);
+            if (USER_PROPERTY_NAMES.contains(name) || GROUP_PROPERTY_NAMES.contains(name)
|| path.contains(REP_MEMBERS)) {
+                return true;
+            } else {
+                // undefined: unable to determine if the specified location
+                // defines a user or group node (missing node type information
+                // on non-existing location
+                return false;
+            }
         }
     }
+
+    @Override
+    public boolean hasChildItems(Tree parent) {
+        if (NODE_TYPE_NAMES.contains(TreeUtil.getPrimaryTypeName(parent))) {
+            // covers all properties
+            return true;
+        }
+        for (Tree child : parent.getChildren()) {
+            String ntName = TreeUtil.getPrimaryTypeName(child);
+            if (NODE_TYPE_NAMES.contains(ntName)) {
+                return true;
+            }
+        }
+        return false;
+    }
 }
\ No newline at end of file

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/Context.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/Context.java?rev=1468819&r1=1468818&r2=1468819&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/Context.java
(original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/Context.java
Wed Apr 17 10:04:17 2013
@@ -30,4 +30,28 @@ public interface Context {
     boolean definesTree(Tree tree);
 
     boolean definesLocation(TreeLocation location);
+
+    boolean hasChildItems(Tree parent);
+
+    class Default implements Context {
+        @Override
+        public boolean definesProperty(Tree parent, PropertyState property) {
+            return false;
+        }
+
+        @Override
+        public boolean definesTree(Tree tree) {
+            return false;
+        }
+
+        @Override
+        public boolean definesLocation(TreeLocation location) {
+            return false;
+        }
+
+        @Override
+        public boolean hasChildItems(Tree parent) {
+            return false;
+        }
+    }
 }
\ No newline at end of file

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/SecurityConfiguration.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/SecurityConfiguration.java?rev=1468819&r1=1468818&r2=1468819&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/SecurityConfiguration.java
(original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/SecurityConfiguration.java
Wed Apr 17 10:04:17 2013
@@ -20,9 +20,6 @@ import java.util.Collections;
 import java.util.List;
 import javax.annotation.Nonnull;
 
-import org.apache.jackrabbit.oak.api.PropertyState;
-import org.apache.jackrabbit.oak.api.Tree;
-import org.apache.jackrabbit.oak.api.TreeLocation;
 import org.apache.jackrabbit.oak.spi.commit.CommitHook;
 import org.apache.jackrabbit.oak.spi.commit.ValidatorProvider;
 import org.apache.jackrabbit.oak.spi.lifecycle.WorkspaceInitializer;
@@ -96,22 +93,7 @@ public interface SecurityConfiguration {
 
         @Override
         public Context getContext() {
-            return new Context() {
-                @Override
-                public boolean definesProperty(Tree parent, PropertyState property) {
-                    return false;
-                }
-
-                @Override
-                public boolean definesTree(Tree tree) {
-                    return false;
-                }
-
-                @Override
-                public boolean definesLocation(TreeLocation location) {
-                    return false;
-                }
-            };
+            return new Context.Default();
         }
     }
 }

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/permission/ReadStatus.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/permission/ReadStatus.java?rev=1468819&r1=1468818&r2=1468819&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/permission/ReadStatus.java
(original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/permission/ReadStatus.java
Wed Apr 17 10:04:17 2013
@@ -26,21 +26,35 @@ import org.apache.jackrabbit.oak.securit
  */
 public class ReadStatus {
 
-    public static final ReadStatus ALLOW_THIS = new ReadStatus(1, true);
-    public static final ReadStatus ALLOW_CHILDREN = new ReadStatus(2, true);
-    public static final ReadStatus ALLOW_NODES = new ReadStatus(3, true);
-    public static final ReadStatus ALLOW_PROPERTIES = new ReadStatus(4, true);
-    public static final ReadStatus ALLOW_THIS_PROPERTIES = new ReadStatus(5, true);
-    public static final ReadStatus ALLOW_CHILDITEMS = new ReadStatus(6, true);
-    public static final ReadStatus ALLOW_ALL = new ReadStatus(7, true);
-
-    public static final ReadStatus DENY_THIS = new ReadStatus(1, false);
-    public static final ReadStatus DENY_CHILDREN = new ReadStatus(2, false);
-    public static final ReadStatus DENY_NODES = new ReadStatus(3, false);
-    public static final ReadStatus DENY_PROPERTIES = new ReadStatus(4, false);
-    public static final ReadStatus DENY_THIS_PROPERTIES = new ReadStatus(5, false);
-    public static final ReadStatus DENY_CHILDITEMS = new ReadStatus(6, false);
-    public static final ReadStatus DENY_ALL = new ReadStatus(7, false);
+    private static final int STATUS_THIS = 1;
+    private static final int STATUS_CHILDREN = 2;
+    private static final int STATUS_NODES = 3;
+    private static final int STATUS_PROPERTIES = 4;
+    private static final int STATUS_THIS_PROPERTIES = 5;
+    private static final int STATUS_CHILDITEMS = 6;
+    private static final int STATUS_ALL_REGULAR = 7;
+    private static final int STATUS_ACCESS_CONTROL = 8;
+    private static final int STATUS_ALL = 15;
+
+    public static final ReadStatus ALLOW_THIS = new ReadStatus(STATUS_THIS, true);
+    public static final ReadStatus ALLOW_CHILDREN = new ReadStatus(STATUS_CHILDREN, true);
+    public static final ReadStatus ALLOW_NODES = new ReadStatus(STATUS_NODES, true);
+    public static final ReadStatus ALLOW_PROPERTIES = new ReadStatus(STATUS_PROPERTIES, true);
+    public static final ReadStatus ALLOW_THIS_PROPERTIES = new ReadStatus(STATUS_THIS_PROPERTIES,
true);
+    public static final ReadStatus ALLOW_CHILDITEMS = new ReadStatus(STATUS_CHILDITEMS, true);
+    public static final ReadStatus ALLOW_ALL_REGULAR = new ReadStatus(STATUS_ALL_REGULAR,
true);
+    public static final ReadStatus ALLOW_ACCESS_CONTROL = new ReadStatus(STATUS_ACCESS_CONTROL,
true);
+    public static final ReadStatus ALLOW_ALL = new ReadStatus(STATUS_ALL, true);
+
+    public static final ReadStatus DENY_THIS = new ReadStatus(STATUS_THIS, false);
+    public static final ReadStatus DENY_CHILDREN = new ReadStatus(STATUS_CHILDREN, false);
+    public static final ReadStatus DENY_NODES = new ReadStatus(STATUS_NODES, false);
+    public static final ReadStatus DENY_PROPERTIES = new ReadStatus(STATUS_PROPERTIES, false);
+    public static final ReadStatus DENY_THIS_PROPERTIES = new ReadStatus(STATUS_THIS_PROPERTIES,
false);
+    public static final ReadStatus DENY_CHILDITEMS = new ReadStatus(STATUS_CHILDITEMS, false);
+    public static final ReadStatus DENY_ALL_REGULAR = new ReadStatus(STATUS_ALL_REGULAR,
false);
+    public static final ReadStatus DENY_ACCESS_CONTROL = new ReadStatus(STATUS_ACCESS_CONTROL,
false);
+    public static final ReadStatus DENY_ALL = new ReadStatus(STATUS_ALL, false);
 
     private final int status;
     private final boolean isAllow;
@@ -64,19 +78,29 @@ public class ReadStatus {
     }
 
     @CheckForNull
-    public static ReadStatus getChildStatus(@Nullable ReadStatus parentStatus) {
+    public static ReadStatus getChildStatus(@Nullable ReadStatus parentStatus,
+                                            boolean hasAcChildren) {
         if (parentStatus == null) {
             return null;
         }
         // TODO
         switch (parentStatus.status) {
-            case 1: return null; // recalculate for child items
-            case 2:
-            case 3: return (parentStatus.isAllow) ? ALLOW_THIS : DENY_THIS;
-            case 4:
-            case 5: return null; // recalculate for properties of child node
-            case 6:
-            case 7: return (parentStatus.isAllow) ? ALLOW_ALL : DENY_ALL;
+            case STATUS_THIS:
+                return null; // recalculate for child items
+            case STATUS_CHILDREN:
+            case STATUS_NODES:
+                return (hasAcChildren) ? null : parentStatus;
+            case STATUS_PROPERTIES:
+            case STATUS_THIS_PROPERTIES:
+                return null; // recalculate for properties of child node
+            case STATUS_CHILDITEMS:
+            case STATUS_ALL_REGULAR:
+                return (hasAcChildren) ? null : parentStatus;
+            case STATUS_ACCESS_CONTROL:
+                // TODO
+                return null; // recalculate
+            case STATUS_ALL:
+                return (parentStatus.isAllow) ? ALLOW_ALL : DENY_ALL;
             default: throw new IllegalArgumentException("invalid status");
         }
     }
@@ -94,11 +118,11 @@ public class ReadStatus {
     }
 
     public boolean isAll() {
-        return status == 7;
+        return status == STATUS_ALL;
     }
 
     public boolean appliesToThis() {
-        return status == 1;
+        return status == STATUS_THIS;
     }
 
     public int getStatus() {

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/user/UserConstants.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/user/UserConstants.java?rev=1468819&r1=1468818&r2=1468819&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/user/UserConstants.java
(original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/user/UserConstants.java
Wed Apr 17 10:04:17 2013
@@ -31,6 +31,7 @@ public interface UserConstants {
     String NT_REP_GROUP = "rep:Group";
     String NT_REP_MEMBERS = "rep:Members";
     String MIX_REP_IMPERSONATABLE = "rep:Impersonatable";
+
     String REP_PRINCIPAL_NAME = "rep:principalName";
     String REP_AUTHORIZABLE_ID = "rep:authorizableId";
     String REP_PASSWORD = "rep:password";
@@ -52,6 +53,8 @@ public interface UserConstants {
             REP_IMPERSONATORS
     );
 
+    Collection<String> NODE_TYPE_NAMES = ImmutableSet.of(NT_REP_AUTHORIZABLE, NT_REP_USER,
NT_REP_GROUP, NT_REP_MEMBERS);
+
     /**
      * Configuration option defining the ID of the administrator user.
      */

Modified: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/permission/ReadStatusTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/permission/ReadStatusTest.java?rev=1468819&r1=1468818&r2=1468819&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/permission/ReadStatusTest.java
(original)
+++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/permission/ReadStatusTest.java
Wed Apr 17 10:04:17 2013
@@ -29,12 +29,15 @@ public class ReadStatusTest {
     @Test
     public void testAllowAll() {
         ReadStatus allowAll = ReadStatus.ALLOW_ALL;
+
         assertTrue(allowAll.includes(ReadStatus.ALLOW_THIS));
         assertTrue(allowAll.includes(ReadStatus.ALLOW_CHILDREN));
         assertTrue(allowAll.includes(ReadStatus.ALLOW_NODES));
         assertTrue(allowAll.includes(ReadStatus.ALLOW_PROPERTIES));
         assertTrue(allowAll.includes(ReadStatus.ALLOW_THIS_PROPERTIES));
         assertTrue(allowAll.includes(ReadStatus.ALLOW_CHILDITEMS));
+        assertTrue(allowAll.includes(ReadStatus.ALLOW_ALL_REGULAR));
+        assertTrue(allowAll.includes(ReadStatus.ALLOW_ACCESS_CONTROL));
         assertTrue(allowAll.includes(ReadStatus.ALLOW_ALL));
     }
 }



Mime
View raw message