/* * Copyright (c) 2014 EMC Corporation * All Rights Reserved */ package com.emc.storageos.security.password; import com.emc.storageos.db.client.model.PasswordHistory; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.text.MessageFormat; import java.util.*; public class Password { private static final Logger _log = LoggerFactory.getLogger(Password.class); private String username; private String password; private String oldPassword; private PasswordHistory passwordHistory; private final static String specialCharacters = "~!@#$%^&*()-_+=,<.>?/`;:'\"{}[] "; private List<CharInString> alphabetic = new ArrayList<CharInString>(); private List<CharInString> numeric = new ArrayList<CharInString>(); private List<CharInString> lowercase = new ArrayList<CharInString>(); private List<CharInString> uppercase = new ArrayList<CharInString>(); private List<CharInString> special = new ArrayList<CharInString>(); private List<CharInString> others = new ArrayList<CharInString>(); public Password(String password) { this(null, password); } public Password(String oldPassword, String password) { this(null, oldPassword, password); } public PasswordHistory getPasswordHistory() { return passwordHistory; } public void setPasswordHistory(PasswordHistory passwordHistory) { this.passwordHistory = passwordHistory; } public Password(String username, String oldPassword, String password) { this.username = username; this.oldPassword = oldPassword; this.password = password; analysePassword(); } public String getUsername() { return username; } public String getOldPassword() { return oldPassword; } public String getPassword() { return password; } private void analysePassword() { if (password == null) { return; } for (int i = 0; i < password.length(); i++) { char c = password.charAt(i); CharInString charInString = new CharInString(i, c); if (Character.isDigit(c)) { numeric.add(charInString); } else if (Character.isLetter(c)) { alphabetic.add(charInString); if (Character.isUpperCase(c)) { uppercase.add(charInString); } else if (Character.isLowerCase(c)) { lowercase.add(charInString); } } else if (specialCharacters.indexOf(c) != -1) { special.add(charInString); } else { others.add(charInString); } } } private class CharInString { private int index; private char character; CharInString(int index, char character) { this.index = index; this.character = character; } int getIndex() { return index; } char getCharacter() { return character; } } /** * Returns the number of digits in this password. * * @return number of digits in the password */ public int getNumberOfDigits() { return numeric.size(); } /** * Returns the number of alphabetical characters in this password. * * @return number of alphabetical characters in this password */ public int getNumberOfAlphabets() { return alphabetic.size(); } /** * Returns the number of uppercase characters in this password. * * @return number of uppercase characters in this password */ public int getNumberOfUppercase() { return uppercase.size(); } /** * Returns the number of lowercase characters in this password. * * @return number of lowercase characters in this password */ public int getNumberOfLowercase() { return lowercase.size(); } /** * Returns the number of speical characters in this password. * * @return number of whitespace characters in this password */ public int getNumberOfSpeicial() { return special.size(); } public long getLatestChangedTime() { List<Map.Entry<String, Long>> l = getSortedPasswordByTime(); if (l != null && !l.isEmpty()) { return l.get(0).getValue(); } else { return 0; } } public List<String> getPreviousPasswords(int number) { List<String> passwords = new ArrayList<String>(); List<Map.Entry<String, Long>> l = getSortedPasswordByTime(); if (l == null) { return passwords; } int length = Math.min(number, l.size()); for (int i = 0; i < length; i++) { passwords.add(l.get(i).getKey()); _log.info(MessageFormat.format("password {0} modify time: {1}", i, l.get(i).getValue())); } return passwords; } private List<Map.Entry<String, Long>> getSortedPasswordByTime() { PasswordHistory lph = getPasswordHistory(); if (lph == null || lph.getUserPasswordHash() == null) { return null; } ArrayList<Map.Entry<String, Long>> list = new ArrayList<Map.Entry<String, Long>>(lph.getUserPasswordHash().entrySet()); Collections.sort(list, new Comparator<Map.Entry<String, Long>>() { public int compare(Map.Entry<String, Long> o1, Map.Entry<String, Long> o2) { // for fixing CTRL-10305, it should NOT use intValue() of a long, as it may get overflow. if (o2.getValue() == o1.getValue()) { return 0; } else if (o2.getValue() > o1.getValue()) { return 1; } else { return -1; } } }); return list; } }