Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ buildscript {
guavaVersion = '33.6.0-jre'
kotlinVersion = '2.3.21'
ktlintVersion = '1.5.0'
passayVersion = '1.6.6'
passayVersion = '2.0.0'
springBootVersion = '4.0.6'
mariadbJdbcVersion = '2.7.13' // Bumping to v3 breaks some pipeline jobs, so pinning to v2 for now. v2 (current version) is stable and will be supported until about September 2025 (https://mariadb.com/kb/en/about-mariadb-connector-j/).
grpcVersion = '1.81.0'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
import java.util.List;

import org.cloudfoundry.credhub.requests.StringGenerationParameters;
import org.passay.CharacterRule;
import org.passay.EnglishCharacterData;
import org.passay.data.EnglishCharacterData;
import org.passay.rule.CharacterRule;

public final class CharacterRuleProvider {

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package org.cloudfoundry.credhub.generators;

import org.cloudfoundry.credhub.ErrorMessages;
import org.passay.CharacterData;
import org.passay.data.CharacterData;

public enum CredHubCharacterData implements CharacterData {
// reusing library string that indicates whether a validation failed
Expand Down
Original file line number Diff line number Diff line change
@@ -1,36 +1,36 @@
package org.cloudfoundry.credhub.generators;

import java.security.SecureRandom;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import org.cloudfoundry.credhub.credential.StringCredentialValue;
import org.cloudfoundry.credhub.requests.StringGenerationParameters;
import org.passay.CharacterRule;
import org.passay.PasswordGenerator;
import org.passay.generate.PasswordGenerator;
import org.passay.rule.CharacterRule;

@Component
public class PassayStringCredentialGenerator {

public static final int DEFAULT_LENGTH = 30;
public static final int MIN_LENGTH = 4;
public static final int MAX_LENGTH = 200;
private final PasswordGenerator passwordGenerator;

private final SecureRandom secureRandom;

@Autowired
PassayStringCredentialGenerator(final PasswordGenerator passwordGenerator) {
PassayStringCredentialGenerator(final SecureRandom secureRandom) {
super();
this.passwordGenerator = passwordGenerator;
this.secureRandom = secureRandom;
}

public StringCredentialValue generateCredential(final StringGenerationParameters parameters) {
final int passwordLength = normalizedLength(parameters.getLength());

final List<CharacterRule> characterRules = CharacterRuleProvider.getCharacterRules(parameters);

return new StringCredentialValue(
passwordGenerator.generatePassword(passwordLength, characterRules));
new PasswordGenerator(secureRandom, passwordLength, 2, characterRules).generate().toString());
}

private int normalizedLength(final int length) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@
import org.hamcrest.Description;
import org.hamcrest.Matcher;
import org.junit.jupiter.api.Test;
import org.passay.CharacterData;
import org.passay.CharacterRule;
import org.passay.EnglishCharacterData;
import org.passay.data.CharacterData;
import org.passay.data.EnglishCharacterData;
import org.passay.rule.CharacterRule;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.containsInAnyOrder;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,73 +1,53 @@
package org.cloudfoundry.credhub.generators;

import java.security.SecureRandom;

import org.cloudfoundry.credhub.credential.StringCredentialValue;
import org.cloudfoundry.credhub.requests.StringGenerationParameters;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.passay.PasswordGenerator;

import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.mockito.ArgumentMatchers.anyList;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;


public class PassayStringCredentialValueGeneratorTest {

private PasswordGenerator passwordGenerator;
private PassayStringCredentialGenerator subject;

@BeforeEach
public void beforeEach() {
passwordGenerator = mock(PasswordGenerator.class);
subject = new PassayStringCredentialGenerator(passwordGenerator);
subject = new PassayStringCredentialGenerator(new SecureRandom());
}

@Test
public void canGenerateCredential() {
final StringGenerationParameters generationParameters = new StringGenerationParameters();

when(passwordGenerator.generatePassword(eq(subject.DEFAULT_LENGTH), anyList()))
.thenReturn("very-credential");

final StringCredentialValue stringCredentialValue = subject.generateCredential(generationParameters);
assertThat(stringCredentialValue.getStringCredential(), equalTo("very-credential"));
final StringCredentialValue result = subject.generateCredential(generationParameters);
assertThat(result.getStringCredential().length(), equalTo(subject.DEFAULT_LENGTH));
}

@Test
public void canGenerateCredentialWithSpecificLength() {
when(passwordGenerator.generatePassword(eq(42), anyList())).thenReturn("very-credential");

final StringGenerationParameters generationParameters = new StringGenerationParameters();
generationParameters.setLength(42);

final StringCredentialValue stringCredentialValue = subject.generateCredential(generationParameters);
assertThat(stringCredentialValue.getStringCredential(), equalTo("very-credential"));
final StringCredentialValue result = subject.generateCredential(generationParameters);
assertThat(result.getStringCredential().length(), equalTo(42));
}

@Test
public void ignoresTooSmallLengthValues() {
when(passwordGenerator.generatePassword(eq(subject.DEFAULT_LENGTH), anyList()))
.thenReturn("very-credential");

final StringGenerationParameters generationParameters = new StringGenerationParameters();
generationParameters.setLength(3);

final StringCredentialValue stringCredentialValue = subject.generateCredential(generationParameters);
assertThat(stringCredentialValue.getStringCredential(), equalTo("very-credential"));
final StringCredentialValue result = subject.generateCredential(generationParameters);
assertThat(result.getStringCredential().length(), equalTo(subject.DEFAULT_LENGTH));
}

@Test
public void ignoresTooLargeLengthValues() {
when(passwordGenerator.generatePassword(eq(subject.DEFAULT_LENGTH), anyList()))
.thenReturn("very-credential");

final StringGenerationParameters generationParameters = new StringGenerationParameters();
generationParameters.setLength(201);

final StringCredentialValue stringCredentialValue = subject.generateCredential(generationParameters);
assertThat(stringCredentialValue.getStringCredential(), equalTo("very-credential"));
final StringCredentialValue result = subject.generateCredential(generationParameters);
assertThat(result.getStringCredential().length(), equalTo(subject.DEFAULT_LENGTH));
}
}
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
package org.cloudfoundry.credhub.config;

import java.security.SecureRandom;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import org.cloudfoundry.credhub.services.RandomNumberGenerator;
import org.passay.PasswordGenerator;

@Configuration
public class PassayConfiguration {

@Bean
public PasswordGenerator passwordGenerator(final RandomNumberGenerator randomNumberGenerator) {
return new PasswordGenerator(randomNumberGenerator.getSecureRandom());
public SecureRandom secureRandom(final RandomNumberGenerator randomNumberGenerator) {
return randomNumberGenerator.getSecureRandom();
}

}