UI: Allow admin to reset password for other users 80/1280/2
authorYevgeny Khodorkovsky <ykhodork@cisco.com>
Wed, 18 Sep 2013 20:11:00 +0000 (13:11 -0700)
committerYevgeny Khodorkovsky <ykhodork@cisco.com>
Thu, 19 Sep 2013 00:05:51 +0000 (17:05 -0700)
- Allow admin to reset password for other users
  without providing current password.
- enforce re-login if changed own password

Change-Id: I4553739315fe7a93328e54cf4d345e79011246bc
Signed-off-by: Yevgeny Khodorkovsky <ykhodork@cisco.com>
opendaylight/web/root/src/main/java/org/opendaylight/controller/web/DaylightWebAdmin.java
opendaylight/web/root/src/main/resources/WEB-INF/jsp/main.jsp
opendaylight/web/root/src/main/resources/js/open.js

index 2b58bcc4cb6c1fb50b12801e2e6133078a13e47f..eafd8c54a773eb9bb933dd9f0d3f1cdd14d2b9c5 100644 (file)
@@ -15,6 +15,7 @@ import java.util.List;
 import java.util.Set;
 
 import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpSession;
 
 import org.opendaylight.controller.clustering.services.IClusterGlobalServices;
 import org.opendaylight.controller.connectionmanager.IConnectionManager;
@@ -212,24 +213,63 @@ public class DaylightWebAdmin {
 
     @RequestMapping(value = "/users/password/{username}", method = RequestMethod.POST)
     @ResponseBody
-    public Status changePassword(@PathVariable("username") String username, HttpServletRequest request,
-            @RequestParam("currentPassword") String currentPassword, @RequestParam("newPassword") String newPassword) {
+    public Status changePassword(
+            @PathVariable("username") String username, HttpServletRequest request,
+            @RequestParam(value = "currentPassword", required=false) String currentPassword,
+            @RequestParam("newPassword") String newPassword) {
         IUserManager userManager = (IUserManager) ServiceHelper.getGlobalInstance(IUserManager.class, this);
         if (userManager == null) {
-            return new Status(StatusCode.GONE, "User Manager not found");
+            return new Status(StatusCode.NOSERVICE, "User Manager unavailable");
         }
 
-        if (!authorize(userManager, UserLevel.NETWORKADMIN, request)) {
-            return new Status(StatusCode.FORBIDDEN, "Operation not permitted");
-        }
+        Status status;
+        String requestingUser = request.getUserPrincipal().getName();
+
+        //changing own password
+        if (requestingUser.equals(username) ) {
+            status = userManager.changeLocalUserPassword(username, currentPassword, newPassword);
+            //enforce the user to re-login with new password
+            if (status.isSuccess() && !newPassword.equals(currentPassword)) {
+                userManager.userLogout(username);
+                HttpSession session = request.getSession(false);
+                if ( session != null) {
+                    session.invalidate();
+                }
+            }
+
+        //admin level user resetting other's password
+        } else if (authorize(userManager, UserLevel.NETWORKADMIN, request)) {
+
+            //Since User Manager doesn't have an unprotected password change API,
+            //we re-create the user with the new password (and current roles).
+            List<String> roles = userManager.getUserRoles(username);
+            UserConfig newConfig = new UserConfig(username, newPassword, roles);
+
+            //validate before removing existing config, so we don't remove but fail to add
+            status = newConfig.validate();
+            if (!status.isSuccess()) {
+                return status;
+            }
+
+            userManager.userLogout(username);
+            status = userManager.removeLocalUser(username);
+            if (!status.isSuccess()) {
+                return status;
+            }
+            if (userManager.addLocalUser(newConfig).isSuccess()) {
+                status = new Status(StatusCode.SUCCESS, "Password for user " + username + " reset successfully.");
+            } else {
+                //unexpected
+                status = new Status(StatusCode.INTERNALERROR, "Failed resetting password for user " + username + ". User is now removed.");
+            }
 
-        if (newPassword.isEmpty()) {
-            return new Status(StatusCode.BADREQUEST, "Empty passwords not allowed");
+        //unauthorized
+        } else {
+            status = new Status(StatusCode.UNAUTHORIZED, "Operation not permitted");
         }
 
-        Status status = userManager.changeLocalUserPassword(username, currentPassword, newPassword);
         if (status.isSuccess()) {
-            DaylightWebUtil.auditlog("User", request.getUserPrincipal().getName(), "changed password for", username);
+            DaylightWebUtil.auditlog("User", requestingUser, "changed password for", username);
         }
         return status;
     }
index c795a5d56b920de6111141bea501a8b3dbcfaa57..4b0ce2d07d3d55a51c2ac873b642ce081c659728 100644 (file)
@@ -67,6 +67,7 @@
    </div>
    <div class="span3">
     <div id="toolbar" class="btn-group">
+    <input type="hidden" id="currentuser" value="${username}" data-role="${role}">
      <a class="btn dropdown-toggle" data-toggle="dropdown" href="#">
       <div class="icon-user"></div> ${username} <span class="caret"></span>
      </a>
index 43a7dfdc443ab7447fb472dc31afa1b83402f9d7..619edcaf2cba5ed4bb5d5d08359c13333a702d5a 100644 (file)
@@ -443,9 +443,12 @@ one.main.admin = {
       // change password binding
       $('#'+one.main.admin.id.modal.password.submit, $modal).click(function() {
         one.main.admin.password.submit(id, $modal, function(result) {
-          if (result.code == 'SUCCESS') {
-            $modal.modal('hide');
-            successCallback();
+          if (result.success) {
+            //if changed own password, enforce relogin
+            if (id.trim() == $('#currentuser').val().trim()) {
+                alert("Password changed successfully. Please re-login with your new password.");
+                window.location = '/';
+            }
           } else {
             alert(result.code+': '+result.description);
           }