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 2012/08/16 18:43:24 UTC
svn commit: r1373912 - in /jackrabbit/oak/trunk:
oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/identifier/
oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/
oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/user/ oa...
Author: angela
Date: Thu Aug 16 16:43:23 2012
New Revision: 1373912
URL: http://svn.apache.org/viewvc?rev=1373912&view=rev
Log:
OAK-50 : Implement User Management (WIP)
Added:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/user/MembershipProvider.java
Removed:
jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/security/user/AuthorizableTypePredicate.java
jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/security/user/InheritingAuthorizableIterator.java
jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/security/user/MembershipManager.java
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/identifier/IdentifierManager.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/UserProviderImpl.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/UserValidator.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/UserValidatorProvider.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/user/UserConstants.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/user/UserProvider.java
jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/security/user/AuthorizableImpl.java
jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/security/user/AuthorizableIterator.java
jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/security/user/GroupImpl.java
jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/security/user/ImpersonationImpl.java
jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/security/user/UserImpl.java
jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/security/user/UserManagerImpl.java
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/identifier/IdentifierManager.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/identifier/IdentifierManager.java?rev=1373912&r1=1373911&r2=1373912&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/identifier/IdentifierManager.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/identifier/IdentifierManager.java Thu Aug 16 16:43:23 2012
@@ -24,7 +24,7 @@ import java.util.Set;
import java.util.UUID;
import javax.annotation.CheckForNull;
import javax.annotation.Nonnull;
-import javax.jcr.RepositoryException;
+import javax.jcr.PropertyType;
import javax.jcr.query.Query;
import org.apache.jackrabbit.JcrConstants;
@@ -60,12 +60,12 @@ public class IdentifierManager {
}
@Nonnull
- public static String generateUUID(String hint) throws RepositoryException {
+ public static String generateUUID(String hint) {
try {
UUID uuid = UUID.nameUUIDFromBytes(hint.getBytes("UTF-8"));
return uuid.toString();
} catch (UnsupportedEncodingException e) {
- throw new RepositoryException("Unexpected error while creating authorizable node", e);
+ throw new RuntimeException("Unexpected error while creating authorizable node", e);
}
}
@@ -109,7 +109,7 @@ public class IdentifierManager {
@CheckForNull
public Tree getTree(String identifier) {
if (isValidUUID(identifier)) {
- return findByJcrUuid(identifier);
+ return findTreeByJcrUuid(identifier);
} else {
// TODO as stated in NodeDelegate#getIdentifier() a non-uuid ID should
// TODO consisting of closest referenceable parent and a relative path
@@ -119,6 +119,43 @@ public class IdentifierManager {
}
/**
+ * The path of the tree identified by the specified {@code identifier} or {@code null}.
+ *
+ * @param identifier The identifier of the Tree such as exposed by {@link javax.jcr.Node#getIdentifier()}
+ * @return The tree with the given {@code identifier} or {@code null} if no
+ * such tree exists or isn't accessible to the content session.
+ */
+ @CheckForNull
+ public String getPath(String identifier) {
+ if (isValidUUID(identifier)) {
+ return resolveUUID(identifier);
+ } else {
+ // TODO as stated in NodeDelegate#getIdentifier() a non-uuid ID should
+ // TODO consisting of closest referenceable parent and a relative path
+ // TODO irrespective of the accessibility of the parent node(s)
+ return root.getTree(identifier).getPath();
+ }
+ }
+
+ /**
+ * Returns the path of the tree references by the specified (weak)
+ * reference {@code CoreValue value}.
+ *
+ * @param referenceValue A (weak) reference value.
+ * @return The tree with the given {@code identifier} or {@code null} if no
+ * such tree exists or isn't accessible to the content session.
+ */
+ @CheckForNull
+ public String getPath(CoreValue referenceValue) {
+ int type = referenceValue.getType();
+ if (type == PropertyType.REFERENCE || type == PropertyType.WEAKREFERENCE) {
+ return resolveUUID(referenceValue);
+ } else {
+ throw new IllegalArgumentException("Invalid value type");
+ }
+ }
+
+ /**
* Searches all reference properties to the specified {@code tree} that match
* the given name and node type constraints.
*
@@ -170,10 +207,13 @@ public class IdentifierManager {
}
@CheckForNull
- private Tree findByJcrUuid(String id) {
- try {
- Map<String, CoreValue> bindings = Collections.singletonMap("id", contentSession.getCoreValueFactory().createValue(id));
+ private String resolveUUID(String uuid) {
+ return resolveUUID(contentSession.getCoreValueFactory().createValue(uuid));
+ }
+ private String resolveUUID(CoreValue uuid) {
+ try {
+ Map<String, CoreValue> bindings = Collections.singletonMap("id", uuid);
Result result = contentSession.getQueryEngine().executeQuery("SELECT * FROM [nt:base] WHERE [jcr:uuid] = $id", Query.JCR_SQL2,
Long.MAX_VALUE, 0, bindings, new NamePathMapper.Default());
@@ -186,10 +226,16 @@ public class IdentifierManager {
path = rr.getPath();
}
}
- return path == null ? null : root.getTree(path);
+ return path == null ? null : path;
} catch (ParseException ex) {
log.error("query failed", ex);
return null;
}
}
+
+ @CheckForNull
+ private Tree findTreeByJcrUuid(String uuid) {
+ String path = resolveUUID(uuid);
+ return (path == null) ? null : root.getTree(path);
+ }
}
\ No newline at end of file
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/UserProviderImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/UserProviderImpl.java?rev=1373912&r1=1373911&r2=1373912&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/UserProviderImpl.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/UserProviderImpl.java Thu Aug 16 16:43:23 2012
@@ -16,15 +16,30 @@
*/
package org.apache.jackrabbit.oak.security.user;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+import javax.annotation.Nullable;
+import javax.jcr.PropertyType;
import javax.jcr.RepositoryException;
import javax.jcr.nodetype.ConstraintViolationException;
+import com.google.common.base.Function;
+import com.google.common.base.Predicate;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Iterators;
import org.apache.jackrabbit.JcrConstants;
import org.apache.jackrabbit.api.security.user.UserManager;
+import org.apache.jackrabbit.commons.iterator.RangeIteratorAdapter;
import org.apache.jackrabbit.oak.api.ContentSession;
+import org.apache.jackrabbit.oak.api.CoreValue;
+import org.apache.jackrabbit.oak.api.PropertyState;
import org.apache.jackrabbit.oak.api.Root;
import org.apache.jackrabbit.oak.api.Tree;
import org.apache.jackrabbit.oak.plugins.identifier.IdentifierManager;
+import org.apache.jackrabbit.oak.spi.security.user.MembershipProvider;
import org.apache.jackrabbit.oak.spi.security.user.UserConstants;
import org.apache.jackrabbit.oak.spi.security.user.UserManagerConfig;
import org.apache.jackrabbit.oak.spi.security.user.UserProvider;
@@ -34,7 +49,13 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
- * User provider implementation creating the JCR nodes corresponding the a given
+ * User provider implementation and manager for group memberships with the
+ * following characteristics:
+ *
+ * <h1>UserProvider</h1>
+ *
+ * <h2>Creation</h2>
+ * This implementation creates the JCR nodes corresponding the a given
* authorizable ID with the following behavior:
* <ul>
* <li>Users are created below /rep:security/rep:authorizables/rep:users or
@@ -108,8 +129,15 @@ import org.slf4j.LoggerFactory;
* <li>autoExpandTree</li>
* <li>autoExpandSize</li>
* </ul>
+ *
+ * <h2>Access by ID</h2>
+ * TODO
+ *
+ * <h1>MembershipProvider</h1>
+ *
+ * TODO
*/
-public class UserProviderImpl implements UserProvider {
+public class UserProviderImpl implements UserProvider, MembershipProvider, UserConstants {
/**
* logger instance
@@ -124,6 +152,7 @@ public class UserProviderImpl implements
private final IdentifierManager identifierManager;
private final int defaultDepth;
+ private final int splitSize;
private final String groupPath;
private final String userPath;
@@ -134,11 +163,18 @@ public class UserProviderImpl implements
this.identifierManager = new IdentifierManager(contentSession, root);
defaultDepth = config.getConfigValue(UserManagerConfig.PARAM_DEFAULT_DEPTH, DEFAULT_DEPTH);
+ int splitValue = config.getConfigValue(UserManagerConfig.PARAM_GROUP_MEMBERSHIP_SPLIT_SIZE, 0);
+ if (splitValue < 4) {
+ log.warn("Invalid value {} for {}. Expected integer >= 4", splitValue, UserManagerConfig.PARAM_GROUP_MEMBERSHIP_SPLIT_SIZE);
+ splitValue = 0;
+ }
+ this.splitSize = splitValue;
- groupPath = config.getConfigValue(UserManagerConfig.PARAM_GROUP_PATH, UserConstants.DEFAULT_GROUP_PATH);
- userPath = config.getConfigValue(UserManagerConfig.PARAM_USER_PATH, UserConstants.DEFAULT_USER_PATH);
+ groupPath = config.getConfigValue(UserManagerConfig.PARAM_GROUP_PATH, DEFAULT_GROUP_PATH);
+ userPath = config.getConfigValue(UserManagerConfig.PARAM_USER_PATH, DEFAULT_USER_PATH);
}
+ //-------------------------------------------------------< UserProvider >---
@Override
public Tree createUser(String userID, String intermediateJcrPath) throws RepositoryException {
return createAuthorizableNode(userID, false, intermediateJcrPath);
@@ -150,7 +186,7 @@ public class UserProviderImpl implements
}
@Override
- public Tree getAuthorizable(String authorizableId) throws RepositoryException {
+ public Tree getAuthorizable(String authorizableId) {
Tree tree = identifierManager.getTree(getContentID(authorizableId));
if (isAuthorizableTree(tree, UserManager.SEARCH_TYPE_AUTHORIZABLE)) {
return tree;
@@ -160,7 +196,7 @@ public class UserProviderImpl implements
}
@Override
- public Tree getAuthorizable(String authorizableId, int authorizableType) throws RepositoryException {
+ public Tree getAuthorizable(String authorizableId, int authorizableType) {
Tree tree = identifierManager.getTree(getContentID(authorizableId));
if (isAuthorizableTree(tree, authorizableType)) {
return tree;
@@ -179,24 +215,215 @@ public class UserProviderImpl implements
}
}
+ //--------------------------------------------------< MembershipProvider>---
+ @Override
+ public Iterator<String> getMembership(String authorizableId, boolean includeInherited) {
+ return getMembership(getAuthorizable(authorizableId), includeInherited);
+ }
+
+ @Override
+ public Iterator<String> getMembership(Tree authorizableTree, boolean includeInherited) {
+ Set<String> groupPaths = new HashSet<String>();
+ Set<String> refPaths = identifierManager.getWeakReferences(authorizableTree, null, NT_REP_GROUP, NT_REP_MEMBERS);
+ for (String propPath : refPaths) {
+ int index = propPath.indexOf('/'+REP_MEMBERS);
+ if (index > 0) {
+ groupPaths.add(propPath.substring(0, index));
+ } else {
+ log.debug("Not a membership reference property " + propPath);
+ }
+ }
+
+ Iterator<String> it = groupPaths.iterator();
+ if (includeInherited && it.hasNext()) {
+ return getAllMembership(groupPaths.iterator());
+ } else {
+ return new RangeIteratorAdapter(it, groupPaths.size());
+ }
+ }
+
+ @Override
+ public Iterator<String> getMembers(String groupId, int authorizableType, boolean includeInherited) {
+ return getMembers(getAuthorizable(groupId), UserManager.SEARCH_TYPE_AUTHORIZABLE, includeInherited);
+ }
+
+ @Override
+ public Iterator<String> getMembers(Tree groupTree, int authorizableType, boolean includeInherited) {
+ Iterable memberPaths = Collections.emptySet();
+ if (useMemberNode(groupTree)) {
+ Tree membersTree = groupTree.getChild(REP_MEMBERS);
+ if (membersTree != null) {
+ // FIXME: replace usage of PropertySequence (oak-api not possible there)
+// PropertySequence propertySequence = getPropertySequence(membersTree);
+// iterator = new AuthorizableIterator(propertySequence, authorizableType, userManager);
+ }
+ } else {
+ PropertyState property = groupTree.getProperty(REP_MEMBERS);
+ if (property != null) {
+ List<CoreValue> vs = property.getValues();
+ memberPaths = Iterables.transform(vs, new Function<CoreValue,String>() {
+ @Override
+ public String apply(@Nullable CoreValue value) {
+ return identifierManager.getPath(value);
+ }
+ });
+ }
+ }
+
+ Iterator it = memberPaths.iterator();
+ if (includeInherited && it.hasNext()) {
+ return getAllMembers(it, authorizableType);
+ } else {
+ return new RangeIteratorAdapter(it, Iterables.size(memberPaths));
+ }
+ }
+
+ @Override
+ public boolean isMember(Tree groupTree, Tree authorizableTree, boolean includeInherited) {
+ if (includeInherited) {
+ Iterator<String> groupPaths = getMembership(authorizableTree, true);
+ String path = groupTree.getPath();
+ while (groupPaths.hasNext()) {
+ if (path.equals(groupPaths.next())) {
+ return true;
+ }
+ }
+ } else {
+ if (useMemberNode(groupTree)) {
+ Tree membersTree = groupTree.getChild(REP_MEMBERS);
+ if (membersTree != null) {
+ // FIXME: fix.. testing for property name isn't correct.
+ // FIXME: usage of PropertySequence isn't possible when operating on oak-API
+// PropertySequence propertySequence = getPropertySequence(membersTree);
+// return propertySequence.hasItem(authorizable.getID());
+ return false;
+ }
+ } else {
+ PropertyState property = groupTree.getProperty(REP_MEMBERS);
+ if (property != null) {
+ List<CoreValue> members = property.getValues();
+ String authorizableUUID = getContentID(authorizableTree);
+ for (CoreValue v : members) {
+ if (authorizableUUID.equals(v.getString())) {
+ return true;
+ }
+ }
+ }
+ }
+ }
+ // no a member of the specified group
+ return false;
+ }
+
+ @Override
+ public boolean addMember(Tree groupTree, Tree newMemberTree) {
+ if (useMemberNode(groupTree)) {
+ NodeUtil groupNode = new NodeUtil(groupTree, contentSession);
+ NodeUtil membersNode = groupNode.getOrAddChild(REP_MEMBERS, NT_REP_MEMBERS);
+
+ //FIXME: replace usage of PropertySequence with oak-compatible utility
+// PropertySequence properties = getPropertySequence(membersTree);
+// String propName = Text.escapeIllegalJcrChars(authorizable.getID());
+// if (properties.hasItem(propName)) {
+// log.debug("Authorizable {} is already member of {}", authorizable, this);
+// return false;
+// } else {
+// CoreValue newMember = createCoreValue(authorizable);
+// properties.addProperty(propName, newMember);
+// }
+ } else {
+ List<CoreValue> values;
+ CoreValue toAdd = createCoreValue(newMemberTree);
+ PropertyState property = groupTree.getProperty(REP_MEMBERS);
+ if (property != null) {
+ values = property.getValues();
+ if (values.contains(toAdd)) {
+ return false;
+ } else {
+ values.add(toAdd);
+ }
+ } else {
+ values = Collections.singletonList(toAdd);
+ }
+ groupTree.setProperty(REP_MEMBERS, values);
+ }
+ return true;
+ }
+
+ @Override
+ public boolean removeMember(Tree groupTree, Tree memberTree) {
+ if (useMemberNode(groupTree)) {
+ Tree membersTree = groupTree.getChild(REP_MEMBERS);
+ if (membersTree != null) {
+ // FIXME: replace usage of PropertySequence with oak-compatible utility
+// PropertySequence properties = getPropertySequence(membersTree);
+// String propName = authorizable.getTree().getName();
+ // FIXME: fix.. testing for property name isn't correct.
+// if (properties.hasItem(propName)) {
+// Property p = properties.getItem(propName);
+// userManager.removeInternalProperty(p.getParent(), propName);
+// }
+// return true;
+ return false;
+ }
+ } else {
+ PropertyState property = groupTree.getProperty(REP_MEMBERS);
+ if (property != null) {
+ CoreValue toRemove = createCoreValue(memberTree);
+ List<CoreValue> values = property.getValues();
+ if (values.remove(toRemove)) {
+ if (values.isEmpty()) {
+ groupTree.removeProperty(REP_MEMBERS);
+ } else {
+ groupTree.setProperty(REP_MEMBERS, values);
+ }
+ return true;
+ }
+ }
+ }
+
+ // nothing changed
+ log.debug("Authorizable {} was not member of {}", memberTree.getName(), groupTree.getName());
+ return false;
+ }
+
//------------------------------------------------------------< private >---
- private String getContentID(String authorizableId) throws RepositoryException {
+
+ private String getContentID(String authorizableId) {
return IdentifierManager.generateUUID(authorizableId.toLowerCase());
}
+ private String getContentID(Tree authorizableTree) {
+ return identifierManager.getIdentifier(authorizableTree);
+ }
+
private boolean isAuthorizableTree(Tree tree, int type) {
- // TODO: check for node type according to the specified type constraint
- return true;
+ // FIXME: check for node type according to the specified type constraint
+ if (tree.hasProperty(JcrConstants.JCR_PRIMARYTYPE)) {
+ String ntName = tree.getProperty(JcrConstants.JCR_PRIMARYTYPE).getValue().getString();
+ switch (type) {
+ case UserManager.SEARCH_TYPE_GROUP:
+ return NT_REP_GROUP.equals(ntName);
+ case UserManager.SEARCH_TYPE_USER:
+ return NT_REP_USER.equals(ntName);
+ default:
+ return NT_REP_USER.equals(ntName) || NT_REP_GROUP.equals(ntName);
+ }
+ }
+ return false;
}
+ //-----------------------------------------------< private UserProvider >---
+
private Tree createAuthorizableNode(String authorizableId, boolean isGroup, String intermediatePath) throws RepositoryException {
String nodeName = Text.escapeIllegalJcrChars(authorizableId);
NodeUtil folder = createFolderNodes(authorizableId, nodeName, isGroup, intermediatePath);
- String ntName = (isGroup) ? UserConstants.NT_REP_GROUP : UserConstants.NT_REP_USER;
+ String ntName = (isGroup) ? NT_REP_GROUP : NT_REP_USER;
NodeUtil authorizableNode = folder.addChild(nodeName, ntName);
String nodeID = getContentID(authorizableId);
+ authorizableNode.setString(REP_AUTHORIZABLE_ID, authorizableId);
authorizableNode.setString(JcrConstants.JCR_UUID, nodeID);
return authorizableNode.getTree();
@@ -223,7 +450,7 @@ public class UserProviderImpl implements
if (authTree == null) {
folder = new NodeUtil(root.getTree(""), contentSession);
for (String name : Text.explode(authRoot, '/', false)) {
- folder = folder.getOrAddChild(name, UserConstants.NT_REP_AUTHORIZABLE_FOLDER);
+ folder = folder.getOrAddChild(name, NT_REP_AUTHORIZABLE_FOLDER);
}
} else {
folder = new NodeUtil(authTree, contentSession);
@@ -231,9 +458,9 @@ public class UserProviderImpl implements
String folderPath = getFolderPath(authorizableId, intermediatePath);
String[] segmts = Text.explode(folderPath, '/', false);
for (String segment : segmts) {
- folder = folder.getOrAddChild(segment, UserConstants.NT_REP_AUTHORIZABLE_FOLDER);
+ folder = folder.getOrAddChild(segment, NT_REP_AUTHORIZABLE_FOLDER);
// TODO: remove check once UserValidator is active
- if (!folder.hasPrimaryNodeTypeName(UserConstants.NT_REP_AUTHORIZABLE_FOLDER)) {
+ if (!folder.hasPrimaryNodeTypeName(NT_REP_AUTHORIZABLE_FOLDER)) {
String msg = "Cannot create user/group: Intermediate folders must be of type rep:AuthorizableFolder.";
throw new ConstraintViolationException(msg);
}
@@ -243,7 +470,7 @@ public class UserProviderImpl implements
while (folder.hasChild(nodeName)) {
NodeUtil colliding = folder.getChild(nodeName);
// TODO: remove check once UserValidator is active
- if (colliding.hasPrimaryNodeTypeName(UserConstants.NT_REP_AUTHORIZABLE_FOLDER)) {
+ if (colliding.hasPrimaryNodeTypeName(NT_REP_AUTHORIZABLE_FOLDER)) {
log.debug("Existing folder node collides with user/group to be created. Expanding path by: " + colliding.getName());
folder = colliding;
} else {
@@ -280,4 +507,93 @@ public class UserProviderImpl implements
}
return sb.toString();
}
+
+ //-----------------------------------------< private MembershipProvider >---
+
+ private CoreValue createCoreValue(Tree authorizableTree) {
+ return contentSession.getCoreValueFactory().createValue(getContentID(authorizableTree), PropertyType.WEAKREFERENCE);
+ }
+
+ private boolean useMemberNode(Tree groupTree) {
+ return splitSize >= 4 && !groupTree.hasProperty(REP_MEMBERS);
+ }
+
+ /**
+ * Returns an iterator of authorizables which includes all indirect members
+ * of the given iterator of authorizables.
+ *
+ *
+ * @param declaredMembers
+ * @param authorizableType
+ * @return Iterator of Authorizable objects
+ */
+ private Iterator<String> getAllMembers(final Iterator<String> declaredMembers,
+ final int authorizableType) {
+ Iterator<Iterator<String>> inheritedMembers = new Iterator<Iterator<String>>() {
+ @Override
+ public boolean hasNext() {
+ return declaredMembers.hasNext();
+ }
+
+ @Override
+ public Iterator<String> next() {
+ String memberPath = declaredMembers.next();
+ return Iterators.concat(Iterators.singletonIterator(memberPath), inherited(memberPath));
+ }
+
+ @Override
+ public void remove() {
+ throw new UnsupportedOperationException();
+ }
+
+ private Iterator<String> inherited(String authorizablePath) {
+ Tree group = getAuthorizableByPath(authorizablePath);
+ if (isAuthorizableTree(group, UserManager.SEARCH_TYPE_GROUP)) {
+ return getMembers(group, authorizableType, true);
+ } else {
+ return Iterators.emptyIterator();
+ }
+ }
+ };
+ return Iterators.filter(Iterators.concat(inheritedMembers), new ProcessedPathPredicate());
+ }
+
+ private Iterator<String> getAllMembership(final Iterator<String> groupPaths) {
+ Iterator<Iterator<String>> inheritedMembership = new Iterator<Iterator<String>>() {
+ @Override
+ public boolean hasNext() {
+ return groupPaths.hasNext();
+ }
+
+ @Override
+ public Iterator<String> next() {
+ String groupPath = groupPaths.next();
+ return Iterators.concat(Iterators.singletonIterator(groupPath), inherited(groupPath));
+ }
+
+ @Override
+ public void remove() {
+ throw new UnsupportedOperationException();
+ }
+
+ private Iterator<String> inherited(String authorizablePath) {
+ Tree group = getAuthorizableByPath(authorizablePath);
+ if (isAuthorizableTree(group, UserManager.SEARCH_TYPE_GROUP)) {
+ return getMembership(group, true);
+ } else {
+ return Iterators.emptyIterator();
+ }
+ }
+ };
+
+ return Iterators.filter(Iterators.concat(inheritedMembership), new ProcessedPathPredicate());
+ }
+
+ private static final class ProcessedPathPredicate implements Predicate<String> {
+ private final Set<String> processed = new HashSet<String>();
+ @Override
+ public boolean apply(@Nullable String path) {
+ return processed.add(path);
+ }
+ }
}
\ No newline at end of file
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/UserValidator.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/UserValidator.java?rev=1373912&r1=1373911&r2=1373912&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/UserValidator.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/UserValidator.java Thu Aug 16 16:43:23 2012
@@ -16,11 +16,11 @@
*/
package org.apache.jackrabbit.oak.security.user;
-import java.util.Collections;
import java.util.Set;
import javax.annotation.Nonnull;
import javax.jcr.nodetype.ConstraintViolationException;
+import com.google.common.collect.ImmutableSet;
import org.apache.jackrabbit.oak.api.CommitFailedException;
import org.apache.jackrabbit.oak.api.PropertyState;
import org.apache.jackrabbit.oak.spi.commit.UniquePropertyValidator;
@@ -36,6 +36,9 @@ import org.apache.jackrabbit.util.Text;
*/
class UserValidator extends UniquePropertyValidator {
+ private final static Set<String> PROPERTY_NAMES = ImmutableSet.copyOf(new String[] {
+ UserConstants.REP_AUTHORIZABLE_ID, UserConstants.REP_PRINCIPAL_NAME});
+
private final UserValidatorProvider provider;
private final NodeUtil parentBefore;
@@ -52,7 +55,7 @@ class UserValidator extends UniqueProper
@Override
protected Set<String> getPropertyNames() {
// TODO: make configurable
- return Collections.singleton(UserConstants.REP_PRINCIPAL_NAME);
+ return PROPERTY_NAMES;
}
//----------------------------------------------------------< Validator >---
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/UserValidatorProvider.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/UserValidatorProvider.java?rev=1373912&r1=1373911&r2=1373912&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/UserValidatorProvider.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/UserValidatorProvider.java Thu Aug 16 16:43:23 2012
@@ -32,9 +32,16 @@ import org.apache.jackrabbit.oak.util.No
*/
public class UserValidatorProvider implements ValidatorProvider {
- private final UserManagerConfig config = null; // TODO
- private final ContentSession contentSession = null; // TODO
+ private final ContentSession contentSession;
+ private final UserManagerConfig config;
+ public UserValidatorProvider(ContentSession contentSession, UserManagerConfig config) {
+ assert contentSession != null;
+ assert config != null;
+
+ this.contentSession = contentSession;
+ this.config = config;
+ }
//--------------------------------------------------< ValidatorProvider >---
@Nonnull
@Override
@@ -47,12 +54,18 @@ public class UserValidatorProvider imple
}
//-----------------------------------------------------------< internal >---
-
+ @Nonnull
UserManagerConfig getConfig() {
return config;
}
+ @Nonnull
CoreValueFactory getValueFactory() {
return contentSession.getCoreValueFactory();
}
+
+ @Nonnull
+ ContentSession getContentSession() {
+ return contentSession;
+ }
}
\ No newline at end of file
Added: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/user/MembershipProvider.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/user/MembershipProvider.java?rev=1373912&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/user/MembershipProvider.java (added)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/user/MembershipProvider.java Thu Aug 16 16:43:23 2012
@@ -0,0 +1,47 @@
+/*
+ * 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.spi.security.user;
+
+import java.util.Iterator;
+
+import javax.annotation.Nonnull;
+
+import org.apache.jackrabbit.oak.api.Tree;
+
+/**
+ * MembershipProvider... TODO
+ */
+public interface MembershipProvider {
+
+ @Nonnull
+ Iterator<String> getMembership(String authorizableId, boolean includeInherited);
+
+ @Nonnull
+ Iterator<String> getMembership(Tree authorizableTree, boolean includeInherited);
+
+ @Nonnull
+ Iterator<String> getMembers(String groupId, int authorizableType, boolean includeInherited);
+
+ @Nonnull
+ Iterator<String> getMembers(Tree groupTree, int authorizableType, boolean includeInherited);
+
+ boolean isMember(Tree groupTree, Tree authorizableTree, boolean includeInherited);
+
+ boolean addMember(Tree groupTree, Tree newMemberTree);
+
+ boolean removeMember(Tree groupTree, Tree memberTree);
+}
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=1373912&r1=1373911&r2=1373912&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 Thu Aug 16 16:43:23 2012
@@ -27,6 +27,7 @@ public interface UserConstants {
String NT_REP_GROUP = "rep:Group";
String NT_REP_MEMBERS = "rep:Members";
String REP_PRINCIPAL_NAME = "rep:principalName";
+ String REP_AUTHORIZABLE_ID = "rep:authorizableId";
String REP_PASSWORD = "rep:password";
String REP_DISABLED = "rep:disabled";
String REP_MEMBERS = "rep:members";
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/user/UserProvider.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/user/UserProvider.java?rev=1373912&r1=1373911&r2=1373912&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/user/UserProvider.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/user/UserProvider.java Thu Aug 16 16:43:23 2012
@@ -35,10 +35,10 @@ public interface UserProvider {
Tree createGroup(String groupId, String intermediateJcrPath) throws RepositoryException;
@CheckForNull
- Tree getAuthorizable(String authorizableId) throws RepositoryException;
+ Tree getAuthorizable(String authorizableId);
@CheckForNull
- Tree getAuthorizable(String authorizableId, int authorizableType) throws RepositoryException;
+ Tree getAuthorizable(String authorizableId, int authorizableType);
@CheckForNull
Tree getAuthorizableByPath(String authorizableOakPath);
Modified: jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/security/user/AuthorizableImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/security/user/AuthorizableImpl.java?rev=1373912&r1=1373911&r2=1373912&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/security/user/AuthorizableImpl.java (original)
+++ jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/security/user/AuthorizableImpl.java Thu Aug 16 16:43:23 2012
@@ -16,28 +16,32 @@
*/
package org.apache.jackrabbit.oak.jcr.security.user;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import javax.jcr.Node;
+import javax.jcr.Property;
+import javax.jcr.PropertyIterator;
+import javax.jcr.RepositoryException;
+import javax.jcr.Value;
+import javax.jcr.nodetype.NodeType;
+import javax.jcr.nodetype.PropertyDefinition;
+
import org.apache.jackrabbit.api.security.user.Authorizable;
import org.apache.jackrabbit.api.security.user.Group;
import org.apache.jackrabbit.api.security.user.User;
+import org.apache.jackrabbit.api.security.user.UserManager;
+import org.apache.jackrabbit.commons.iterator.RangeIteratorAdapter;
+import org.apache.jackrabbit.oak.api.PropertyState;
import org.apache.jackrabbit.oak.api.Tree;
import org.apache.jackrabbit.oak.spi.security.principal.EveryonePrincipal;
+import org.apache.jackrabbit.oak.spi.security.user.MembershipProvider;
import org.apache.jackrabbit.oak.spi.security.user.UserConstants;
import org.apache.jackrabbit.util.Text;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import javax.jcr.Node;
-import javax.jcr.Property;
-import javax.jcr.PropertyIterator;
-import javax.jcr.RepositoryException;
-import javax.jcr.Value;
-import javax.jcr.nodetype.NodeType;
-import javax.jcr.nodetype.PropertyDefinition;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.List;
-
/**
* AuthorizableImpl... TODO
*
@@ -76,8 +80,13 @@ abstract class AuthorizableImpl implemen
* @see org.apache.jackrabbit.api.security.user.Authorizable#getID()
*/
@Override
- public String getID() throws RepositoryException {
- return Text.unescapeIllegalJcrChars(getNode().getName());
+ public String getID() {
+ PropertyState idProp = tree.getProperty(UserConstants.REP_AUTHORIZABLE_ID);
+ if (idProp != null) {
+ return idProp.getValue().getString();
+ } else {
+ return Text.unescapeIllegalJcrChars(getTree().getName());
+ }
}
/**
@@ -107,7 +116,7 @@ abstract class AuthorizableImpl implemen
throw new RepositoryException("The administrator cannot be removed.");
}
userManager.onRemove(this);
- node.remove();
+ tree.remove();
}
/**
@@ -272,12 +281,8 @@ abstract class AuthorizableImpl implemen
*/
@Override
public String toString() {
- try {
- String typeStr = (isGroup()) ? "Group '" : "User '";
- return new StringBuilder().append(typeStr).append(getID()).append('\'').toString();
- } catch (RepositoryException e) {
- return super.toString();
- }
+ String typeStr = (isGroup()) ? "Group '" : "User '";
+ return new StringBuilder().append(typeStr).append(getID()).append('\'').toString();
}
//--------------------------------------------------------------------------
@@ -292,10 +297,6 @@ abstract class AuthorizableImpl implemen
return tree;
}
- String getContentID() throws RepositoryException {
- return getNode().getUUID();
- }
-
String getJcrName(String oakName) {
return userManager.getJcrName(oakName);
}
@@ -314,8 +315,8 @@ abstract class AuthorizableImpl implemen
String getPrincipalName() throws RepositoryException {
String principalName;
String propName = getJcrName(REP_PRINCIPAL_NAME);
- if (node.hasProperty(propName)) {
- principalName = node.getProperty(propName).getString();
+ if (tree.hasProperty(propName)) {
+ principalName = tree.getProperty(propName).getValue().getString();
} else {
log.debug("Authorizable without principal name -> using ID as fallback.");
principalName = getID();
@@ -421,7 +422,13 @@ abstract class AuthorizableImpl implemen
return Collections.<Group>emptySet().iterator();
}
- MembershipManager membershipManager = userManager.getMembershipManager();
- return membershipManager.getMembership(this, includeInherited);
+ MembershipProvider mMgr = userManager.getMembershipProvider();
+ Iterator<String> oakPaths = mMgr.getMembership(tree, includeInherited);
+ if (oakPaths.hasNext()) {
+ AuthorizableIterator groups = new AuthorizableIterator(oakPaths, userManager, UserManager.SEARCH_TYPE_AUTHORIZABLE);
+ return new RangeIteratorAdapter(groups, groups.getSize());
+ } else {
+ return RangeIteratorAdapter.EMPTY;
+ }
}
}
\ No newline at end of file
Modified: jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/security/user/AuthorizableIterator.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/security/user/AuthorizableIterator.java?rev=1373912&r1=1373911&r2=1373912&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/security/user/AuthorizableIterator.java (original)
+++ jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/security/user/AuthorizableIterator.java Thu Aug 16 16:43:23 2012
@@ -16,18 +16,17 @@
*/
package org.apache.jackrabbit.oak.jcr.security.user;
-import java.util.Arrays;
-import java.util.Collection;
import java.util.Iterator;
-import java.util.List;
-import java.util.NoSuchElementException;
-import javax.jcr.Property;
+import javax.annotation.Nullable;
+import javax.jcr.RangeIterator;
import javax.jcr.RepositoryException;
-import javax.jcr.Value;
+import com.google.common.base.Function;
+import com.google.common.base.Predicate;
+import com.google.common.base.Predicates;
+import com.google.common.collect.Iterators;
import org.apache.jackrabbit.api.security.user.Authorizable;
-import org.apache.jackrabbit.commons.flat.PropertySequence;
-import org.apache.jackrabbit.oak.api.CoreValue;
+import org.apache.jackrabbit.api.security.user.UserManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -38,50 +37,35 @@ class AuthorizableIterator implements It
private static final Logger log = LoggerFactory.getLogger(AuthorizableIterator.class);
- private final Iterator<?> authorizableIds;
- private final AuthorizableTypePredicate predicate;
- private final UserManagerImpl userManager;
+ private final Iterator<Authorizable> authorizables;
private final long size;
private Authorizable next;
- AuthorizableIterator(List<CoreValue> authorizableNodeIds, int authorizableType, UserManagerImpl userManager) {
- this(Arrays.asList(authorizableNodeIds).iterator(), authorizableType, userManager, authorizableNodeIds.size());
+ AuthorizableIterator(Iterator<String> authorizableOakPath, UserManagerImpl userManager) {
+ this(authorizableOakPath, userManager, UserManager.SEARCH_TYPE_AUTHORIZABLE);
}
- AuthorizableIterator(PropertySequence authorizableNodeIds, int authorizableType, UserManagerImpl userManager) {
- this(authorizableNodeIds.iterator(), authorizableType, userManager, -1); // TODO calculate size here
- }
-
- AuthorizableIterator(Collection<String> authorizablePaths, int authorizableType, UserManagerImpl userManager) {
- this(authorizablePaths.iterator(), authorizableType, userManager, authorizablePaths.size());
- }
+ AuthorizableIterator(Iterator<String> authorizableOakPaths, UserManagerImpl userManager, int authorizableType) {
+ Iterator<Authorizable> it = Iterators.transform(authorizableOakPaths, new ToAuthorizable(userManager, authorizableType));
+ this.authorizables = Iterators.filter(it, Predicates.notNull());
- private AuthorizableIterator(Iterator<?> authorizableIds, int authorizableType,
- UserManagerImpl userManager, long size) {
- this.authorizableIds = authorizableIds;
- this.predicate = new AuthorizableTypePredicate(authorizableType);
- this.userManager = userManager;
- this.size = size;
-
- next = fetchNext();
+ if (authorizableOakPaths instanceof RangeIterator) {
+ size = ((RangeIterator) authorizableOakPaths).getSize();
+ } else {
+ size = -1;
+ }
}
//-----------------------------------------------------------< Iterator >---
@Override
public boolean hasNext() {
- return next != null;
+ return authorizables.hasNext();
}
@Override
public Authorizable next() {
- if (next == null) {
- throw new NoSuchElementException();
- }
-
- Authorizable a = next;
- next = fetchNext();
- return a;
+ return authorizables.next();
}
@Override
@@ -94,36 +78,57 @@ class AuthorizableIterator implements It
return size;
}
- private Authorizable fetchNext() {
- while (authorizableIds.hasNext()) {
- Object next = authorizableIds.next();
+ //--------------------------------------------------------------------------
+
+ private static class ToAuthorizable implements Function<String, Authorizable> {
+
+ private final UserManagerImpl userManager;
+ private final Predicate predicate;
+
+ public ToAuthorizable(UserManagerImpl userManager, int type) {
+ this.userManager = userManager;
+ this.predicate = new AuthorizableTypePredicate(type);
+ }
+
+ @Override
+ public Authorizable apply(@Nullable String oakPath) {
+ String jcrPath = userManager.getNamePathMapper().getJcrPath(oakPath);
try {
- Authorizable a;
- if (next instanceof String) {
- a = userManager.getAuthorizableByPath(next.toString());
- } else {
- String nid = getNodeId(next);
- a = userManager.getAuthorizableByNodeID(nid);
- }
- if (a != null && predicate.evaluate(a)) {
+ Authorizable a = userManager.getAuthorizableByPath(jcrPath);
+ if (predicate.apply(a)) {
return a;
}
} catch (RepositoryException e) {
- log.debug(e.getMessage());
+ log.debug("Failed to access authorizable " + jcrPath);
}
+ return null;
}
- return null;
}
- private static String getNodeId(Object o) throws RepositoryException {
- if (o instanceof CoreValue) {
- return ((CoreValue) o).getString();
- } else if (o instanceof Value) {
- return ((Value) o).getString();
- } else if (o instanceof Property) {
- return ((Property) o).getParent().getUUID();
- } else {
- return o.toString();
+ private static class AuthorizableTypePredicate implements Predicate<Authorizable> {
+
+ private final int authorizableType;
+
+ AuthorizableTypePredicate(int authorizableType) {
+ this.authorizableType = authorizableType;
+ }
+
+ @Override
+ public boolean apply(Authorizable authorizable) {
+ if (authorizable == null) {
+ return false;
+ }
+ switch (authorizableType) {
+ case UserManager.SEARCH_TYPE_AUTHORIZABLE:
+ return true;
+ case UserManager.SEARCH_TYPE_GROUP:
+ return authorizable.isGroup();
+ case UserManager.SEARCH_TYPE_USER:
+ return !authorizable.isGroup();
+ default:
+ log.warn("Illegal authorizable type " + authorizableType);
+ return false;
+ }
}
}
}
\ No newline at end of file
Modified: jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/security/user/GroupImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/security/user/GroupImpl.java?rev=1373912&r1=1373911&r2=1373912&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/security/user/GroupImpl.java (original)
+++ jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/security/user/GroupImpl.java Thu Aug 16 16:43:23 2012
@@ -25,9 +25,11 @@ import javax.jcr.RepositoryException;
import org.apache.jackrabbit.api.security.user.Authorizable;
import org.apache.jackrabbit.api.security.user.Group;
import org.apache.jackrabbit.api.security.user.UserManager;
+import org.apache.jackrabbit.commons.iterator.RangeIteratorAdapter;
import org.apache.jackrabbit.oak.api.Tree;
import org.apache.jackrabbit.oak.spi.security.principal.TreeBasedPrincipal;
import org.apache.jackrabbit.oak.spi.security.principal.EveryonePrincipal;
+import org.apache.jackrabbit.oak.spi.security.user.MembershipProvider;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -117,8 +119,9 @@ class GroupImpl extends AuthorizableImpl
return false;
}
+ String memberID = authorizable.getID();
if (authorizableImpl.isGroup()) {
- if (getID().equals(authorizableImpl.getID())) {
+ if (getID().equals(memberID)) {
String msg = "Attempt to add a group as member of itself (" + getID() + ").";
log.debug(msg);
return false;
@@ -130,11 +133,11 @@ class GroupImpl extends AuthorizableImpl
}
if (isDeclaredMember(authorizable)) {
- log.debug("Authorizable {} is already declared member of {}", authorizable.getID(), getID());
+ log.debug("Authorizable {} is already declared member of {}", memberID, getID());
return false;
}
- return getUserManager().getMembershipManager().addMember(this, authorizableImpl);
+ return getUserManager().getMembershipProvider().addMember(getTree(), authorizableImpl.getTree());
}
/**
@@ -149,7 +152,8 @@ class GroupImpl extends AuthorizableImpl
if (isEveryone()) {
return false;
} else {
- return getUserManager().getMembershipManager().removeMember(this, (AuthorizableImpl) authorizable);
+ MembershipProvider mMgr = getUserManager().getMembershipProvider();
+ return mMgr.removeMember(getTree(), ((AuthorizableImpl) authorizable).getTree());
}
}
@@ -163,13 +167,21 @@ class GroupImpl extends AuthorizableImpl
* @throws RepositoryException If an error occurs.
*/
private Iterator<Authorizable> getMembers(boolean includeInherited) throws RepositoryException {
+ UserManagerImpl uMgr = getUserManager();
if (isEveryone()) {
// TODO: improve using authorizable-query
String propName = getJcrName(REP_PRINCIPAL_NAME);
- return getUserManager().findAuthorizables(propName, null, UserManager.SEARCH_TYPE_AUTHORIZABLE);
+ return uMgr.findAuthorizables(propName, null, UserManager.SEARCH_TYPE_AUTHORIZABLE);
} else {
- MembershipManager mMgr = getUserManager().getMembershipManager();
- return mMgr.getMembers(this, UserManager.SEARCH_TYPE_AUTHORIZABLE, includeInherited);
+ MembershipProvider mMgr = uMgr.getMembershipProvider();
+ Iterator oakPaths = mMgr.getMembers(getTree(), UserManager.SEARCH_TYPE_AUTHORIZABLE, includeInherited);
+ if (!oakPaths.hasNext()) {
+ AuthorizableIterator iterator = new AuthorizableIterator(oakPaths, uMgr);
+ return new RangeIteratorAdapter(iterator, iterator.getSize());
+ } else {
+ return RangeIteratorAdapter.EMPTY;
+
+ }
}
}
@@ -193,8 +205,9 @@ class GroupImpl extends AuthorizableImpl
} else if (getID().equals(authorizable.getID())) {
return false;
} else {
- AuthorizableImpl authorizableImpl = (AuthorizableImpl) authorizable;
- return getUserManager().getMembershipManager().isMember(this, authorizableImpl, includeInherited);
+ Tree authorizableTree = ((AuthorizableImpl) authorizable).getTree();
+ MembershipProvider mgr = getUserManager().getMembershipProvider();
+ return mgr.isMember(this.getTree(), authorizableTree, includeInherited);
}
}
@@ -204,7 +217,7 @@ class GroupImpl extends AuthorizableImpl
private class GroupPrincipal extends TreeBasedPrincipal implements java.security.acl.Group {
GroupPrincipal(String principalName) {
- super(principalName, getTree(), getUserManager().getSessionDelegate().getNamePathMapper());
+ super(principalName, getTree(), getUserManager().getNamePathMapper());
}
@Override
Modified: jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/security/user/ImpersonationImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/security/user/ImpersonationImpl.java?rev=1373912&r1=1373911&r2=1373912&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/security/user/ImpersonationImpl.java (original)
+++ jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/security/user/ImpersonationImpl.java Thu Aug 16 16:43:23 2012
@@ -31,6 +31,7 @@ import org.apache.jackrabbit.api.securit
import org.apache.jackrabbit.api.security.principal.PrincipalManager;
import org.apache.jackrabbit.api.security.user.Authorizable;
import org.apache.jackrabbit.api.security.user.Impersonation;
+import org.apache.jackrabbit.api.security.user.User;
import org.apache.jackrabbit.oak.api.CoreValue;
import org.apache.jackrabbit.oak.api.PropertyState;
import org.apache.jackrabbit.oak.api.Tree;
@@ -111,7 +112,7 @@ class ImpersonationImpl implements Imper
// make sure the given principal doesn't refer to the admin user.
Authorizable a = user.getUserManager().getAuthorizable(p);
- if (a != null && user.getUserManager().isAdminId(a.getID())) {
+ if (a != null && !a.isGroup() && ((User)a).isAdmin()) {
log.debug("Admin principal is already granted impersonation.");
return false;
}
@@ -192,8 +193,11 @@ class ImpersonationImpl implements Imper
private void updateImpersonatorNames(Set<String> principalNames) throws RepositoryException {
String[] pNames = principalNames.toArray(new String[principalNames.size()]);
+ Tree userTree = user.getTree();
if (pNames.length == 0) {
- user.getUserManager().removeInternalProperty(user.getTree(), REP_IMPERSONATORS);
+ if (userTree.hasProperty(REP_IMPERSONATORS)) {
+ userTree.removeProperty(REP_IMPERSONATORS);
+ } // nothing to do.
} else {
user.getUserManager().setInternalProperty(user.getTree(), REP_IMPERSONATORS, pNames, PropertyType.STRING);
}
@@ -207,4 +211,4 @@ class ImpersonationImpl implements Imper
throw new UnsupportedRepositoryOperationException("Principal management not supported.");
}
}
-}
\ No newline at end of file
+}
Modified: jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/security/user/UserImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/security/user/UserImpl.java?rev=1373912&r1=1373911&r2=1373912&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/security/user/UserImpl.java (original)
+++ jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/security/user/UserImpl.java Thu Aug 16 16:43:23 2012
@@ -67,7 +67,7 @@ class UserImpl extends AuthorizableImpl
@Override
public Principal getPrincipal() throws RepositoryException {
String principalName = getPrincipalName();
- return new TreeBasedPrincipal(principalName, getTree(), getUserManager().getSessionDelegate().getNamePathMapper());
+ return new TreeBasedPrincipal(principalName, getTree(), getUserManager().getNamePathMapper());
}
@@ -77,13 +77,7 @@ class UserImpl extends AuthorizableImpl
*/
@Override
public boolean isAdmin() {
- try {
- return getUserManager().isAdminId(getID());
- } catch (RepositoryException e) {
- // should never get here
- log.error("Internal error while retrieving UserID.", e);
- return false;
- }
+ return getUserManager().isAdminId(getID());
}
/**
@@ -139,11 +133,12 @@ class UserImpl extends AuthorizableImpl
if (isAdmin()) {
throw new RepositoryException("The administrator user cannot be disabled.");
}
+ Tree userTree = getTree();
if (reason == null) {
if (isDisabled()) {
// enable the user again.
- getUserManager().removeInternalProperty(getTree(), REP_DISABLED);
- } // else: nothing to do.
+ userTree.removeProperty(REP_DISABLED);
+ }
} else {
getUserManager().setInternalProperty(getTree(), REP_DISABLED, reason, PropertyType.STRING);
}
Modified: jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/security/user/UserManagerImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/security/user/UserManagerImpl.java?rev=1373912&r1=1373911&r2=1373912&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/security/user/UserManagerImpl.java (original)
+++ jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/security/user/UserManagerImpl.java Thu Aug 16 16:43:23 2012
@@ -23,7 +23,6 @@ import java.util.Iterator;
import java.util.List;
import javax.annotation.CheckForNull;
import javax.jcr.Node;
-import javax.jcr.PathNotFoundException;
import javax.jcr.PropertyType;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
@@ -37,19 +36,19 @@ import org.apache.jackrabbit.api.securit
import org.apache.jackrabbit.api.security.user.User;
import org.apache.jackrabbit.api.security.user.UserManager;
import org.apache.jackrabbit.oak.api.CoreValue;
-import org.apache.jackrabbit.oak.api.PropertyState;
import org.apache.jackrabbit.oak.api.Root;
import org.apache.jackrabbit.oak.api.Tree;
import org.apache.jackrabbit.oak.jcr.SessionDelegate;
import org.apache.jackrabbit.oak.jcr.security.user.query.XPathQueryBuilder;
import org.apache.jackrabbit.oak.jcr.security.user.query.XPathQueryEvaluator;
import org.apache.jackrabbit.oak.jcr.value.ValueConverter;
+import org.apache.jackrabbit.oak.namepath.NamePathMapper;
import org.apache.jackrabbit.oak.security.user.UserProviderImpl;
import org.apache.jackrabbit.oak.spi.security.principal.EveryonePrincipal;
+import org.apache.jackrabbit.oak.spi.security.user.MembershipProvider;
import org.apache.jackrabbit.oak.spi.security.user.PasswordUtility;
import org.apache.jackrabbit.oak.spi.security.user.UserConstants;
import org.apache.jackrabbit.oak.spi.security.user.UserManagerConfig;
-import org.apache.jackrabbit.oak.spi.security.user.UserProvider;
import org.apache.jackrabbit.oak.spi.security.user.action.AuthorizableAction;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -63,11 +62,9 @@ public class UserManagerImpl implements
private final SessionDelegate sessionDelegate;
private final UserManagerConfig config;
- private final UserProvider userProvider;
+ private final UserProviderImpl userProvider;
private final NodeTreeUtil util;
- private MembershipManager membershipManager;
-
public UserManagerImpl(SessionDelegate sessionDelegate, Root root, UserManagerConfig config) {
this.sessionDelegate = sessionDelegate;
this.config = (config == null) ? new UserManagerConfig("admin") : config;
@@ -352,37 +349,16 @@ public class UserManagerImpl implements
userNode.setProperty(oakName, cvs);
}
- void setInternalProperty(Tree userNode, String oakName, List<CoreValue> values) throws RepositoryException {
- userNode.setProperty(oakName, values);
- }
-
- void removeInternalProperty(Tree userNode, String oakName) throws RepositoryException {
- PropertyState pd = userNode.getProperty(oakName);
- if (pd == null) {
- throw new PathNotFoundException("Missing authorizable property " + oakName);
- } else {
- userNode.removeProperty(oakName);
- }
- }
-
Session getSession() {
return sessionDelegate.getSession();
}
- SessionDelegate getSessionDelegate() {
- return sessionDelegate;
+ NamePathMapper getNamePathMapper() {
+ return sessionDelegate.getNamePathMapper();
}
- MembershipManager getMembershipManager() {
- if (membershipManager == null) {
- int splitSize = config.getConfigValue(UserManagerConfig.PARAM_GROUP_MEMBERSHIP_SPLIT_SIZE, 0);
- if (splitSize < 4) {
- log.warn("Invalid value {} for {}. Expected integer >= 4", splitSize, UserManagerConfig.PARAM_GROUP_MEMBERSHIP_SPLIT_SIZE);
- splitSize = 0;
- }
- membershipManager = new MembershipManager(this, splitSize);
- }
- return membershipManager;
+ MembershipProvider getMembershipProvider() {
+ return userProvider;
}
@CheckForNull
@@ -400,11 +376,6 @@ public class UserManagerImpl implements
}
}
- @CheckForNull
- Authorizable getAuthorizableByNodeID(String identifier) throws RepositoryException {
- return getAuthorizable(sessionDelegate.getIdManager().getTree(identifier));
- }
-
String getJcrName(String oakName) {
return sessionDelegate.getNamePathMapper().getJcrName(oakName);
}