/** * This method will generate a random string * * @return a secure random token. */ public static String getRandomToken() throws APIException { Random rng = new Random(); return encodeString(Long.toString(System.currentTimeMillis()) + Long.toString(rng.nextLong())); }
/** * Compare the given hash and the given string-to-hash to see if they are equal. The * string-to-hash is usually of the form password + salt. <br> * <br> * This should be used so that this class can compare against the new correct hashing algorithm * and the old incorrect hashing algorithm. * * @param hashedPassword a stored password that has been hashed previously * @param passwordToHash a string to encode/hash and compare to hashedPassword * @return true/false whether the two are equal * @since 1.5 * @should match strings hashed with incorrect sha1 algorithm * @should match strings hashed with sha1 algorithm * @should match strings hashed with sha512 algorithm and 128 characters salt */ public static boolean hashMatches(String hashedPassword, String passwordToHash) { if (hashedPassword == null || passwordToHash == null) { throw new APIException("password.cannot.be.null", (Object[]) null); } return hashedPassword.equals(encodeString(passwordToHash)) || hashedPassword.equals(encodeStringSHA1(passwordToHash)) || hashedPassword.equals(incorrectlyEncodeString(passwordToHash)); }
/** * @see org.openmrs.api.UserService#isSecretAnswer(User, java.lang.String) */ @Override public boolean isSecretAnswer(User u, String answer) throws DAOException { if (StringUtils.isEmpty(answer)) { return false; } LoginCredential credentials = getLoginCredential(u); String answerOnRecord = credentials.getSecretAnswer(); String hashedAnswer = Security.encodeString(answer.toLowerCase() + credentials.getSalt()); return (hashedAnswer.equals(answerOnRecord)); }
/** * @see org.openmrs.api.db.UserDAO#getLoginCredentialByActivationKey(java.lang.String) */ @Override public LoginCredential getLoginCredentialByActivationKey(String activationKey) { String key = Security.encodeString(activationKey); LoginCredential loginCred = (LoginCredential) sessionFactory.getCurrentSession().createCriteria(LoginCredential.class) .add(Restrictions.like("activationKey", key, MatchMode.START)).uniqueResult(); if(loginCred != null) { String[] credTokens = loginCred.getActivationKey().split(":"); if(credTokens[0].equals(key)){ return loginCred; } } return null; }
String answer = rs.getString("secret_answer"); String salt = rs.getString("salt"); String encryptedAnswer = Security.encodeString(answer.toLowerCase() + salt);
/** * @see org.openmrs.api.db.UserDAO#changePassword(org.openmrs.User, java.lang.String) */ @Override public void changePassword(User u, String pw) throws DAOException { User authUser = Context.getAuthenticatedUser(); if (authUser == null) { authUser = u; } log.debug("updating password"); //update the user with the new password String salt = getLoginCredential(u).getSalt(); String newHashedPassword = Security.encodeString(pw + salt); updateUserPassword(newHashedPassword, salt, authUser.getUserId(), new Date(), u.getUserId()); }
/** * @see Security#encodeString(String) */ @Test public void encodeString_shouldEncodeStringsTo128Characters() { String hash = Security.encodeString("test" + "c788c6ad82a157b712392ca695dfcf2eed193d7f"); Assert.assertEquals(HASH_LENGTH, hash.length()); }
/** * @see org.openmrs.api.UserService#changeQuestionAnswer(User, String, String) */ @Override public void changeQuestionAnswer(User u, String question, String answer) throws DAOException { log.info("Updating secret question and answer for " + u.getUsername()); LoginCredential credentials = getLoginCredential(u); credentials.setSecretQuestion(question); String hashedAnswer = Security.encodeString(answer.toLowerCase() + credentials.getSalt()); credentials.setSecretAnswer(hashedAnswer); credentials.setDateChanged(new Date()); credentials.setChangedBy(u); updateLoginCredential(credentials); }
/** * @see org.openmrs.api.UserService#saveUser(org.openmrs.User, java.lang.String) */ @Override public User saveUser(User user, String password) { // only change the user's password when creating a new user boolean isNewUser = user.getUserId() == null; sessionFactory.getCurrentSession().saveOrUpdate(user); if (isNewUser && password != null) { //update the new user with the password String salt = Security.getRandomToken(); String hashedPassword = Security.encodeString(password + salt); updateUserPassword(hashedPassword, salt, Context.getAuthenticatedUser().getUserId(), new Date(), user .getUserId()); } return user; }
/** * @see org.openmrs.api.UserService#changePassword(java.lang.String, java.lang.String) */ @Override public void changePassword(String pw, String pw2) throws DAOException { User u = Context.getAuthenticatedUser(); LoginCredential credentials = getLoginCredential(u); if (!credentials.checkPassword(pw)) { log.error("Passwords don't match"); throw new DAOException("Passwords don't match"); } log.info("updating password for " + u.getUsername()); // update the user with the new password String salt = getLoginCredential(u).getSalt(); String newHashedPassword = Security.encodeString(pw2 + salt); updateUserPassword(newHashedPassword, salt, u.getUserId(), new Date(), u.getUserId()); }
/** * @see Security#encodeString(String) */ @Test public void encodeString_shouldEncodeStringsToXCharactersWithXCharactersSalt() { String hash = Security.encodeString("test" + Security.getRandomToken()); Assert.assertEquals(HASH_LENGTH, hash.length()); }
/** * @throws APIException * @throws MessageException * @see org.openmrs.api.UserService#setUserActivationKey(org.openmrs.User) */ @Override public User setUserActivationKey(User user) throws MessageException { String token = RandomStringUtils.randomAlphanumeric(20); long time = System.currentTimeMillis() + getValidTime(); String hashedKey = Security.encodeString(token); String activationKey = hashedKey + ":" + time; LoginCredential credentials = dao.getLoginCredential(user); credentials.setActivationKey(activationKey); dao.setUserActivationKey(credentials); MessageSourceService messages = Context.getMessageSourceService(); AdministrationService adminService = Context.getAdministrationService(); String link = adminService.getGlobalProperty(OpenmrsConstants.GP_HOST_URL) .replace("{activationKey}", token); String msg = messages.getMessage("mail.passwordreset.content").replace("{name}", user.getUsername()) .replace("{link}", link) .replace("{time}", String.valueOf(getValidTime() / 60000)); Context.getMessageService().sendMessage(user.getEmail(), adminService.getGlobalProperty("mail.from"), messages.getMessage("mail.passwordreset.subject"), msg); return user; }
/** * @see UserService#changeHashedPassword(User,String,String) */ @Test public void changeHashedPassword_shouldChangeTheHashedPasswordForTheGivenUser() { User user = userService.getUser(1); String salt = Security.getRandomToken(); String hash = Security.encodeString("new password" + salt); userService.changeHashedPassword(user, hash, salt); // TODO Review this a little further // This is the assert - checks to see if current user can use the new password userService.changePassword("new password", "Another new password1"); // try to change the password with the new one }
@Test public void updateUserPassword_shouldNotOverwriteUserSecretQuestionOrAnswer() { dao.changePassword(userJoe, PASSWORD); dao.changeQuestionAnswer(userJoe, SECRET_QUESTION, SECRET_ANSWER); LoginCredential lc = dao.getLoginCredential(userJoe); String hashedSecretAnswer = Security.encodeString(SECRET_ANSWER + lc.getSalt()); assertEquals("question should be set", SECRET_QUESTION, lc.getSecretQuestion()); assertEquals("answer should be set", hashedSecretAnswer, lc.getSecretAnswer()); dao.changePassword(userJoe, "Openmr6zz"); lc = dao.getLoginCredential(userJoe); assertEquals("question should not have changed", SECRET_QUESTION, lc.getSecretQuestion()); assertEquals("answer should not have changed", hashedSecretAnswer, lc.getSecretAnswer()); }
@Test public void saveUser_shouldNotOverwriteUserSecretQuestionOrAnswer() { dao.saveUser(userJoe, PASSWORD); dao.changeQuestionAnswer(userJoe, SECRET_QUESTION, SECRET_ANSWER); LoginCredential lc = dao.getLoginCredential(userJoe); String hashedSecretAnswer = Security.encodeString(SECRET_ANSWER + lc.getSalt()); assertEquals("question should be set", SECRET_QUESTION, lc.getSecretQuestion()); assertEquals("answer should be set", hashedSecretAnswer, lc.getSecretAnswer()); userJoe.setUserProperty("foo", "bar"); dao.saveUser(userJoe, PASSWORD); lc = dao.getLoginCredential(userJoe); assertEquals("question should not have changed", SECRET_QUESTION, lc.getSecretQuestion()); assertEquals("answer should not have changed", hashedSecretAnswer, lc.getSecretAnswer()); }
@Test public void changeHashedPassword_shouldNotOverwriteUserSecretQuestionOrAnswer() { dao.changePassword(userJoe, PASSWORD); dao.changeQuestionAnswer(userJoe, SECRET_QUESTION, SECRET_ANSWER); LoginCredential lc = dao.getLoginCredential(userJoe); String hashedSecretAnswer = Security.encodeString(SECRET_ANSWER + lc.getSalt()); assertEquals("question should be set", SECRET_QUESTION, lc.getSecretQuestion()); assertEquals("answer should be set", hashedSecretAnswer, lc.getSecretAnswer()); userJoe.setUserProperty("foo", "bar"); dao.changeHashedPassword(userJoe, "VakesJkw1", Security.getRandomToken()); lc = dao.getLoginCredential(userJoe); assertEquals("question should not have changed", SECRET_QUESTION, lc.getSecretQuestion()); assertEquals("answer should not have changed", hashedSecretAnswer, lc.getSecretAnswer()); }
@Test public void changePassword_shouldNotOverwriteUserSecretQuestionOrAnswer() { dao.changePassword(userJoe, PASSWORD); dao.changeQuestionAnswer(userJoe, SECRET_QUESTION, SECRET_ANSWER); LoginCredential lc = dao.getLoginCredential(userJoe); String hashedSecretAnswer = Security.encodeString(SECRET_ANSWER + lc.getSalt()); assertEquals("question should be set", SECRET_QUESTION, lc.getSecretQuestion()); assertEquals("answer should be set", hashedSecretAnswer, lc.getSecretAnswer()); Context.authenticate(userJoe.getUsername(), PASSWORD); dao.changePassword(PASSWORD, PASSWORD + "foo"); lc = dao.getLoginCredential(userJoe); assertEquals("question should not have changed", SECRET_QUESTION, lc.getSecretQuestion()); assertEquals("answer should not have changed", hashedSecretAnswer, lc.getSecretAnswer()); }