[pwd] keep old passwords expired
authorAsier Lostalé <asier.lostale@openbravo.com>
Mon, 07 Oct 2019 13:21:15 +0200
changeset 36617 4e2c05b7b614
parent 36616 dee41e082133
child 36618 2e7550a9ae5e
[pwd] keep old passwords expired

When expired passwords hashed with the old algorithm were checked, they were
marked as not expired by DB trigger when password got updated.

To prevent this, do not promote password in case it is expired.
src-test/src/org/openbravo/authentication/hashing/PasswordHashing.java
src/org/openbravo/authentication/hashing/PasswordHash.java
--- a/src-test/src/org/openbravo/authentication/hashing/PasswordHashing.java	Wed Oct 02 14:56:58 2019 +0200
+++ b/src-test/src/org/openbravo/authentication/hashing/PasswordHashing.java	Mon Oct 07 13:21:15 2019 +0200
@@ -24,10 +24,10 @@
 import static org.hamcrest.Matchers.not;
 import static org.junit.Assert.assertThat;
 
+import java.util.Date;
 import java.util.Optional;
 
 import org.junit.Test;
-import org.openbravo.authentication.hashing.PasswordHash;
 import org.openbravo.dal.service.OBDal;
 import org.openbravo.model.ad.access.User;
 import org.openbravo.test.base.OBBaseTest;
@@ -122,4 +122,32 @@
     // then password gets promoted to new algorithm
     assertThat("password is not changed", user.get().getPassword(), is(SHA512SALT_OPENBRAVO));
   }
+
+  @Test
+  public void oldPasswordsCanBeExpired() {
+    try {
+      setSystemAdministratorContext();
+
+      // Given a user with an expired password hashed with old algorithm
+      User obUser = OBDal.getInstance().get(User.class, TestConstants.Users.OPENBRAVO);
+      obUser.setPassword(SHA1_OPENBRAVO);
+      obUser.setPasswordExpired(true);
+      OBDal.getInstance().flush();
+      OBDal.getInstance().refresh(obUser);
+      Date lastPasswordUpdate = obUser.getLastPasswordUpdate();
+
+      // when credentials are checked first time and password is automatically updated to new
+      // algorithm
+      Optional<User> opUser = PasswordHash.getUserWithPassword("Openbravo", "openbravo");
+      User user = opUser.get();
+      OBDal.getInstance().refresh(user);
+
+      // then password continues being expired
+      assertThat("Last password update timestamp didn't change", user.getLastPasswordUpdate(),
+          is(lastPasswordUpdate));
+      assertThat("Password is expired", user.isPasswordExpired(), is(true));
+    } finally {
+      OBDal.getInstance().rollbackAndClose();
+    }
+  }
 }
--- a/src/org/openbravo/authentication/hashing/PasswordHash.java	Wed Oct 02 14:56:58 2019 +0200
+++ b/src/org/openbravo/authentication/hashing/PasswordHash.java	Mon Oct 07 13:21:15 2019 +0200
@@ -91,7 +91,8 @@
         return Optional.empty();
       }
 
-      if (algorithm.getAlgorithmVersion() < DEFAULT_CURRENT_ALGORITHM_VERSION) {
+      if (algorithm.getAlgorithmVersion() < DEFAULT_CURRENT_ALGORITHM_VERSION
+          && !user.isPasswordExpired()) {
         log.debug("Upgrading password hash for user {}, from algorithm version {} to {}.",
             user.getUsername(), algorithm.getAlgorithmVersion(), DEFAULT_CURRENT_ALGORITHM_VERSION);
         String newPassword = ALGORITHMS.get(DEFAULT_CURRENT_ALGORITHM_VERSION)