cdmlib part of fix #4121 (Changing password does not work)
[cdmlib.git] / cdmlib-services / src / main / java / eu / etaxonomy / cdm / api / service / UserService.java
index 125a8134169e56d26dcdae73c7ebb1874895b08b..2f0e87c6eb55a7eb3f7d426265c5eb37fc8f9d3e 100644 (file)
@@ -106,16 +106,15 @@ public class UserService extends ServiceBase<User,IUserDao> implements IUserServ
         this.grantedAuthorityDao = grantedAuthorityDao;\r
     }\r
 \r
-    @Transactional(readOnly=false)\r
-    protected Authentication createNewAuthentication(Authentication currentAuth, String newPassword) {\r
-        UserDetails user = loadUserByUsername(currentAuth.getName());\r
-\r
-        UsernamePasswordAuthenticationToken newAuthentication = new UsernamePasswordAuthenticationToken(user, user.getPassword(), user.getAuthorities());\r
-        newAuthentication.setDetails(currentAuth.getDetails());\r
-\r
-        return newAuthentication;\r
-    }\r
-\r
+    /**\r
+     * Changes the own password of in the database of the user which is\r
+     * currently authenticated. Requires to supply the old password for security\r
+     * reasons. Refreshes the authentication in the SecurityContext after the\r
+     * password change by re-authenticating the user with the new password.\r
+     *\r
+     * @see org.springframework.security.provisioning.UserDetailsManager#changePassword(java.lang.String,\r
+     *      java.lang.String)\r
+     */\r
     @Override\r
     @Transactional(readOnly=false)\r
     @PreAuthorize("isAuthenticated()")\r
@@ -124,18 +123,28 @@ public class UserService extends ServiceBase<User,IUserDao> implements IUserServ
         Assert.hasText(newPassword);\r
         Authentication authentication = SecurityContextHolder.getContext().getAuthentication();\r
         if(authentication != null && authentication.getPrincipal() != null && authentication.getPrincipal() instanceof User) {\r
+\r
+            // get current authentication and load it from the persistence layer,\r
+            // to make sure we are modifying the instance which is\r
+            // attached to the hibernate session\r
             User user = (User)authentication.getPrincipal();\r
+            user = dao.load(user.getUuid());\r
 \r
+            // check if old password is valid\r
             authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(user.getUsername(), oldPassword));\r
 \r
+            // make new password and set it\r
             Object salt = this.saltSource.getSalt(user);\r
-\r
             String password = passwordEncoder.encodePassword(newPassword, salt);\r
             user.setPassword(password);\r
-\r
             dao.update(user);\r
-            SecurityContextHolder.getContext().setAuthentication(createNewAuthentication(authentication, newPassword));\r
+\r
+            // authenticate the user again with the new password\r
+            UsernamePasswordAuthenticationToken newAuthentication = new UsernamePasswordAuthenticationToken(user, user.getPassword(), user.getAuthorities());\r
+            newAuthentication.setDetails(authentication.getDetails());\r
+            SecurityContextHolder.getContext().setAuthentication(newAuthentication);\r
             userCache.removeUserFromCache(user.getUsername());\r
+\r
         } else {\r
             throw new AccessDeniedException("Can't change password as no Authentication object found in context for current user.");\r
         }\r
@@ -185,11 +194,11 @@ public class UserService extends ServiceBase<User,IUserDao> implements IUserServ
         ((User)user).setPassword(password);\r
 \r
         UUID userUUID = dao.save((User)user);\r
-        \r
-        \r
+\r
+\r
     }\r
-    \r
-    \r
+\r
+\r
 \r
     /* (non-Javadoc)\r
      * @see org.springframework.security.provisioning.UserDetailsManager#deleteUser(java.lang.String)\r
@@ -454,7 +463,7 @@ public class UserService extends ServiceBase<User,IUserDao> implements IUserServ
         return grantedAuthorityDao.save((GrantedAuthorityImpl)grantedAuthority);\r
     }\r
 \r
-    \r
+\r
 \r
     /* (non-Javadoc)\r
      * @see eu.etaxonomy.cdm.api.service.IUserService#listByUsername(java.lang.String, eu.etaxonomy.cdm.persistence.query.MatchMode, java.util.List, java.lang.Integer, java.lang.Integer, java.util.List, java.util.List)\r