From 926de97c910f6ba7e11832250ec5b45f4f4f534d Mon Sep 17 00:00:00 2001 From: Scott Frederick Date: Tue, 23 Oct 2018 18:18:04 -0500 Subject: [PATCH] Add regenerate method to certificate operations. Fixes #41 --- .../CredHubCertificateOperations.java | 11 ++++ .../CredHubCertificateTemplate.java | 51 +++++++++++++++++++ .../CredHubCertificateTemplateUnitTests.java | 35 +++++++++++++ .../CertificateIntegrationTests.java | 20 ++++++++ 4 files changed, 117 insertions(+) diff --git a/spring-credhub-core/src/main/java/org/springframework/credhub/core/certificate/CredHubCertificateOperations.java b/spring-credhub-core/src/main/java/org/springframework/credhub/core/certificate/CredHubCertificateOperations.java index 621a7fe..591b466 100644 --- a/spring-credhub-core/src/main/java/org/springframework/credhub/core/certificate/CredHubCertificateOperations.java +++ b/spring-credhub-core/src/main/java/org/springframework/credhub/core/certificate/CredHubCertificateOperations.java @@ -17,7 +17,9 @@ package org.springframework.credhub.core.certificate; import org.springframework.credhub.support.CertificateSummary; +import org.springframework.credhub.support.CredentialDetails; import org.springframework.credhub.support.CredentialName; +import org.springframework.credhub.support.certificate.CertificateCredential; import java.util.List; @@ -42,4 +44,13 @@ public interface CredHubCertificateOperations { * @return the details of the retrieved certificate credential */ CertificateSummary getByName(final CredentialName name); + + /** + * Regenerate a certificate. + * + * @param id the CredHub-generated ID of the certificate credential; must not be {@literal null} + * @param setAsTransitional make the certificate version transitional or not + * @return the details of the certificate credential + */ + CredentialDetails regenerate(final String id, final boolean setAsTransitional); } diff --git a/spring-credhub-core/src/main/java/org/springframework/credhub/core/certificate/CredHubCertificateTemplate.java b/spring-credhub-core/src/main/java/org/springframework/credhub/core/certificate/CredHubCertificateTemplate.java index de64f56..6369459 100644 --- a/spring-credhub-core/src/main/java/org/springframework/credhub/core/certificate/CredHubCertificateTemplate.java +++ b/spring-credhub-core/src/main/java/org/springframework/credhub/core/certificate/CredHubCertificateTemplate.java @@ -16,17 +16,25 @@ package org.springframework.credhub.core.certificate; +import org.springframework.core.ParameterizedTypeReference; import org.springframework.credhub.core.CredHubOperations; import org.springframework.credhub.core.ExceptionUtils; import org.springframework.credhub.core.RestOperationsCallback; import org.springframework.credhub.support.CertificateSummary; import org.springframework.credhub.support.CertificateSummaryData; +import org.springframework.credhub.support.CredentialDetails; import org.springframework.credhub.support.CredentialName; +import org.springframework.credhub.support.certificate.CertificateCredential; +import org.springframework.http.HttpEntity; import org.springframework.http.ResponseEntity; import org.springframework.util.Assert; import org.springframework.web.client.RestOperations; +import java.util.HashMap; import java.util.List; +import java.util.Map; + +import static org.springframework.http.HttpMethod.POST; /** * Implements the interactions with CredHub to retrieve, regenerate, and update @@ -37,6 +45,8 @@ import java.util.List; public class CredHubCertificateTemplate implements CredHubCertificateOperations { static final String BASE_URL_PATH = "/api/v1/certificates"; static final String NAME_URL_QUERY = BASE_URL_PATH + "?name={name}"; + static final String REGENERATE_URL_PATH = BASE_URL_PATH + "/{id}/regenerate"; + static final String TRANSITIONAL_REQUEST_FIELD = "set_as_transitional"; private CredHubOperations credHubOperations; @@ -49,6 +59,11 @@ public class CredHubCertificateTemplate implements CredHubCertificateOperations this.credHubOperations = credHubOperations; } + /** + * Retrieve all certificates from CredHub. + * + * @return a collection of certificates + */ @Override public List getAll() { return credHubOperations.doWithRest(new RestOperationsCallback>() { @@ -65,6 +80,12 @@ public class CredHubCertificateTemplate implements CredHubCertificateOperations }); } + /** + * Retrieve a certificate using its name. + * + * @param name the name of the certificate credential; must not be {@literal null} + * @return the details of the retrieved certificate credential + */ @Override public CertificateSummary getByName(final CredentialName name) { Assert.notNull(name, "certificate name must not be null"); @@ -82,4 +103,34 @@ public class CredHubCertificateTemplate implements CredHubCertificateOperations } }); } + + /** + * Regenerate a certificate. + * + * @param id the CredHub-generated ID of the certificate credential; must not be {@literal null} + * @return the details of the certificate credential + */ + @Override + public CredentialDetails regenerate(final String id, final boolean setAsTransitional) { + Assert.notNull(id, "credential ID must not be null"); + + final ParameterizedTypeReference> ref = + new ParameterizedTypeReference>() {}; + + return credHubOperations.doWithRest(new RestOperationsCallback>() { + @Override + public CredentialDetails doWithRestOperations(RestOperations restOperations) { + Map request = new HashMap<>(); + request.put(TRANSITIONAL_REQUEST_FIELD, setAsTransitional); + + ResponseEntity> response = + restOperations.exchange(REGENERATE_URL_PATH, POST, + new HttpEntity(request), ref, id); + + ExceptionUtils.throwExceptionOnError(response); + + return response.getBody(); + } + }); + } } diff --git a/spring-credhub-core/src/test/java/org/springframework/credhub/core/certificate/CredHubCertificateTemplateUnitTests.java b/spring-credhub-core/src/test/java/org/springframework/credhub/core/certificate/CredHubCertificateTemplateUnitTests.java index 6bc5def..010862b 100644 --- a/spring-credhub-core/src/test/java/org/springframework/credhub/core/certificate/CredHubCertificateTemplateUnitTests.java +++ b/spring-credhub-core/src/test/java/org/springframework/credhub/core/certificate/CredHubCertificateTemplateUnitTests.java @@ -21,19 +21,31 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; +import org.springframework.core.ParameterizedTypeReference; import org.springframework.credhub.core.CredHubTemplate; import org.springframework.credhub.support.CertificateSummary; import org.springframework.credhub.support.CertificateSummaryData; +import org.springframework.credhub.support.CredentialDetails; +import org.springframework.credhub.support.CredentialType; import org.springframework.credhub.support.SimpleCredentialName; +import org.springframework.credhub.support.certificate.CertificateCredential; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpMethod; import org.springframework.http.ResponseEntity; import org.springframework.web.client.RestTemplate; +import java.util.HashMap; import java.util.List; +import java.util.Map; import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.ArgumentMatchers.isA; import static org.mockito.Mockito.when; import static org.springframework.credhub.core.certificate.CredHubCertificateTemplate.BASE_URL_PATH; import static org.springframework.credhub.core.certificate.CredHubCertificateTemplate.NAME_URL_QUERY; +import static org.springframework.credhub.core.certificate.CredHubCertificateTemplate.REGENERATE_URL_PATH; +import static org.springframework.credhub.core.certificate.CredHubCertificateTemplate.TRANSITIONAL_REQUEST_FIELD; import static org.springframework.http.HttpStatus.OK; @RunWith(MockitoJUnitRunner.class) @@ -83,4 +95,27 @@ public class CredHubCertificateTemplateUnitTests { assertThat(response.getId()).isEqualTo("id1"); assertThat(response.getName()).isEqualTo("name1"); } + + @Test + public void regenerate() { + CredentialDetails expectedCertificates = + new CredentialDetails<>("id", NAME, CredentialType.CERTIFICATE, + new CertificateCredential("cert", "authority", "key")); + + Map request = new HashMap<>(); + request.put(TRANSITIONAL_REQUEST_FIELD, true); + + when(restTemplate.exchange(eq(REGENERATE_URL_PATH), eq(HttpMethod.POST), + eq(new HttpEntity(request)), isA(ParameterizedTypeReference.class), eq("id"))) + .thenReturn(new ResponseEntity<>(expectedCertificates, OK)); + + CredentialDetails response = credHubTemplate.regenerate("id", true); + + assertThat(response).isNotNull(); + assertThat(response.getId()).isEqualTo("id"); + assertThat(response.getCredentialType()).isEqualTo(CredentialType.CERTIFICATE); + assertThat(response.getValue().getCertificate()).isEqualTo("cert"); + assertThat(response.getValue().getCertificateAuthority()).isEqualTo("authority"); + assertThat(response.getValue().getPrivateKey()).isEqualTo("key"); + } } \ No newline at end of file diff --git a/spring-credhub-integration-tests/src/test/java/org/springframework/credhub/integration/CertificateIntegrationTests.java b/spring-credhub-integration-tests/src/test/java/org/springframework/credhub/integration/CertificateIntegrationTests.java index 7dc69fe..eb26901 100644 --- a/spring-credhub-integration-tests/src/test/java/org/springframework/credhub/integration/CertificateIntegrationTests.java +++ b/spring-credhub-integration-tests/src/test/java/org/springframework/credhub/integration/CertificateIntegrationTests.java @@ -87,4 +87,24 @@ public class CertificateIntegrationTests extends CredHubIntegrationTests { assertThat(allCertificates.size()).isGreaterThan(0); assertThat(allCertificates).extracting("name").contains(CREDENTIAL_NAME.getName()); } + + @Test + public void regenerateCertificate() { + CredentialDetails certificate = credentials.generate(CertificateParametersRequest.builder() + .name(CREDENTIAL_NAME) + .parameters(CertificateParameters.builder() + .commonName("example.com") + .selfSign(true) + .build()) + .build()); + assertThat(certificate.getName().getName()).isEqualTo(CREDENTIAL_NAME.getName()); + + CertificateSummary byName = certificates.getByName(CREDENTIAL_NAME); + + CredentialDetails regenerated = certificates.regenerate(byName.getId(), true); + assertThat(regenerated.getName().getName()).isEqualTo(CREDENTIAL_NAME.getName()); + assertThat(regenerated.getValue().getCertificate()).isNotEqualTo(certificate.getValue().getCertificate()); + assertThat(regenerated.getValue().getCertificateAuthority()).isNotEqualTo(certificate.getValue().getCertificateAuthority()); + assertThat(regenerated.getValue().getPrivateKey()).isNotEqualTo(certificate.getValue().getPrivateKey()); + } }