vt-middleware / passay

Password policy enforcement for Java.
http://www.passay.org
Other
277 stars 63 forks source link

Consider adding validation rule displayable hint messages #99

Open jnorvell opened 5 years ago

jnorvell commented 5 years ago

Similar map of messages, one for each rule, that could be obtained from a PasswordValidator instance for the configured rules. The expected use would be to display to a user before validation, for the rules actually configured.

exampless: INSUFFICIENT_LOWERCASE=At least %1$s uppercase characters INSUFFICIENT_SPECIAL=At least %1$s special character (ex. @%$#& etc.) TOO_SHORT=At least %1$s characters in length TOO_LONG=No more than %1$s characters in length

Map<String,String> hintMap = validator.getRuleHints();

jamesrgrinter commented 3 years ago

I have implemented some variation of this atop the library, as part of making it possible to construct a password policy from a configuration and then serialize it into a more structured representation (so I assembled a list of these messages though I haven't yet made it possible to configure them or integrated it with the library code itself)

This is what I came up with, anyway:

AllowedCharacterRule:
 Password must %s only characters from '%s'  [getMatchBehavior(), getAllowedCharacters()]

AllowedRegexRule:
 Password must match the pattern '%s'  [getPattern()]

CharacterCharacteristicsRule:
 Password must match %d of: [getNumberOfCharacteristics()] + the list of CharacterRule descriptions

CharacterRule:
 Password must contain %d %s character%s [getNumberOfCharacters(), getCharacterData(), plural(getNumberOfCharacters())]

CharacterOccurrencesRule:
 Password must contain at most %d of any character [getMaxOccurrences()]

DictionaryRule:
 Password must not be in the proscribed list

DictionarySubstringRule:
 Password must not contain a word in the proscribed list

IllegalCharacterRule:
 Password must not %s any of '%s' [getMatchBehavior(), getIllegalCharacters()]

IllegalRegexRule:
 Password must not match the pattern '%s' [getPattern()]

IllegalSequenceRule:
 Password must not contain %s sequence [getSequenceData()]

LengthComplexityRule:
 Password must:

 (Interval Entry):
 If %s characters [getInterval()] + the list of individual entry Rule descriptions

LengthRule:
 Password must be %d characters in length [getMinimumLength()]

LengthRule:
 Password must be between %d and %d characters in length [getMinimumLength(), getMaximumLength()]

NumberRangeRule:
 Password must not %s a number in the range %d to %d [getMatchBehavior(), getLowerRange(), getUpperRange()]

RepeatCharacterRegexRule:
 Password must not contain more than %d repeated characters [getSequenceLength()]

RepeatCharactersRule:
 Password must not contain more than %d sets of %d or more repeated characters [getSequenceCount(), getSequenceLength()]

UsernameRule:
 Password must not %s your username [getMatchBehavior()]

WhitespaceRule:
 Password must not %s whitespace  [getMatchBehavior()]

(I didn't make any attempt to include 'wrap' or 'backwards' behaviours in the descriptions so far.)

Per above, it also requires some transformation of MatchBehavior, CharacterData, and SequenceData into a natural language form, and a string representation of an Interval. It would also benefit from a "user-intelligible" description of a Regex Pattern.

Maybe that will help someone take the idea further.