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.0 in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-jcr-jackrabbit-usermanager.git
commit 82447c70c988d2b84997a97eba9ca69783707594 Author: Eric Norman <[email protected]> AuthorDate: Thu May 19 05:17:48 2011 +0000 SLING-1555 UserManager permissions manipulation services that mirror the functionality of the REST operations for programmatic user management code. git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/bundles/jcr/jackrabbit-usermanager@1124537 13f79535-47bb-0310-9956-ffa450edef68 --- .../jackrabbit/usermanager/ChangeUserPassword.java | 58 ++++++ .../sling/jackrabbit/usermanager/CreateGroup.java | 55 ++++++ .../sling/jackrabbit/usermanager/CreateUser.java | 59 ++++++ .../usermanager/DeleteAuthorizables.java | 53 +++++ .../sling/jackrabbit/usermanager/DeleteGroup.java | 50 +++++ .../sling/jackrabbit/usermanager/DeleteUser.java | 50 +++++ .../sling/jackrabbit/usermanager/UpdateGroup.java | 55 ++++++ .../sling/jackrabbit/usermanager/UpdateUser.java | 55 ++++++ .../impl/post/AbstractAuthorizablePostServlet.java | 220 +++++++++++++++++++-- .../impl/post/AbstractGroupPostServlet.java | 53 ++--- .../impl/post/ChangeUserPasswordServlet.java | 84 +++++--- .../usermanager/impl/post/CreateGroupServlet.java | 82 +++++--- .../usermanager/impl/post/CreateUserServlet.java | 104 +++++++--- .../impl/post/DeleteAuthorizableServlet.java | 140 +++++++++---- .../usermanager/impl/post/UpdateGroupServlet.java | 76 ++++--- .../usermanager/impl/post/UpdateUserServlet.java | 64 +++--- 16 files changed, 1043 insertions(+), 215 deletions(-) diff --git a/src/main/java/org/apache/sling/jackrabbit/usermanager/ChangeUserPassword.java b/src/main/java/org/apache/sling/jackrabbit/usermanager/ChangeUserPassword.java new file mode 100644 index 0000000..d98f676 --- /dev/null +++ b/src/main/java/org/apache/sling/jackrabbit/usermanager/ChangeUserPassword.java @@ -0,0 +1,58 @@ +/* + * 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.sling.jackrabbit.usermanager; + +import java.util.List; + +import javax.jcr.RepositoryException; +import javax.jcr.Session; + +import org.apache.jackrabbit.api.security.user.User; +import org.apache.sling.servlets.post.Modification; + +/** + * The <code>ChangeUserPassword</code> service api. + * <p> + * This interface is not intended to be implemented by bundles. It is + * implemented by this bundle and may be used by client bundles. + * </p> + */ +public interface ChangeUserPassword { + + /** + * Update the password of a user in the repository + * + * @param jcrSession the JCR session of the user updating the user + * @param name The name of the user to update (required) + * @param oldPassword The current password of the user (required for non-admin users) + * @param newPassword The password value to apply (required) + * @param newPasswordConfirm The password value to apply again (required) + * @param changes The list of changes for this operation (optional) + * @return the user whose password was changed + * @throws RepositoryException + */ + public User changePassword(Session jcrSession, + String name, + String oldPassword, + String newPassword, + String newPasswordConfirm, + List<Modification> changes + ) throws RepositoryException; + +} diff --git a/src/main/java/org/apache/sling/jackrabbit/usermanager/CreateGroup.java b/src/main/java/org/apache/sling/jackrabbit/usermanager/CreateGroup.java new file mode 100644 index 0000000..934e502 --- /dev/null +++ b/src/main/java/org/apache/sling/jackrabbit/usermanager/CreateGroup.java @@ -0,0 +1,55 @@ +/* + * 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.sling.jackrabbit.usermanager; + +import java.util.List; +import java.util.Map; + +import javax.jcr.RepositoryException; +import javax.jcr.Session; + +import org.apache.jackrabbit.api.security.user.Group; +import org.apache.sling.servlets.post.Modification; + +/** + * The <code>CreateGroup</code> service api. + * <p> + * This interface is not intended to be implemented by bundles. It is + * implemented by this bundle and may be used by client bundles. + * </p> + */ +public interface CreateGroup { + + /** + * Create a new group for the repository + * + * @param jcrSession the JCR session of the user creating the group + * @param name The name of the new group (required) + * @param properties Extra properties to update on the group. The entry values should be either a String or String[] (optional) + * @param changes The list of changes for this operation (optional) + * @return the group that was created + * @throws RepositoryException + */ + public Group createGroup(Session jcrSession, + String name, + Map<String, ?> properties, + List<Modification> changes + ) throws RepositoryException; + +} diff --git a/src/main/java/org/apache/sling/jackrabbit/usermanager/CreateUser.java b/src/main/java/org/apache/sling/jackrabbit/usermanager/CreateUser.java new file mode 100644 index 0000000..51c7b02 --- /dev/null +++ b/src/main/java/org/apache/sling/jackrabbit/usermanager/CreateUser.java @@ -0,0 +1,59 @@ +/* + * 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.sling.jackrabbit.usermanager; + +import java.util.List; +import java.util.Map; + +import javax.jcr.RepositoryException; +import javax.jcr.Session; + +import org.apache.jackrabbit.api.security.user.User; +import org.apache.sling.servlets.post.Modification; + +/** + * The <code>CreateUser</code> service api. + * <p> + * This interface is not intended to be implemented by bundles. It is + * implemented by this bundle and may be used by client bundles. + * </p> + */ +public interface CreateUser { + + /** + * Create a new user for the repository + * + * @param jcrSession the JCR session of the user creating the user + * @param name The name of the new user (required) + * @param password The password of the new user (required) + * @param password The password of the new user again (required) + * @param properties Extra properties to update on the user. The entry values should be either a String or String[] (optional) + * @param changes The list of changes for this operation (optional) + * @return the user that was created + * @throws RepositoryException + */ + public User createUser(Session jcrSession, + String name, + String password, + String passwordConfirm, + Map<String, ?> properties, + List<Modification> changes + ) throws RepositoryException; + +} diff --git a/src/main/java/org/apache/sling/jackrabbit/usermanager/DeleteAuthorizables.java b/src/main/java/org/apache/sling/jackrabbit/usermanager/DeleteAuthorizables.java new file mode 100644 index 0000000..98f93bf --- /dev/null +++ b/src/main/java/org/apache/sling/jackrabbit/usermanager/DeleteAuthorizables.java @@ -0,0 +1,53 @@ +/* + * 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.sling.jackrabbit.usermanager; + +import java.util.List; + +import javax.jcr.RepositoryException; +import javax.jcr.Session; + +import org.apache.sling.api.resource.Resource; +import org.apache.sling.servlets.post.Modification; + +/** + * The <code>DeleteAuthorizables</code> service api. + * <p> + * This interface is not intended to be implemented by bundles. It is + * implemented by this bundle and may be used by client bundles. + * </p> + */ +public interface DeleteAuthorizables { + + /** + * Deletes one or more users or groups from the repository + * + * @param jcrSession the JCR session of the user creating the user + * @param baseResource the base resource to calculate the relative paths from (required) + * @param paths An array of relative resource paths to Authorizables to be deleted (required) + * @param changes The list of changes for this operation (optional) + * @throws RepositoryException + */ + public void deleteAuthorizables(Session jcrSession, + Resource baseResource, + String [] paths, + List<Modification> changes + ) throws RepositoryException; + +} diff --git a/src/main/java/org/apache/sling/jackrabbit/usermanager/DeleteGroup.java b/src/main/java/org/apache/sling/jackrabbit/usermanager/DeleteGroup.java new file mode 100644 index 0000000..3c9f9b1 --- /dev/null +++ b/src/main/java/org/apache/sling/jackrabbit/usermanager/DeleteGroup.java @@ -0,0 +1,50 @@ +/* + * 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.sling.jackrabbit.usermanager; + +import java.util.List; + +import javax.jcr.RepositoryException; +import javax.jcr.Session; + +import org.apache.sling.servlets.post.Modification; + +/** + * The <code>DeleteGroup</code> service api. + * <p> + * This interface is not intended to be implemented by bundles. It is + * implemented by this bundle and may be used by client bundles. + * </p> + */ +public interface DeleteGroup { + + /** + * Deletes a group from the repository + * + * @param jcrSession the JCR session of the user creating the user + * @param name The name of the group to delete (required) + * @param changes The list of changes for this operation (optional) + * @throws RepositoryException + */ + public void deleteGroup(Session jcrSession, + String name, + List<Modification> changes + ) throws RepositoryException; + +} diff --git a/src/main/java/org/apache/sling/jackrabbit/usermanager/DeleteUser.java b/src/main/java/org/apache/sling/jackrabbit/usermanager/DeleteUser.java new file mode 100644 index 0000000..506ae79 --- /dev/null +++ b/src/main/java/org/apache/sling/jackrabbit/usermanager/DeleteUser.java @@ -0,0 +1,50 @@ +/* + * 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.sling.jackrabbit.usermanager; + +import java.util.List; + +import javax.jcr.RepositoryException; +import javax.jcr.Session; + +import org.apache.sling.servlets.post.Modification; + +/** + * The <code>DeleteUser</code> service api. + * <p> + * This interface is not intended to be implemented by bundles. It is + * implemented by this bundle and may be used by client bundles. + * </p> + */ +public interface DeleteUser { + + /** + * Deletes a user from the repository + * + * @param jcrSession the JCR session of the user creating the user + * @param name The name of the user to delete (required) + * @param changes The list of changes for this operation (optional) + * @throws RepositoryException + */ + public void deleteUser(Session jcrSession, + String name, + List<Modification> changes + ) throws RepositoryException; + +} diff --git a/src/main/java/org/apache/sling/jackrabbit/usermanager/UpdateGroup.java b/src/main/java/org/apache/sling/jackrabbit/usermanager/UpdateGroup.java new file mode 100644 index 0000000..64bdacd --- /dev/null +++ b/src/main/java/org/apache/sling/jackrabbit/usermanager/UpdateGroup.java @@ -0,0 +1,55 @@ +/* + * 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.sling.jackrabbit.usermanager; + +import java.util.List; +import java.util.Map; + +import javax.jcr.RepositoryException; +import javax.jcr.Session; + +import org.apache.jackrabbit.api.security.user.Group; +import org.apache.sling.servlets.post.Modification; + +/** + * The <code>UpdateGroup</code> service api. + * <p> + * This interface is not intended to be implemented by bundles. It is + * implemented by this bundle and may be used by client bundles. + * </p> + */ +public interface UpdateGroup { + + /** + * Update a group in the repository + * + * @param jcrSession the JCR session of the user creating the group + * @param name The name of the group to update (required) + * @param properties Extra properties to update on the group. The entry values should be either a String or String[] (optional) + * @param changes The list of changes for this operation (optional) + * @return the group that was updated or null if not found + * @throws RepositoryException + */ + public Group updateGroup(Session jcrSession, + String name, + Map<String, ?> properties, + List<Modification> changes + ) throws RepositoryException; + +} diff --git a/src/main/java/org/apache/sling/jackrabbit/usermanager/UpdateUser.java b/src/main/java/org/apache/sling/jackrabbit/usermanager/UpdateUser.java new file mode 100644 index 0000000..aac6a0a --- /dev/null +++ b/src/main/java/org/apache/sling/jackrabbit/usermanager/UpdateUser.java @@ -0,0 +1,55 @@ +/* + * 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.sling.jackrabbit.usermanager; + +import java.util.List; +import java.util.Map; + +import javax.jcr.RepositoryException; +import javax.jcr.Session; + +import org.apache.jackrabbit.api.security.user.User; +import org.apache.sling.servlets.post.Modification; + +/** + * The <code>UpdateUser</code> service api. + * <p> + * This interface is not intended to be implemented by bundles. It is + * implemented by this bundle and may be used by client bundles. + * </p> + */ +public interface UpdateUser { + + /** + * Update a user in the repository + * + * @param jcrSession the JCR session of the user updating the user + * @param name The name of the user to update (required) + * @param properties Extra properties to update on the user. The entry values should be either a String or String[] (optional) + * @param changes The list of changes for this operation (optional) + * @return the user that was updated or null if not found + * @throws RepositoryException + */ + public User updateUser(Session jcrSession, + String name, + Map<String, ?> properties, + List<Modification> changes + ) throws RepositoryException; + +} 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 9b7e0e7..d6d743a 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 @@ -16,12 +16,15 @@ */ package org.apache.sling.jackrabbit.usermanager.impl.post; +import java.io.ByteArrayInputStream; import java.io.IOException; +import java.io.InputStream; +import java.io.UnsupportedEncodingException; import java.util.ArrayList; import java.util.Calendar; import java.util.Dictionary; -import java.util.Enumeration; import java.util.HashMap; +import java.util.Iterator; import java.util.List; import java.util.Map; @@ -37,6 +40,7 @@ import javax.servlet.http.HttpServletResponse; import org.apache.jackrabbit.api.security.user.Authorizable; import org.apache.sling.api.SlingHttpServletRequest; import org.apache.sling.api.SlingHttpServletResponse; +import org.apache.sling.api.SlingIOException; import org.apache.sling.api.request.RequestParameter; import org.apache.sling.api.resource.ResourceNotFoundException; import org.apache.sling.api.resource.ResourceUtil; @@ -305,14 +309,14 @@ public abstract class AbstractAuthorizablePostServlet extends * @throws ServletException if an internal error occurs */ protected Map<String, RequestProperty> collectContent( - SlingHttpServletRequest request, HtmlResponse response, + Map<String, ?> properties, String authorizablePath) { - boolean requireItemPrefix = requireItemPathPrefix(request); + boolean requireItemPrefix = requireItemPathPrefix(properties); // walk the request parameters and collect the properties Map<String, RequestProperty> reqProperties = new HashMap<String, RequestProperty>(); - for (Map.Entry<String, RequestParameter[]> e : request.getRequestParameterMap().entrySet()) { + for (Map.Entry<String, ?> e : properties.entrySet()) { final String paramName = e.getKey(); // do not store parameters with names starting with sling:post @@ -352,9 +356,9 @@ public abstract class AbstractAuthorizablePostServlet extends reqProperties, propPath, SlingPostConstants.TYPE_HINT_SUFFIX); - final RequestParameter[] rp = e.getValue(); - if (rp.length > 0) { - prop.setTypeHintValue(rp[0].getString()); + String typeHintValue = convertToString(e.getValue()); + if (typeHintValue != null) { + prop.setTypeHintValue(typeHintValue); } continue; @@ -366,7 +370,7 @@ public abstract class AbstractAuthorizablePostServlet extends reqProperties, propPath, SlingPostConstants.DEFAULT_VALUE_SUFFIX); - prop.setDefaultValues(e.getValue()); + prop.setDefaultValues(convertToRequestParameterArray(e.getValue())); continue; } @@ -383,9 +387,10 @@ public abstract class AbstractAuthorizablePostServlet extends SlingPostConstants.VALUE_FROM_SUFFIX); // @ValueFrom params must have exactly one value, else ignored - if (e.getValue().length == 1) { - String refName = e.getValue()[0].getString(); - RequestParameter[] refValues = request.getRequestParameters(refName); + String [] valueFrom = convertToStringArray(e.getValue()); + if (valueFrom.length == 1) { + String refName = valueFrom[0]; + RequestParameter[] refValues = convertToRequestParameterArray(refName); if (refValues != null) { prop.setValues(refValues); } @@ -430,7 +435,7 @@ public abstract class AbstractAuthorizablePostServlet extends // plain property, create from values RequestProperty prop = getOrCreateRequestProperty(reqProperties, propPath, null); - prop.setValues(e.getValue()); + prop.setValues(convertToRequestParameterArray(e.getValue())); } return reqProperties; @@ -744,17 +749,200 @@ public abstract class AbstractAuthorizablePostServlet extends * parameters to be stored. */ protected final boolean requireItemPathPrefix( - SlingHttpServletRequest request) { + Map<String, ?> properties) { boolean requirePrefix = false; - Enumeration<?> names = request.getParameterNames(); - while (names.hasMoreElements() && !requirePrefix) { - String name = (String) names.nextElement(); + Iterator<String> iterator = properties.keySet().iterator(); + while (iterator.hasNext() && !requirePrefix) { + String name = iterator.next(); requirePrefix = name.startsWith(SlingPostConstants.ITEM_PREFIX_RELATIVE_CURRENT); } return requirePrefix; } + + protected String convertToString(Object obj) { + if (obj == null) { + return null; + } + + if (obj instanceof String) { + return (String)obj; + } else if (obj instanceof String[]) { + String [] values = (String[])obj; + if (values.length > 0) { + return values[0]; + } + return null; + } else if (obj instanceof RequestParameter) { + ((RequestParameter)obj).getString(); + } else if (obj instanceof RequestParameter[]) { + RequestParameter[] values = (RequestParameter[])obj; + if (values.length > 0) { + return values[0].getString(); + } + return null; + } + return null; + } + + protected String[] convertToStringArray(Object obj) { + if (obj == null) { + return null; + } + + if (obj instanceof String) { + return new String[] {(String)obj}; + } else if (obj instanceof String[]) { + return (String[])obj; + } else if (obj instanceof RequestParameter) { + return new String[] {((RequestParameter)obj).getString()}; + } else if (obj instanceof RequestParameter[]) { + RequestParameter[] values = (RequestParameter[])obj; + String [] strValues = new String[values.length]; + for (int i=0; i < values.length; i++) { + strValues[i] = values[i].getString(); + } + return strValues; + } + return null; + } + + protected RequestParameter[] convertToRequestParameterArray(Object obj) { + if (obj == null) { + return null; + } + + if (obj instanceof String) { + return new RequestParameter[] { + new RequestParameterImpl((String)obj, null) + }; + } else if (obj instanceof String[]) { + String [] strValues = (String[])obj; + RequestParameter [] values = new RequestParameter[strValues.length]; + for (int i=0; i < strValues.length; i++) { + values[i] = new RequestParameterImpl(strValues[i], null); + } + return values; + } else if (obj instanceof RequestParameter) { + return new RequestParameter[] {(RequestParameter)obj}; + } else if (obj instanceof RequestParameter[]) { + return (RequestParameter[])obj; + } + return null; + } + + static class RequestParameterImpl implements RequestParameter { + + private String value; + private String encoding; + + private byte[] content; + + RequestParameterImpl(String value, String encoding) { + this.encoding = encoding; + this.value = value; + this.content = null; + } + + String getEncoding() { + return this.encoding; + } + + void setEncoding(String encoding) { + // recode this parameter by encoding the string with the current + // encoding and decode the bytes with the encoding + try { + this.value = getString(encoding); + } catch (UnsupportedEncodingException uee) { + throw new SlingUnsupportedEncodingException(uee); + } + this.encoding = encoding; + } + + /** + * @see org.apache.sling.api.request.RequestParameter#get() + */ + public byte[] get() { + if (content == null) { + try { + content = getString().getBytes(getEncoding()); + } catch (Exception e) { + // UnsupportedEncodingException, IllegalArgumentException + content = getString().getBytes(); + } + } + return content; + } + + /** + * @see org.apache.sling.api.request.RequestParameter#getContentType() + */ + public String getContentType() { + // none known for www-form-encoded parameters + return null; + } + + /** + * @see org.apache.sling.api.request.RequestParameter#getInputStream() + */ + public InputStream getInputStream() { + return new ByteArrayInputStream(this.get()); + } + + /** + * @see org.apache.sling.api.request.RequestParameter#getFileName() + */ + public String getFileName() { + // no original file name + return null; + } + + /** + * @see org.apache.sling.api.request.RequestParameter#getSize() + */ + public long getSize() { + return this.get().length; + } + + /** + * @see org.apache.sling.api.request.RequestParameter#getString() + */ + public String getString() { + return value; + } + + /** + * @see org.apache.sling.api.request.RequestParameter#getString(java.lang.String) + */ + public String getString(String encoding) + throws UnsupportedEncodingException { + return new String(this.get(), encoding); + } + + /** + * @see org.apache.sling.api.request.RequestParameter#isFormField() + */ + public boolean isFormField() { + // www-form-encoded are always form fields + return true; + } + + public String toString() { + return this.getString(); + } + } + + static class SlingUnsupportedEncodingException extends SlingIOException { + + private static final long serialVersionUID = -4482276105859280247L; + + SlingUnsupportedEncodingException(UnsupportedEncodingException uee) { + super(uee); + } + + } + } diff --git a/src/main/java/org/apache/sling/jackrabbit/usermanager/impl/post/AbstractGroupPostServlet.java b/src/main/java/org/apache/sling/jackrabbit/usermanager/impl/post/AbstractGroupPostServlet.java index 57b9dc3..5d10d6c 100644 --- a/src/main/java/org/apache/sling/jackrabbit/usermanager/impl/post/AbstractGroupPostServlet.java +++ b/src/main/java/org/apache/sling/jackrabbit/usermanager/impl/post/AbstractGroupPostServlet.java @@ -17,6 +17,7 @@ package org.apache.sling.jackrabbit.usermanager.impl.post; import java.util.List; +import java.util.Map; import javax.jcr.RepositoryException; import javax.jcr.Session; @@ -24,7 +25,6 @@ import javax.jcr.Session; 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.sling.api.SlingHttpServletRequest; import org.apache.sling.api.resource.Resource; import org.apache.sling.api.resource.ResourceResolver; import org.apache.sling.jackrabbit.usermanager.impl.resource.AuthorizableResourceProvider; @@ -48,23 +48,24 @@ public abstract class AbstractGroupPostServlet extends * @param authorizable * @throws RepositoryException */ - protected void updateGroupMembership(SlingHttpServletRequest request, - Authorizable authorizable, List<Modification> changes) + protected void updateGroupMembership(Resource baseResource, + Map<String, ?> properties, + Authorizable authorizable, + List<Modification> changes) throws RepositoryException { if (authorizable.isGroup()) { Group group = ((Group) authorizable); String groupPath = AuthorizableResourceProvider.SYSTEM_USER_MANAGER_GROUP_PREFIX + group.getID(); - ResourceResolver resolver = request.getResourceResolver(); - Resource baseResource = request.getResource(); + ResourceResolver resolver = baseResource.getResourceResolver(); boolean changed = false; UserManager userManager = AccessControlUtil.getUserManager(resolver.adaptTo(Session.class)); // first remove any members posted as ":member@Delete" - String[] membersToDelete = request.getParameterValues(SlingPostConstants.RP_PREFIX - + "member" + SlingPostConstants.SUFFIX_DELETE); + String[] membersToDelete = convertToStringArray(properties.get(SlingPostConstants.RP_PREFIX + + "member" + SlingPostConstants.SUFFIX_DELETE)); if (membersToDelete != null) { for (String member : membersToDelete) { @@ -78,8 +79,8 @@ public abstract class AbstractGroupPostServlet extends } // second add any members posted as ":member" - String[] membersToAdd = request.getParameterValues(SlingPostConstants.RP_PREFIX - + "member"); + String[] membersToAdd = convertToStringArray(properties.get(SlingPostConstants.RP_PREFIX + + "member")); if (membersToAdd != null) { for (String member : membersToAdd) { Authorizable memberAuthorizable = getAuthorizable(baseResource, member,userManager,resolver); @@ -105,21 +106,23 @@ public abstract class AbstractGroupPostServlet extends * @param resolver the resource resolver for this request. * @return the authorizable, or null if no authorizable was found. */ - private Authorizable getAuthorizable(Resource baseResource, String member, UserManager userManager, - ResourceResolver resolver) { - Authorizable memberAuthorizable = null; - try { - memberAuthorizable = userManager.getAuthorizable(member); - } catch (RepositoryException e) { - // if we can't find the members then it may be resolvable as a resource. - } - if ( memberAuthorizable == null ) { - Resource res = resolver.getResource(baseResource, member); - if (res != null) { - memberAuthorizable = res.adaptTo(Authorizable.class); - } - } - return memberAuthorizable; - } + private Authorizable getAuthorizable(Resource baseResource, + String member, + UserManager userManager, + ResourceResolver resolver) { + Authorizable memberAuthorizable = null; + try { + memberAuthorizable = userManager.getAuthorizable(member); + } catch (RepositoryException e) { + // if we can't find the members then it may be resolvable as a resource. + } + if ( memberAuthorizable == null ) { + Resource res = resolver.getResource(baseResource, member); + if (res != null) { + memberAuthorizable = res.adaptTo(Authorizable.class); + } + } + return memberAuthorizable; + } } diff --git a/src/main/java/org/apache/sling/jackrabbit/usermanager/impl/post/ChangeUserPasswordServlet.java b/src/main/java/org/apache/sling/jackrabbit/usermanager/impl/post/ChangeUserPasswordServlet.java index 0bb1b1e..eb31397 100644 --- a/src/main/java/org/apache/sling/jackrabbit/usermanager/impl/post/ChangeUserPasswordServlet.java +++ b/src/main/java/org/apache/sling/jackrabbit/usermanager/impl/post/ChangeUserPasswordServlet.java @@ -33,6 +33,8 @@ import org.apache.sling.api.resource.Resource; import org.apache.sling.api.resource.ResourceNotFoundException; import org.apache.sling.api.servlets.HtmlResponse; import org.apache.sling.commons.osgi.OsgiUtil; +import org.apache.sling.jackrabbit.usermanager.ChangeUserPassword; +import org.apache.sling.jackrabbit.usermanager.impl.resource.AuthorizableResourceProvider; import org.apache.sling.jcr.base.util.AccessControlUtil; import org.apache.sling.servlets.post.Modification; import org.osgi.service.component.ComponentContext; @@ -79,11 +81,12 @@ import org.slf4j.LoggerFactory; * * @scr.component immediate="true" * @scr.service interface="javax.servlet.Servlet" + * @scr.service interface="org.apache.sling.jackrabbit.usermanager.ChangeUserPassword" * @scr.property name="sling.servlet.resourceTypes" value="sling/user" * @scr.property name="sling.servlet.methods" value="POST" * @scr.property name="sling.servlet.selectors" value="changePassword" */ -public class ChangeUserPasswordServlet extends AbstractUserPostServlet { +public class ChangeUserPasswordServlet extends AbstractUserPostServlet implements ChangeUserPassword { private static final long serialVersionUID = 1923614318474654502L; /** @@ -137,39 +140,52 @@ public class ChangeUserPasswordServlet extends AbstractUserPostServlet { protected void handleOperation(SlingHttpServletRequest request, HtmlResponse htmlResponse, List<Modification> changes) throws RepositoryException { - Authorizable authorizable = null; + Resource resource = request.getResource(); - if (resource != null) { - authorizable = resource.adaptTo(Authorizable.class); - } - - // check that the user was located. - if (authorizable == null || authorizable.isGroup()) { - throw new ResourceNotFoundException( - "User to update could not be determined."); - } - - if ("anonymous".equals(authorizable.getID())) { + Session session = request.getResourceResolver().adaptTo(Session.class); + changePassword(session, + resource.getName(), + request.getParameter("oldPwd"), + request.getParameter("newPwd"), + request.getParameter("newPwdConfirm"), + changes); + } + + /* (non-Javadoc) + * @see org.apache.sling.jackrabbit.usermanager.ChangeUserPassword#changePassword(javax.jcr.Session, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.util.List) + */ + public User changePassword(Session jcrSession, + String name, + String oldPassword, + String newPassword, + String newPasswordConfirm, + List<Modification> changes) + throws RepositoryException { + + if ("anonymous".equals(name)) { throw new RepositoryException( "Can not change the password of the anonymous user."); } - - Session session = request.getResourceResolver().adaptTo(Session.class); - if (session == null) { - throw new RepositoryException("JCR Session not found"); + + User user; + UserManager userManager = AccessControlUtil.getUserManager(jcrSession); + Authorizable authorizable = userManager.getAuthorizable(name); + if (authorizable instanceof User) { + user = (User)authorizable; + } else { + throw new ResourceNotFoundException( + "User to update could not be determined"); } - + //SLING-2069: if the current user is an administrator, then a missing oldPwd is ok, // otherwise the oldPwd must be supplied. boolean administrator = false; // check that the submitted parameter values have valid values. - String oldPwd = request.getParameter("oldPwd"); - if (oldPwd == null || oldPwd.length() == 0) { + if (oldPassword == null || oldPassword.length() == 0) { try { - Session currentSession = request.getResourceResolver().adaptTo(Session.class); - UserManager um = AccessControlUtil.getUserManager(currentSession); - User currentUser = (User) um.getAuthorizable(currentSession.getUserID()); + UserManager um = AccessControlUtil.getUserManager(jcrSession); + User currentUser = (User) um.getAuthorizable(jcrSession.getUserID()); administrator = currentUser.isAdmin(); if (!administrator) { @@ -191,30 +207,34 @@ public class ChangeUserPasswordServlet extends AbstractUserPostServlet { throw new RepositoryException("Old Password was not submitted"); } } - String newPwd = request.getParameter("newPwd"); - if (newPwd == null || newPwd.length() == 0) { + if (newPassword == null || newPassword.length() == 0) { throw new RepositoryException("New Password was not submitted"); } - String newPwdConfirm = request.getParameter("newPwdConfirm"); - if (!newPwd.equals(newPwdConfirm)) { + if (!newPassword.equals(newPasswordConfirm)) { throw new RepositoryException( "New Password does not match the confirmation password"); } - if (oldPwd != null && oldPwd.length() > 0) { + if (oldPassword != null && oldPassword.length() > 0) { // verify old password - checkPassword(authorizable, oldPwd); + checkPassword(authorizable, oldPassword); } try { - ((User) authorizable).changePassword(digestPassword(newPwd)); + ((User) authorizable).changePassword(digestPassword(newPassword)); - changes.add(Modification.onModified(resource.getPath() + String userPath = AuthorizableResourceProvider.SYSTEM_USER_MANAGER_GROUP_PREFIX + + user.getID(); + + changes.add(Modification.onModified(userPath + "/rep:password")); } catch (RepositoryException re) { throw new RepositoryException("Failed to change user password.", re); } - } + + return user; + } + private void checkPassword(Authorizable authorizable, String oldPassword) throws RepositoryException { 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 5e2ea88..64fdf48 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 @@ -27,10 +27,14 @@ 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.sling.api.SlingHttpServletRequest; +import org.apache.sling.api.resource.Resource; +import org.apache.sling.api.resource.ResourceResolver; import org.apache.sling.api.servlets.HtmlResponse; import org.apache.sling.servlets.post.impl.helper.RequestProperty; +import org.apache.sling.jackrabbit.usermanager.CreateGroup; import org.apache.sling.jackrabbit.usermanager.impl.resource.AuthorizableResourceProvider; import org.apache.sling.jcr.base.util.AccessControlUtil; +import org.apache.sling.jcr.resource.JcrResourceResolverFactory; import org.apache.sling.servlets.post.Modification; import org.apache.sling.servlets.post.SlingPostConstants; @@ -74,13 +78,17 @@ import org.apache.sling.servlets.post.SlingPostConstants; * * @scr.component immediate="true" * @scr.service interface="javax.servlet.Servlet" + * @scr.service interface="org.apache.sling.jackrabbit.usermanager.CreateGroup" * @scr.property name="sling.servlet.resourceTypes" value="sling/groups" * @scr.property name="sling.servlet.methods" value="POST" * @scr.property name="sling.servlet.selectors" value="create" */ -public class CreateGroupServlet extends AbstractGroupPostServlet { +public class CreateGroupServlet extends AbstractGroupPostServlet implements CreateGroup { private static final long serialVersionUID = -1084915263933901466L; + /** @scr.reference */ + private JcrResourceResolverFactory resourceResolverFactory; + /* * (non-Javadoc) * @see @@ -93,29 +101,50 @@ public class CreateGroupServlet extends AbstractGroupPostServlet { HtmlResponse response, List<Modification> changes) throws RepositoryException { - // check that the submitted parameter values have valid values. - final String principalName = request.getParameter(SlingPostConstants.RP_NODE_NAME); - if (principalName == null || principalName.length() == 0) { - throw new RepositoryException("Group name was not submitted"); + Session session = request.getResourceResolver().adaptTo(Session.class); + String principalName = request.getParameter(SlingPostConstants.RP_NODE_NAME); + Group group = createGroup(session, + principalName, + request.getRequestParameterMap(), + changes); + + String groupPath = AuthorizableResourceProvider.SYSTEM_USER_MANAGER_GROUP_PREFIX + + group.getID(); + response.setPath(groupPath); + response.setLocation(externalizePath(request, groupPath)); + response.setParentLocation(externalizePath(request, + AuthorizableResourceProvider.SYSTEM_USER_MANAGER_GROUP_PATH)); + + } + + /* (non-Javadoc) + * @see org.apache.sling.jackrabbit.usermanager.CreateGroup#createGroup(javax.jcr.Session, java.lang.String, java.util.Map, java.util.List) + */ + public Group createGroup(Session jcrSession, final String name, + Map<String, ?> properties, List<Modification> changes) + throws RepositoryException { + // check that the parameter values have valid values. + if (jcrSession == null) { + throw new IllegalArgumentException("JCR Session not found"); } - Session session = request.getResourceResolver().adaptTo(Session.class); - if (session == null) { - throw new RepositoryException("JCR Session not found"); + if (name == null || name.length() == 0) { + throw new IllegalArgumentException("Group name was not supplied"); } - UserManager userManager = AccessControlUtil.getUserManager(session); - Authorizable authorizable = userManager.getAuthorizable(principalName); + UserManager userManager = AccessControlUtil.getUserManager(jcrSession); + Authorizable authorizable = userManager.getAuthorizable(name); + Group group = null; if (authorizable != null) { // principal already exists! throw new RepositoryException( - "A principal already exists with the requested name: " - + principalName); + "A group already exists with the requested name: " + + name); } else { - Group group = userManager.createGroup(new Principal() { + group = userManager.createGroup(new Principal() { public String getName() { - return principalName; + return name; } }); @@ -123,18 +152,27 @@ public class CreateGroupServlet extends AbstractGroupPostServlet { + group.getID(); Map<String, RequestProperty> reqProperties = collectContent( - request, response, groupPath); - response.setPath(groupPath); - response.setLocation(externalizePath(request, groupPath)); - response.setParentLocation(externalizePath(request, - AuthorizableResourceProvider.SYSTEM_USER_MANAGER_GROUP_PATH)); + properties, groupPath); changes.add(Modification.onCreated(groupPath)); // write content from form - writeContent(session, group, reqProperties, changes); + writeContent(jcrSession, group, reqProperties, changes); // update the group memberships - updateGroupMembership(request, group, changes); + ResourceResolver resourceResolver = null; + try { + //create a resource resolver to resolve the relative paths used for group membership values + resourceResolver = resourceResolverFactory.getResourceResolver(jcrSession); + Resource baseResource = resourceResolver.getResource(AuthorizableResourceProvider.SYSTEM_USER_MANAGER_GROUP_PATH); + updateGroupMembership(baseResource, properties, group, changes); + } finally { + if (resourceResolver != null) { + resourceResolver.close(); + } + } } - } + + return group; + } + } 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 551a933..ec95910 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 @@ -31,6 +31,7 @@ import org.apache.sling.api.SlingHttpServletRequest; import org.apache.sling.api.servlets.HtmlResponse; import org.apache.sling.commons.osgi.OsgiUtil; import org.apache.sling.servlets.post.impl.helper.RequestProperty; +import org.apache.sling.jackrabbit.usermanager.CreateUser; import org.apache.sling.jackrabbit.usermanager.impl.resource.AuthorizableResourceProvider; import org.apache.sling.jcr.api.SlingRepository; import org.apache.sling.jcr.base.util.AccessControlUtil; @@ -83,11 +84,12 @@ import org.slf4j.LoggerFactory; * @scr.component immediate="true" label="%createUser.post.operation.name" * description="%createUser.post.operation.description" * @scr.service interface="javax.servlet.Servlet" + * @scr.service interface="org.apache.sling.jackrabbit.usermanager.CreateUser" * @scr.property name="sling.servlet.resourceTypes" value="sling/users" * @scr.property name="sling.servlet.methods" value="POST" * @scr.property name="sling.servlet.selectors" value="create" */ -public class CreateUserServlet extends AbstractUserPostServlet { +public class CreateUserServlet extends AbstractUserPostServlet implements CreateUser { private static final long serialVersionUID = 6871481922737658675L; /** @@ -192,12 +194,44 @@ public class CreateUserServlet extends AbstractUserPostServlet { HtmlResponse response, List<Modification> changes) throws RepositoryException { + + Session session = request.getResourceResolver().adaptTo(Session.class); + String principalName = request.getParameter(SlingPostConstants.RP_NODE_NAME); + User user = createUser(session, + principalName, + request.getParameter("pwd"), + request.getParameter("pwdConfirm"), + request.getRequestParameterMap(), + changes); + + String userPath = AuthorizableResourceProvider.SYSTEM_USER_MANAGER_USER_PREFIX + + user.getID(); + response.setPath(userPath); + response.setLocation(externalizePath(request, userPath)); + response.setParentLocation(externalizePath(request, + AuthorizableResourceProvider.SYSTEM_USER_MANAGER_USER_PATH)); + } + + /* (non-Javadoc) + * @see org.apache.sling.jackrabbit.usermanager.CreateUser#createUser(javax.jcr.Session, java.lang.String, java.lang.String, java.lang.String, java.util.Map, java.util.List) + */ + public User createUser(Session jcrSession, + String name, + String password, + String passwordConfirm, + Map<String, ?> properties, + List<Modification> changes) + throws RepositoryException { + + if (jcrSession == null) { + throw new RepositoryException("JCR Session not found"); + } + // check for an administrator boolean administrator = false; try { - Session currentSession = request.getResourceResolver().adaptTo(Session.class); - UserManager um = AccessControlUtil.getUserManager(currentSession); - User currentUser = (User) um.getAuthorizable(currentSession.getUserID()); + UserManager um = AccessControlUtil.getUserManager(jcrSession); + User currentUser = (User) um.getAuthorizable(jcrSession.getUserID()); administrator = currentUser.isAdmin(); if (!administrator) { @@ -212,7 +246,7 @@ public class CreateUserServlet extends AbstractUserPostServlet { } } catch ( Exception ex ) { - log.warn("Failed to determin if the user is an admin, assuming not. Cause: "+ex.getMessage()); + log.warn("Failed to determine if the user is an admin, assuming not. Cause: "+ex.getMessage()); administrator = false; } @@ -223,51 +257,46 @@ public class CreateUserServlet extends AbstractUserPostServlet { "Sorry, registration of new users is not currently enabled. Please try again later."); } - Session session = request.getResourceResolver().adaptTo(Session.class); - if (session == null) { - throw new RepositoryException("JCR Session not found"); - } // check that the submitted parameter values have valid values. - String principalName = request.getParameter(SlingPostConstants.RP_NODE_NAME); - if (principalName == null || principalName.length() == 0) { + if (name == null || name.length() == 0) { throw new RepositoryException("User name was not submitted"); } - String pwd = request.getParameter("pwd"); - if (pwd == null) { + if (password == null) { throw new RepositoryException("Password was not submitted"); } - String pwdConfirm = request.getParameter("pwdConfirm"); - if (!pwd.equals(pwdConfirm)) { + if (!password.equals(passwordConfirm)) { throw new RepositoryException( "Password value does not match the confirmation password"); } - - Session selfRegSession = null; + + User user = null; + Session selfRegSession = jcrSession; + boolean useAdminSession = !administrator && selfRegistrationEnabled; try { - selfRegSession = getSession(); + if (useAdminSession) { + //the current user doesn't have permission to create the user, + // but self-registration is enabled, so use an admin session + // to do the work. + selfRegSession = getSession(); + } UserManager userManager = AccessControlUtil.getUserManager(selfRegSession); - Authorizable authorizable = userManager.getAuthorizable(principalName); + Authorizable authorizable = userManager.getAuthorizable(name); if (authorizable != null) { // user already exists! throw new RepositoryException( "A principal already exists with the requested name: " - + principalName); + + name); } else { - User user = userManager.createUser(principalName, - digestPassword(pwd)); + user = userManager.createUser(name, digestPassword(password)); String userPath = AuthorizableResourceProvider.SYSTEM_USER_MANAGER_USER_PREFIX + user.getID(); Map<String, RequestProperty> reqProperties = collectContent( - request, response, userPath); + properties, userPath); - response.setPath(userPath); - response.setLocation(externalizePath(request, userPath)); - response.setParentLocation(externalizePath(request, - AuthorizableResourceProvider.SYSTEM_USER_MANAGER_USER_PATH)); changes.add(Modification.onCreated(userPath)); // write content from form @@ -276,9 +305,26 @@ public class CreateUserServlet extends AbstractUserPostServlet { if (selfRegSession.hasPendingChanges()) { selfRegSession.save(); } + + if (useAdminSession) { + //lookup the user from the user session so we can return a live object + UserManager userManager2 = AccessControlUtil.getUserManager(jcrSession); + Authorizable authorizable2 = userManager2.getAuthorizable(user.getID()); + if (authorizable2 instanceof User) { + user = (User)authorizable2; + } else { + user = null; + } + } } } finally { - ungetSession(selfRegSession); + if (useAdminSession) { + //done with the self-reg admin session, so clean it up + ungetSession(selfRegSession); + } } - } + + return user; + } + } diff --git a/src/main/java/org/apache/sling/jackrabbit/usermanager/impl/post/DeleteAuthorizableServlet.java b/src/main/java/org/apache/sling/jackrabbit/usermanager/impl/post/DeleteAuthorizableServlet.java index 72b9921..1de78f6 100644 --- a/src/main/java/org/apache/sling/jackrabbit/usermanager/impl/post/DeleteAuthorizableServlet.java +++ b/src/main/java/org/apache/sling/jackrabbit/usermanager/impl/post/DeleteAuthorizableServlet.java @@ -21,14 +21,23 @@ import java.util.List; import java.util.NoSuchElementException; import javax.jcr.RepositoryException; +import javax.jcr.Session; import javax.servlet.http.HttpServletResponse; 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.sling.api.SlingHttpServletRequest; import org.apache.sling.api.resource.Resource; import org.apache.sling.api.resource.ResourceNotFoundException; import org.apache.sling.api.resource.ResourceResolver; import org.apache.sling.api.servlets.HtmlResponse; +import org.apache.sling.jackrabbit.usermanager.DeleteAuthorizables; +import org.apache.sling.jackrabbit.usermanager.DeleteGroup; +import org.apache.sling.jackrabbit.usermanager.DeleteUser; +import org.apache.sling.jackrabbit.usermanager.impl.resource.AuthorizableResourceProvider; +import org.apache.sling.jcr.base.util.AccessControlUtil; import org.apache.sling.servlets.post.Modification; import org.apache.sling.servlets.post.SlingPostConstants; @@ -69,12 +78,16 @@ import org.apache.sling.servlets.post.SlingPostConstants; * * @scr.component metatype="no" immediate="true" * @scr.service interface="javax.servlet.Servlet" + * @scr.service interface="org.apache.sling.jackrabbit.usermanager.DeleteUser" + * @scr.service interface="org.apache.sling.jackrabbit.usermanager.DeleteGroup" + * @scr.service interface="org.apache.sling.jackrabbit.usermanager.DeleteAuthorizables" * @scr.property name="sling.servlet.resourceTypes" values.0="sling/user" * values.1="sling/group" values.2="sling/userManager" * @scr.property name="sling.servlet.methods" value="POST" * @scr.property name="sling.servlet.selectors" value="delete" */ -public class DeleteAuthorizableServlet extends AbstractAuthorizablePostServlet { +public class DeleteAuthorizableServlet extends AbstractAuthorizablePostServlet + implements DeleteUser, DeleteGroup, DeleteAuthorizables { private static final long serialVersionUID = 5874621724096106496L; /* @@ -89,54 +102,95 @@ public class DeleteAuthorizableServlet extends AbstractAuthorizablePostServlet { HtmlResponse htmlResponse, List<Modification> changes) throws RepositoryException { - Iterator<Resource> res = getApplyToResources(request); - if (res == null) { - Resource resource = request.getResource(); + Session session = request.getResourceResolver().adaptTo(Session.class); + Resource resource = request.getResource(); + String[] applyTo = request.getParameterValues(SlingPostConstants.RP_APPLY_TO); + if (applyTo != null) { + deleteAuthorizables(session, + resource, + applyTo, + changes); + } else { Authorizable item = resource.adaptTo(Authorizable.class); if (item == null) { String msg = "Missing source " + resource.getPath() + " for delete"; htmlResponse.setStatus(HttpServletResponse.SC_NOT_FOUND, msg); throw new ResourceNotFoundException(msg); - } - - item.remove(); - changes.add(Modification.onDeleted(resource.getPath())); - } else { - while (res.hasNext()) { - Resource resource = res.next(); - Authorizable item = resource.adaptTo(Authorizable.class); - if (item != null) { - item.remove(); - changes.add(Modification.onDeleted(resource.getPath())); - } + } else { + if (item instanceof User) { + deleteUser(session, item.getID(), changes); + } else if (item instanceof Group) { + deleteGroup(session, item.getID(), changes); + } } } } - - /** - * Returns an iterator on <code>Resource</code> instances addressed in the - * {@link SlingPostConstants#RP_APPLY_TO} request parameter. If the request - * parameter is not set, <code>null</code> is returned. If the parameter is - * set with valid resources an empty iterator is returned. Any resources - * addressed in the {@link SlingPostConstants#RP_APPLY_TO} parameter is - * ignored. - * - * @param request The <code>SlingHttpServletRequest</code> object used to - * get the {@link SlingPostConstants#RP_APPLY_TO} parameter. - * @return The iterator of resources listed in the parameter or - * <code>null</code> if the parameter is not set in the request. - */ - protected Iterator<Resource> getApplyToResources( - SlingHttpServletRequest request) { - - String[] applyTo = request.getParameterValues(SlingPostConstants.RP_APPLY_TO); - if (applyTo == null) { - return null; + + /* (non-Javadoc) + * @see org.apache.sling.jackrabbit.usermanager.DeleteUser#deleteUser(javax.jcr.Session, java.lang.String, java.util.List) + */ + public void deleteUser(Session jcrSession, String name, + List<Modification> changes) throws RepositoryException { + + User user; + UserManager userManager = AccessControlUtil.getUserManager(jcrSession); + Authorizable authorizable = userManager.getAuthorizable(name); + if (authorizable instanceof User) { + user = (User)authorizable; + } else { + throw new ResourceNotFoundException( + "User to delete could not be determined"); } - - return new ApplyToIterator(request, applyTo); - } + + String userPath = AuthorizableResourceProvider.SYSTEM_USER_MANAGER_USER_PREFIX + + user.getID(); + user.remove(); + changes.add(Modification.onDeleted(userPath)); + } + + /* (non-Javadoc) + * @see org.apache.sling.jackrabbit.usermanager.DeleteGroup#deleteGroup(javax.jcr.Session, java.lang.String, java.util.List) + */ + public void deleteGroup(Session jcrSession, + String name, + List<Modification> changes) throws RepositoryException { + + Group group; + UserManager userManager = AccessControlUtil.getUserManager(jcrSession); + Authorizable authorizable = userManager.getAuthorizable(name); + if (authorizable instanceof Group) { + group = (Group)authorizable; + } else { + throw new ResourceNotFoundException( + "Group to delete could not be determined"); + } + + String groupPath = AuthorizableResourceProvider.SYSTEM_USER_MANAGER_GROUP_PREFIX + + group.getID(); + group.remove(); + changes.add(Modification.onDeleted(groupPath)); + } + + /* (non-Javadoc) + * @see org.apache.sling.jackrabbit.usermanager.DeleteAuthorizables#deleteAuthorizables(javax.jcr.Session, org.apache.sling.api.resource.Resource, java.lang.String[], java.util.List) + */ + public void deleteAuthorizables(Session jcrSession, + Resource baseResource, + String[] paths, + List<Modification> changes) + throws RepositoryException { + + ApplyToIterator iterator = new ApplyToIterator(baseResource, paths); + while (iterator.hasNext()) { + Resource resource = iterator.next(); + Authorizable item = resource.adaptTo(Authorizable.class); + if (item != null) { + item.remove(); + changes.add(Modification.onDeleted(resource.getPath())); + } + } + } private static class ApplyToIterator implements Iterator<Resource> { @@ -144,15 +198,15 @@ public class DeleteAuthorizableServlet extends AbstractAuthorizablePostServlet { private final Resource baseResource; - private final String[] paths; + private final String [] paths; private int pathIndex; private Resource nextResource; - ApplyToIterator(SlingHttpServletRequest request, String[] paths) { - this.resolver = request.getResourceResolver(); - this.baseResource = request.getResource(); + ApplyToIterator(Resource baseResource, String [] paths) { + this.resolver = baseResource.getResourceResolver(); + this.baseResource = baseResource; this.paths = paths; this.pathIndex = 0; 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 e9de57c..461e8e7 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 @@ -23,13 +23,19 @@ import javax.jcr.RepositoryException; import javax.jcr.Session; 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.sling.api.SlingHttpServletRequest; import org.apache.sling.api.resource.Resource; import org.apache.sling.api.resource.ResourceNotFoundException; +import org.apache.sling.api.resource.ResourceResolver; import org.apache.sling.api.servlets.HtmlResponse; -import org.apache.sling.servlets.post.impl.helper.RequestProperty; +import org.apache.sling.jackrabbit.usermanager.UpdateGroup; import org.apache.sling.jackrabbit.usermanager.impl.resource.AuthorizableResourceProvider; +import org.apache.sling.jcr.base.util.AccessControlUtil; +import org.apache.sling.jcr.resource.JcrResourceResolverFactory; import org.apache.sling.servlets.post.Modification; +import org.apache.sling.servlets.post.impl.helper.RequestProperty; /** * <p> @@ -72,13 +78,18 @@ import org.apache.sling.servlets.post.Modification; * * @scr.component metatype="no" immediate="true" * @scr.service interface="javax.servlet.Servlet" + * @scr.service interface="org.apache.sling.jackrabbit.usermanager.UpdateGroup" * @scr.property name="sling.servlet.resourceTypes" values="sling/group" * @scr.property name="sling.servlet.methods" value="POST" * @scr.property name="sling.servlet.selectors" value="update" */ -public class UpdateGroupServlet extends AbstractGroupPostServlet { +public class UpdateGroupServlet extends AbstractGroupPostServlet + implements UpdateGroup { private static final long serialVersionUID = -8292054361992488797L; + /** @scr.reference */ + private JcrResourceResolverFactory resourceResolverFactory; + /* * (non-Javadoc) * @see @@ -90,41 +101,60 @@ public class UpdateGroupServlet extends AbstractGroupPostServlet { protected void handleOperation(SlingHttpServletRequest request, HtmlResponse htmlResponse, List<Modification> changes) throws RepositoryException { - Authorizable authorizable = null; Resource resource = request.getResource(); - if (resource != null) { - authorizable = resource.adaptTo(Authorizable.class); - } + Session session = request.getResourceResolver().adaptTo(Session.class); + updateGroup(session, + resource.getName(), + request.getRequestParameterMap(), + changes); + } + + /* (non-Javadoc) + * @see org.apache.sling.jackrabbit.usermanager.UpdateGroup#updateGroup(javax.jcr.Session, java.lang.String, java.util.Map, java.util.List) + */ + public Group updateGroup(Session jcrSession, + String name, + Map<String, ?> properties, + List<Modification> changes) + throws RepositoryException { - // check that the group was located. - if (authorizable == null) { + Group group = null; + UserManager userManager = AccessControlUtil.getUserManager(jcrSession); + Authorizable authorizable = userManager.getAuthorizable(name); + if (authorizable instanceof Group) { + group = (Group)authorizable; + } else { throw new ResourceNotFoundException( - "Group to update could not be determined"); + "Group to update could not be determined"); } - - Session session = request.getResourceResolver().adaptTo(Session.class); - if (session == null) { - throw new RepositoryException("JCR Session not found"); - } - + String groupPath = AuthorizableResourceProvider.SYSTEM_USER_MANAGER_GROUP_PREFIX - + authorizable.getID(); + + group.getID(); - Map<String, RequestProperty> reqProperties = collectContent(request, - htmlResponse, groupPath); + Map<String, RequestProperty> reqProperties = collectContent(properties, groupPath); try { // cleanup any old content (@Delete parameters) - processDeletes(authorizable, reqProperties, changes); + processDeletes(group, reqProperties, changes); // write content from form - writeContent(session, authorizable, reqProperties, changes); + writeContent(jcrSession, group, reqProperties, changes); // update the group memberships - if (authorizable.isGroup()) { - updateGroupMembership(request, authorizable, changes); + ResourceResolver resourceResolver = null; + try { + //create a resource resolver to resolve the relative paths used for group membership values + resourceResolver = resourceResolverFactory.getResourceResolver(jcrSession); + Resource baseResource = resourceResolver.getResource(groupPath); + updateGroupMembership(baseResource, properties, group, changes); + } finally { + if (resourceResolver != null) { + resourceResolver.close(); + } } } catch (RepositoryException re) { throw new RepositoryException("Failed to update group.", re); } - } + return group; + } + } 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 31210b5..13915a8 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 @@ -22,12 +22,16 @@ import java.util.Map; import javax.jcr.RepositoryException; import javax.jcr.Session; +import org.apache.jackrabbit.api.security.user.Authorizable; import org.apache.jackrabbit.api.security.user.User; +import org.apache.jackrabbit.api.security.user.UserManager; import org.apache.sling.api.SlingHttpServletRequest; import org.apache.sling.api.resource.Resource; import org.apache.sling.api.resource.ResourceNotFoundException; import org.apache.sling.api.servlets.HtmlResponse; +import org.apache.sling.jackrabbit.usermanager.UpdateUser; import org.apache.sling.jackrabbit.usermanager.impl.resource.AuthorizableResourceProvider; +import org.apache.sling.jcr.base.util.AccessControlUtil; import org.apache.sling.servlets.post.Modification; import org.apache.sling.servlets.post.impl.helper.RequestProperty; @@ -73,11 +77,13 @@ import org.apache.sling.servlets.post.impl.helper.RequestProperty; * * @scr.component metatype="no" immediate="true" * @scr.service interface="javax.servlet.Servlet" + * @scr.service interface="org.apache.sling.jackrabbit.usermanager.UpdateUser" * @scr.property name="sling.servlet.resourceTypes" value="sling/user" * @scr.property name="sling.servlet.methods" value="POST" * @scr.property name="sling.servlet.selectors" value="update" */ -public class UpdateUserServlet extends AbstractUserPostServlet { +public class UpdateUserServlet extends AbstractUserPostServlet + implements UpdateUser { private static final long serialVersionUID = 5874621724096106496L; /* @@ -91,51 +97,59 @@ public class UpdateUserServlet extends AbstractUserPostServlet { protected void handleOperation(SlingHttpServletRequest request, HtmlResponse htmlResponse, List<Modification> changes) throws RepositoryException { - User authorizable = null; Resource resource = request.getResource(); - if (resource != null) { - authorizable = resource.adaptTo(User.class); - } - - // check that the group was located. - if (authorizable == null) { - throw new ResourceNotFoundException( - "User to update could not be determined"); - } - Session session = request.getResourceResolver().adaptTo(Session.class); - if (session == null) { - throw new RepositoryException("JCR Session not found"); + updateUser(session, + resource.getName(), + request.getRequestParameterMap(), + changes); + } + + /* (non-Javadoc) + * @see org.apache.sling.jackrabbit.usermanager.UpdateUser#updateUser(javax.jcr.Session, java.lang.String, java.util.Map, java.util.List) + */ + public User updateUser(Session jcrSession, String name, + Map<String, ?> properties, List<Modification> changes) + throws RepositoryException { + + User user; + UserManager userManager = AccessControlUtil.getUserManager(jcrSession); + Authorizable authorizable = userManager.getAuthorizable(name); + if (authorizable instanceof User) { + user = (User)authorizable; + } else { + throw new ResourceNotFoundException( + "User to update could not be determined"); } String userPath = AuthorizableResourceProvider.SYSTEM_USER_MANAGER_GROUP_PREFIX - + authorizable.getID(); + + user.getID(); - Map<String, RequestProperty> reqProperties = collectContent(request, - htmlResponse, userPath); + Map<String, RequestProperty> reqProperties = collectContent(properties, userPath); try { // cleanup any old content (@Delete parameters) - processDeletes(authorizable, reqProperties, changes); + processDeletes(user, reqProperties, changes); // write content from form - writeContent(session, authorizable, reqProperties, changes); + writeContent(jcrSession, user, reqProperties, changes); //SLING-2072 set the user as enabled or disabled if the request - // has supplied the relev - String disabledParam = request.getParameter(":disabled"); + // has supplied the relevant properties + String disabledParam = convertToString(properties.get(":disabled")); if ("true".equalsIgnoreCase(disabledParam)) { //set the user as disabled - String disabledReason = request.getParameter(":disabledReason"); + String disabledReason = convertToString(properties.get(":disabledReason")); if (disabledReason == null) { disabledReason = ""; } - authorizable.disable(disabledReason); + user.disable(disabledReason); } else if ("false".equalsIgnoreCase(disabledParam)) { //re-enable a disabled user - authorizable.disable(null); + user.disable(null); } } catch (RepositoryException re) { throw new RepositoryException("Failed to update user.", re); } - } + return user; + } } -- To stop receiving notification emails like this one, please contact "[email protected]" <[email protected]>.
