strolch/privilege/src/main/java/li/strolch/privilege/handler/BasicPasswordStrengthHandle...

102 lines
3.3 KiB
Java

package li.strolch.privilege.handler;
import static java.lang.Boolean.parseBoolean;
import static java.lang.Integer.parseInt;
import static li.strolch.privilege.i18n.PrivilegeMessages.getString;
import java.text.MessageFormat;
import java.util.Locale;
import java.util.Map;
public class BasicPasswordStrengthHandler implements PasswordStrengthHandler {
protected int minLength;
protected int maxLength;
protected boolean needsNumbers;
protected boolean needsLowerCase;
protected boolean needsUpperCase;
protected boolean needsSpecialChars;
@Override
public void initialize(Map<String, String> parameterMap) {
this.minLength = parseInt(parameterMap.getOrDefault("minLength", "8"));
this.maxLength = parseInt(parameterMap.getOrDefault("maxLength", String.valueOf(1024)));
this.needsNumbers = parseBoolean(parameterMap.getOrDefault("needsNumbers", "true"));
this.needsLowerCase = parseBoolean(parameterMap.getOrDefault("needsLowerCase", "true"));
this.needsUpperCase = parseBoolean(parameterMap.getOrDefault("needsUpperCase", "true"));
this.needsSpecialChars = parseBoolean(parameterMap.getOrDefault("needsSpecialChars", "false"));
if (this.minLength < 8)
throw new IllegalStateException("minLength can not be less than 8");
if (this.maxLength > 1024)
throw new IllegalStateException("maxLength can not be greater than 1024");
}
@Override
public String getDescription(Locale locale) {
String description;
if (this.maxLength < 100)
description = MessageFormat.format(getString(locale, "Privilege.passwordLengthBetween"), this.minLength,
this.maxLength);
else
description = MessageFormat.format(getString(locale, "Privilege.passwordLengthAtLeast"), this.minLength);
if (this.needsNumbers)
description += ", " + getString(locale, "Privilege.passwordMustContainNumbers");
if (this.needsLowerCase && this.needsUpperCase)
description += ", " + getString(locale, "Privilege.passwordMustContainLowerAndUpperCase");
else if (this.needsLowerCase)
description += ", " + getString(locale, "Privilege.passwordMustContainLowerCase");
else
description += ", " + getString(locale, "Privilege.passwordMustContainUpperCase");
if (this.needsSpecialChars)
description += ", " + getString(locale, "Privilege.passwordMustContainSpecialCharacters");
return description;
}
@Override
public boolean validateStrength(char[] password) {
if (password.length < this.minLength || password.length > this.maxLength)
return false;
boolean numbersOk = !this.needsNumbers;
boolean lowerCaseOk = !this.needsLowerCase;
boolean upperCaseOk = !this.needsUpperCase;
boolean specialCharsOk = !this.needsSpecialChars;
for (char c : password) {
if (numbersOk && lowerCaseOk && upperCaseOk && specialCharsOk)
return true;
if (!numbersOk && Character.isDigit(c)) {
numbersOk = true;
continue;
}
if (!lowerCaseOk && Character.isLowerCase(c)) {
lowerCaseOk = true;
continue;
}
if (!upperCaseOk && Character.isUpperCase(c)) {
upperCaseOk = true;
continue;
}
if (!specialCharsOk && isSpecial(c))
specialCharsOk = true;
}
return numbersOk && lowerCaseOk && upperCaseOk && specialCharsOk;
}
public static boolean isSpecial(char c) {
return !(Character.isDigit(c) || Character.isLowerCase(c) || Character.isUpperCase(c));
}
}