-
Notifications
You must be signed in to change notification settings - Fork 66
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Added: Random Passwords #48
base: develop
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -10,9 +10,12 @@ | |
import org.slf4j.LoggerFactory; | ||
|
||
import com.kinancity.api.model.AccountData; | ||
import com.kinancity.core.generator.PasswordGenerator; | ||
import com.kinancity.core.generator.account.CsvReaderAccountGenerator; | ||
import com.kinancity.core.generator.account.SequenceAccountGenerator; | ||
import com.kinancity.core.generator.account.SingleAccountGenerator; | ||
import com.kinancity.core.generator.password.RandomPasswordGenerator; | ||
import com.kinancity.core.generator.password.SinglePasswordGenerator; | ||
import com.kinancity.core.proxy.bottleneck.ProxyNoBottleneck; | ||
import com.kinancity.core.proxy.policies.UnlimitedUsePolicy; | ||
|
||
|
@@ -106,22 +109,36 @@ private static Configuration updateConfiguration(Configuration config, Options o | |
|
||
// 3 types of generation : unique, csv and sequence | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Password generator could also be used with csv input, if the password header is not added in file. This could be part of another PR. |
||
|
||
if (cmd.hasOption(CliOptions.SEQ_ACCOUNTS_FORMAT.shortName) && cmd.hasOption(CliOptions.SEQ_ACCOUNTS_COUNT.shortName) && cmd.hasOption(CliOptions.EMAIL.shortName) && cmd.hasOption(CliOptions.PASSWORD.shortName)) { | ||
if (cmd.hasOption(CliOptions.SEQ_ACCOUNTS_FORMAT.shortName) && cmd.hasOption(CliOptions.SEQ_ACCOUNTS_COUNT.shortName) && cmd.hasOption(CliOptions.EMAIL.shortName)) { | ||
LOGGER.info("Use a Sequence Account Generator"); | ||
SequenceAccountGenerator sequenceGenerator = new SequenceAccountGenerator(); | ||
sequenceGenerator.setBaseEmail(cmd.getOptionValue(CliOptions.EMAIL.shortName)); | ||
sequenceGenerator.setStaticPassword(cmd.getOptionValue(CliOptions.PASSWORD.shortName)); | ||
sequenceGenerator.setUsernamePattern(cmd.getOptionValue(CliOptions.SEQ_ACCOUNTS_FORMAT.shortName)); | ||
sequenceGenerator.setNbAccounts(Integer.parseInt(cmd.getOptionValue(CliOptions.SEQ_ACCOUNTS_COUNT.shortName))); | ||
sequenceGenerator.setStartFrom(Integer.parseInt(cmd.getOptionValue(CliOptions.SEQ_ACCOUNTS_START.shortName, "0"))); | ||
if (cmd.hasOption(CliOptions.PASSWORD.shortName)) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Duplicate code should be joined as one. PasswordGenerator definition could be done before the "3 types of generation" fork |
||
sequenceGenerator.setPasswordGenerator(new SinglePasswordGenerator(cmd.getOptionValue(CliOptions.PASSWORD.shortName))); | ||
} | ||
else { | ||
Integer length = Integer.valueOf(cmd.getOptionValue(CliOptions.PASSWORD_LENGTH.shortName, "-1")); | ||
sequenceGenerator.setPasswordGenerator(new RandomPasswordGenerator(length)); | ||
} | ||
config.setAccountGenerator(sequenceGenerator); | ||
|
||
} else if (cmd.hasOption(CliOptions.EMAIL.shortName) && cmd.hasOption(CliOptions.SINGLE_USERNAME.shortName) && cmd.hasOption(CliOptions.PASSWORD.shortName)) { | ||
} | ||
else if (cmd.hasOption(CliOptions.EMAIL.shortName) && cmd.hasOption(CliOptions.SINGLE_USERNAME.shortName)) { | ||
LOGGER.info("Create a single account"); | ||
AccountData account = new AccountData(); | ||
account.setEmail(cmd.getOptionValue(CliOptions.EMAIL.shortName)); | ||
account.setUsername(cmd.getOptionValue(CliOptions.SINGLE_USERNAME.shortName)); | ||
account.setPassword(cmd.getOptionValue(CliOptions.PASSWORD.shortName)); | ||
PasswordGenerator pwGen; | ||
if (cmd.hasOption(CliOptions.PASSWORD.shortName)) { | ||
pwGen = new SinglePasswordGenerator(cmd.getOptionValue(CliOptions.PASSWORD.shortName)); | ||
} | ||
else { | ||
Integer length = Integer.valueOf(cmd.getOptionValue(CliOptions.PASSWORD_LENGTH.shortName, "-1")); | ||
pwGen = new RandomPasswordGenerator(length); | ||
} | ||
account.setPassword(pwGen.generatePassword()); | ||
config.setAccountGenerator(new SingleAccountGenerator(account)); | ||
|
||
// No need to use multiple thread for 1 account only | ||
|
@@ -134,9 +151,9 @@ private static Configuration updateConfiguration(Configuration config, Options o | |
|
||
HelpFormatter formatter = new HelpFormatter(); | ||
String cmdLineSyntax = " one of \n" | ||
+ " -m <email> -u <username> -p <password> \n" | ||
+ " -m <email> -u <username> (-p <password> -pl <passwordLength>) \n" | ||
+ " -a <accounts.csv> \n" | ||
+ " -m <email> -c <#ofAccounts> -f <format**> -p <password> (-s <first#>)\n" | ||
+ " -m <email> -c <#ofAccounts> -f <format**> (-p <password> -pl <passwordLength> -s <first#>)\n" | ||
+ " and optional : -ck <captchakey> \n\n"; | ||
formatter.setWidth(180); | ||
formatter.printHelp(cmdLineSyntax, options); | ||
|
@@ -157,6 +174,7 @@ private static Options setupCliOptions() { | |
options.addOption(CliOptions.EMAIL.asOption()); | ||
options.addOption(CliOptions.SINGLE_USERNAME.asOption()); | ||
options.addOption(CliOptions.PASSWORD.asOption()); | ||
options.addOption(CliOptions.PASSWORD_LENGTH.asOption()); | ||
|
||
// Create Multiple accounts | ||
options.addOption(CliOptions.CSV_ACCOUNTS.asOption()); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
package com.kinancity.core.generator.password; | ||
|
||
import java.util.ArrayList; | ||
import java.util.Collections; | ||
import java.util.concurrent.ThreadLocalRandom; | ||
import java.util.stream.Collectors; | ||
|
||
import org.slf4j.Logger; | ||
import org.slf4j.LoggerFactory; | ||
|
||
import com.kinancity.core.KinanCityCli; | ||
import com.kinancity.core.generator.PasswordGenerator; | ||
|
||
/** | ||
* Random Password generator | ||
* @author 0815Flo0815 | ||
* | ||
*/ | ||
public class RandomPasswordGenerator implements PasswordGenerator { | ||
|
||
private static final char[][] CHAR_POOL = { | ||
{'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'}, | ||
{'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'}, | ||
{'1','2','3','4','5','6','7','8','9','0'}, | ||
{'#','?','!','@','$','%','%','^','&','>','<','+','`','*','(',')','-',']'} | ||
}; | ||
private static final int MIN_LENGTH = 8; | ||
private static final int MAX_LENGTH = 50; | ||
|
||
private static Logger LOGGER = LoggerFactory.getLogger(KinanCityCli.class); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. On other classes I currently use instance loggers : |
||
|
||
private int length; | ||
|
||
public RandomPasswordGenerator(Integer length) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There is no need to take an Integer as paramter, primitive int would be better to avoid null checks |
||
super(); | ||
if (length == null) { | ||
LOGGER.warn("Password length must be a number! Using a random length!"); | ||
this.length = -1; | ||
} | ||
else if (length < 0) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. style : |
||
this.length = -1; | ||
} | ||
else if (length < MIN_LENGTH) { | ||
LOGGER.warn("The minimum password length is " + MIN_LENGTH + "! Using " + MIN_LENGTH + "!"); | ||
this.length = MIN_LENGTH; | ||
} | ||
else if (length > MAX_LENGTH) { | ||
LOGGER.warn("The maximum password length is " + MAX_LENGTH + "! Using " + MAX_LENGTH + "!"); | ||
this.length = MAX_LENGTH; | ||
} | ||
else { | ||
this.length = length; | ||
} | ||
} | ||
|
||
@Override | ||
public String generatePassword() { | ||
int length; | ||
if (this.length == -1) { | ||
length = ThreadLocalRandom.current().nextInt(MIN_LENGTH, MAX_LENGTH + 1); | ||
} | ||
else { | ||
length = this.length; | ||
} | ||
|
||
ArrayList<Character> passwordPool = new ArrayList<Character>(); | ||
for (int i = 0; i < length; i++) { | ||
char[] currentPool = CHAR_POOL[i % CHAR_POOL.length]; | ||
int randomIndexPool = ThreadLocalRandom.current().nextInt(currentPool.length); | ||
int randomIndexPosition = ThreadLocalRandom.current().nextInt(passwordPool.size() + 1); | ||
passwordPool.add(randomIndexPosition, currentPool[randomIndexPool]); | ||
} | ||
Collections.shuffle(passwordPool); | ||
return String.valueOf(passwordPool.stream().map(e->e.toString()).collect(Collectors.joining())); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,6 +6,8 @@ | |
|
||
import com.kinancity.api.model.AccountData; | ||
import com.kinancity.core.generator.account.SequenceAccountGenerator; | ||
import com.kinancity.core.generator.password.RandomPasswordGenerator; | ||
import com.kinancity.core.generator.password.SinglePasswordGenerator; | ||
|
||
public class SequenceAccountGeneratorTest { | ||
|
||
|
@@ -16,21 +18,37 @@ public void sequenceTest() { | |
generator.setBaseEmail("myname@domain.fr"); | ||
generator.setUsernamePattern("pref*****suf"); | ||
generator.setStartFrom(1234); | ||
generator.setNbAccounts(3); | ||
generator.setNbAccounts(4); | ||
|
||
AccountData data; | ||
|
||
generator.setPasswordGenerator(new SinglePasswordGenerator("Test")); | ||
|
||
data = generator.next(); | ||
assertThat(data).isNotNull(); | ||
assertThat(data.getUsername()).isEqualTo("pref01234suf"); | ||
assertThat(data.getPassword()).isEqualTo("Test"); | ||
|
||
generator.setPasswordGenerator(new RandomPasswordGenerator(-1)); | ||
|
||
data = generator.next(); | ||
assertThat(data).isNotNull(); | ||
assertThat(data.getUsername()).isEqualTo("pref01235suf"); | ||
assertThat(data.getPassword().length()).isBetween(8, 50); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Using the same regexp or calling directly isAccountValid would be better. |
||
|
||
generator.setPasswordGenerator(new RandomPasswordGenerator(5)); | ||
|
||
data = generator.next(); | ||
assertThat(data).isNotNull(); | ||
assertThat(data.getUsername()).isEqualTo("pref01236suf"); | ||
assertThat(data.getPassword().length()).isEqualTo(8); | ||
|
||
generator.setPasswordGenerator(new RandomPasswordGenerator(100)); | ||
|
||
data = generator.next(); | ||
assertThat(data).isNotNull(); | ||
assertThat(data.getUsername()).isEqualTo("pref01237suf"); | ||
assertThat(data.getPassword().length()).isEqualTo(50); | ||
|
||
data = generator.next(); | ||
assertThat(data).isNull(); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Options key should not overlap each other one should not start like the other.
"p" is contained in "pl"