/** * ============================================================================= * * ORCID (R) Open Source * http://orcid.org * * Copyright (c) 2012-2014 ORCID, Inc. * Licensed under an MIT-Style License (MIT) * http://orcid.org/open-source-license * * This copyright and license information (including a link to the full license) * shall be included in its entirety in all copies or substantial portion of * the software. * * ============================================================================= */ package org.orcid.core.manager.impl; import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.RandomStringUtils; import org.orcid.core.manager.PasswordGenerationManager; import org.orcid.password.constants.OrcidPasswordConstants; /** * Class to randomly generate a password of given length and that satisfies the rules for the Orcid password policy * @author jamesb * */ public class PasswordGenerationManagerImpl implements PasswordGenerationManager { private int passwordLength; private static final int NUM_PRESET_CHARS = 3; public PasswordGenerationManagerImpl(int passwordLength) { super(); this.passwordLength = passwordLength; } public int getPasswordLength() { return passwordLength; } public void setPasswordLength(int passwordLength) { this.passwordLength = passwordLength; } @Override public char[] createNewPassword() { // must contain at least 12 chars char[] presetChars = new char[NUM_PRESET_CHARS]; // one each of symbol, character and number presetChars[0] = randomSymbol(); presetChars[1] = randomNumber(); presetChars[2] = randomCharacter(); //rest are also random but from any of the classes char[] mixedCharacterClasses = RandomStringUtils.random(passwordLength - NUM_PRESET_CHARS, OrcidPasswordConstants.getEntirePasswordCharsRange()).toCharArray(); // shuffle the string so that the pattern of first 3 chars // doesn't become predictable return shuffleChar(ArrayUtils.addAll(mixedCharacterClasses, presetChars)); } private char randomSymbol() { return RandomStringUtils.random(1, OrcidPasswordConstants.UNESCAPED_SYMBOL_RANGE).charAt(0); } private char randomNumber() { return RandomStringUtils.random(1, OrcidPasswordConstants.CHAR_CLASS_NUMBERS).charAt(0); } private char randomCharacter() { return RandomStringUtils.random(1, OrcidPasswordConstants.LOWERCASE_ALPHABET).charAt(0); } private char[] shuffleChar(char[] randomChars) { for (int i = randomChars.length; i > 1; i--) { char temp = randomChars[i - 1]; int randIx = (int) (Math.random() * i); randomChars[i - 1] = randomChars[randIx]; randomChars[randIx] = temp; } return randomChars; } }