User Manager to hash users passwords 89/1189/1
authorAlessandro Boch <aboch@cisco.com>
Sun, 15 Sep 2013 02:05:15 +0000 (19:05 -0700)
committerAlessandro Boch <aboch@cisco.com>
Sun, 15 Sep 2013 02:08:02 +0000 (19:08 -0700)
- When a UserConfig object is created, hash the user password

Change-Id: I7eb85c7b0119e1a8f913562a83cd409864a9f1c0
Signed-off-by: Alessandro Boch <aboch@cisco.com>
opendaylight/usermanager/api/src/main/java/org/opendaylight/controller/usermanager/AuthorizationConfig.java
opendaylight/usermanager/api/src/main/java/org/opendaylight/controller/usermanager/ODLUserLevel.java
opendaylight/usermanager/api/src/main/java/org/opendaylight/controller/usermanager/UserConfig.java
opendaylight/usermanager/api/src/test/java/org/opendaylight/controller/usermanager/AuthorizationUserConfigTest.java
opendaylight/usermanager/implementation/src/main/java/org/opendaylight/controller/usermanager/internal/Activator.java
opendaylight/usermanager/implementation/src/main/java/org/opendaylight/controller/usermanager/internal/UserManager.java [moved from opendaylight/usermanager/implementation/src/main/java/org/opendaylight/controller/usermanager/internal/UserManagerImpl.java with 94% similarity]
opendaylight/usermanager/implementation/src/test/java/org/opendaylight/controller/usermanager/internal/UserManagerImplTest.java
opendaylight/web/root/src/main/java/org/opendaylight/controller/web/DaylightWebAdmin.java

index bad8fa5..a484943 100644 (file)
@@ -9,7 +9,6 @@
 package org.opendaylight.controller.usermanager;
 
 import java.util.ArrayList;
-import java.util.Iterator;
 import java.util.List;
 
 import org.opendaylight.controller.sal.utils.Status;
@@ -42,10 +41,12 @@ public class AuthorizationConfig extends UserConfig {
         return status;
     }
 
+    @Override
     public String toString() {
         return "AuthorizationConfig=[user: " + user + ", roles: " + roles + "]";
     }
 
+    @Override
     public String getRolesString() {
         return super.getRolesString();
     }
index ca6000a..045002e 100644 (file)
@@ -9,6 +9,8 @@
 
 package org.opendaylight.controller.usermanager;
 
+import java.util.Locale;
+
 import org.opendaylight.controller.sal.authorization.UserLevel;
 import org.springframework.security.core.GrantedAuthority;
 
@@ -22,7 +24,7 @@ public class ODLUserLevel implements GrantedAuthority {
 
     @Override
     public String getAuthority() {
-        return "ROLE_" + this.userLevel.toString().toUpperCase();
+        return "ROLE_" + this.userLevel.toString().toUpperCase(Locale.ENGLISH);
     }
 
 }
index 0e6a48a..cca194e 100644 (file)
@@ -9,6 +9,9 @@
 package org.opendaylight.controller.usermanager;
 
 import java.io.Serializable;
+import java.nio.charset.Charset;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
 import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.List;
@@ -16,6 +19,7 @@ import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
 import org.opendaylight.controller.sal.authorization.AuthResultEnum;
+import org.opendaylight.controller.sal.utils.HexEncode;
 import org.opendaylight.controller.sal.utils.Status;
 import org.opendaylight.controller.sal.utils.StatusCode;
 import org.opendaylight.controller.usermanager.AuthResponse;
@@ -27,27 +31,50 @@ import org.opendaylight.controller.usermanager.AuthResponse;
 public class UserConfig implements Serializable {
     private static final long serialVersionUID = 1L;
 
-    /*
-     * Clear text password as we are moving to some MD5 digest for when saving
-     * configurations
-     */
     protected String user;
     protected List<String> roles;
     private String password;
     private static final int USERNAME_MAXLENGTH = 32;
     private static final int PASSWORD_MINLENGTH = 5;
     private static final int PASSWORD_MAXLENGTH = 256;
-    private static final Pattern INVALID_USERNAME_CHARACTERS = Pattern
-            .compile("([/\\s\\.\\?#%;\\\\]+)");
+    private static final Pattern INVALID_USERNAME_CHARACTERS = Pattern.compile("([/\\s\\.\\?#%;\\\\]+)");
+    private static MessageDigest oneWayFunction = null;
+    static {
+        try {
+            UserConfig.oneWayFunction = MessageDigest.getInstance("SHA-1");
+        } catch (NoSuchAlgorithmException e) {
+            e.printStackTrace();
+        }
+    }
 
     public UserConfig() {
     }
 
+    /**
+     * Construct a UserConfig object and takes care of hashing the user password
+     *
+     * @param user
+     *            the user name
+     * @param password
+     *            the plain text password
+     * @param roles
+     *            the list of roles
+     */
     public UserConfig(String user, String password, List<String> roles) {
         this.user = user;
+
         this.password = password;
-        this.roles = (roles == null) ? new ArrayList<String>()
-                : new ArrayList<String>(roles);
+        if (this.validatePassword().isSuccess()) {
+            /*
+             * Only if the password is a valid one, hash it. So in case it is not
+             * valid, when UserConfig.validate() is called, the proper
+             * validation error will be returned to the caller. If we hashed a
+             * priori instead, the mis-configuration would be masked
+             */
+            this.password = hash(this.password);
+        }
+
+        this.roles = (roles == null) ? new ArrayList<String>() : new ArrayList<String>(roles);
     }
 
     public String getUser() {
@@ -75,28 +102,37 @@ public class UserConfig implements Serializable {
 
     @Override
     public boolean equals(Object obj) {
-        if (this == obj)
+        if (this == obj) {
             return true;
-        if (obj == null)
+        }
+        if (obj == null) {
             return false;
-        if (getClass() != obj.getClass())
+        }
+        if (getClass() != obj.getClass()) {
             return false;
+        }
         UserConfig other = (UserConfig) obj;
         if (password == null) {
-            if (other.password != null)
+            if (other.password != null) {
                 return false;
-        } else if (!password.equals(other.password))
+            }
+        } else if (!password.equals(other.password)) {
             return false;
+        }
         if (roles == null) {
-            if (other.roles != null)
+            if (other.roles != null) {
                 return false;
-        } else if (!roles.equals(other.roles))
+            }
+        } else if (!roles.equals(other.roles)) {
             return false;
+        }
         if (user == null) {
-            if (other.user != null)
+            if (other.user != null) {
                 return false;
-        } else if (!user.equals(other.user))
+            }
+        } else if (!user.equals(other.user)) {
             return false;
+        }
         return true;
     }
 
@@ -122,8 +158,7 @@ public class UserConfig implements Serializable {
         }
 
         Matcher mUser = UserConfig.INVALID_USERNAME_CHARACTERS.matcher(user);
-        if (user.length() > UserConfig.USERNAME_MAXLENGTH
-                || mUser.find() == true) {
+        if (user.length() > UserConfig.USERNAME_MAXLENGTH || mUser.find() == true) {
             return new Status(StatusCode.BADREQUEST,
                     "Username can have 1-32 non-whitespace "
                             + "alphanumeric characters and any special "
@@ -153,20 +188,19 @@ public class UserConfig implements Serializable {
         return new Status(StatusCode.SUCCESS);
     }
 
-    public Status update(String currentPassword, String newPassword,
-            List<String> newRoles) {
+    public Status update(String currentPassword, String newPassword, List<String> newRoles) {
+
         // To make any changes to a user configured profile, current password
         // must always be provided
-        if (!this.password.equals(currentPassword)) {
-            return new Status(StatusCode.BADREQUEST,
-                    "Current password is incorrect");
+        if (!this.password.equals(hash(currentPassword))) {
+            return new Status(StatusCode.BADREQUEST, "Current password is incorrect");
         }
 
         // Create a new object with the proposed modifications
         UserConfig proposed = new UserConfig();
         proposed.user = this.user;
-        proposed.password = (newPassword != null)? newPassword : this.password;
-        proposed.roles = (newRoles != null)? newRoles : this.roles;
+        proposed.password = (newPassword == null)? this.password : hash(newPassword);
+        proposed.roles = (newRoles == null)? this.roles : newRoles;
 
         // Validate it
         Status status = proposed.validate();
@@ -184,7 +218,7 @@ public class UserConfig implements Serializable {
 
     public AuthResponse authenticate(String clearTextPass) {
         AuthResponse locResponse = new AuthResponse();
-        if (password.equals(clearTextPass)) {
+        if (password.equals(hash(clearTextPass))) {
             locResponse.setStatus(AuthResultEnum.AUTH_ACCEPT_LOC);
             locResponse.addData(getRolesString());
         } else {
@@ -205,4 +239,12 @@ public class UserConfig implements Serializable {
         }
         return buffer.toString();
     }
+
+    public static String hash(String message) {
+        if (message == null) {
+            return message;
+        }
+        UserConfig.oneWayFunction.reset();
+        return HexEncode.bytesToHexString(UserConfig.oneWayFunction.digest(message.getBytes(Charset.defaultCharset())));
+    }
 }
index cccbe24..4c2a19e 100644 (file)
@@ -27,7 +27,7 @@ import org.opendaylight.controller.usermanager.UserConfig;
 public class AuthorizationUserConfigTest {
 
     @Test
-    public void AuthorizationConfigTest() {
+    public void authorizationConfigTest() {
         AuthorizationConfig authConfig;
         List<String> roles = new ArrayList<String>();
 
@@ -42,7 +42,7 @@ public class AuthorizationUserConfigTest {
     }
 
     @Test
-    public void UserConfigTest() {
+    public void userConfigTest() {
         UserConfig userConfig;
         List<String> roles = new ArrayList<String>();
 
@@ -75,12 +75,12 @@ public class AuthorizationUserConfigTest {
                 .isSuccess());
 
         // New Password = null, No change in password
-        assertTrue(userConfig.getPassword().equals("ciscocisco"));
+        assertTrue(userConfig.getPassword().equals(UserConfig.hash("ciscocisco")));
 
         // Password changed successfully, no change in user role
         assertTrue(userConfig.update("ciscocisco", "cisco123", roles)
                 .isSuccess());
-        assertTrue(userConfig.getPassword().equals("cisco123"));
+        assertTrue(userConfig.getPassword().equals(UserConfig.hash("cisco123")));
         assertTrue(userConfig.getRoles().get(0).equals(
                 UserLevel.NETWORKOPERATOR.toString()));
 
@@ -89,14 +89,14 @@ public class AuthorizationUserConfigTest {
         roles.add(UserLevel.SYSTEMADMIN.toString());
         assertTrue(userConfig.update("cisco123", "cisco123", roles)
                 .isSuccess());
-        assertTrue(userConfig.getPassword().equals("cisco123"));
+        assertTrue(userConfig.getPassword().equals(UserConfig.hash("cisco123")));
         assertTrue(userConfig.getRoles().get(0)
                 .equals(UserLevel.SYSTEMADMIN.toString()));
 
         // Password and role changed successfully
         assertTrue(userConfig.update("cisco123", "ciscocisco", roles)
                 .isSuccess());
-        assertTrue(userConfig.getPassword().equals("ciscocisco"));
+        assertTrue(userConfig.getPassword().equals(UserConfig.hash("ciscocisco")));
         assertTrue(userConfig.getRoles().get(0)
                 .equals(UserLevel.SYSTEMADMIN.toString()));
 
index e54953f..0e7e2a3 100644 (file)
@@ -9,11 +9,6 @@
 
 package org.opendaylight.controller.usermanager.internal;
 
-import java.util.Dictionary;
-import java.util.HashSet;
-import java.util.Hashtable;
-import java.util.Set;
-
 import org.apache.felix.dm.Component;
 import org.opendaylight.controller.clustering.services.IClusterGlobalServices;
 import org.opendaylight.controller.configuration.IConfigurationAware;
@@ -40,6 +35,7 @@ public class Activator extends ComponentActivatorAbstractBase {
      * ComponentActivatorAbstractBase.
      *
      */
+    @Override
     public void init() {
 
     }
@@ -49,6 +45,7 @@ public class Activator extends ComponentActivatorAbstractBase {
      * cleanup done by ComponentActivatorAbstractBase
      *
      */
+    @Override
     public void destroy() {
 
     }
@@ -62,6 +59,7 @@ public class Activator extends ComponentActivatorAbstractBase {
      * instantiated in order to get an fully working implementation
      * Object
      */
+    @Override
     public Object[] getImplementations() {
         return null;
     }
@@ -79,6 +77,7 @@ public class Activator extends ComponentActivatorAbstractBase {
      * also optional per-container different behavior if needed, usually
      * should not be the case though.
      */
+    @Override
     public void configureInstance(Component c, Object imp, String containerName) {
     }
 
@@ -95,8 +94,9 @@ public class Activator extends ComponentActivatorAbstractBase {
      * @return The list of implementations the bundle will support,
      * in Global version
      */
+    @Override
     protected Object[] getGlobalImplementations() {
-        Object[] res = { UserManagerImpl.class };
+        Object[] res = { UserManager.class };
         return res;
     }
 
@@ -108,8 +108,9 @@ public class Activator extends ComponentActivatorAbstractBase {
      * @param imp implementation to be configured
      * @param containerName container on which the configuration happens
      */
+    @Override
     protected void configureGlobalInstance(Component c, Object imp) {
-        if (imp.equals(UserManagerImpl.class)) {
+        if (imp.equals(UserManager.class)) {
 
             // export the service
             c.setInterface(new String[] {
@@ -69,16 +69,13 @@ import org.springframework.security.web.context.SecurityContextRepository;
 /**
  * The internal implementation of the User Manager.
  */
-public class UserManagerImpl implements IUserManager, IObjectReader,
+public class UserManager implements IUserManager, IObjectReader,
         IConfigurationAware, CommandProvider, AuthenticationProvider {
-    private static final Logger logger = LoggerFactory
-            .getLogger(UserManagerImpl.class);
+    private static final Logger logger = LoggerFactory.getLogger(UserManager.class);
     private static final String defaultAdmin = "admin";
     private static final String defaultAdminPassword = "admin";
-    private static final String defaultAdminRole = UserLevel.NETWORKADMIN
-            .toString();
+    private static final String defaultAdminRole = UserLevel.NETWORKADMIN.toString();
     private static final String ROOT = GlobalConstants.STARTUPHOME.toString();
-    private static final String SAVE = "save";
     private static final String usersFileName = ROOT + "users.conf";
     private static final String serversFileName = ROOT + "servers.conf";
     private static final String authFileName = ROOT + "authorization.conf";
@@ -88,8 +85,6 @@ public class UserManagerImpl implements IUserManager, IObjectReader,
     private ConcurrentMap<String, AuthorizationConfig> authorizationConfList;
     private ConcurrentMap<String, AuthenticatedUser> activeUsers;
     private ConcurrentMap<String, IAAAProvider> authProviders;
-    private ConcurrentMap<Long, String> localUserListSaveConfigEvent,
-    remoteServerSaveConfigEvent, authorizationSaveConfigEvent;
     private IClusterGlobalServices clusterGlobalService = null;
     private SecurityContextRepository securityContextRepo = new UserSecurityContextRepository();
     private IContainerAuthorization containerAuthorizationClient;
@@ -122,10 +117,8 @@ public class UserManagerImpl implements IUserManager, IObjectReader,
         return authProviders.keySet();
     }
 
-    @SuppressWarnings("deprecation")
     private void allocateCaches() {
-        this.applicationAuthorizationClients = Collections
-                .synchronizedSet(new HashSet<IResourceAuthorization>());
+        this.applicationAuthorizationClients = Collections.synchronizedSet(new HashSet<IResourceAuthorization>());
         if (clusterGlobalService == null) {
             logger.error("un-initialized clusterGlobalService, can't create cache");
             return;
@@ -145,18 +138,6 @@ public class UserManagerImpl implements IUserManager, IObjectReader,
 
             clusterGlobalService.createCache("usermanager.activeUsers",
                     EnumSet.of(IClusterServices.cacheMode.TRANSACTIONAL));
-
-            clusterGlobalService.createCache(
-                    "usermanager.localUserSaveConfigEvent",
-                    EnumSet.of(IClusterServices.cacheMode.TRANSACTIONAL));
-
-            clusterGlobalService.createCache(
-                    "usermanager.remoteServerSaveConfigEvent",
-                    EnumSet.of(IClusterServices.cacheMode.TRANSACTIONAL));
-
-            clusterGlobalService.createCache(
-                    "usermanager.authorizationSaveConfigEvent",
-                    EnumSet.of(IClusterServices.cacheMode.TRANSACTIONAL));
         } catch (CacheConfigException cce) {
             logger.error("Cache configuration invalid - check cache mode");
         } catch (CacheExistException ce) {
@@ -164,7 +145,7 @@ public class UserManagerImpl implements IUserManager, IObjectReader,
         }
     }
 
-    @SuppressWarnings({ "unchecked", "deprecation" })
+    @SuppressWarnings({ "unchecked" })
     private void retrieveCaches() {
         if (clusterGlobalService == null) {
             logger.error("un-initialized clusterService, can't retrieve cache");
@@ -194,24 +175,6 @@ public class UserManagerImpl implements IUserManager, IObjectReader,
         if (authorizationConfList == null) {
             logger.error("Failed to get cache for authorizationConfList");
         }
-
-        localUserListSaveConfigEvent = (ConcurrentMap<Long, String>) clusterGlobalService
-                .getCache("usermanager.localUserSaveConfigEvent");
-        if (localUserListSaveConfigEvent == null) {
-            logger.error("Failed to get cache for localUserSaveConfigEvent");
-        }
-
-        remoteServerSaveConfigEvent = (ConcurrentMap<Long, String>) clusterGlobalService
-                .getCache("usermanager.remoteServerSaveConfigEvent");
-        if (remoteServerSaveConfigEvent == null) {
-            logger.error("Failed to get cache for remoteServerSaveConfigEvent");
-        }
-
-        authorizationSaveConfigEvent = (ConcurrentMap<Long, String>) clusterGlobalService
-                .getCache("usermanager.authorizationSaveConfigEvent");
-        if (authorizationSaveConfigEvent == null) {
-            logger.error("Failed to get cache for authorizationSaveConfigEvent");
-        }
     }
 
     private void loadConfigurations() {
@@ -239,12 +202,11 @@ public class UserManagerImpl implements IUserManager, IObjectReader,
 
     private void checkDefaultNetworkAdmin() {
         // If startup config is not there, it's old or it was deleted,
-        // need to add Default Admin
+        // need to add Default Network Admin User
         if (!localUserConfigList.containsKey(defaultAdmin)) {
             List<String> roles = new ArrayList<String>(1);
             roles.add(defaultAdminRole);
-            localUserConfigList.put(defaultAdmin, new UserConfig(defaultAdmin,
-                    defaultAdminPassword, roles));
+            localUserConfigList.put(defaultAdmin, new UserConfig(defaultAdmin, defaultAdminPassword, roles));
         }
     }
 
@@ -493,7 +455,7 @@ public class UserManagerImpl implements IUserManager, IObjectReader,
         String user = AAAconf.getUser();
 
         // Check default admin user
-        if (user.equals(UserManagerImpl.defaultAdmin)) {
+        if (user.equals(UserManager.defaultAdmin)) {
             String msg = "Invalid Request: Default Network Admin  User cannot be " + ((delete)? "removed" : "added");
             logger.debug(msg);
             return new Status(StatusCode.NOTALLOWED, msg);
@@ -632,8 +594,7 @@ public class UserManagerImpl implements IUserManager, IObjectReader,
     }
 
     @Override
-    public Status changeLocalUserPassword(String user, String curPassword,
-            String newPassword) {
+    public Status changeLocalUserPassword(String user, String curPassword, String newPassword) {
         UserConfig targetConfigEntry = null;
 
         // update configuration entry
@@ -641,8 +602,7 @@ public class UserManagerImpl implements IUserManager, IObjectReader,
         if (targetConfigEntry == null) {
             return new Status(StatusCode.NOTFOUND, "User not found");
         }
-        Status status = targetConfigEntry
-                .update(curPassword, newPassword, null);
+        Status status = targetConfigEntry.update(curPassword, newPassword, null);
         if (!status.isSuccess()) {
             return status;
         }
@@ -701,8 +661,7 @@ public class UserManagerImpl implements IUserManager, IObjectReader,
             role = ci.nextArgument();
         }
 
-        if (userName == null || userName.trim().isEmpty() || password == null
-                || password.trim().isEmpty() || roles == null
+        if (userName == null || userName.trim().isEmpty() || password == null || password.trim().isEmpty()
                 || roles.isEmpty()) {
             ci.println("Invalid Arguments");
             ci.println("umAddUser <user_name> <password> <user_role>");
index e84396b..67c273b 100644 (file)
@@ -31,11 +31,11 @@ import org.opendaylight.controller.usermanager.UserConfig;
 import org.opendaylight.controller.usermanager.AuthorizationConfig;
 
 /**
- * Unit Tests for UserManagerImpl
+ * Unit Tests for UserManager
  */
 public class UserManagerImplTest {
 
-    private static UserManagerImpl um;
+    private static UserManager um;
 
     /**
      * @throws java.lang.Exception
@@ -45,10 +45,10 @@ public class UserManagerImplTest {
 
         IUserManager userManager = (IUserManager) ServiceHelper
                 .getGlobalInstance(IUserManager.class, new Object());
-        if (userManager instanceof UserManagerImpl) {
-            um = (UserManagerImpl) userManager;
+        if (userManager instanceof UserManager) {
+            um = (UserManager) userManager;
         } else {
-            um = new UserManagerImpl();
+            um = new UserManager();
             um.setAuthProviders(new ConcurrentHashMap<String, IAAAProvider>());
 
             // mock up a remote server list with a dummy server
@@ -106,7 +106,7 @@ public class UserManagerImplTest {
 
     /**
      * Test method for
-     * {@link org.opendaylight.controller.usermanager.internal.UserManagerImpl#addAAAProvider(org.opendaylight.controller.usermanager.IAAAProvider)}
+     * {@link org.opendaylight.controller.usermanager.internal.UserManager#addAAAProvider(org.opendaylight.controller.usermanager.IAAAProvider)}
      * .
      */
     @Test
@@ -133,9 +133,9 @@ public class UserManagerImplTest {
 
     /**
      * Test method for
-     * {@link org.opendaylight.controller.usermanager.internal.UserManagerImpl#removeAAAProvider(org.opendaylight.controller.usermanager.IAAAProvider)}
+     * {@link org.opendaylight.controller.usermanager.internal.UserManager#removeAAAProvider(org.opendaylight.controller.usermanager.IAAAProvider)}
      * and for for
-     * {@link org.opendaylight.controller.usermanager.internal.UserManagerImpl#getAAAProvider(java.lang.String)}
+     * {@link org.opendaylight.controller.usermanager.internal.UserManager#getAAAProvider(java.lang.String)}
      * .
      */
     @Test
@@ -146,7 +146,7 @@ public class UserManagerImplTest {
 
     /**
      * Test method for
-     * {@link org.opendaylight.controller.usermanager.internal.UserManagerImpl#authenticate(java.lang.String, java.lang.String)}
+     * {@link org.opendaylight.controller.usermanager.internal.UserManager#authenticate(java.lang.String, java.lang.String)}
      * .
      */
     @Test
@@ -161,7 +161,7 @@ public class UserManagerImplTest {
 
     /**
      * Test method for
-     * {@link org.opendaylight.controller.usermanager.internal.UserManagerImpl#addRemoveLocalUser(org.opendaylight.controller.usermanager.org.opendaylight.controller.usermanager.internal.UserConfig, boolean)}
+     * {@link org.opendaylight.controller.usermanager.internal.UserManager#addRemoveLocalUser(org.opendaylight.controller.usermanager.org.opendaylight.controller.usermanager.internal.UserConfig, boolean)}
      * .
      */
     @Test
@@ -178,7 +178,7 @@ public class UserManagerImplTest {
 
     /**
      * Test method for
-     * {@link org.opendaylight.controller.usermanager.internal.UserManagerImpl#changeLocalUserPassword(java.lang.String, java.lang.String, java.lang.String)}
+     * {@link org.opendaylight.controller.usermanager.internal.UserManager#changeLocalUserPassword(java.lang.String, java.lang.String, java.lang.String)}
      * .
      */
     @Test
@@ -188,7 +188,7 @@ public class UserManagerImplTest {
 
     /**
      * Test method for
-     * {@link org.opendaylight.controller.usermanager.internal.UserManagerImpl#userLogout(java.lang.String)}
+     * {@link org.opendaylight.controller.usermanager.internal.UserManager#userLogout(java.lang.String)}
      * .
      */
     @Test
@@ -198,7 +198,7 @@ public class UserManagerImplTest {
 
     /**
      * Test method for
-     * {@link org.opendaylight.controller.usermanager.internal.UserManagerImpl#userTimedOut(java.lang.String)}
+     * {@link org.opendaylight.controller.usermanager.internal.UserManager#userTimedOut(java.lang.String)}
      * .
      */
     @Test
@@ -208,7 +208,7 @@ public class UserManagerImplTest {
 
     /**
      * Test method for
-     * {@link org.opendaylight.controller.usermanager.internal.UserManagerImpl#authenticate(org.springframework.security.core.Authentication)}
+     * {@link org.opendaylight.controller.usermanager.internal.UserManager#authenticate(org.springframework.security.core.Authentication)}
      * .
      */
     @Test
@@ -218,7 +218,7 @@ public class UserManagerImplTest {
 
     /**
      * Test method for
-     * {@link org.opendaylight.controller.usermanager.internal.UserManagerImpl#saveLocalUserList()}
+     * {@link org.opendaylight.controller.usermanager.internal.UserManager#saveLocalUserList()}
      * .
      */
     @Test
@@ -228,7 +228,7 @@ public class UserManagerImplTest {
 
     /**
      * Test method for
-     * {@link org.opendaylight.controller.usermanager.internal.UserManagerImpl#saveAAAServerList()}
+     * {@link org.opendaylight.controller.usermanager.internal.UserManager#saveAAAServerList()}
      * .
      */
     @Test
@@ -238,7 +238,7 @@ public class UserManagerImplTest {
 
     /**
      * Test method for
-     * {@link org.opendaylight.controller.usermanager.internal.UserManagerImpl#saveAuthorizationList()}
+     * {@link org.opendaylight.controller.usermanager.internal.UserManager#saveAuthorizationList()}
      * .
      */
     @Test
@@ -248,7 +248,7 @@ public class UserManagerImplTest {
 
     /**
      * Test method for
-     * {@link org.opendaylight.controller.usermanager.internal.UserManagerImpl#readObject(java.io.ObjectInputStream)}
+     * {@link org.opendaylight.controller.usermanager.internal.UserManager#readObject(java.io.ObjectInputStream)}
      * .
      */
     @Test
index 13a3a10..2b58bcc 100644 (file)
@@ -171,7 +171,9 @@ public class DaylightWebAdmin {
         }
 
         Gson gson = new Gson();
-        UserConfig config = gson.fromJson(json, UserConfig.class);
+        UserConfig plainConfig = gson.fromJson(json, UserConfig.class);
+        // Recreate using the proper constructor which will hash the password
+        UserConfig config = new UserConfig(plainConfig.getUser(), plainConfig.getPassword(), plainConfig.getRoles());
 
         Status result = (action.equals("add")) ? userManager.addLocalUser(config) : userManager.removeLocalUser(config);
         if (result.isSuccess()) {