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));
}
}