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 <[email protected]> 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 "[email protected]" <[email protected]>.
