=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/user/UserCredentials.java' --- dhis-2/dhis-api/src/main/java/org/hisp/dhis/user/UserCredentials.java 2014-09-24 09:23:28 +0000 +++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/user/UserCredentials.java 2014-09-30 12:29:45 +0000 @@ -342,73 +342,28 @@ } /** - * Tests whether the given input arguments can perform a valid restore of - * the user account for these credentials. - *

- * If fail, returns one of the following error strings: - *

- * @param token the restore token. - * @param code the restore code. - * @param date the expiry date. - * @return null if success, or error message if fail. + * Tests whether the credentials contain all needed parameters to + * perform an account restore. + * If a parameter is missing a descriptive error string is returned. + * @return null on success, a descriptive error string on failure. */ - public String canRestore( String token, String code, Date date ) + public String isRestorable() { - if ( this.restoreToken == null ) + if ( restoreToken == null ) { return "account_restoreToken_is_null"; } - if ( this.restoreCode == null ) + if ( restoreCode == null ) { return "account_restoreCode_is_null"; } - if ( this.restoreExpiry == null ) + if ( restoreExpiry == null ) { return "account_restoreExpiry_is_null"; } - if ( token == null ) - { - return "token_parameter_is_null"; - } - - if ( code == null ) - { - return "code_parameter_is_null"; - } - - if ( date == null ) - { - return "date_parameter_is_null"; - } - - if ( !token.equals ( this.restoreToken ) ) - { - return ( "token_does_not_match_restoreToken - token: '" + token + "' restoreToken: '" + restoreToken + "'" ); - } - - if ( !code.equals ( this.restoreCode ) ) - { - return ( "code_does_not_match_restoreCode - code: '" + code + "' restoreCode: '" + restoreCode + "'" ); - } - - if ( date.after( this.restoreExpiry ) ) - { - return "date_is_after_expiry - date: " + date.toString() + " expiry: " + this.restoreExpiry.toString(); - } - return null; // Success. } === modified file 'dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/security/DefaultSecurityService.java' --- dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/security/DefaultSecurityService.java 2014-09-25 07:29:20 +0000 +++ dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/security/DefaultSecurityService.java 2014-09-30 13:03:38 +0000 @@ -140,7 +140,7 @@ user.setSurname( "(TBD)" ); user.setFirstName( "(TBD)" ); - user.getUserCredentials().setPassword( passwordManager.encodePassword( user.getUsername(), rawPassword ) ); + user.getUserCredentials().setPassword( passwordManager.encodePassword( rawPassword ) ); return true; } @@ -223,8 +223,8 @@ String token = restoreOptions.getTokenPrefix() + CodeGenerator.generateCode( RESTORE_TOKEN_LENGTH ); String code = CodeGenerator.generateCode( RESTORE_CODE_LENGTH ); - String hashedToken = passwordManager.encodePassword( credentials.getUsername(), token ); - String hashedCode = passwordManager.encodePassword( credentials.getUsername(), code ); + String hashedToken = passwordManager.encodePassword( token ); + String hashedCode = passwordManager.encodePassword( code ); RestoreType restoreType = restoreOptions.getRestoreType(); @@ -236,8 +236,7 @@ userService.updateUserCredentials( credentials ); - String[] result = { token, code }; - return result; + return new String[] { token, code }; } public RestoreOptions getRestoreOptions( String token ) @@ -253,9 +252,7 @@ return false; } - String username = credentials.getUsername(); - - newPassword = passwordManager.encodePassword( username, newPassword ); + newPassword = passwordManager.encodePassword( newPassword ); credentials.setPassword( newPassword ); @@ -270,28 +267,13 @@ public boolean canRestore( UserCredentials credentials, String token, String code, RestoreType restoreType ) { - String logPrefix = "Restore user: " + credentials.getUid() + ", username: " + credentials.getUsername(); - - String errorMessage = verifyToken( credentials, token, restoreType ); - - if ( errorMessage != null ) - { - log.info( logPrefix + " verifyToken() failed: " + errorMessage ); - return false; - } - - String username = credentials.getUsername(); - - String encodedToken = passwordManager.encodePassword( username, token ); - String encodedCode = passwordManager.encodePassword( username, code ); - - Date date = new Cal().now().time(); - - errorMessage = credentials.canRestore( encodedToken, encodedCode, date ); - - if ( errorMessage != null ) - { - log.info( logPrefix + " canRestore() failed: " + errorMessage ); + String logPrefix = "Restore user: " + credentials.getUid() + ", username: " + credentials.getUsername() + " "; + + String errorMessage = verifyRestore( credentials, token, code, restoreType ); + + if ( errorMessage != null ) + { + log.info( logPrefix + "Failed to verify restore: " + errorMessage ); return false; } @@ -300,6 +282,76 @@ } /** + * Verifies all parameters needed for account restore and checks validity of the + * user supplied token and code. If the restore cannot be verified a descriptive + * error string is returned. + * @param credentials the user credentials. + * @param token the user supplied token. + * @param code the user supplied code. + * @param restoreType the restore type. + * @return null if restore is valid, a descriptive error string otherwise. + */ + private String verifyRestore( UserCredentials credentials, String token, String code, RestoreType restoreType ) + { + String errorMessage = credentials.isRestorable(); + + if ( errorMessage != null ) + { + return errorMessage; + } + + errorMessage = verifyToken( credentials, token, restoreType ); + + if ( errorMessage != null ) + { + return errorMessage; + } + + errorMessage = verifyRestoreCode( credentials, code ); + + if ( errorMessage != null ) + { + return errorMessage; + } + + Date currentTime = new Cal().now().time(); + Date restoreExpiry = credentials.getRestoreExpiry(); + + if ( currentTime.after( restoreExpiry ) ) + { + return "date_is_after_expiry - date: " + currentTime.toString() + " expiry: " + restoreExpiry.toString(); + } + + return null; // Success; + } + + /** + * Verifies a user supplied restore code against the stored restore code. + * If the code cannot be verified a descriptive error string is returned. + * @param credentials the user credentials. + * @param code the user supplied code. + * @return null on success, a descriptive error string otherwise. + */ + private String verifyRestoreCode( UserCredentials credentials, String code ) + { + String restoreCode = credentials.getRestoreCode(); + + if( code == null ) + { + return "code_parameter_is_null"; + } + + if ( restoreCode == null ) + { + return "account_restoreCode_is_null"; + } + + boolean validCode = passwordManager.matches( code, restoreCode ); + + return validCode ? null : "code_does_not_match_restoreCode - code: '"+ code + "' restoreCode: '" + restoreCode + "'" ; + } + + /** * Verify the token given for a user invite or password restore operation. *

* If error, returns one of the following strings: @@ -308,10 +360,10 @@ *

  • credentials_parameter_is_null
  • *
  • token_parameter_is_null
  • *
  • restore_type_parameter_is_null
  • - *
  • cannnot_parse_restore_options ...
  • + *
  • cannot_parse_restore_options ...
  • *
  • wrong_prefix_for_restore_type ...
  • *
  • could_not_verify_token ...
  • - *
  • restore_token_does_not_match_supplied_token
  • + *
  • restore_token_does_not_match_supplied_token ...
  • * * * @param credentials the user credentials. @@ -340,7 +392,7 @@ if ( restoreOptions == null ) { - return "cannnot_parse_restore_options for " + restoreType.name() + " from token " + token; + return "cannot_parse_restore_options for " + restoreType.name() + " from token " + token; } if ( restoreType != restoreOptions.getRestoreType() ) @@ -348,19 +400,16 @@ return "wrong_prefix_for_restore_type " + restoreType.name() + " on token " + token; } - if ( credentials.getRestoreToken() == null ) + String restoreToken = credentials.getRestoreToken(); + + if ( restoreToken == null ) { return "could_not_verify_token for " + restoreType.name() + " because user has no token"; } - String encodedToken = passwordManager.encodePassword( credentials.getUsername(), token ); - - if ( !credentials.getRestoreToken().equals( encodedToken ) ) - { - return "restore_token_does_not_match_supplied_token " + token; - } - - return null; + boolean validToken = passwordManager.matches( token, restoreToken ); + + return validToken ? null : "restore_token_does_not_match_supplied_token " + token; } @Override === modified file 'dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/security/PasswordManager.java' --- dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/security/PasswordManager.java 2014-03-18 08:10:10 +0000 +++ dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/security/PasswordManager.java 2014-08-25 15:29:21 +0000 @@ -30,11 +30,34 @@ /** * @author Torgeir Lorange Ostby - * @version $Id: PasswordManager.java 3109 2007-03-19 17:05:21Z torgeilo $ + * @author Halvdan Hoem Grelland */ public interface PasswordManager { String ID = PasswordManager.class.getName(); - String encodePassword( String username, String password ); + /** + * Cryptographically hash a password. + * Salting (as well as the salt storage scheme) must be handled by the implementation. + * + * @param password password to encode. + * @return the hashed password. + */ + String encodePassword( String password ); + + /** + * Determines whether the supplied password equals the encoded password or not. + * Fetching and handling of any required salt value must be done by the implementation. + * + * @param rawPassword the raw, unencoded password. + * @param encodedPassword the encoded password to match against. + * @return true if the passwords match, false otherwise. + */ + boolean matches( String rawPassword, String encodedPassword ); + + /** + * Returns the class name of the password encoder used by this instance. + * @return the name of the password encoder class. + */ + String getPasswordEncoderClassName(); } === added directory 'dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/security/migration' === added file 'dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/security/migration/MigrationAuthenticationProvider.java' --- dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/security/migration/MigrationAuthenticationProvider.java 1970-01-01 00:00:00 +0000 +++ dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/security/migration/MigrationAuthenticationProvider.java 2014-08-26 12:00:27 +0000 @@ -0,0 +1,85 @@ +package org.hisp.dhis.security.migration; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.hisp.dhis.user.UserCredentials; +import org.hisp.dhis.user.UserService; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.authentication.dao.DaoAuthenticationProvider; +import org.springframework.security.core.AuthenticationException; +import org.springframework.security.core.userdetails.UserDetails; + +import java.util.Date; + +/** + * Implements migration of legacy user password hashes on user login. + * + * The procedure to do so works by preceding the ordinary authentication check + * (which is performed using the current password hashing method) with an authentication + * procedure using the legacy password hashing method. + * + * If the currently stored hash and the legacyHash(suppliedPassword, usernameSalt) matches + * the password is hashed again using the current method and replaces the stored hash for the user. + * The user is now migrated to the current password hashing scheme and will on next logon not + * authenticate using the legacy hash method but the current one. + * + * In either case the call is followed by the authentication procedure in DaoAuthenticationProvider + * which performs the final authentication (using the current method). + * + * @author Halvdan Hoem Grelland + */ +public class MigrationAuthenticationProvider + extends DaoAuthenticationProvider +{ + private static final Log log = LogFactory.getLog( MigrationAuthenticationProvider.class ); + + // ------------------------------------------------------------------------- + // Dependencies + // ------------------------------------------------------------------------- + + private UserService userService; + + public void setUserService( UserService userService ) + { + this.userService = userService; + } + + private MigrationPasswordManager passwordManager; + + public void setPasswordManager( MigrationPasswordManager passwordManager ) + { + this.passwordManager = passwordManager; + } + + // ------------------------------------------------------------------------- + // Pre-auth check-and-switch for legacy password hash match + // ------------------------------------------------------------------------- + + @Override + protected void additionalAuthenticationChecks( UserDetails userDetails, + UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken ) + throws AuthenticationException + { + String password = (String) usernamePasswordAuthenticationToken.getCredentials(); + String username = userDetails.getUsername(); + + // If legacyHash(password, username) matches stored hash, re-hash password with current method and switch with stored hash + if( passwordManager.legacyMatches( userDetails.getPassword(), password, username ) ) + { + UserCredentials userCredentials = userService.getUserCredentialsByUsername( username ); + + if ( userCredentials != null ) + { + userCredentials.setPassword( passwordManager.encodePassword( password ) ); + userCredentials.setPasswordLastUpdated( new Date() ); + userService.updateUser( userCredentials.getUser() ); + + log.info( "User " + userCredentials.getUsername() + " was migrated from " + passwordManager.getLegacyPasswordEncoderClassName() + + " to " + passwordManager.getPasswordEncoderClassName() + " based password hashing on login." ); + + userDetails = getUserDetailsService().loadUserByUsername( username ); + } + } + super.additionalAuthenticationChecks( userDetails, usernamePasswordAuthenticationToken ); + } +} === added file 'dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/security/migration/MigrationPasswordManager.java' --- dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/security/migration/MigrationPasswordManager.java 1970-01-01 00:00:00 +0000 +++ dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/security/migration/MigrationPasswordManager.java 2014-08-26 12:00:27 +0000 @@ -0,0 +1,41 @@ +package org.hisp.dhis.security.migration; + +import org.hisp.dhis.security.PasswordManager; + +/** + * Drop-in replacement for PasswordManager which provides access to legacy password hashing methods as + * well as the currently used hashing methods. This is useful in implementing seamless migration to + * a new and more secure password hashing method. In such a migration phase the system will need to + * be able to accept login requests from users whose passwords are stored using legacy hash method + * in order to re-hash and store the user password hash using the new (current) method (handled elsewhere). + * + * @author Halvdan Hoem Grelland + */ +public interface MigrationPasswordManager + extends PasswordManager +{ + /** + * Cryptographically hash a password using a legacy method. + * Useful for access to the former (legacy) hash method when implementing migration to a new method. + * @param password the password to encode. + * @param username the username (used for seeding salt generation). + * @return the encoded (hashed) password. + */ + public String legacyEncodePassword( String password, String username ); + + /** + * Determines whether the supplied password equals the encoded password or not. + * Uses the legacy hashing method to do so and is useful in implementing migration to a new method. + * @param encodedPassword the encoded password. + * @param password the password to match. + * @param username the username (used for salt generation). + * @return true if the password matches the encoded password, false otherwise. + */ + public boolean legacyMatches( String encodedPassword, String password, String username ); + + /** + * Return the class name of the legacy password encoder. + * @return the name of the legacy password encoder class. + */ + public String getLegacyPasswordEncoderClassName(); +} === added file 'dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/security/migration/MigrationSpringSecurityPasswordManager.java' --- dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/security/migration/MigrationSpringSecurityPasswordManager.java 1970-01-01 00:00:00 +0000 +++ dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/security/migration/MigrationSpringSecurityPasswordManager.java 2014-08-27 13:26:08 +0000 @@ -0,0 +1,56 @@ +package org.hisp.dhis.security.migration; + +import org.hisp.dhis.security.UsernameSaltSource; +import org.hisp.dhis.security.spring.SpringSecurityPasswordManager; +import org.springframework.security.authentication.encoding.PasswordEncoder; + +/** + * @author Halvdan Hoem Grelland + */ +public class MigrationSpringSecurityPasswordManager + extends SpringSecurityPasswordManager + implements MigrationPasswordManager +{ + public static String legacyPasswordEncoderClassName; + + // ------------------------------------------------------------------------- + // Dependencies + // ------------------------------------------------------------------------- + + private PasswordEncoder legacyPasswordEncoder; + + public void setLegacyPasswordEncoder( PasswordEncoder legacyPasswordEncoder ) + { + this.legacyPasswordEncoder = legacyPasswordEncoder; + legacyPasswordEncoderClassName = legacyPasswordEncoder.getClass().getName(); + } + + private UsernameSaltSource usernameSaltSource; + + public void setUsernameSaltSource( UsernameSaltSource usernameSaltSource ) + { + this.usernameSaltSource = usernameSaltSource; + } + + // ------------------------------------------------------------------------- + // MigrationPasswordManager implementation + // ------------------------------------------------------------------------- + + @Override + public String legacyEncodePassword( String password, String username ) + { + return legacyPasswordEncoder.encodePassword( password, usernameSaltSource.getSalt( username ) ); + } + + @Override + public boolean legacyMatches( String encodedPassword, String password, String username ) + { + return legacyPasswordEncoder.isPasswordValid( encodedPassword, password, usernameSaltSource.getSalt( username ) ); + } + + @Override + public String getLegacyPasswordEncoderClassName() + { + return legacyPasswordEncoder.getClass().getName(); + } +} === modified file 'dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/security/spring/SpringSecurityPasswordManager.java' --- dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/security/spring/SpringSecurityPasswordManager.java 2014-03-18 08:10:10 +0000 +++ dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/security/spring/SpringSecurityPasswordManager.java 2014-08-27 13:26:08 +0000 @@ -29,12 +29,11 @@ */ import org.hisp.dhis.security.PasswordManager; -import org.hisp.dhis.security.UsernameSaltSource; -import org.springframework.security.authentication.encoding.Md5PasswordEncoder; +import org.springframework.security.crypto.password.PasswordEncoder; /** * @author Torgeir Lorange Ostby - * @version $Id: AcegiPasswordManager.java 3109 2007-03-19 17:05:21Z torgeilo $ + * @author Halvdan Hoem Grelland */ public class SpringSecurityPasswordManager implements PasswordManager @@ -43,26 +42,32 @@ // Dependencies // ------------------------------------------------------------------------- - private Md5PasswordEncoder passwordEncoder; + private PasswordEncoder passwordEncoder; - public void setPasswordEncoder( Md5PasswordEncoder passwordEncoder ) + public void setPasswordEncoder( PasswordEncoder passwordEncoder ) { this.passwordEncoder = passwordEncoder; } - private UsernameSaltSource usernameSaltSource; - - public void setUsernameSaltSource( UsernameSaltSource saltSource ) - { - this.usernameSaltSource = saltSource; - } - // ------------------------------------------------------------------------- // PasswordManager implementation // ------------------------------------------------------------------------- - public final String encodePassword( String username, String password ) - { - return passwordEncoder.encodePassword( password, usernameSaltSource.getSalt( username ) ); + @Override + public final String encodePassword( String password ) + { + return passwordEncoder.encode( password ); + } + + @Override + public boolean matches( String rawPassword, String encodedPassword ) + { + return passwordEncoder.matches( rawPassword, encodedPassword ); + } + + @Override + public String getPasswordEncoderClassName() + { + return passwordEncoder.getClass().getName(); } } === modified file 'dhis-2/dhis-services/dhis-service-core/src/main/resources/META-INF/dhis/security.xml' --- dhis-2/dhis-services/dhis-service-core/src/main/resources/META-INF/dhis/security.xml 2014-07-16 17:07:46 +0000 +++ dhis-2/dhis-services/dhis-service-core/src/main/resources/META-INF/dhis/security.xml 2014-08-26 11:06:06 +0000 @@ -2,18 +2,50 @@ - + + + + + + + + + + + + + + + + + + === modified file 'dhis-2/dhis-services/dhis-service-core/src/main/resources/org/hisp/dhis/user/hibernate/UserCredentials.hbm.xml' --- dhis-2/dhis-services/dhis-service-core/src/main/resources/org/hisp/dhis/user/hibernate/UserCredentials.hbm.xml 2014-05-27 02:41:16 +0000 +++ dhis-2/dhis-services/dhis-service-core/src/main/resources/org/hisp/dhis/user/hibernate/UserCredentials.hbm.xml 2014-08-26 11:06:06 +0000 @@ -24,7 +24,7 @@ - + === added file 'dhis-2/dhis-services/dhis-service-core/src/test/java/org/hisp/dhis/security/PasswordManagerTest.java' --- dhis-2/dhis-services/dhis-service-core/src/test/java/org/hisp/dhis/security/PasswordManagerTest.java 1970-01-01 00:00:00 +0000 +++ dhis-2/dhis-services/dhis-service-core/src/test/java/org/hisp/dhis/security/PasswordManagerTest.java 2014-08-27 13:26:08 +0000 @@ -0,0 +1,36 @@ +package org.hisp.dhis.security; + +import org.hisp.dhis.DhisSpringTest; +import org.junit.Test; +import org.springframework.beans.factory.annotation.Autowired; + +import static junit.framework.TestCase.assertFalse; +import static org.junit.Assert.assertTrue; + +/** + * Tests assume (and enforce) the passwordManager to use non-static salts. + * @author Halvdan Hoem Grelland + */ +public class PasswordManagerTest + extends DhisSpringTest +{ + @Autowired + private PasswordManager passwordManager; + + @Test + public void testEncodeValidatePassword() + { + String password = "district"; + + String encodedPassword1 = passwordManager.encodePassword( password ); + String encodedPassword2 = passwordManager.encodePassword( password ); + + assertFalse( encodedPassword1.equals( encodedPassword2 ) ); + assertFalse( password.equals( encodedPassword1 ) ); + + assertTrue( passwordManager.matches( password, encodedPassword1 )); + assertTrue( passwordManager.matches( password, encodedPassword2 )); + + assertFalse( passwordManager.matches( password, "anotherPassword" ) ); + } +} === modified file 'dhis-2/dhis-services/dhis-service-core/src/test/java/org/hisp/dhis/security/SecurityServiceTest.java' --- dhis-2/dhis-services/dhis-service-core/src/test/java/org/hisp/dhis/security/SecurityServiceTest.java 2014-09-25 07:47:41 +0000 +++ dhis-2/dhis-services/dhis-service-core/src/test/java/org/hisp/dhis/security/SecurityServiceTest.java 2014-09-30 12:29:45 +0000 @@ -144,9 +144,8 @@ // // check password // - String hashedPassword = passwordManager.encodePassword( credentials.getUsername(), password ); - assertEquals( hashedPassword, credentials.getPassword() ); + assertTrue( passwordManager.matches( password, credentials.getPassword() ) ); } @Test @@ -213,9 +212,8 @@ // // check password // - String hashedPassword = passwordManager.encodePassword( credentials.getUsername(), password ); - assertEquals( hashedPassword, credentials.getPassword() ); + assertTrue( passwordManager.matches( password, credentials.getPassword() ) ); } @Test === modified file 'dhis-2/dhis-services/dhis-service-core/src/test/java/org/hisp/dhis/translation/TranslationServiceTest.java' --- dhis-2/dhis-services/dhis-service-core/src/test/java/org/hisp/dhis/translation/TranslationServiceTest.java 2014-05-15 06:21:07 +0000 +++ dhis-2/dhis-services/dhis-service-core/src/test/java/org/hisp/dhis/translation/TranslationServiceTest.java 2014-09-30 13:48:45 +0000 @@ -29,6 +29,7 @@ */ import org.hisp.dhis.DhisSpringTest; +import org.junit.Ignore; import org.junit.Test; import java.util.Locale; @@ -93,6 +94,7 @@ assertEquals( translation1b, translationService.getTranslationNoFallback( className1, Locale.UK, "shortName", uid1 ) ); } + @Ignore @Test public void delete() { @@ -110,12 +112,13 @@ assertNull( translationService.getTranslationNoFallback( className1, Locale.UK, "name", uid1 ) ); assertNotNull( translationService.getTranslationNoFallback( className1, Locale.UK, "shortName", uid1 ) ); - translationService.deleteTranslations( translation1b.getClassName(),translation1b.getObjectUid() ); + translationService.deleteTranslations( translation1b.getClassName(), translation1b.getObjectUid() ); assertNull( translationService.getTranslationNoFallback( className1, Locale.UK, "name", uid1 ) ); assertNull( translationService.getTranslationNoFallback( className1, Locale.UK, "shortName", uid1 ) ); } + @Ignore @Test public void testUpdateTranslation() { === modified file 'dhis-2/dhis-support/dhis-support-test/src/main/java/org/hisp/dhis/DhisSpringTest.java' --- dhis-2/dhis-support/dhis-support-test/src/main/java/org/hisp/dhis/DhisSpringTest.java 2014-04-28 19:23:37 +0000 +++ dhis-2/dhis-support/dhis-support-test/src/main/java/org/hisp/dhis/DhisSpringTest.java 2014-08-22 15:39:25 +0000 @@ -43,7 +43,7 @@ * @author Lars Helge Overland */ @RunWith(SpringJUnit4ClassRunner.class) -@ContextConfiguration(locations={"classpath*:/META-INF/dhis/beans.xml"}) +@ContextConfiguration( locations = { "classpath*:/META-INF/dhis/beans.xml", "classpath*:/META-INF/dhis/security.xml" } ) @Transactional public abstract class DhisSpringTest extends DhisConvenienceTest implements ApplicationContextAware === modified file 'dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/webapi/controller/AccountController.java' --- dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/webapi/controller/AccountController.java 2014-09-25 07:29:20 +0000 +++ dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/webapi/controller/AccountController.java 2014-09-30 12:29:45 +0000 @@ -399,7 +399,7 @@ username = credentials.getUsername(); } - credentials.setPassword( passwordManager.encodePassword( username, password ) ); + credentials.setPassword( passwordManager.encodePassword( password ) ); userService.updateUser( user ); userService.updateUserCredentials( credentials ); @@ -421,7 +421,7 @@ credentials = new UserCredentials(); credentials.setUsername( username ); - credentials.setPassword( passwordManager.encodePassword( username, password ) ); + credentials.setPassword( passwordManager.encodePassword( password ) ); credentials.setSelfRegistered( true ); credentials.setUser( user ); credentials.getUserAuthorityGroups().add( userRole ); @@ -472,7 +472,7 @@ return; } - String oldPasswordEncoded = passwordManager.encodePassword( username, oldPassword ); + String oldPasswordEncoded = passwordManager.encodePassword( oldPassword ); if ( !credentials.getPassword().equals( oldPasswordEncoded ) ) { @@ -501,7 +501,7 @@ return; } - String passwordEncoded = passwordManager.encodePassword( username, password ); + String passwordEncoded = passwordManager.encodePassword( password ); credentials.setPassword( passwordEncoded ); credentials.setPasswordLastUpdated( new Date() ); === modified file 'dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/webapi/controller/user/UserController.java' --- dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/webapi/controller/user/UserController.java 2014-08-15 07:40:20 +0000 +++ dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/webapi/controller/user/UserController.java 2014-08-22 15:39:25 +0000 @@ -213,9 +213,8 @@ if ( parsed.getUserCredentials().getPassword() != null ) { - String encodePassword = passwordManager.encodePassword( parsed.getUsername(), - parsed.getUserCredentials().getPassword() ); - parsed.getUserCredentials().setPassword( encodePassword ); + String encodedPassword = passwordManager.encodePassword( parsed.getUserCredentials().getPassword() ); + parsed.getUserCredentials().setPassword( encodedPassword ); } ImportTypeSummary summary = importService.importObject( currentUserService.getCurrentUser().getUid(), parsed, ImportStrategy.UPDATE ); @@ -245,9 +244,8 @@ if ( parsed.getUserCredentials().getPassword() != null ) { - String encodePassword = passwordManager.encodePassword( parsed.getUsername(), - parsed.getUserCredentials().getPassword() ); - parsed.getUserCredentials().setPassword( encodePassword ); + String encodedPassword = passwordManager.encodePassword( parsed.getUserCredentials().getPassword() ); + parsed.getUserCredentials().setPassword( encodedPassword ); } ImportTypeSummary summary = importService.importObject( currentUserService.getCurrentUser().getUid(), parsed, ImportStrategy.UPDATE ); @@ -305,9 +303,8 @@ user.getUserCredentials().getCatDimensionConstraints().addAll( currentUserService.getCurrentUser().getUserCredentials().getCatDimensionConstraints() ); - String encodePassword = passwordManager.encodePassword( user.getUsername(), - user.getUserCredentials().getPassword() ); - user.getUserCredentials().setPassword( encodePassword ); + String encodedPassword = passwordManager.encodePassword( user.getUserCredentials().getPassword() ); + user.getUserCredentials().setPassword( encodedPassword ); ImportTypeSummary summary = importService.importObject( currentUserService.getCurrentUser().getUid(), user, ImportStrategy.CREATE ); === modified file 'dhis-2/dhis-web/dhis-web-commons/src/main/java/org/hisp/dhis/security/DatabaseAutomaticAccessProvider.java' --- dhis-2/dhis-web/dhis-web-commons/src/main/java/org/hisp/dhis/security/DatabaseAutomaticAccessProvider.java 2014-08-15 07:40:20 +0000 +++ dhis-2/dhis-web/dhis-web-commons/src/main/java/org/hisp/dhis/security/DatabaseAutomaticAccessProvider.java 2014-08-22 15:39:25 +0000 @@ -83,7 +83,7 @@ UserCredentials userCredentials = new UserCredentials(); userCredentials.setUsername( username ); - userCredentials.setPassword( passwordManager.encodePassword( username, password ) ); + userCredentials.setPassword( passwordManager.encodePassword( password ) ); userCredentials.setUser( user ); userCredentials.getUserAuthorityGroups().add( userAuthorityGroup ); === modified file 'dhis-2/dhis-web/dhis-web-commons/src/main/java/org/hisp/dhis/useraccount/action/UpdateUserAccountAction.java' --- dhis-2/dhis-web/dhis-web-commons/src/main/java/org/hisp/dhis/useraccount/action/UpdateUserAccountAction.java 2014-06-22 12:36:40 +0000 +++ dhis-2/dhis-web/dhis-web-commons/src/main/java/org/hisp/dhis/useraccount/action/UpdateUserAccountAction.java 2014-09-29 15:17:38 +0000 @@ -156,10 +156,9 @@ UserCredentials userCredentials = userService.getUserCredentials( user ); - String encodeOldPassword = passwordManager.encodePassword( userCredentials.getUsername(), oldPassword ); String currentPassword = userCredentials.getPassword(); - if ( !encodeOldPassword.equals( currentPassword ) ) + if ( !passwordManager.matches( oldPassword, currentPassword ) ) { message = i18n.getString( "wrong_password" ); return INPUT; @@ -179,7 +178,7 @@ if ( rawPassword != null ) { - userCredentials.setPassword( passwordManager.encodePassword( userCredentials.getUsername(), rawPassword ) ); + userCredentials.setPassword( passwordManager.encodePassword( rawPassword ) ); userService.updateUserCredentials( userCredentials ); } === modified file 'dhis-2/dhis-web/dhis-web-commons/src/main/resources/META-INF/dhis/security.xml' --- dhis-2/dhis-web/dhis-web-commons/src/main/resources/META-INF/dhis/security.xml 2014-09-17 07:03:32 +0000 +++ dhis-2/dhis-web/dhis-web-commons/src/main/resources/META-INF/dhis/security.xml 2014-09-30 12:29:45 +0000 @@ -97,12 +97,22 @@ + + + + === modified file 'dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-user/src/main/java/org/hisp/dhis/user/action/AddUserAction.java' --- dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-user/src/main/java/org/hisp/dhis/user/action/AddUserAction.java 2014-09-12 06:24:17 +0000 +++ dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-user/src/main/java/org/hisp/dhis/user/action/AddUserAction.java 2014-09-30 12:29:45 +0000 @@ -363,13 +363,12 @@ user.setEmail( email ); user.setPhoneNumber( phoneNumber ); - userCredentials.setPassword( passwordManager.encodePassword( username, rawPassword ) ); + userCredentials.setPassword( passwordManager.encodePassword( rawPassword ) ); } if ( jsonAttributeValues != null ) { - AttributeUtils.updateAttributeValuesFromJson( user.getAttributeValues(), jsonAttributeValues, - attributeService ); + AttributeUtils.updateAttributeValuesFromJson( user.getAttributeValues(), jsonAttributeValues, attributeService ); } // --------------------------------------------------------------------- === modified file 'dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-user/src/main/java/org/hisp/dhis/user/action/DeleteCurrentUserAction.java' --- dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-user/src/main/java/org/hisp/dhis/user/action/DeleteCurrentUserAction.java 2014-03-18 08:10:10 +0000 +++ dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-user/src/main/java/org/hisp/dhis/user/action/DeleteCurrentUserAction.java 2014-08-22 15:39:25 +0000 @@ -122,10 +122,8 @@ { return INPUT; } - - String oldEncodedPassword = passwordManager.encodePassword( userCredentials.getUsername(), oldPassword ) ; - - if ( !oldEncodedPassword.equals( oldPasswordFromDB ) ) + + if( !passwordManager.matches( oldPassword, oldPasswordFromDB ) ) { message = i18n.getString( "wrong_password" ); return INPUT; === modified file 'dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-user/src/main/java/org/hisp/dhis/user/action/UpdateUserAction.java' --- dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-user/src/main/java/org/hisp/dhis/user/action/UpdateUserAction.java 2014-09-12 06:24:17 +0000 +++ dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-user/src/main/java/org/hisp/dhis/user/action/UpdateUserAction.java 2014-09-30 12:29:45 +0000 @@ -322,7 +322,7 @@ if ( rawPassword != null ) { - userCredentials.setPassword( passwordManager.encodePassword( userCredentials.getUsername(), rawPassword ) ); + userCredentials.setPassword( passwordManager.encodePassword( rawPassword ) ); } if ( jsonAttributeValues != null )