diff --git a/spring-credhub-core/src/main/java/org/springframework/credhub/core/credential/CredHubCredentialOperations.java b/spring-credhub-core/src/main/java/org/springframework/credhub/core/credential/CredHubCredentialOperations.java index 0d77a7a..62b7832 100644 --- a/spring-credhub-core/src/main/java/org/springframework/credhub/core/credential/CredHubCredentialOperations.java +++ b/spring-credhub-core/src/main/java/org/springframework/credhub/core/credential/CredHubCredentialOperations.java @@ -58,11 +58,12 @@ public interface CredHubCredentialOperations { * Regenerate a credential in CredHub. Only credentials that were previously generated can be * re-generated. * - * @param name the name of the credential; must not be {@literal null} * @param the credential implementation type + * @param name the name of the credential; must not be {@literal null} + * @param credentialType the type of the credential to be regenerated; must not be {@literal null} * @return the details of the regenerated credential */ - CredentialDetails regenerate(final CredentialName name); + CredentialDetails regenerate(final CredentialName name, Class credentialType); /** * Retrieve a credential using its ID, as returned in a write request. diff --git a/spring-credhub-core/src/main/java/org/springframework/credhub/core/credential/CredHubCredentialTemplate.java b/spring-credhub-core/src/main/java/org/springframework/credhub/core/credential/CredHubCredentialTemplate.java index ab96169..d5bcaab 100644 --- a/spring-credhub-core/src/main/java/org/springframework/credhub/core/credential/CredHubCredentialTemplate.java +++ b/spring-credhub-core/src/main/java/org/springframework/credhub/core/credential/CredHubCredentialTemplate.java @@ -113,8 +113,9 @@ public class CredHubCredentialTemplate implements CredHubCredentialOperations { } @Override - public CredentialDetails regenerate(final CredentialName name) { + public CredentialDetails regenerate(final CredentialName name, Class credentialType) { Assert.notNull(name, "credential name must not be null"); + Assert.notNull(credentialType, "credential type must not be null"); final ParameterizedTypeReference> ref = new ParameterizedTypeReference>() {}; diff --git a/spring-credhub-core/src/test/java/org/springframework/credhub/core/credential/CredHubTemplateDetailUnitTestsBase.java b/spring-credhub-core/src/test/java/org/springframework/credhub/core/credential/CredHubTemplateDetailUnitTestsBase.java index d7f90b0..e16b932 100644 --- a/spring-credhub-core/src/test/java/org/springframework/credhub/core/credential/CredHubTemplateDetailUnitTestsBase.java +++ b/spring-credhub-core/src/test/java/org/springframework/credhub/core/credential/CredHubTemplateDetailUnitTestsBase.java @@ -139,7 +139,7 @@ public abstract class CredHubTemplateDetailUnitTestsBase extends CredHubCr if (!expectedResponse.getStatusCode().equals(HttpStatus.OK)) { try { - credHubTemplate.regenerate(NAME); + credHubTemplate.regenerate(NAME, getType()); fail("Exception should have been thrown"); } catch (CredHubException e) { @@ -147,7 +147,7 @@ public abstract class CredHubTemplateDetailUnitTestsBase extends CredHubCr } } else { - CredentialDetails response = credHubTemplate.regenerate(NAME); + CredentialDetails response = credHubTemplate.regenerate(NAME, getType()); assertDetailsResponseContainsExpectedCredential(expectedResponse, response); } diff --git a/spring-credhub-integration-tests/src/test/java/org/springframework/credhub/integration/CredHubIntegrationTests.java b/spring-credhub-integration-tests/src/test/java/org/springframework/credhub/integration/CredHubIntegrationTests.java index 8b81d8c..0023385 100644 --- a/spring-credhub-integration-tests/src/test/java/org/springframework/credhub/integration/CredHubIntegrationTests.java +++ b/spring-credhub-integration-tests/src/test/java/org/springframework/credhub/integration/CredHubIntegrationTests.java @@ -21,4 +21,11 @@ public abstract class CredHubIntegrationTests { @Autowired protected CredHubOperations operations; + protected boolean serverApiIsV1() { + return operations.info().version().isVersion1(); + } + + protected boolean serverApiIsV2() { + return operations.info().version().isVersion2(); + } } diff --git a/spring-credhub-integration-tests/src/test/java/org/springframework/credhub/integration/CredentialIntegrationTests.java b/spring-credhub-integration-tests/src/test/java/org/springframework/credhub/integration/CredentialIntegrationTests.java index 48f516a..3003510 100644 --- a/spring-credhub-integration-tests/src/test/java/org/springframework/credhub/integration/CredentialIntegrationTests.java +++ b/spring-credhub-integration-tests/src/test/java/org/springframework/credhub/integration/CredentialIntegrationTests.java @@ -18,21 +18,27 @@ package org.springframework.credhub.integration; import org.junit.Before; import org.junit.Test; +import org.springframework.credhub.core.CredHubException; import org.springframework.credhub.core.credential.CredHubCredentialOperations; import org.springframework.credhub.support.CredentialDetails; import org.springframework.credhub.support.CredentialSummary; import org.springframework.credhub.support.CredentialType; import org.springframework.credhub.support.SimpleCredentialName; +import org.springframework.credhub.support.WriteMode; +import org.springframework.credhub.support.password.PasswordParameters; +import org.springframework.credhub.support.user.UserCredential; +import org.springframework.credhub.support.user.UserParametersRequest; import org.springframework.credhub.support.value.ValueCredential; import org.springframework.credhub.support.value.ValueCredentialRequest; import java.util.List; import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.Assume.assumeTrue; public class CredentialIntegrationTests extends CredHubIntegrationTests { private static final SimpleCredentialName CREDENTIAL_NAME = - new SimpleCredentialName("spring-credhub", "integration-test", "test-value-credential"); + new SimpleCredentialName("spring-credhub", "integration-test", "test-credential"); private static final String CREDENTIAL_VALUE = "test-value"; private CredHubCredentialOperations credentials; @@ -40,8 +46,14 @@ public class CredentialIntegrationTests extends CredHubIntegrationTests { @Before public void setUp() { credentials = operations.credentials(); + + try { + credentials.deleteByName(CREDENTIAL_NAME); + } catch (CredHubException e) { + // ignore failing deletes on cleanup + } } - + @Test public void writeCredential() { CredentialDetails written = credentials.write(ValueCredentialRequest.builder() @@ -72,7 +84,85 @@ public class CredentialIntegrationTests extends CredHubIntegrationTests { assertThat(foundByPath).extracting("name").extracting("name").containsExactly(CREDENTIAL_NAME.getName()); credentials.deleteByName(CREDENTIAL_NAME); - + + List afterDelete = credentials.findByName(CREDENTIAL_NAME); + assertThat(afterDelete).hasSize(0); + } + + @Test + public void overwriteCredentialV2() { + assumeTrue(serverApiIsV2()); + + CredentialDetails written = credentials.write(ValueCredentialRequest.builder() + .name(CREDENTIAL_NAME) + .value(CREDENTIAL_VALUE) + .build()); + assertThat(written.getName().getName()).isEqualTo(CREDENTIAL_NAME.getName()); + assertThat(written.getValue().getValue()).isEqualTo(CREDENTIAL_VALUE); + assertThat(written.getCredentialType()).isEqualTo(CredentialType.VALUE); + assertThat(written.getId()).isNotNull(); + + CredentialDetails overwritten = credentials.write(ValueCredentialRequest.builder() + .name(CREDENTIAL_NAME) + .value("new-value") + .build()); + assertThat(overwritten.getName().getName()).isEqualTo(CREDENTIAL_NAME.getName()); + assertThat(overwritten.getValue().getValue()).isEqualTo("new-value"); + } + + @Test + public void overwriteCredentialV1() { + assumeTrue(serverApiIsV1()); + + CredentialDetails written = credentials.write(ValueCredentialRequest.builder() + .name(CREDENTIAL_NAME) + .value(CREDENTIAL_VALUE) + .mode(WriteMode.OVERWRITE) + .build()); + assertThat(written.getName().getName()).isEqualTo(CREDENTIAL_NAME.getName()); + assertThat(written.getValue().getValue()).isEqualTo(CREDENTIAL_VALUE); + assertThat(written.getCredentialType()).isEqualTo(CredentialType.VALUE); + assertThat(written.getId()).isNotNull(); + + CredentialDetails overwritten = credentials.write(ValueCredentialRequest.builder() + .name(CREDENTIAL_NAME) + .value("new-value") + .build()); + assertThat(overwritten.getName().getName()).isEqualTo(CREDENTIAL_NAME.getName()); + assertThat(overwritten.getValue().getValue()).isEqualTo("new-value"); + } + + @Test + public void generateCredential() { + CredentialDetails generated = credentials.generate(UserParametersRequest.builder() + .name(CREDENTIAL_NAME) + .username("test-user") + .parameters(PasswordParameters.builder() + .length(12) + .excludeLower(false) + .excludeUpper(false) + .excludeNumber(false) + .includeSpecial(true) + .build()) + .build()); + assertThat(generated.getName().getName()).isEqualTo(CREDENTIAL_NAME.getName()); + assertThat(generated.getCredentialType()).isEqualTo(CredentialType.USER); + assertThat(generated.getValue().getUsername()).isEqualTo("test-user"); + assertThat(generated.getValue().getPassword()).matches("^[a-zA-Z0-9\\p{Punct}]{12}$"); + assertThat(generated.getValue().getPasswordHash()).isNotNull(); + + CredentialDetails retrieved = credentials.getById(generated.getId(), UserCredential.class); + assertThat(retrieved.getName().getName()).isEqualTo(CREDENTIAL_NAME.getName()); + + CredentialDetails regenerated = credentials.regenerate(CREDENTIAL_NAME, UserCredential.class); + assertThat(regenerated.getName().getName()).isEqualTo(CREDENTIAL_NAME.getName()); + assertThat(regenerated.getValue().getUsername()).isEqualTo("test-user"); + assertThat(regenerated.getValue().getPassword()).matches("^[a-zA-Z0-9\\p{Punct}]{12}$"); + assertThat(regenerated.getValue().getPassword()).isNotEqualTo(generated.getValue().getPassword()); + assertThat(regenerated.getValue().getPasswordHash()).isNotEqualTo(generated.getValue().getPasswordHash()); + + credentials.deleteByName(CREDENTIAL_NAME); + List afterDelete = credentials.findByName(CREDENTIAL_NAME); assertThat(afterDelete).hasSize(0); }