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/10 15:46:06 UTC
svn commit: r1371699 - in
/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak:
namepath/ security/user/ spi/commit/ spi/security/user/
spi/security/user/action/ util/
Author: angela
Date: Fri Aug 10 13:46:06 2012
New Revision: 1371699
URL: http://svn.apache.org/viewvc?rev=1371699&view=rev
Log:
OAK-50 : Implement User Management (WIP)
Added:
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/commit/UniquePropertyValidator.java
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/namepath/NamePathMapper.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/spi/security/user/UserConstants.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/user/action/AuthorizableAction.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/util/NodeUtil.java
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/namepath/NamePathMapper.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/namepath/NamePathMapper.java?rev=1371699&r1=1371698&r2=1371699&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/namepath/NamePathMapper.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/namepath/NamePathMapper.java Fri Aug 10 13:46:06 2012
@@ -16,8 +16,49 @@
*/
package org.apache.jackrabbit.oak.namepath;
+import javax.annotation.Nonnull;
+
/**
- * NamePathMapper...
+ * The {@code NamePathMapper} interface combines {@code NameMapper} and
+ * {@code PathMapper}.
*/
public interface NamePathMapper extends NameMapper, PathMapper {
+
+ /**
+ * Default implementation that doesn't perform any conversions for cases
+ * where a mapper object only deals with oak internal names and paths.
+ */
+ public class Default implements NamePathMapper {
+
+ @Override
+ public String getOakName(String jcrName) {
+ return jcrName;
+ }
+
+ @Override
+ public boolean hasSessionLocalMappings() {
+ return false;
+ }
+
+ @Override
+ public String getJcrName(String oakName) {
+ return oakName;
+ }
+
+ @Override
+ public String getOakPath(String jcrPath) {
+ return jcrPath;
+ }
+
+ @Override
+ public String getOakPathKeepIndex(String jcrPath) {
+ return jcrPath;
+ }
+
+ @Nonnull
+ @Override
+ public String getJcrPath(String oakPath) {
+ return oakPath;
+ }
+ }
}
\ 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=1371699&r1=1371698&r2=1371699&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 Fri Aug 10 13:46:06 2012
@@ -138,8 +138,8 @@ public class UserProviderImpl implements
defaultDepth = config.getConfigValue(UserManagerConfig.PARAM_DEFAULT_DEPTH, DEFAULT_DEPTH);
- groupPath = config.getConfigValue(UserManagerConfig.PARAM_GROUP_PATH, "/rep:security/rep:authorizables/rep:groups");
- userPath = config.getConfigValue(UserManagerConfig.PARAM_USER_PATH, "/rep:security/rep:authorizables/rep:users");
+ groupPath = config.getConfigValue(UserManagerConfig.PARAM_GROUP_PATH, UserConstants.DEFAULT_GROUP_PATH);
+ userPath = config.getConfigValue(UserManagerConfig.PARAM_USER_PATH, UserConstants.DEFAULT_USER_PATH);
}
@Override
@@ -205,6 +205,7 @@ public class UserProviderImpl implements
String[] segmts = Text.explode(folderPath, '/', false);
for (String segment : segmts) {
folder = folder.getOrAddChild(segment, UserConstants.NT_REP_AUTHORIZABLE_FOLDER);
+ // TODO: remove check once UserValidator is active
if (!folder.hasPrimaryNodeTypeName(UserConstants.NT_REP_AUTHORIZABLE_FOLDER)) {
String msg = "Cannot create user/group: Intermediate folders must be of type rep:AuthorizableFolder.";
throw new ConstraintViolationException(msg);
@@ -214,6 +215,7 @@ public class UserProviderImpl implements
// test for colliding folder child node.
while (folder.hasChild(nodeName)) {
NodeUtil colliding = folder.getChild(nodeName);
+ // TODO: remove check once UserValidator is active
if (colliding.hasPrimaryNodeTypeName(UserConstants.NT_REP_AUTHORIZABLE_FOLDER)) {
log.debug("Existing folder node collides with user/group to be created. Expanding path by: " + colliding.getName());
folder = colliding;
@@ -225,6 +227,7 @@ public class UserProviderImpl implements
}
}
+ // TODO: remove check once UserValidator is active
if (!Text.isDescendantOrEqual(authRoot, folder.getTree().getPath())) {
throw new ConstraintViolationException("Attempt to create user/group outside of configured scope " + authRoot);
}
Added: 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=1371699&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/UserValidator.java (added)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/UserValidator.java Fri Aug 10 13:46:06 2012
@@ -0,0 +1,127 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.oak.security.user;
+
+import java.util.Collections;
+import java.util.Set;
+import javax.annotation.Nonnull;
+import javax.jcr.nodetype.ConstraintViolationException;
+
+import org.apache.jackrabbit.oak.api.CommitFailedException;
+import org.apache.jackrabbit.oak.api.PropertyState;
+import org.apache.jackrabbit.oak.spi.commit.UniquePropertyValidator;
+import org.apache.jackrabbit.oak.spi.commit.Validator;
+import org.apache.jackrabbit.oak.spi.security.user.UserConstants;
+import org.apache.jackrabbit.oak.spi.security.user.UserManagerConfig;
+import org.apache.jackrabbit.oak.spi.state.NodeState;
+import org.apache.jackrabbit.oak.util.NodeUtil;
+import org.apache.jackrabbit.util.Text;
+
+/**
+ * UserValidator... TODO
+ */
+class UserValidator extends UniquePropertyValidator {
+
+ private final UserValidatorProvider provider;
+
+ private final NodeUtil parentBefore;
+ private final NodeUtil parentAfter;
+
+ UserValidator(NodeUtil parentBefore, NodeUtil parentAfter, UserValidatorProvider provider) {
+ this.parentBefore = parentBefore;
+ this.parentAfter = parentAfter;
+
+ this.provider = provider;
+ }
+
+ @Nonnull
+ @Override
+ protected Set<String> getPropertyNames() {
+ // TODO: make configurable
+ return Collections.singleton(UserConstants.REP_PRINCIPAL_NAME);
+ }
+
+ //----------------------------------------------------------< Validator >---
+ @Override
+ public void propertyAdded(PropertyState after) throws CommitFailedException {
+ super.propertyAdded(after);
+ }
+
+ @Override
+ public void propertyChanged(PropertyState before, PropertyState after) throws CommitFailedException {
+ super.propertyChanged(before, after);
+ }
+
+ @Override
+ public void propertyDeleted(PropertyState before) throws CommitFailedException {
+ // nothing to do
+ }
+
+ @Override
+ public Validator childNodeAdded(String name, NodeState after) throws CommitFailedException {
+ NodeUtil node = parentAfter.getChild(name);
+ String authRoot = null;
+ if (node.hasPrimaryNodeTypeName(UserConstants.NT_REP_USER)) {
+ authRoot = provider.getConfig().getConfigValue(UserManagerConfig.PARAM_USER_PATH, UserConstants.DEFAULT_USER_PATH);
+ } else if (node.hasPrimaryNodeTypeName(UserConstants.NT_REP_GROUP)) {
+ authRoot = provider.getConfig().getConfigValue(UserManagerConfig.PARAM_GROUP_PATH, UserConstants.DEFAULT_GROUP_PATH);
+ }
+ if (authRoot != null) {
+ assertHierarchy(node, authRoot);
+ }
+ return new UserValidator(null, node, provider);
+ }
+
+ @Override
+ public Validator childNodeChanged(String name, NodeState before, NodeState after) throws CommitFailedException {
+ // TODO: anything to do here?
+ return new UserValidator(parentBefore.getChild(name), parentAfter.getChild(name), provider);
+ }
+
+ @Override
+ public Validator childNodeDeleted(String name, NodeState before) throws CommitFailedException {
+ // nothing to do
+ return null;
+ }
+
+ //------------------------------------------------------------< private >---
+
+ /**
+ * Make sure user and group nodes are located underneath the configured path
+ * and that path consists of rep:authorizableFolder nodes.
+ *
+ * @param userNode
+ * @param pathConstraint
+ * @throws CommitFailedException
+ */
+ void assertHierarchy(NodeUtil userNode, String pathConstraint) throws CommitFailedException {
+ if (!Text.isDescendant(pathConstraint, userNode.getTree().getPath())) {
+ Exception e = new ConstraintViolationException("Attempt to create user/group outside of configured scope " + pathConstraint);
+ throw new CommitFailedException(e);
+ }
+
+ NodeUtil parent = userNode.getParent();
+ while (!parent.getTree().isRoot()) {
+ if (!parent.hasPrimaryNodeTypeName(UserConstants.NT_REP_AUTHORIZABLE_FOLDER)) {
+ String msg = "Cannot create user/group: Intermediate folders must be of type rep:AuthorizableFolder.";
+ Exception e = new ConstraintViolationException(msg);
+ throw new CommitFailedException(e);
+ }
+ parent = parent.getParent();
+ }
+ }
+}
\ No newline at end of file
Added: 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=1371699&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/UserValidatorProvider.java (added)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/UserValidatorProvider.java Fri Aug 10 13:46:06 2012
@@ -0,0 +1,61 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.oak.security.user;
+
+import javax.annotation.Nonnull;
+
+import org.apache.jackrabbit.oak.api.ContentSession;
+import org.apache.jackrabbit.oak.api.CoreValueFactory;
+import org.apache.jackrabbit.oak.core.ReadOnlyTree;
+import org.apache.jackrabbit.oak.namepath.NamePathMapper;
+import org.apache.jackrabbit.oak.spi.commit.Validator;
+import org.apache.jackrabbit.oak.spi.commit.ValidatorProvider;
+import org.apache.jackrabbit.oak.spi.security.user.UserManagerConfig;
+import org.apache.jackrabbit.oak.spi.state.NodeState;
+import org.apache.jackrabbit.oak.util.NodeUtil;
+
+/**
+ * Provides a validator for user and group management.
+ */
+public class UserValidatorProvider implements ValidatorProvider {
+
+ private final UserManagerConfig config = null; // TODO
+ private final ContentSession contentSession = null; // TODO
+
+ //--------------------------------------------------< ValidatorProvider >---
+ @Nonnull
+ @Override
+ public Validator getRootValidator(NodeState before, NodeState after) {
+ NamePathMapper mapper = new NamePathMapper.Default();
+ CoreValueFactory vf = contentSession.getCoreValueFactory();
+
+ NodeUtil rootBefore = new NodeUtil(vf, mapper, new ReadOnlyTree(before));
+ NodeUtil rootAfter = new NodeUtil(vf, mapper, new ReadOnlyTree(after));
+
+ return new UserValidator(rootBefore, rootAfter, this);
+ }
+
+ //-----------------------------------------------------------< internal >---
+
+ UserManagerConfig getConfig() {
+ return config;
+ }
+
+ CoreValueFactory getValueFactory() {
+ return contentSession.getCoreValueFactory();
+ }
+}
\ No newline at end of file
Added: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/commit/UniquePropertyValidator.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/commit/UniquePropertyValidator.java?rev=1371699&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/commit/UniquePropertyValidator.java (added)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/commit/UniquePropertyValidator.java Fri Aug 10 13:46:06 2012
@@ -0,0 +1,86 @@
+/*
+ * 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.commit;
+
+import java.util.Set;
+import javax.annotation.Nonnull;
+
+import org.apache.jackrabbit.oak.api.CommitFailedException;
+import org.apache.jackrabbit.oak.api.PropertyState;
+import org.apache.jackrabbit.oak.spi.state.NodeState;
+
+/**
+ * Base implementation of a validator that enforces uniqueness constraints
+ * within a given workspace: this includes unique property values for the
+ * properties listed in {@link #getPropertyNames()}.
+ */
+public abstract class UniquePropertyValidator implements Validator {
+
+ // TODO: verify if enforcing uniqueness constraints is really feasible in oak-core
+ // TODO: check if constraint validation needs to take property definition into account
+ // e.g. a jcr:uuid property that isn't defined by mix:referenceable may
+ // not necessarily be subject to the validation.
+
+ /**
+ * The property names for which the uniqueness constraint needs to
+ * be enforced.
+ *
+ * @return a set of property names.
+ */
+ @Nonnull
+ protected abstract Set<String> getPropertyNames();
+
+
+ protected void assertUniqueValue(PropertyState property) throws CommitFailedException {
+ // TODO:
+ }
+
+ //----------------------------------------------------------< Validator >---
+ @Override
+ public void propertyAdded(PropertyState after) throws CommitFailedException {
+ if (getPropertyNames().contains(after.getName())) {
+ assertUniqueValue(after);
+ }
+ }
+
+ @Override
+ public void propertyChanged(PropertyState before, PropertyState after) throws CommitFailedException {
+ if (getPropertyNames().contains(after.getName())) {
+ assertUniqueValue(after);
+ }
+ }
+
+ @Override
+ public void propertyDeleted(PropertyState before) throws CommitFailedException {
+ // nothing to do
+ }
+
+ @Override
+ public Validator childNodeAdded(String name, NodeState after) throws CommitFailedException {
+ return this;
+ }
+
+ @Override
+ public Validator childNodeChanged(String name, NodeState before, NodeState after) throws CommitFailedException {
+ return this;
+ }
+
+ @Override
+ public Validator childNodeDeleted(String name, NodeState before) throws CommitFailedException {
+ return this;
+ }
+}
\ No newline at end of file
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=1371699&r1=1371698&r2=1371699&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 Fri Aug 10 13:46:06 2012
@@ -32,4 +32,7 @@ public interface UserConstants {
String REP_MEMBERS = "rep:members";
String REP_IMPERSONATORS = "rep:impersonators";
+ String DEFAULT_USER_PATH = "/rep:security/rep:authorizables/rep:users";
+ String DEFAULT_GROUP_PATH = "/rep:security/rep:authorizables/rep:groups";
+
}
\ No newline at end of file
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/user/action/AuthorizableAction.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/user/action/AuthorizableAction.java?rev=1371699&r1=1371698&r2=1371699&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/user/action/AuthorizableAction.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/user/action/AuthorizableAction.java Fri Aug 10 13:46:06 2012
@@ -34,7 +34,7 @@ import javax.jcr.Session;
* <li>{@link #onPasswordChange(org.apache.jackrabbit.api.security.user.User, String, javax.jcr.Session) User password modification}.</li>
* </ul>
*
- * @see org.apache.jackrabbit.oak.jcr.security.user.UserManagerConfig
+ * @see org.apache.jackrabbit.oak.spi.security.user.UserManagerConfig
*/
public interface AuthorizableAction {
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/util/NodeUtil.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/util/NodeUtil.java?rev=1371699&r1=1371698&r2=1371699&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/util/NodeUtil.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/util/NodeUtil.java Fri Aug 10 13:46:06 2012
@@ -65,6 +65,10 @@ public class NodeUtil {
return mapper.getJcrName(tree.getName());
}
+ public NodeUtil getParent() {
+ return new NodeUtil(factory, mapper, tree.getParent());
+ }
+
public boolean hasChild(String name) {
return tree.getChild(name) != null;
}
@@ -160,8 +164,7 @@ public class NodeUtil {
throw new IllegalArgumentException("Invalid name:" + name);
}
- tree.setProperty(name, factory.createValue(
- oakName, PropertyType.NAME));
+ tree.setProperty(name, factory.createValue(oakName, PropertyType.NAME));
}
public String[] getNames(String name, String... defaultValues) {
@@ -183,8 +186,7 @@ public class NodeUtil {
throw new IllegalArgumentException("Invalid name:" + name);
}
- cvs.add(factory.createValue(
- oakName, PropertyType.NAME));
+ cvs.add(factory.createValue(oakName, PropertyType.NAME));
}
tree.setProperty(name, cvs);
}