@Override public void storeHashPassword(UserDto user, String password) { requireNonNull(password, "Password cannot be null"); byte[] saltRandom = new byte[20]; SECURE_RANDOM.nextBytes(saltRandom); String salt = DigestUtils.sha1Hex(saltRandom); user.setHashMethod(HashMethod.SHA1.name()) .setCryptedPassword(hash(salt, password)) .setSalt(salt); }
@Override public void storeHashPassword(UserDto user, String password) { requireNonNull(password, "Password cannot be null"); user.setHashMethod(HashMethod.BCRYPT.name()) .setCryptedPassword(BCrypt.hashpw(password, BCrypt.gensalt(12))) .setSalt(null); } }
assertThat(dto.getHashMethod()).isEqualTo(HashMethod.BCRYPT.name()); assertThat(dto.getCryptedPassword()).isNotNull(); assertThat(dto.getCreatedAt())
@Test public void reactivate_user() { UserDto user = db.users().insertUser(u -> u.setActive(false)); createDefaultGroup(); underTest.reactivateAndCommit(db.getSession(), user, NewUser.builder() .setLogin("marius") .setName("Marius2") .setEmail("marius2@mail.com") .setPassword("password2") .build(), u -> { }); UserDto reloaded = dbClient.userDao().selectByUuid(session, user.getUuid()); assertThat(reloaded.isActive()).isTrue(); assertThat(reloaded.getLogin()).isEqualTo("marius"); assertThat(reloaded.getName()).isEqualTo("Marius2"); assertThat(reloaded.getEmail()).isEqualTo("marius2@mail.com"); assertThat(reloaded.getScmAccounts()).isNull(); assertThat(reloaded.isLocal()).isTrue(); assertThat(reloaded.getSalt()).isNull(); assertThat(reloaded.getHashMethod()).isEqualTo(HashMethod.BCRYPT.name()); assertThat(reloaded.getCryptedPassword()).isNotNull().isNotEqualTo("650d2261c98361e2f67f90ce5c65a95e7d8ea2fg"); assertThat(reloaded.getCreatedAt()).isEqualTo(user.getCreatedAt()); assertThat(reloaded.getUpdatedAt()).isGreaterThan(user.getCreatedAt()); }
@Test public void authentication_upgrade_hash_function_when_SHA1_was_used() { String password = randomAlphanumeric(60); byte[] saltRandom = new byte[20]; RANDOM.nextBytes(saltRandom); String salt = DigestUtils.sha1Hex(saltRandom); UserDto user = newUserDto() .setLogin("myself") .setHashMethod(SHA1.name()) .setCryptedPassword(DigestUtils.sha1Hex("--" + salt + "--" + password + "--")) .setSalt(salt); db.users().insertUser(user); underTest.authenticate(db.getSession(), user, password, AuthenticationEvent.Method.BASIC); Optional<UserDto> myself = db.users().selectUserByLogin("myself"); assertThat(myself).isPresent(); assertThat(myself.get().getHashMethod()).isEqualTo(BCRYPT.name()); assertThat(myself.get().getSalt()).isNull(); // authentication must work with upgraded hash method underTest.authenticate(db.getSession(), user, password, AuthenticationEvent.Method.BASIC); } }
@Test public void fail_to_authenticate_local_user_that_have_no_salt() { insertUser(newUserDto() .setLogin(LOGIN) .setCryptedPassword(ENCRYPTED_PASSWORD) .setSalt(null) .setHashMethod(CredentialsLocalAuthentication.HashMethod.SHA1.name()) .setLocal(true)); expectedException.expect(authenticationException().from(Source.local(BASIC_TOKEN)).withLogin(LOGIN).andNoPublicMessage()); expectedException.expectMessage("null salt"); try { executeAuthenticate(BASIC_TOKEN); } finally { verifyZeroInteractions(authenticationEvent); } }
@Test public void fail_to_authenticate_local_user_when_password_is_wrong() { insertUser(newUserDto() .setLogin(LOGIN) .setCryptedPassword("Wrong password") .setSalt("Wrong salt") .setHashMethod(CredentialsLocalAuthentication.HashMethod.SHA1.name()) .setLocal(true)); expectedException.expect(authenticationException().from(Source.local(BASIC)).withLogin(LOGIN).andNoPublicMessage()); expectedException.expectMessage("wrong password"); try { executeAuthenticate(BASIC); } finally { verifyZeroInteractions(authenticationEvent); } }
@Test public void fail_to_authenticate_local_user_that_have_no_password() { insertUser(newUserDto() .setLogin(LOGIN) .setCryptedPassword(null) .setSalt(SALT) .setHashMethod(CredentialsLocalAuthentication.HashMethod.SHA1.name()) .setLocal(true)); expectedException.expect(authenticationException().from(Source.local(BASIC)).withLogin(LOGIN).andNoPublicMessage()); expectedException.expectMessage("null password in DB"); try { executeAuthenticate(BASIC); } finally { verifyZeroInteractions(authenticationEvent); } }
@Test public void authentication_with_sha1_with_incorrect_password_should_throw_AuthenticationException() { String password = randomAlphanumeric(60); byte[] saltRandom = new byte[20]; RANDOM.nextBytes(saltRandom); String salt = DigestUtils.sha1Hex(saltRandom); UserDto user = newUserDto() .setHashMethod(SHA1.name()) .setCryptedPassword(DigestUtils.sha1Hex("--" + salt + "--" + password + "--")) .setSalt(salt); expectedException.expect(AuthenticationException.class); expectedException.expectMessage("wrong password"); underTest.authenticate(db.getSession(), user, "WHATEVER", AuthenticationEvent.Method.BASIC); }
@Test public void authentication_with_sha1_with_empty_password_should_throw_AuthenticationException() { byte[] saltRandom = new byte[20]; RANDOM.nextBytes(saltRandom); String salt = DigestUtils.sha1Hex(saltRandom); UserDto user = newUserDto() .setCryptedPassword(null) .setHashMethod(SHA1.name()) .setSalt(salt); expectedException.expect(AuthenticationException.class); expectedException.expectMessage("null password in DB"); underTest.authenticate(db.getSession(), user, "WHATEVER", AuthenticationEvent.Method.BASIC); }
@Test public void authenticate_local_user() { insertUser(newUserDto() .setLogin(LOGIN) .setCryptedPassword(ENCRYPTED_PASSWORD) .setHashMethod(CredentialsLocalAuthentication.HashMethod.SHA1.name()) .setSalt(SALT) .setLocal(true)); UserDto userDto = executeAuthenticate(BASIC); assertThat(userDto.getLogin()).isEqualTo(LOGIN); verify(authenticationEvent).loginSuccess(request, LOGIN, Source.local(BASIC)); }
@Test public void authentication_with_bcrypt_with_incorrect_password_should_throw_AuthenticationException() { String password = randomAlphanumeric(60); UserDto user = newUserDto() .setHashMethod(BCRYPT.name()) .setCryptedPassword(BCrypt.hashpw(password, BCrypt.gensalt(12))); expectedException.expect(AuthenticationException.class); expectedException.expectMessage("wrong password"); underTest.authenticate(db.getSession(), user, "WHATEVER", AuthenticationEvent.Method.BASIC); }
@Test public void authentication_with_sha1_with_correct_password_should_work() { String password = randomAlphanumeric(60); byte[] saltRandom = new byte[20]; RANDOM.nextBytes(saltRandom); String salt = DigestUtils.sha1Hex(saltRandom); UserDto user = newUserDto() .setHashMethod(SHA1.name()) .setCryptedPassword(DigestUtils.sha1Hex("--" + salt + "--" + password + "--")) .setSalt(salt); underTest.authenticate(db.getSession(), user, password, AuthenticationEvent.Method.BASIC); }
@Test public void authentication_with_bcrypt_with_correct_password_should_work() { String password = randomAlphanumeric(60); UserDto user = newUserDto() .setHashMethod(BCRYPT.name()) .setCryptedPassword(BCrypt.hashpw(password, BCrypt.gensalt(12))); underTest.authenticate(db.getSession(), user, password, AuthenticationEvent.Method.BASIC); }
@Test public void authentication_with_sha1_with_empty_salt_should_throw_AuthenticationException() { String password = randomAlphanumeric(60); UserDto user = newUserDto() .setHashMethod(SHA1.name()) .setCryptedPassword(DigestUtils.sha1Hex("--0242b0b4c0a93ddfe09dd886de50bc25ba000b51--" + password + "--")) .setSalt(null); expectedException.expect(AuthenticationException.class); expectedException.expectMessage("null salt"); underTest.authenticate(db.getSession(), user, "WHATEVER", AuthenticationEvent.Method.BASIC); }