You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by ro...@apache.org on 2017/11/07 09:50:10 UTC
[sling-org-apache-sling-jcr-jackrabbit-usermanager] 06/14:
SLING-6747 support setting nested properties
This is an automated email from the ASF dual-hosted git repository.
rombert pushed a commit to annotated tag org.apache.sling.jcr.jackrabbit.usermanager-2.2.6
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-jcr-jackrabbit-usermanager.git
commit a6edcb4e19999c89ea96590bc6aa8ec2f018d0e7
Author: Konrad Windszus <kw...@apache.org>
AuthorDate: Thu Mar 30 09:58:45 2017 +0000
SLING-6747 support setting nested properties
git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/bundles/jcr/jackrabbit-usermanager@1789483 13f79535-47bb-0310-9956-ffa450edef68
---
.../impl/post/AbstractAuthorizablePostServlet.java | 107 ++++++++++++---------
.../usermanager/impl/post/CreateGroupServlet.java | 4 +-
.../usermanager/impl/post/CreateUserServlet.java | 4 +-
.../usermanager/impl/post/UpdateGroupServlet.java | 3 +-
.../usermanager/impl/post/UpdateUserServlet.java | 3 +-
5 files changed, 67 insertions(+), 54 deletions(-)
diff --git a/src/main/java/org/apache/sling/jackrabbit/usermanager/impl/post/AbstractAuthorizablePostServlet.java b/src/main/java/org/apache/sling/jackrabbit/usermanager/impl/post/AbstractAuthorizablePostServlet.java
index bbdc579..464b471 100644
--- a/src/main/java/org/apache/sling/jackrabbit/usermanager/impl/post/AbstractAuthorizablePostServlet.java
+++ b/src/main/java/org/apache/sling/jackrabbit/usermanager/impl/post/AbstractAuthorizablePostServlet.java
@@ -20,6 +20,7 @@ import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.util.Calendar;
+import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
@@ -41,6 +42,8 @@ import org.apache.sling.servlets.post.Modification;
import org.apache.sling.servlets.post.SlingPostConstants;
import org.apache.sling.servlets.post.impl.helper.DateParser;
import org.apache.sling.servlets.post.impl.helper.RequestProperty;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
/**
* Base class for all the POST servlets for the UserManager operations
@@ -51,6 +54,8 @@ public abstract class AbstractAuthorizablePostServlet extends
public static final String PROP_DATE_FORMAT = "servlet.post.dateFormats";
+ private static final Logger LOG = LoggerFactory.getLogger(AbstractAuthorizablePostServlet.class);
+
private DateParser dateParser;
// ---------- SCR Integration ----------------------------------------------
@@ -72,19 +77,18 @@ public abstract class AbstractAuthorizablePostServlet extends
/**
* Collects the properties that form the content to be written back to the
- * repository. NOTE: In the returned map, the key is the property name not a
- * path.
+ * repository.
*
* @throws RepositoryException if a repository error occurs
* @throws ServletException if an internal error occurs
*/
- protected Map<String, RequestProperty> collectContent(
+ protected Collection<RequestProperty> collectContent(
Map<String, ?> properties,
String authorizablePath) {
boolean requireItemPrefix = requireItemPathPrefix(properties);
- // walk the request parameters and collect the properties
+ // walk the request parameters and collect the properties (the key is the property path).
Map<String, RequestProperty> reqProperties = new HashMap<String, RequestProperty>();
for (Map.Entry<String, ?> e : properties.entrySet()) {
final String paramName = e.getKey();
@@ -102,21 +106,20 @@ public abstract class AbstractAuthorizablePostServlet extends
continue;
}
- // ensure the paramName is an absolute property name
+ // ensure the paramName is an absolute property path (i.e. starts with "/", where root refers to the authorizable's root, https://issues.apache.org/jira/browse/SLING-1577)
String propPath;
if (paramName.startsWith("./")) {
- propPath = paramName.substring(2);
+ propPath = paramName.substring(1);
} else {
- propPath = paramName;
+ propPath = "/" + paramName;
}
- if (propPath.indexOf('/') != -1) {
- // only one path segment is valid here, so this paramter can't
- // be used.
+
+ if (propPath.indexOf("..") != -1) {
+ // it is not supported to set properties potentially outside of the authorizable node
+ LOG.warn("Property path containing '..' is not supported, skipping parameter {}", SlingPostConstants.SUFFIX_COPY_FROM, paramName);
continue; // skip it.
}
- propPath = authorizablePath + "/" + propPath;
-
// @TypeHint example
// <input type="text" name="./age" />
// <input type="hidden" name="./age@TypeHint" value="long" />
@@ -189,6 +192,7 @@ public abstract class AbstractAuthorizablePostServlet extends
// property to Text.
if (propPath.endsWith(SlingPostConstants.SUFFIX_MOVE_FROM)) {
// don't support @MoveFrom here
+ LOG.warn("Suffix {} not supported, skipping parameter {}", SlingPostConstants.SUFFIX_MOVE_FROM, paramName);
continue;
}
@@ -199,6 +203,7 @@ public abstract class AbstractAuthorizablePostServlet extends
// property to Text.
if (propPath.endsWith(SlingPostConstants.SUFFIX_COPY_FROM)) {
// don't support @CopyFrom here
+ LOG.warn("Suffix {} not supported, skipping parameter {}", SlingPostConstants.SUFFIX_COPY_FROM, paramName);
continue;
}
@@ -208,7 +213,7 @@ public abstract class AbstractAuthorizablePostServlet extends
prop.setValues(convertToRequestParameterArray(e.getValue()));
}
- return reqProperties;
+ return reqProperties.values();
}
/**
@@ -216,7 +221,8 @@ public abstract class AbstractAuthorizablePostServlet extends
* request property does not exist yet it is created and stored in the
* <code>props</code>.
*
- * @param props The map of already seen request properties.
+ * @param props The map of already seen request properties
+ * (key is the property path).
* @param paramPath The absolute path of the property including the
* <code>suffix</code> to be looked up.
* @param suffix The (optional) suffix to remove from the
@@ -246,7 +252,7 @@ public abstract class AbstractAuthorizablePostServlet extends
* @param authorizable The
* <code>org.apache.jackrabbit.api.security.user.Authorizable</code>
* that should have properties deleted.
- * @param reqProperties The map of request properties to check for
+ * @param reqProperties The collection of request properties to check for
* properties to be removed.
* @param changes The <code>List</code> to be updated with
* information on deleted properties.
@@ -254,10 +260,10 @@ public abstract class AbstractAuthorizablePostServlet extends
* removing properties.
*/
protected void processDeletes(Authorizable authorizable,
- Map<String, RequestProperty> reqProperties,
+ Collection<RequestProperty> reqProperties,
List<Modification> changes) throws RepositoryException {
- for (RequestProperty property : reqProperties.values()) {
+ for (RequestProperty property : reqProperties) {
if (property.isDelete()) {
if (authorizable.hasProperty(property.getName())) {
authorizable.removeProperty(property.getName());
@@ -274,25 +280,28 @@ public abstract class AbstractAuthorizablePostServlet extends
* @throws ServletException if an internal error occurs
*/
protected void writeContent(Session session, Authorizable authorizable,
- Map<String, RequestProperty> reqProperties,
+ Collection<RequestProperty> reqProperties,
List<Modification> changes) throws RepositoryException {
- for (RequestProperty prop : reqProperties.values()) {
+ for (RequestProperty prop : reqProperties) {
if (prop.hasValues()) {
+ // remove artificial "/" prepended to the prop path
+ String relativePath = prop.getPath().substring(1);
+
// skip jcr special properties
- if (prop.getName().equals("jcr:primaryType")
- || prop.getName().equals("jcr:mixinTypes")) {
+ if (relativePath.equals("jcr:primaryType")
+ || relativePath.equals("jcr:mixinTypes")) {
continue;
}
if (authorizable.isGroup()) {
- if (prop.getName().equals("groupId")) {
+ if (relativePath.equals("groupId")) {
// skip these
continue;
}
} else {
- if (prop.getName().equals("userId")
- || prop.getName().equals("pwd")
- || prop.getName().equals("pwdConfirm")) {
+ if (relativePath.equals("userId")
+ || relativePath.equals("pwd")
+ || relativePath.equals("pwdConfirm")) {
// skip these
continue;
}
@@ -337,31 +346,33 @@ public abstract class AbstractAuthorizablePostServlet extends
// ignore
}
}
+ // remove artificial "/" prepended to the prop path
+ String relativePath = prop.getPath().substring(1);
String[] values = prop.getStringValues();
if (values == null) {
// remove property
- boolean removedProp = removePropertyIfExists(parent, prop.getName());
+ boolean removedProp = removePropertyIfExists(parent, relativePath);
if (removedProp) {
changes.add(Modification.onDeleted(parentPath + "/"
- + prop.getName()));
+ + relativePath));
}
} else if (values.length == 0) {
// do not create new prop here, but clear existing
- if (parent.hasProperty(prop.getName())) {
+ if (parent.hasProperty(relativePath) {
Value val = session.getValueFactory().createValue("");
- parent.setProperty(prop.getName(), val);
+ parent.setProperty(relativePath, val);
changes.add(Modification.onModified(parentPath + "/"
- + prop.getName()));
+ + relativePath));
}
} else if (values.length == 1) {
- boolean removedProp = removePropertyIfExists(parent, prop.getName());
+ boolean removedProp = removePropertyIfExists(parent, relativePath);
// if the provided value is the empty string, we don't have to do
// anything.
if (values[0].length() == 0) {
if (removedProp) {
changes.add(Modification.onDeleted(parentPath + "/"
- + prop.getName()));
+ + relativePath));
}
} else {
// modify property
@@ -372,15 +383,15 @@ public abstract class AbstractAuthorizablePostServlet extends
if (prop.hasMultiValueTypeHint()) {
final Value[] array = new Value[1];
array[0] = session.getValueFactory().createValue(c);
- parent.setProperty(prop.getName(), array);
+ parent.setProperty(relativePath, array);
changes.add(Modification.onModified(parentPath
- + "/" + prop.getName()));
+ + "/" + relativePath));
} else {
Value cVal = session.getValueFactory().createValue(
c);
parent.setProperty(prop.getName(), cVal);
changes.add(Modification.onModified(parentPath
- + "/" + prop.getName()));
+ + "/" + relativePath));
}
return;
}
@@ -389,32 +400,32 @@ public abstract class AbstractAuthorizablePostServlet extends
if (type == PropertyType.UNDEFINED) {
Value val = session.getValueFactory().createValue(
values[0], PropertyType.STRING);
- parent.setProperty(prop.getName(), val);
+ parent.setProperty(relativePath, val);
} else {
if (prop.hasMultiValueTypeHint()) {
final Value[] array = new Value[1];
array[0] = session.getValueFactory().createValue(
values[0], type);
- parent.setProperty(prop.getName(), array);
+ parent.setProperty(relativePath, array);
} else {
Value val = session.getValueFactory().createValue(
values[0], type);
- parent.setProperty(prop.getName(), val);
+ parent.setProperty(relativePath, val);
}
}
changes.add(Modification.onModified(parentPath + "/"
- + prop.getName()));
+ + relativePath));
}
} else {
- removePropertyIfExists(parent, prop.getName());
+ removePropertyIfExists(parent, relativePath);
if (type == PropertyType.DATE) {
// try conversion
ValueFactory valFac = session.getValueFactory();
Value[] c = dateParser.parse(values, valFac);
if (c != null) {
- parent.setProperty(prop.getName(), c);
+ parent.setProperty(relativePath, c);
changes.add(Modification.onModified(parentPath + "/"
- + prop.getName()));
+ + relativePath));
return;
}
// fall back to default behaviour
@@ -431,9 +442,9 @@ public abstract class AbstractAuthorizablePostServlet extends
type);
}
}
- parent.setProperty(prop.getName(), vals);
+ parent.setProperty(relativePath, vals);
changes.add(Modification.onModified(parentPath + "/"
- + prop.getName()));
+ + relativePath));
}
}
@@ -444,15 +455,15 @@ public abstract class AbstractAuthorizablePostServlet extends
*
* @param authorizable the <code>org.apache.jackrabbit.api.security.user.Authorizable</code>
* that should have properties deleted.
- * @param name the name of the property to remove
+ * @param path the path of the property to remove
* @return path of the property that was removed or <code>null</code> if it
* was not removed
* @throws RepositoryException if a repository error occurs.
*/
- private boolean removePropertyIfExists(Authorizable authorizable, String name)
+ private boolean removePropertyIfExists(Authorizable authorizable, String path)
throws RepositoryException {
- if (authorizable.getProperty(name) != null) {
- authorizable.removeProperty(name);
+ if (authorizable.getProperty(path) != null) {
+ authorizable.removeProperty(path);
return true;
}
return false;
diff --git a/src/main/java/org/apache/sling/jackrabbit/usermanager/impl/post/CreateGroupServlet.java b/src/main/java/org/apache/sling/jackrabbit/usermanager/impl/post/CreateGroupServlet.java
index d0e26a7..c2c60dd 100644
--- a/src/main/java/org/apache/sling/jackrabbit/usermanager/impl/post/CreateGroupServlet.java
+++ b/src/main/java/org/apache/sling/jackrabbit/usermanager/impl/post/CreateGroupServlet.java
@@ -17,6 +17,7 @@
package org.apache.sling.jackrabbit.usermanager.impl.post;
import java.security.Principal;
+import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -176,8 +177,7 @@ public class CreateGroupServlet extends AbstractGroupPostServlet implements Crea
String groupPath = AuthorizableResourceProvider.SYSTEM_USER_MANAGER_GROUP_PREFIX
+ group.getID();
- Map<String, RequestProperty> reqProperties = collectContent(
- properties, groupPath);
+ Collection<RequestProperty> reqProperties = collectContent(properties, groupPath);
changes.add(Modification.onCreated(groupPath));
// write content from form
diff --git a/src/main/java/org/apache/sling/jackrabbit/usermanager/impl/post/CreateUserServlet.java b/src/main/java/org/apache/sling/jackrabbit/usermanager/impl/post/CreateUserServlet.java
index 4992055..76fd94b 100644
--- a/src/main/java/org/apache/sling/jackrabbit/usermanager/impl/post/CreateUserServlet.java
+++ b/src/main/java/org/apache/sling/jackrabbit/usermanager/impl/post/CreateUserServlet.java
@@ -16,6 +16,7 @@
*/
package org.apache.sling.jackrabbit.usermanager.impl.post;
+import java.util.Collection;
import java.util.List;
import java.util.Map;
@@ -296,8 +297,7 @@ public class CreateUserServlet extends AbstractAuthorizablePostServlet implement
String userPath = AuthorizableResourceProvider.SYSTEM_USER_MANAGER_USER_PREFIX
+ user.getID();
- Map<String, RequestProperty> reqProperties = collectContent(
- properties, userPath);
+ Collection<RequestProperty> reqProperties = collectContent(properties, userPath);
changes.add(Modification.onCreated(userPath));
diff --git a/src/main/java/org/apache/sling/jackrabbit/usermanager/impl/post/UpdateGroupServlet.java b/src/main/java/org/apache/sling/jackrabbit/usermanager/impl/post/UpdateGroupServlet.java
index 0a8df63..b1f4e4c 100644
--- a/src/main/java/org/apache/sling/jackrabbit/usermanager/impl/post/UpdateGroupServlet.java
+++ b/src/main/java/org/apache/sling/jackrabbit/usermanager/impl/post/UpdateGroupServlet.java
@@ -16,6 +16,7 @@
*/
package org.apache.sling.jackrabbit.usermanager.impl.post;
+import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -156,7 +157,7 @@ public class UpdateGroupServlet extends AbstractGroupPostServlet
String groupPath = AuthorizableResourceProvider.SYSTEM_USER_MANAGER_GROUP_PREFIX
+ group.getID();
- Map<String, RequestProperty> reqProperties = collectContent(properties, groupPath);
+ Collection<RequestProperty> reqProperties = collectContent(properties, groupPath);
try {
// cleanup any old content (@Delete parameters)
processDeletes(group, reqProperties, changes);
diff --git a/src/main/java/org/apache/sling/jackrabbit/usermanager/impl/post/UpdateUserServlet.java b/src/main/java/org/apache/sling/jackrabbit/usermanager/impl/post/UpdateUserServlet.java
index aa11544..139ebab 100644
--- a/src/main/java/org/apache/sling/jackrabbit/usermanager/impl/post/UpdateUserServlet.java
+++ b/src/main/java/org/apache/sling/jackrabbit/usermanager/impl/post/UpdateUserServlet.java
@@ -16,6 +16,7 @@
*/
package org.apache.sling.jackrabbit.usermanager.impl.post;
+import java.util.Collection;
import java.util.List;
import java.util.Map;
@@ -146,7 +147,7 @@ public class UpdateUserServlet extends AbstractAuthorizablePostServlet
String userPath = AuthorizableResourceProvider.SYSTEM_USER_MANAGER_GROUP_PREFIX
+ user.getID();
- Map<String, RequestProperty> reqProperties = collectContent(properties, userPath);
+ Collection<RequestProperty> reqProperties = collectContent(properties, userPath);
try {
// cleanup any old content (@Delete parameters)
processDeletes(user, reqProperties, changes);
--
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.