You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by en...@apache.org on 2011/05/04 17:11:26 UTC
svn commit: r1099482 - in /sling/trunk:
bundles/jcr/jackrabbit-usermanager/src/main/java/org/apache/sling/jackrabbit/usermanager/impl/post/
launchpad/integration-tests/src/main/java/org/apache/sling/launchpad/webapp/integrationtest/userManager/
samples...
Author: enorman
Date: Wed May 4 15:11:25 2011
New Revision: 1099482
URL: http://svn.apache.org/viewvc?rev=1099482&view=rev
Log:
SLING-2069 PW reset through administrator is not possible.
Following the jackrabbit model, members of the UserAdmin group can set the password of other users.
Modified:
sling/trunk/bundles/jcr/jackrabbit-usermanager/src/main/java/org/apache/sling/jackrabbit/usermanager/impl/post/ChangeUserPasswordServlet.java
sling/trunk/launchpad/integration-tests/src/main/java/org/apache/sling/launchpad/webapp/integrationtest/userManager/UpdateUserTest.java
sling/trunk/samples/usermanager-ui/src/main/resources/libs/sling/user/update_body.html.esp
Modified: sling/trunk/bundles/jcr/jackrabbit-usermanager/src/main/java/org/apache/sling/jackrabbit/usermanager/impl/post/ChangeUserPasswordServlet.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/jcr/jackrabbit-usermanager/src/main/java/org/apache/sling/jackrabbit/usermanager/impl/post/ChangeUserPasswordServlet.java?rev=1099482&r1=1099481&r2=1099482&view=diff
==============================================================================
--- sling/trunk/bundles/jcr/jackrabbit-usermanager/src/main/java/org/apache/sling/jackrabbit/usermanager/impl/post/ChangeUserPasswordServlet.java (original)
+++ sling/trunk/bundles/jcr/jackrabbit-usermanager/src/main/java/org/apache/sling/jackrabbit/usermanager/impl/post/ChangeUserPasswordServlet.java Wed May 4 15:11:25 2011
@@ -17,6 +17,7 @@
package org.apache.sling.jackrabbit.usermanager.impl.post;
import java.lang.reflect.Method;
+import java.util.Dictionary;
import java.util.List;
import javax.jcr.Credentials;
@@ -24,12 +25,19 @@ import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.SimpleCredentials;
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.servlets.HtmlResponse;
+import org.apache.sling.commons.osgi.OsgiUtil;
+import org.apache.sling.jcr.base.util.AccessControlUtil;
import org.apache.sling.servlets.post.Modification;
+import org.osgi.service.component.ComponentContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
/**
* <p>
@@ -45,7 +53,7 @@ import org.apache.sling.servlets.post.Mo
* <h4>Post Parameters</h4>
* <dl>
* <dt>oldPwd</dt>
- * <dd>The current password for the user (required)</dd>
+ * <dd>The current password for the user (required for non-administrators)</dd>
* <dt>newPwd</dt>
* <dd>The new password for the user (required)</dd>
* <dt>newPwdConfirm</dt>
@@ -63,13 +71,13 @@ import org.apache.sling.servlets.post.Mo
* <h4>Example</h4>
*
* <code>
- * curl -FoldPwd=oldpassword -FnewPwd=newpassword =FnewPwdConfirm=newpassword http://localhost:8080/system/userManager/user/ieb.changePassword.html
+ * curl -FoldPwd=oldpassword -FnewPwd=newpassword -FnewPwdConfirm=newpassword http://localhost:8080/system/userManager/user/ieb.changePassword.html
* </code>
*
* <h4>Notes</h4>
*
*
- * @scr.component metatype="no" immediate="true"
+ * @scr.component immediate="true"
* @scr.service interface="javax.servlet.Servlet"
* @scr.property name="sling.servlet.resourceTypes" value="sling/user"
* @scr.property name="sling.servlet.methods" value="POST"
@@ -78,6 +86,46 @@ import org.apache.sling.servlets.post.Mo
public class ChangeUserPasswordServlet extends AbstractUserPostServlet {
private static final long serialVersionUID = 1923614318474654502L;
+ /**
+ * default log
+ */
+ private final Logger log = LoggerFactory.getLogger(getClass());
+
+ /**
+ * The name of the configuration parameter providing the
+ * name of the group whose members are allowed to reset the password
+ * of a user without the 'oldPwd' value.
+ *
+ * @scr.property valueRef="DEFAULT_USER_ADMIN_GROUP_NAME"
+ */
+ private static final String PAR_USER_ADMIN_GROUP_NAME = "user.admin.group.name";
+
+ /**
+ * The default 'User administrator' group name
+ *
+ * @see #PAR_USER_ADMIN_GROUP_NAME
+ */
+ private static final String DEFAULT_USER_ADMIN_GROUP_NAME = "UserAdmin";
+
+ private String userAdminGroupName = DEFAULT_USER_ADMIN_GROUP_NAME;
+
+ // ---------- SCR integration ---------------------------------------------
+
+ /**
+ * Activates this component.
+ *
+ * @param componentContext The OSGi <code>ComponentContext</code> of this
+ * component.
+ */
+ protected void activate(ComponentContext componentContext) {
+ super.activate(componentContext);
+ Dictionary<?, ?> props = componentContext.getProperties();
+
+ this.userAdminGroupName = OsgiUtil.toString(props.get(PAR_USER_ADMIN_GROUP_NAME),
+ DEFAULT_USER_ADMIN_GROUP_NAME);
+ log.info("User Admin Group Name {}", this.userAdminGroupName);
+ }
+
/*
* (non-Javadoc)
* @see
@@ -111,10 +159,37 @@ public class ChangeUserPasswordServlet e
throw new RepositoryException("JCR Session not found");
}
+ //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) {
- throw new RepositoryException("Old Password was not submitted");
+ try {
+ Session currentSession = request.getResourceResolver().adaptTo(Session.class);
+ UserManager um = AccessControlUtil.getUserManager(currentSession);
+ User currentUser = (User) um.getAuthorizable(currentSession.getUserID());
+ administrator = currentUser.isAdmin();
+
+ if (!administrator) {
+ //check if the user is a member of the 'User administrator' group
+ Authorizable userAdmin = um.getAuthorizable(this.userAdminGroupName);
+ if (userAdmin instanceof Group) {
+ boolean isMember = ((Group)userAdmin).isMember(currentUser);
+ if (isMember) {
+ administrator = true;
+ }
+ }
+
+ }
+ } catch ( Exception ex ) {
+ log.warn("Failed to determine if the user is an admin, assuming not. Cause: "+ex.getMessage());
+ administrator = false;
+ }
+ if (!administrator) {
+ throw new RepositoryException("Old Password was not submitted");
+ }
}
String newPwd = request.getParameter("newPwd");
if (newPwd == null || newPwd.length() == 0) {
@@ -126,8 +201,10 @@ public class ChangeUserPasswordServlet e
"New Password does not match the confirmation password");
}
- // verify old password
- checkPassword(authorizable, oldPwd);
+ if (oldPwd != null && oldPwd.length() > 0) {
+ // verify old password
+ checkPassword(authorizable, oldPwd);
+ }
try {
((User) authorizable).changePassword(digestPassword(newPwd));
Modified: sling/trunk/launchpad/integration-tests/src/main/java/org/apache/sling/launchpad/webapp/integrationtest/userManager/UpdateUserTest.java
URL: http://svn.apache.org/viewvc/sling/trunk/launchpad/integration-tests/src/main/java/org/apache/sling/launchpad/webapp/integrationtest/userManager/UpdateUserTest.java?rev=1099482&r1=1099481&r2=1099482&view=diff
==============================================================================
--- sling/trunk/launchpad/integration-tests/src/main/java/org/apache/sling/launchpad/webapp/integrationtest/userManager/UpdateUserTest.java (original)
+++ sling/trunk/launchpad/integration-tests/src/main/java/org/apache/sling/launchpad/webapp/integrationtest/userManager/UpdateUserTest.java Wed May 4 15:11:25 2011
@@ -131,4 +131,41 @@ public class UpdateUserTest extends Abst
JSONObject jsonObj = new JSONObject(json);
assertNotNull(jsonObj);
}
+
+
+ /**
+ * Test for SLING-2069
+ * @throws IOException
+ */
+ public void testChangeUserPasswordAsAdministratorWithoutOldPwd() throws IOException {
+ testUserId = createTestUser();
+
+ String postUrl = HTTP_BASE_URL + "/system/userManager/user/" + testUserId + ".changePassword.html";
+
+ List<NameValuePair> postParams = new ArrayList<NameValuePair>();
+ postParams.add(new NameValuePair("newPwd", "testNewPwd"));
+ postParams.add(new NameValuePair("newPwdConfirm", "testNewPwd"));
+
+ Credentials creds = new UsernamePasswordCredentials("admin", "admin");
+ assertAuthenticatedPostStatus(creds, postUrl, HttpServletResponse.SC_OK, postParams, null);
+ }
+
+ /**
+ * Test for SLING-2069
+ * @throws IOException
+ */
+ public void testChangeUserPasswordAsUserAdminMemberWithoutOldPwd() throws IOException {
+ testUserId = createTestUser();
+ addUserToUserAdminGroup(testUserId);
+
+ String postUrl = HTTP_BASE_URL + "/system/userManager/user/" + testUserId + ".changePassword.html";
+
+ List<NameValuePair> postParams = new ArrayList<NameValuePair>();
+ postParams.add(new NameValuePair("newPwd", "testNewPwd"));
+ postParams.add(new NameValuePair("newPwdConfirm", "testNewPwd"));
+
+ Credentials creds = new UsernamePasswordCredentials(testUserId, "testPwd");
+ assertAuthenticatedPostStatus(creds, postUrl, HttpServletResponse.SC_OK, postParams, null);
+ }
+
}
Modified: sling/trunk/samples/usermanager-ui/src/main/resources/libs/sling/user/update_body.html.esp
URL: http://svn.apache.org/viewvc/sling/trunk/samples/usermanager-ui/src/main/resources/libs/sling/user/update_body.html.esp?rev=1099482&r1=1099481&r2=1099482&view=diff
==============================================================================
--- sling/trunk/samples/usermanager-ui/src/main/resources/libs/sling/user/update_body.html.esp (original)
+++ sling/trunk/samples/usermanager-ui/src/main/resources/libs/sling/user/update_body.html.esp Wed May 4 15:11:25 2011
@@ -22,7 +22,6 @@ var canEdit = privilegesInfo.canUpdatePr
var canRemove = privilegesInfo.canRemove(currentSession, authorizable.getID());
var canUpdateMembers = privilegesInfo.canUpdateGroupMembers(currentSession, authorizable.getID());
var valueMap = resource.adaptTo(Packages.org.apache.sling.api.resource.ValueMap);
-var isMe = authorizable.getID().equals(request.getRemoteUser());
var rb = request.getResourceBundle("org.apache.sling.usermgr.Resources", null);
@@ -158,7 +157,30 @@ function displayName(path) {
</div>
<% } /*endif(canRemove) */ %>
-<% if (isMe) { %>
+<%
+var canChangePwd = false;
+if (canEdit) {
+ var isMe = authorizable.getID().equals(request.getRemoteUser());
+ if (isMe) {
+ //a user can always change their own password
+ canChangePwd = true;
+ } else {
+ if ("admin".equals(request.getRemoteUser())) {
+ canChangePwd = true;
+ } else {
+ //if the current user is a member of the UserAdmin group, then allow changing the password of other users.
+ var currentUserRes = request.getResourceResolver().resolve("/system/userManager/user/" + request.getRemoteUser());
+ var currentUserAuthorizable = currentUserRes.adaptTo(Packages.org.apache.jackrabbit.api.security.user.Authorizable);
+
+ var userAdminRes = request.getResourceResolver().resolve("/system/userManager/group/UserAdmin");
+ var group = userAdminRes.adaptTo(Packages.org.apache.jackrabbit.api.security.user.Group);
+ if (group) {
+ canChangePwd = group.isMember(currentUserAuthorizable);
+ }
+ }
+ }
+}
+if (canChangePwd) { %>
<div class="ui-widget ui-widget-content ui-corner-all usermgmt-body" id="update-password-body" >
<h3 class="ui-widget-header ui-corner-all usermgmt-header"><%=rb.getString("header.change.password")%></h3>
@@ -177,11 +199,12 @@ function displayName(path) {
<fieldset>
<input type="hidden" value="UTF-8" name="_charset_" />
<input id="pwdRedirect" type="hidden" name=":redirect" value="<%=request.contextPath%><%=resource.path %>.html" />
-
+ <% if (isMe) { %>
<div class="prop-line ui-helper-clearfix">
<label for="oldPwd" accesskey="o"><%=propLabel("oldPwd")%>:</label>
<input id="oldPwd" type="password" name="oldPwd" value=''/>
</div>
+ <% } %>
<div class="prop-line ui-helper-clearfix">
<label for="newPwd" accesskey="p"><%=propLabel("newPwd")%>:</label>
@@ -200,4 +223,4 @@ function displayName(path) {
</fieldset>
</form>
</div>
-<% } /*endif (isme)*/ %>
+<% } /*endif (canChangePwd)*/ %>