BAEL-2165 (#5317)
* BAEL-2165: Guide to Passay * BAEL-2165: Guide to Passay #2 * BAEL-2165: Guide to Passay #3 Fixed formatting.
This commit is contained in:
parent
51914a01e1
commit
56c2b9663e
|
@ -38,6 +38,16 @@
|
|||
<version>${junit.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.passay</groupId>
|
||||
<artifactId>passay</artifactId>
|
||||
<version>1.3.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.cryptacular</groupId>
|
||||
<artifactId>cryptacular</artifactId>
|
||||
<version>1.2.2</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
|
|
|
@ -0,0 +1,149 @@
|
|||
package com.baeldung.passay;
|
||||
|
||||
import org.cryptacular.bean.EncodingHashBean;
|
||||
import org.cryptacular.spec.CodecSpec;
|
||||
import org.cryptacular.spec.DigestSpec;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.passay.DictionaryRule;
|
||||
import org.passay.DictionarySubstringRule;
|
||||
import org.passay.DigestHistoryRule;
|
||||
import org.passay.EnglishSequenceData;
|
||||
import org.passay.HistoryRule;
|
||||
import org.passay.IllegalCharacterRule;
|
||||
import org.passay.IllegalRegexRule;
|
||||
import org.passay.IllegalSequenceRule;
|
||||
import org.passay.NumberRangeRule;
|
||||
import org.passay.PasswordData;
|
||||
import org.passay.PasswordValidator;
|
||||
import org.passay.RepeatCharacterRegexRule;
|
||||
import org.passay.RuleResult;
|
||||
import org.passay.SourceRule;
|
||||
import org.passay.UsernameRule;
|
||||
import org.passay.WhitespaceRule;
|
||||
import org.passay.dictionary.ArrayWordList;
|
||||
import org.passay.dictionary.WordListDictionary;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
|
||||
public class NegativeMatchingRulesUnitTest {
|
||||
|
||||
@Test
|
||||
public void givenDictionaryRules_whenValidatePassword_thenFoundIllegalWordsFromDictionary() {
|
||||
ArrayWordList arrayWordList = new ArrayWordList(new String[] { "bar", "foobar" });
|
||||
|
||||
WordListDictionary wordListDictionary = new WordListDictionary(arrayWordList);
|
||||
|
||||
DictionaryRule dictionaryRule = new DictionaryRule(wordListDictionary);
|
||||
DictionarySubstringRule dictionarySubstringRule = new DictionarySubstringRule(wordListDictionary);
|
||||
|
||||
PasswordValidator passwordValidator = new PasswordValidator(dictionaryRule, dictionarySubstringRule);
|
||||
RuleResult validate = passwordValidator.validate(new PasswordData("foobar"));
|
||||
|
||||
assertFalse(validate.isValid());
|
||||
assertEquals("ILLEGAL_WORD:{matchingWord=foobar}", getDetail(validate, 0));
|
||||
assertEquals("ILLEGAL_WORD:{matchingWord=bar}", getDetail(validate, 1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenHistoryRule_whenValidatePassword_thenFoundIllegalWordsFromHistory() {
|
||||
HistoryRule historyRule = new HistoryRule();
|
||||
|
||||
PasswordData passwordData = new PasswordData("123");
|
||||
passwordData.setPasswordReferences(new PasswordData.HistoricalReference("12345"), new PasswordData.HistoricalReference("1234"), new PasswordData.HistoricalReference("123"));
|
||||
|
||||
PasswordValidator passwordValidator = new PasswordValidator(historyRule);
|
||||
|
||||
RuleResult validate = passwordValidator.validate(passwordData);
|
||||
|
||||
assertFalse(validate.isValid());
|
||||
assertEquals("HISTORY_VIOLATION:{historySize=3}", getDetail(validate, 0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenSeveralIllegalRules_whenValidatePassword_thenFoundSeveralIllegalPatterns() {
|
||||
IllegalCharacterRule illegalCharacterRule = new IllegalCharacterRule(new char[] { 'a' });
|
||||
IllegalRegexRule illegalRegexRule = new IllegalRegexRule("\\w{2}\\d{2}");
|
||||
IllegalSequenceRule illegalSequenceRule = new IllegalSequenceRule(EnglishSequenceData.Alphabetical, 3, true);
|
||||
NumberRangeRule numberRangeRule = new NumberRangeRule(1, 10);
|
||||
WhitespaceRule whitespaceRule = new WhitespaceRule();
|
||||
|
||||
PasswordValidator passwordValidator = new PasswordValidator(illegalCharacterRule, illegalRegexRule, illegalSequenceRule, numberRangeRule, whitespaceRule);
|
||||
|
||||
RuleResult validate = passwordValidator.validate(new PasswordData("abcd22 "));
|
||||
|
||||
assertFalse(validate.isValid());
|
||||
assertEquals("ILLEGAL_CHAR:{illegalCharacter=a, matchBehavior=contains}", getDetail(validate, 0));
|
||||
assertEquals("ILLEGAL_MATCH:{match=cd22, pattern=\\w{2}\\d{2}}", getDetail(validate, 1));
|
||||
assertEquals("ILLEGAL_ALPHABETICAL_SEQUENCE:{sequence=abc}", getDetail(validate, 2));
|
||||
assertEquals("ILLEGAL_ALPHABETICAL_SEQUENCE:{sequence=bcd}", getDetail(validate, 3));
|
||||
assertEquals("ILLEGAL_NUMBER_RANGE:{number=2, matchBehavior=contains}", getDetail(validate, 4));
|
||||
assertEquals("ILLEGAL_WHITESPACE:{whitespaceCharacter= , matchBehavior=contains}", getDetail(validate, 5));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenSourceRule_whenValidatePassword_thenFoundIllegalWordsFromSource() {
|
||||
SourceRule sourceRule = new SourceRule();
|
||||
|
||||
PasswordData passwordData = new PasswordData("password");
|
||||
passwordData.setPasswordReferences(new PasswordData.SourceReference("source", "password"));
|
||||
|
||||
PasswordValidator passwordValidator = new PasswordValidator(sourceRule);
|
||||
RuleResult validate = passwordValidator.validate(passwordData);
|
||||
|
||||
assertFalse(validate.isValid());
|
||||
assertEquals("SOURCE_VIOLATION:{source=source}", getDetail(validate, 0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenRepeatCharacterRegexRuleRule_whenValidatePassword_thenFoundIllegalPatternMatches() {
|
||||
RepeatCharacterRegexRule repeatCharacterRegexRule = new RepeatCharacterRegexRule(3);
|
||||
|
||||
PasswordValidator passwordValidator = new PasswordValidator(repeatCharacterRegexRule);
|
||||
|
||||
RuleResult validate = passwordValidator.validate(new PasswordData("aaabbb"));
|
||||
|
||||
assertFalse(validate.isValid());
|
||||
assertEquals("ILLEGAL_MATCH:{match=aaa, pattern=([^\\x00-\\x1F])\\1{2}}", getDetail(validate, 0));
|
||||
assertEquals("ILLEGAL_MATCH:{match=bbb, pattern=([^\\x00-\\x1F])\\1{2}}", getDetail(validate, 1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenUserNameRule_whenValidatePassword_thenFoundUserNameInPassword() {
|
||||
PasswordValidator passwordValidator = new PasswordValidator(new UsernameRule());
|
||||
|
||||
PasswordData passwordData = new PasswordData("testuser1234");
|
||||
passwordData.setUsername("testuser");
|
||||
|
||||
RuleResult validate = passwordValidator.validate(passwordData);
|
||||
|
||||
assertFalse(validate.isValid());
|
||||
assertEquals("ILLEGAL_USERNAME:{username=testuser, matchBehavior=contains}", getDetail(validate, 0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenPasswordAndHashBeanAndEncryptedReferences_whenValidate_thenPasswordValidationShouldPass() {
|
||||
List<PasswordData.Reference> historicalReferences = Arrays.asList(new PasswordData.HistoricalReference("SHA256", "2e4551de804e27aacf20f9df5be3e8cd384ed64488b21ab079fb58e8c90068ab"));
|
||||
PasswordData passwordData = new PasswordData("example!");
|
||||
passwordData.setPasswordReferences(historicalReferences);
|
||||
|
||||
EncodingHashBean encodingHashBean = new EncodingHashBean(new CodecSpec("Base64"), new DigestSpec("SHA256"), 1, false);
|
||||
|
||||
PasswordValidator passwordValidator = new PasswordValidator(new DigestHistoryRule(encodingHashBean));
|
||||
|
||||
RuleResult validate = passwordValidator.validate(passwordData);
|
||||
|
||||
Assert.assertTrue(validate.isValid());
|
||||
}
|
||||
|
||||
private String getDetail(RuleResult validate, int i) {
|
||||
return validate.getDetails()
|
||||
.get(i)
|
||||
.toString();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
package com.baeldung.passay;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.passay.CharacterData;
|
||||
import org.passay.CharacterRule;
|
||||
import org.passay.EnglishCharacterData;
|
||||
import org.passay.PasswordGenerator;
|
||||
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class PasswordGeneratorUnitTest {
|
||||
|
||||
@Test
|
||||
public void givenDigitsGenerator_whenGeneratingPassword_thenPasswordContainsDigitsHasLength10() {
|
||||
CharacterRule digits = new CharacterRule(EnglishCharacterData.Digit);
|
||||
|
||||
PasswordGenerator passwordGenerator = new PasswordGenerator();
|
||||
String password = passwordGenerator.generatePassword(10, digits);
|
||||
|
||||
Assert.assertTrue(password.length() == 10);
|
||||
Assert.assertTrue(containsOnlyCharactersFromSet(password, "0123456789"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenCustomizedRule_whenGenerating_thenGeneratedPasswordContainsCustomizedCharacters() {
|
||||
CharacterRule specialCharacterRule = new CharacterRule(new CharacterData() {
|
||||
@Override
|
||||
public String getErrorCode() {
|
||||
return "SAMPLE_ERROR_CODE";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCharacters() {
|
||||
return "ABCxyz123!@#";
|
||||
}
|
||||
});
|
||||
|
||||
PasswordGenerator passwordGenerator = new PasswordGenerator();
|
||||
String password = passwordGenerator.generatePassword(10, specialCharacterRule);
|
||||
|
||||
Assert.assertTrue(containsOnlyCharactersFromSet(password, "ABCxyz123!@#"));
|
||||
}
|
||||
|
||||
private boolean containsOnlyCharactersFromSet(String password, String setOfCharacters) {
|
||||
return Stream.of(password.split(""))
|
||||
.allMatch(it -> setOfCharacters.contains(it));
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,81 @@
|
|||
package com.baeldung.passay;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.passay.LengthRule;
|
||||
import org.passay.MessageResolver;
|
||||
import org.passay.PasswordData;
|
||||
import org.passay.PasswordValidator;
|
||||
import org.passay.PropertiesMessageResolver;
|
||||
import org.passay.RuleResult;
|
||||
import org.passay.RuleResultDetail;
|
||||
import org.passay.RuleResultMetadata;
|
||||
import org.passay.WhitespaceRule;
|
||||
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.util.Properties;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
|
||||
public class PasswordValidatorUnitTest {
|
||||
|
||||
@Test
|
||||
public void givenPasswordValidatorWithLengthRule_whenValidation_thenTooShortPassword() {
|
||||
PasswordData passwordData = new PasswordData("1234");
|
||||
|
||||
PasswordValidator passwordValidator = new PasswordValidator(new LengthRule(5));
|
||||
|
||||
RuleResult validate = passwordValidator.validate(passwordData);
|
||||
assertEquals(false, validate.isValid());
|
||||
|
||||
RuleResultDetail ruleResultDetail = validate.getDetails()
|
||||
.get(0);
|
||||
assertEquals("TOO_SHORT", ruleResultDetail.getErrorCode());
|
||||
assertEquals(5, ruleResultDetail.getParameters()
|
||||
.get("minimumLength"));
|
||||
assertEquals(5, ruleResultDetail.getParameters()
|
||||
.get("maximumLength"));
|
||||
|
||||
Integer lengthCount = validate.getMetadata()
|
||||
.getCounts()
|
||||
.get(RuleResultMetadata.CountCategory.Length);
|
||||
assertEquals(Integer.valueOf(4), lengthCount);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenPasswordValidatorWithLengthRule_whenValidation_thenTooLongPassword() {
|
||||
PasswordData passwordData = new PasswordData("123456");
|
||||
|
||||
PasswordValidator passwordValidator = new PasswordValidator(new LengthRule(5));
|
||||
|
||||
RuleResult validate = passwordValidator.validate(passwordData);
|
||||
assertFalse(validate.isValid());
|
||||
Assert.assertEquals("TOO_LONG", validate.getDetails()
|
||||
.get(0)
|
||||
.getErrorCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenPasswordValidatorWithLengthRule_whenValidation_thenCustomizedMeesagesAvailable() throws IOException {
|
||||
URL resource = this.getClass()
|
||||
.getClassLoader()
|
||||
.getResource("messages.properties");
|
||||
Properties props = new Properties();
|
||||
props.load(new FileInputStream(resource.getPath()));
|
||||
|
||||
MessageResolver resolver = new PropertiesMessageResolver(props);
|
||||
PasswordValidator validator = new PasswordValidator(resolver, new LengthRule(8, 16), new WhitespaceRule());
|
||||
|
||||
RuleResult tooShort = validator.validate(new PasswordData("XXXX"));
|
||||
RuleResult tooLong = validator.validate(new PasswordData("ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"));
|
||||
|
||||
assertEquals("Password must not contain less characters than 16.", validator.getMessages(tooShort)
|
||||
.get(0));
|
||||
assertEquals("Password must not have more characters than 16.", validator.getMessages(tooLong)
|
||||
.get(0));
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,76 @@
|
|||
package com.baeldung.passay;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.passay.AllowedCharacterRule;
|
||||
import org.passay.AllowedRegexRule;
|
||||
import org.passay.CharacterCharacteristicsRule;
|
||||
import org.passay.CharacterRule;
|
||||
import org.passay.EnglishCharacterData;
|
||||
import org.passay.LengthComplexityRule;
|
||||
import org.passay.LengthRule;
|
||||
import org.passay.PasswordData;
|
||||
import org.passay.PasswordValidator;
|
||||
import org.passay.RuleResult;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
public class PositiveMatchingRulesUnitTest {
|
||||
|
||||
@Test
|
||||
public void givenPasswordValidationRules_whenValidatingPassword_thenPosswordIsNotValidWithSeveralErrors() {
|
||||
PasswordValidator passwordValidator = new PasswordValidator(new AllowedCharacterRule(new char[] { 'a', 'b', 'c' }), new AllowedRegexRule("\\d{2}\\w{10}"), new CharacterRule(EnglishCharacterData.LowerCase, 5), new LengthRule(8, 10));
|
||||
|
||||
RuleResult validate = passwordValidator.validate(new PasswordData("12abc"));
|
||||
|
||||
assertFalse(validate.isValid());
|
||||
assertEquals("ALLOWED_CHAR:{illegalCharacter=1, matchBehavior=contains}", getDetail(validate, 0));
|
||||
assertEquals("ALLOWED_CHAR:{illegalCharacter=2, matchBehavior=contains}", getDetail(validate, 1));
|
||||
assertEquals("ALLOWED_MATCH:{pattern=\\d{2}\\w{10}}", getDetail(validate, 2));
|
||||
assertEquals("INSUFFICIENT_LOWERCASE:{" + "minimumRequired=5, matchingCharacterCount=3, " + "validCharacters=abcdefghijklmnopqrstuvwxyz, " + "matchingCharacters=abc}", getDetail(validate, 3));
|
||||
assertEquals("TOO_SHORT:{minimumLength=8, maximumLength=10}", getDetail(validate, 4));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenRulesForDifferentPasswordLength_whenValidatingTwoDifferentPassword_thenBothOfThemAreInvalid() {
|
||||
PasswordData shortPassword = new PasswordData("12ab");
|
||||
PasswordData longPassword = new PasswordData("1234abcde");
|
||||
|
||||
LengthComplexityRule lengthComplexityRule = new LengthComplexityRule();
|
||||
lengthComplexityRule.addRules("[1,5]", new CharacterRule(EnglishCharacterData.LowerCase, 5));
|
||||
lengthComplexityRule.addRules("[6,10]", new AllowedCharacterRule(new char[] { 'a', 'b', 'c', 'd' }));
|
||||
|
||||
PasswordValidator passwordValidator = new PasswordValidator(lengthComplexityRule);
|
||||
|
||||
RuleResult validateShort = passwordValidator.validate(shortPassword);
|
||||
RuleResult validateLong = passwordValidator.validate(longPassword);
|
||||
|
||||
assertFalse(validateShort.isValid());
|
||||
assertFalse(validateLong.isValid());
|
||||
|
||||
assertEquals("INSUFFICIENT_LOWERCASE:{" + "minimumRequired=5, " + "matchingCharacterCount=2, " + "validCharacters=abcdefghijklmnopqrstuvwxyz, " + "matchingCharacters=ab}", getDetail(validateShort, 0));
|
||||
assertEquals("ALLOWED_CHAR:{illegalCharacter=1, matchBehavior=contains}", getDetail(validateLong, 0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenCharacterCharacteristicsRule_whenValidatingPassword_thenItIsInvalidAsItBreaksToManyRules() {
|
||||
PasswordData shortPassword = new PasswordData();
|
||||
shortPassword.setPassword("12345abcde!");
|
||||
|
||||
CharacterCharacteristicsRule characterCharacteristicsRule = new CharacterCharacteristicsRule(4, new CharacterRule(EnglishCharacterData.LowerCase, 5), new CharacterRule(EnglishCharacterData.UpperCase, 5), new CharacterRule(EnglishCharacterData.Digit),
|
||||
new CharacterRule(EnglishCharacterData.Special));
|
||||
|
||||
PasswordValidator passwordValidator = new PasswordValidator(characterCharacteristicsRule);
|
||||
|
||||
RuleResult validate = passwordValidator.validate(shortPassword);
|
||||
assertFalse(validate.isValid());
|
||||
|
||||
assertEquals("INSUFFICIENT_UPPERCASE:{" + "minimumRequired=5, " + "matchingCharacterCount=0, " + "validCharacters=ABCDEFGHIJKLMNOPQRSTUVWXYZ, " + "matchingCharacters=}", getDetail(validate, 0));
|
||||
assertEquals("INSUFFICIENT_CHARACTERISTICS:{" + "successCount=3, " + "minimumRequired=4, " + "ruleCount=4}", getDetail(validate, 1));
|
||||
}
|
||||
|
||||
private String getDetail(RuleResult validate, int i) {
|
||||
return validate.getDetails()
|
||||
.get(i)
|
||||
.toString();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
TOO_LONG=Password must not have more characters than %2$s.
|
||||
TOO_SHORT=Password must not contain less characters than %2$s.
|
Loading…
Reference in New Issue