Add support for regeneration of credentials.

This commit is contained in:
Scott Frederick
2017-08-18 15:08:48 -05:00
parent 4d1d37b61c
commit 32d659a831
7 changed files with 91 additions and 2 deletions

View File

@@ -57,6 +57,16 @@ public interface CredHubOperations {
*/
<T, P> CredentialDetails<T> generate(ParametersRequest<P> parametersRequest);
/**
* 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 <T> the credential implementation type
* @return the details of the regenerated credential
*/
<T> CredentialDetails<T> regenerate(CredentialName name);
/**
* Retrieve a credential using its ID, as returned in a write request.
*

View File

@@ -16,7 +16,9 @@
package org.springframework.credhub.core;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.credhub.support.CredentialDetails;
@@ -119,7 +121,7 @@ public class CredHubTemplate implements CredHubOperations {
@Override
@SuppressWarnings("unchecked")
public <T, P> CredentialDetails<T> generate(final ParametersRequest<P> parametersRequest) {
Assert.notNull(parametersRequest, "generateRequest must not be null");
Assert.notNull(parametersRequest, "parametersRequest must not be null");
final ParameterizedTypeReference<CredentialDetails<T>> ref =
new ParameterizedTypeReference<CredentialDetails<T>>() {};
@@ -138,6 +140,31 @@ public class CredHubTemplate implements CredHubOperations {
});
}
@Override
public <T> CredentialDetails<T> regenerate(final CredentialName name) {
Assert.notNull(name, "credential name must not be null");
final ParameterizedTypeReference<CredentialDetails<T>> ref =
new ParameterizedTypeReference<CredentialDetails<T>>() {};
return doWithRest(new RestOperationsCallback<CredentialDetails<T>>() {
@Override
public CredentialDetails<T> doWithRestOperations(RestOperations restOperations) {
Map<String, Object> request = new HashMap<String, Object>(2);
request.put("name", name.getName());
request.put("regenerate", true);
ResponseEntity<CredentialDetails<T>> response =
restOperations.exchange(BASE_URL_PATH, POST,
new HttpEntity<Map<String, Object>>(request), ref);
throwExceptionOnError(response);
return response.getBody();
}
});
}
@Override
public <T> CredentialDetails<T> getById(final String id, Class<T> credentialType) {
Assert.notNull(id, "credential id must not be null");

View File

@@ -88,6 +88,12 @@ public class CredHubTemplateDetailCertificateUnitTests
verifyGenerate(expectedResponse);
}
@Theory
public void regenerate(@FromDataPoints("detail-responses")
ResponseEntity<CredentialDetails<CertificateCredential>> expectedResponse) {
verifyRegenerate(expectedResponse);
}
@Theory
public void getById(@FromDataPoints("detail-responses")
ResponseEntity<CredentialDetails<CertificateCredential>> expectedResponse) {

View File

@@ -84,6 +84,12 @@ public class CredHubTemplateDetailPasswordUnitTests
verifyGenerate(expectedResponse);
}
@Theory
public void regenerate(@FromDataPoints("detail-responses")
ResponseEntity<CredentialDetails<PasswordCredential>> expectedResponse) {
verifyRegenerate(expectedResponse);
}
@Theory
public void getById(@FromDataPoints("detail-responses")
ResponseEntity<CredentialDetails<PasswordCredential>> expectedResponse) {

View File

@@ -85,6 +85,12 @@ public class CredHubTemplateDetailRsaUnitTests
verifyGenerate(expectedResponse);
}
@Theory
public void regenerate(@FromDataPoints("detail-responses")
ResponseEntity<CredentialDetails<RsaCredential>> expectedResponse) {
verifyRegenerate(expectedResponse);
}
@Theory
public void getById(@FromDataPoints("detail-responses")
ResponseEntity<CredentialDetails<RsaCredential>> expectedResponse) {

View File

@@ -85,6 +85,12 @@ public class CredHubTemplateDetailSshUnitTests
verifyGenerate(expectedResponse);
}
@Theory
public void regenerate(@FromDataPoints("detail-responses")
ResponseEntity<CredentialDetails<SshCredential>> expectedResponse) {
verifyRegenerate(expectedResponse);
}
@Theory
public void getById(@FromDataPoints("detail-responses")
ResponseEntity<CredentialDetails<SshCredential>> expectedResponse) {

View File

@@ -17,7 +17,9 @@
package org.springframework.credhub.core;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.credhub.support.CredentialDetails;
@@ -56,7 +58,7 @@ public abstract class CredHubTemplateDetailUnitTestsBase<T, P> extends CredHubTe
protected abstract CredentialRequest<T> getWriteRequest();
protected ParametersRequest<P> getGenerateRequest() {
return null;
throw new IllegalStateException("Tests that verify credential generation must override this method");
}
static <T> List<ResponseEntity<CredentialDetails<T>>> buildDetailResponses(CredentialType type, T credential) {
@@ -126,6 +128,32 @@ public abstract class CredHubTemplateDetailUnitTestsBase<T, P> extends CredHubTe
}
}
void verifyRegenerate(ResponseEntity<CredentialDetails<T>> expectedResponse) {
Map<String, Object> request = new HashMap<String, Object>() {{
put("name", NAME.getName());
put("regenerate", true);
}};
when(restTemplate.exchange(eq(BASE_URL_PATH), eq(POST),
eq(new HttpEntity<Map<String, Object>>(request)), isA(ParameterizedTypeReference.class)))
.thenReturn(expectedResponse);
if (!expectedResponse.getStatusCode().equals(HttpStatus.OK)) {
try {
credHubTemplate.regenerate(NAME);
fail("Exception should have been thrown");
}
catch (CredHubException e) {
assertThat(e.getMessage(), containsString(expectedResponse.getStatusCode().toString()));
}
}
else {
CredentialDetails<T> response = credHubTemplate.regenerate(NAME);
assertResponseContainsExpectedCredentials(expectedResponse, response);
}
}
@SuppressWarnings("deprecation")
void verifyGetById(ResponseEntity<CredentialDetails<T>> expectedResponse) {
when(restTemplate.exchange(eq(ID_URL_PATH), eq(GET), isNull(HttpEntity.class),