From 8c3598b441a3e5f0ba2e3ab887c3d1633ce23638 Mon Sep 17 00:00:00 2001
From: the-java-guy <39062630+the-java-guy@users.noreply.github.com>
Date: Thu, 18 Oct 2018 09:41:25 +0530
Subject: [PATCH] BAEL - 2166 (#5379)
* Bean Object, server side and client side example for event streaming
example
* BAEL-1628
Access a File from the Classpath in a Spring Application
* inputstream retrieval added
* Removed files related to evaluation article
* + Aligning code to the article. Removed Utility methods and classes
* Precommit fix
* PMD fixes
* Code Review changes
Refactored : whenResourceUtils_thenReadSuccessful
* BAEL-1934
* +indentation correction in pom.xml
* synced with master
* Precommit : rebase
* BAEL-1782
* BAEL - 2166 : Password Generation
* Removed unnecessary javaDoc
* Segregated utility method
---
java-strings/pom.xml | 12 +-
.../password/RandomPasswordGenerator.java | 152 ++++++++++++++++++
.../password/StringPasswordUnitTest.java | 64 ++++++++
3 files changed, 227 insertions(+), 1 deletion(-)
create mode 100644 java-strings/src/main/java/com/baeldung/string/password/RandomPasswordGenerator.java
create mode 100644 java-strings/src/test/java/com/baeldung/string/password/StringPasswordUnitTest.java
diff --git a/java-strings/pom.xml b/java-strings/pom.xml
index b1ba49b33a..a43490ce5c 100644
--- a/java-strings/pom.xml
+++ b/java-strings/pom.xml
@@ -68,7 +68,17 @@
emoji-java
4.0.0
-
+
+
+ org.passay
+ passay
+ 1.3.1
+
+
+ org.apache.commons
+ commons-text
+ 1.4
+
diff --git a/java-strings/src/main/java/com/baeldung/string/password/RandomPasswordGenerator.java b/java-strings/src/main/java/com/baeldung/string/password/RandomPasswordGenerator.java
new file mode 100644
index 0000000000..46af4d7c51
--- /dev/null
+++ b/java-strings/src/main/java/com/baeldung/string/password/RandomPasswordGenerator.java
@@ -0,0 +1,152 @@
+package com.baeldung.string.password;
+
+import java.security.SecureRandom;
+import java.util.Collections;
+import java.util.List;
+import java.util.Random;
+import java.util.stream.Collectors;
+import java.util.stream.IntStream;
+import java.util.stream.Stream;
+
+import org.apache.commons.lang3.RandomStringUtils;
+import org.apache.commons.text.RandomStringGenerator;
+import org.passay.CharacterData;
+import org.passay.CharacterRule;
+import org.passay.EnglishCharacterData;
+import org.passay.PasswordGenerator;
+
+public class RandomPasswordGenerator {
+
+ /**
+ * Special characters allowed in password.
+ */
+ public static final String ALLOWED_SPL_CHARACTERS = "!@#$%^&*()_+";
+
+ public static final String ERROR_CODE = "ERRONEOUS_SPECIAL_CHARS";
+
+ Random random = new SecureRandom();
+
+ public String generatePassayPassword() {
+ PasswordGenerator gen = new PasswordGenerator();
+ CharacterData lowerCaseChars = EnglishCharacterData.LowerCase;
+ CharacterRule lowerCaseRule = new CharacterRule(lowerCaseChars);
+ lowerCaseRule.setNumberOfCharacters(2);
+ CharacterData upperCaseChars = EnglishCharacterData.UpperCase;
+ CharacterRule upperCaseRule = new CharacterRule(upperCaseChars);
+ upperCaseRule.setNumberOfCharacters(2);
+ CharacterData digitChars = EnglishCharacterData.Digit;
+ CharacterRule digitRule = new CharacterRule(digitChars);
+ digitRule.setNumberOfCharacters(2);
+ CharacterData specialChars = new CharacterData() {
+ public String getErrorCode() {
+ return ERROR_CODE;
+ }
+
+ public String getCharacters() {
+ return ALLOWED_SPL_CHARACTERS;
+ }
+ };
+ CharacterRule splCharRule = new CharacterRule(specialChars);
+ splCharRule.setNumberOfCharacters(2);
+ String password = gen.generatePassword(10, splCharRule, lowerCaseRule, upperCaseRule, digitRule);
+ return password;
+ }
+
+ public String generateCommonTextPassword() {
+ String pwString = generateRandomSpecialCharacters(2).concat(generateRandomNumbers(2))
+ .concat(generateRandomAlphabet(2, true))
+ .concat(generateRandomAlphabet(2, false))
+ .concat(generateRandomCharacters(2));
+ List pwChars = pwString.chars()
+ .mapToObj(data -> (char) data)
+ .collect(Collectors.toList());
+ Collections.shuffle(pwChars);
+ String password = pwChars.stream()
+ .collect(StringBuilder::new, StringBuilder::append, StringBuilder::append)
+ .toString();
+ return password;
+ }
+
+ public String generateCommonsLang3Password() {
+ String upperCaseLetters = RandomStringUtils.random(2, 65, 90, true, true);
+ String lowerCaseLetters = RandomStringUtils.random(2, 97, 122, true, true);
+ String numbers = RandomStringUtils.randomNumeric(2);
+ String specialChar = RandomStringUtils.random(2, 33, 47, false, false);
+ String totalChars = RandomStringUtils.randomAlphanumeric(2);
+ String combinedChars = upperCaseLetters.concat(lowerCaseLetters)
+ .concat(numbers)
+ .concat(specialChar)
+ .concat(totalChars);
+ List pwdChars = combinedChars.chars()
+ .mapToObj(c -> (char) c)
+ .collect(Collectors.toList());
+ Collections.shuffle(pwdChars);
+ String password = pwdChars.stream()
+ .collect(StringBuilder::new, StringBuilder::append, StringBuilder::append)
+ .toString();
+ return password;
+ }
+
+ public String generateSecureRandomPassword() {
+ Stream pwdStream = Stream.concat(getRandomNumbers(2), Stream.concat(getRandomSpecialChars(2), Stream.concat(getRandomAlphabets(2, true), getRandomAlphabets(4, false))));
+ List charList = pwdStream.collect(Collectors.toList());
+ Collections.shuffle(charList);
+ String password = charList.stream()
+ .collect(StringBuilder::new, StringBuilder::append, StringBuilder::append)
+ .toString();
+ return password;
+ }
+
+ public String generateRandomSpecialCharacters(int length) {
+ RandomStringGenerator pwdGenerator = new RandomStringGenerator.Builder().withinRange(33, 45)
+ .build();
+ return pwdGenerator.generate(length);
+ }
+
+ public String generateRandomNumbers(int length) {
+ RandomStringGenerator pwdGenerator = new RandomStringGenerator.Builder().withinRange(48, 57)
+ .build();
+ return pwdGenerator.generate(length);
+ }
+
+ public String generateRandomCharacters(int length) {
+ RandomStringGenerator pwdGenerator = new RandomStringGenerator.Builder().withinRange(48, 57)
+ .build();
+ return pwdGenerator.generate(length);
+ }
+
+ public String generateRandomAlphabet(int length, boolean lowerCase) {
+ int low;
+ int hi;
+ if (lowerCase) {
+ low = 97;
+ hi = 122;
+ } else {
+ low = 65;
+ hi = 90;
+ }
+ RandomStringGenerator pwdGenerator = new RandomStringGenerator.Builder().withinRange(low, hi)
+ .build();
+ return pwdGenerator.generate(length);
+ }
+
+ public Stream getRandomAlphabets(int count, boolean upperCase) {
+ IntStream characters = null;
+ if (upperCase) {
+ characters = random.ints(count, 65, 90);
+ } else {
+ characters = random.ints(count, 97, 122);
+ }
+ return characters.mapToObj(data -> (char) data);
+ }
+
+ public Stream getRandomNumbers(int count) {
+ IntStream numbers = random.ints(count, 48, 57);
+ return numbers.mapToObj(data -> (char) data);
+ }
+
+ public Stream getRandomSpecialChars(int count) {
+ IntStream specialChars = random.ints(count, 33, 45);
+ return specialChars.mapToObj(data -> (char) data);
+ }
+}
diff --git a/java-strings/src/test/java/com/baeldung/string/password/StringPasswordUnitTest.java b/java-strings/src/test/java/com/baeldung/string/password/StringPasswordUnitTest.java
new file mode 100644
index 0000000000..bfd4b0fe8e
--- /dev/null
+++ b/java-strings/src/test/java/com/baeldung/string/password/StringPasswordUnitTest.java
@@ -0,0 +1,64 @@
+package com.baeldung.string.password;
+
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+
+/**
+ * Examples of passwords conforming to various specifications, using different libraries.
+ *
+ */
+public class StringPasswordUnitTest {
+
+ RandomPasswordGenerator passGen = new RandomPasswordGenerator();
+
+ @Test
+ public void whenPasswordGeneratedUsingPassay_thenSuccessful() {
+ String password = passGen.generatePassayPassword();
+ int specialCharCount = 0;
+ for (char c : password.toCharArray()) {
+ if (c >= 33 || c <= 47) {
+ specialCharCount++;
+ }
+ }
+ assertTrue("Password validation failed in Passay", specialCharCount >= 2);
+ }
+
+ @Test
+ public void whenPasswordGeneratedUsingCommonsText_thenSuccessful() {
+ RandomPasswordGenerator passGen = new RandomPasswordGenerator();
+ String password = passGen.generateCommonTextPassword();
+ int lowerCaseCount = 0;
+ for (char c : password.toCharArray()) {
+ if (c >= 97 || c <= 122) {
+ lowerCaseCount++;
+ }
+ }
+ assertTrue("Password validation failed in commons-text ", lowerCaseCount >= 2);
+ }
+
+ @Test
+ public void whenPasswordGeneratedUsingCommonsLang3_thenSuccessful() {
+ String password = passGen.generateCommonsLang3Password();
+ int numCount = 0;
+ for (char c : password.toCharArray()) {
+ if (c >= 48 || c <= 57) {
+ numCount++;
+ }
+ }
+ assertTrue("Password validation failed in commons-lang3", numCount >= 2);
+ }
+
+ @Test
+ public void whenPasswordGeneratedUsingSecureRandom_thenSuccessful() {
+ String password = passGen.generateSecureRandomPassword();
+ int specialCharCount = 0;
+ for (char c : password.toCharArray()) {
+ if (c >= 33 || c <= 47) {
+ specialCharCount++;
+ }
+ }
+ assertTrue("Password validation failed in Secure Random", specialCharCount >= 2);
+ }
+
+}