diff --git a/spring-credhub-core/src/main/java/org/springframework/credhub/support/certificate/CertificateParameters.java b/spring-credhub-core/src/main/java/org/springframework/credhub/support/certificate/CertificateParameters.java new file mode 100644 index 0000000..a83b606 --- /dev/null +++ b/spring-credhub-core/src/main/java/org/springframework/credhub/support/certificate/CertificateParameters.java @@ -0,0 +1,229 @@ +/* + * Copyright 2016-2017 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.credhub.support.certificate; + +import org.springframework.credhub.support.KeyLength; +import org.springframework.credhub.support.rsa.KeyParameters; +import org.springframework.util.Assert; + +/** + * Parameters for generating a new certificate credential. + * + * @author Scott Frederick + */ +public class CertificateParameters extends KeyParameters { + private String commonName; + private String[] alternativeNames; + private String organization; + private String organizationUnit; + private String locality; + private String state; + private String country; + private String credential; + private Boolean isCertificateAuthority; + private Boolean selfSign; + private Integer duration; + + /** + * Create a {@link CertificateParameters} using defaults for all parameter values. + */ + private CertificateParameters() { + this.commonName = null; + this.alternativeNames = null; + this.organization = null; + this.organizationUnit = null; + this.locality = null; + this.state = null; + this.country = null; + this.duration = null; + this.credential = null; + this.isCertificateAuthority = null; + this.selfSign = null; + } + + private CertificateParameters(KeyLength keyLength, String commonName, String[] alternativeNames, String organization, + String organizationUnit, String locality, String state, String country, + Integer duration, String credential, Boolean isCa, Boolean selfSign) { + super(keyLength); + this.commonName = commonName; + this.alternativeNames = alternativeNames; + this.organization = organization; + this.organizationUnit = organizationUnit; + this.locality = locality; + this.state = state; + this.country = country; + this.duration = duration; + this.credential = credential; + this.isCertificateAuthority = isCa; + this.selfSign = selfSign; + } + + public String getCommonName() { + return commonName; + } + + public String[] getAlternativeNames() { + return alternativeNames; + } + + public String getOrganization() { + return organization; + } + + public String getOrganizationUnit() { + return organizationUnit; + } + + public String getLocality() { + return locality; + } + + public String getState() { + return state; + } + + public String getCountry() { + return country; + } + + public String getCredential() { + return credential; + } + + public Boolean getIsCa() { + return isCertificateAuthority; + } + + public Boolean getSelfSign() { + return selfSign; + } + + public Integer getDuration() { + return duration; + } + + /** + * Create a builder that provides a fluent API for providing the values required + * to construct a {@link CertificateParameters}. + * + * @return a builder + */ + public static CertificateParametersBuilder builder() { + return new CertificateParametersBuilder(); + } + + /** + * A builder that provides a fluent API for constructing {@link CertificateParametersBuilder}s. + */ + public static class CertificateParametersBuilder { + private KeyLength keyLength; + private String commonName; + private String[] alternativeNames; + private String organization; + private String organizationUnit; + private String locality; + private String state; + private String country; + private Integer duration; + private String credential; + private Boolean certificateAuthority; + private Boolean selfSign; + + public CertificateParametersBuilder keyLength(KeyLength keyLength) { + Assert.notNull(keyLength, "keyLength must not be null"); + this.keyLength = keyLength; + return this; + } + + public CertificateParametersBuilder commonName(String commonName) { + Assert.notNull(commonName, "commonName must not be null"); + this.commonName = commonName; + return this; + } + + public CertificateParametersBuilder alternateNames(String... alternativeNames) { + Assert.notNull(alternativeNames, "alternativeNames must not be null"); + this.alternativeNames = alternativeNames; + return this; + } + + public CertificateParametersBuilder organization(String organization) { + Assert.notNull(organization, "organization must not be null"); + this.organization = organization; + return this; + } + + public CertificateParametersBuilder organizationUnit(String organizationUnit) { + Assert.notNull(organizationUnit, "organizationUnit must not be null"); + this.organizationUnit = organizationUnit; + return this; + } + + public CertificateParametersBuilder locality(String locality) { + Assert.notNull(locality, "locality must not be null"); + this.locality = locality; + return this; + } + + public CertificateParametersBuilder state(String state) { + Assert.notNull(state, "state must not be null"); + this.state = state; + return this; + } + + public CertificateParametersBuilder country(String country) { + Assert.notNull(country, "country must not be null"); + this.country = country; + return this; + } + + public CertificateParametersBuilder duration(int duration) { + this.duration = duration; + return this; + } + + public CertificateParametersBuilder credential(String credential) { + this.credential = credential; + return this; + } + + public CertificateParametersBuilder certificateAuthority(boolean certificateAuthority) { + this.certificateAuthority = certificateAuthority; + return this; + } + + public CertificateParametersBuilder selfSign(boolean selfSign) { + this.selfSign = selfSign; + return this; + } + + /** + * Create a {@link CertificateParameters} from the provided values. + * + * @return the created {@link CertificateParameters} + */ + public CertificateParameters build() { + Assert.isTrue(commonName != null || organization != null || organizationUnit != null || + locality != null || state != null || country != null, + "at least one subject parameter must be specified"); + Assert.isTrue(credential != null || certificateAuthority != null || selfSign != null, + "at least one signing parameter must be specified"); + return new CertificateParameters(keyLength, commonName, alternativeNames, organization, organizationUnit, + locality, state, country, duration, credential, certificateAuthority, selfSign); + } + } +} diff --git a/spring-credhub-core/src/main/java/org/springframework/credhub/support/certificate/CertificateParametersRequest.java b/spring-credhub-core/src/main/java/org/springframework/credhub/support/certificate/CertificateParametersRequest.java new file mode 100644 index 0000000..1d083a2 --- /dev/null +++ b/spring-credhub-core/src/main/java/org/springframework/credhub/support/certificate/CertificateParametersRequest.java @@ -0,0 +1,74 @@ +/* + * Copyright 2016-2017 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.credhub.support.certificate; + +import org.springframework.credhub.support.ParametersRequest; +import org.springframework.util.Assert; + +import static org.springframework.credhub.support.CredentialType.CERTIFICATE; + +/** + * The details of a request to generate a new {@link CertificateCredential} in CredHub. + * + * @author Scott Frederick + */ +public class CertificateParametersRequest extends ParametersRequest { + /** + * Create a {@link CertificateParametersRequest}. + */ + CertificateParametersRequest() { + super(CERTIFICATE); + } + + /** + * Create a builder that provides a fluent API for providing the values required + * to construct a {@link CertificateParametersRequest}. + * + * @return a builder + */ + public static CertificateParametersRequestBuilder builder() { + return new CertificateParametersRequestBuilder(); + } + + /** + * A builder that provides a fluent API for constructing {@link CertificateParametersRequest}s. + */ + public static class CertificateParametersRequestBuilder + extends ParametersRequestBuilder { + @Override + protected CertificateParametersRequest createTarget() { + return new CertificateParametersRequest(); + } + + @Override + protected CertificateParametersRequestBuilder createBuilder() { + return this; + } + + /** + * Set the parameters for generation of a password credential. + * + * @param parameters the generation parameters; must not be {@literal null} + * @return the builder + */ + public CertificateParametersRequestBuilder parameters(CertificateParameters parameters) { + Assert.notNull(parameters, "parameters must not be null"); + targetObj.setParameters(parameters); + return this; + } + } +} diff --git a/spring-credhub-core/src/main/java/org/springframework/credhub/support/rsa/KeyParameters.java b/spring-credhub-core/src/main/java/org/springframework/credhub/support/rsa/KeyParameters.java new file mode 100644 index 0000000..ec9dcac --- /dev/null +++ b/spring-credhub-core/src/main/java/org/springframework/credhub/support/rsa/KeyParameters.java @@ -0,0 +1,40 @@ +/* + * Copyright 2016-2017 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.credhub.support.rsa; + +import org.springframework.credhub.support.KeyLength; + +public class KeyParameters { + protected final KeyLength keyLength; + + protected KeyParameters() { + this.keyLength = null; + } + + protected KeyParameters(KeyLength keyLength) { + this.keyLength = keyLength; + } + + /** + * Get the value of the key length parameter. + * + * @return the value of the parameter; will be {@literal null} if not explicitly set + */ + public Integer getKeyLength() { + return keyLength == null ? null : keyLength.getLength(); + } +} diff --git a/spring-credhub-core/src/main/java/org/springframework/credhub/support/rsa/RsaParameters.java b/spring-credhub-core/src/main/java/org/springframework/credhub/support/rsa/RsaParameters.java index ec8c05d..38dce78 100644 --- a/spring-credhub-core/src/main/java/org/springframework/credhub/support/rsa/RsaParameters.java +++ b/spring-credhub-core/src/main/java/org/springframework/credhub/support/rsa/RsaParameters.java @@ -25,14 +25,12 @@ import org.springframework.util.Assert; * * @author Scott Frederick */ -public class RsaParameters { - private final KeyLength keyLength; - +public class RsaParameters extends KeyParameters { /** * Create a {@link RsaParameters} using defaults for all parameter values. */ private RsaParameters() { - keyLength = null; + super(); } /** @@ -41,16 +39,7 @@ public class RsaParameters { * @param keyLength length of generated RSA key; must not be {@literal null} */ public RsaParameters(KeyLength keyLength) { + super(keyLength); Assert.notNull(keyLength, "keyLength must not be null"); - this.keyLength = keyLength; - } - - /** - * Get the value of the key length parameter. - * - * @return the value of the parameter; will be {@literal null} if not explicitly set - */ - public Integer getKeyLength() { - return keyLength == null ? null : keyLength.getLength(); } } diff --git a/spring-credhub-core/src/main/java/org/springframework/credhub/support/ssh/SshParameters.java b/spring-credhub-core/src/main/java/org/springframework/credhub/support/ssh/SshParameters.java index a4f0565..cc5d883 100644 --- a/spring-credhub-core/src/main/java/org/springframework/credhub/support/ssh/SshParameters.java +++ b/spring-credhub-core/src/main/java/org/springframework/credhub/support/ssh/SshParameters.java @@ -17,6 +17,7 @@ package org.springframework.credhub.support.ssh; import org.springframework.credhub.support.KeyLength; +import org.springframework.credhub.support.rsa.KeyParameters; import org.springframework.util.Assert; /** @@ -25,15 +26,14 @@ import org.springframework.util.Assert; * * @author Scott Frederick */ -public class SshParameters { - private final KeyLength keyLength; +public class SshParameters extends KeyParameters { private final String sshComment; /** * Create a {@link SshParameters} using defaults for all parameter values. */ private SshParameters() { - keyLength = null; + super(); sshComment = null; } @@ -43,8 +43,8 @@ public class SshParameters { * @param sshComment comment for the generated SSH key; must not be {@literal null} */ public SshParameters(String sshComment) { + super(); Assert.notNull(sshComment, "sshComment must not be null"); - this.keyLength = null; this.sshComment = sshComment; } @@ -54,8 +54,8 @@ public class SshParameters { * @param keyLength length of generated SSH key; must not be {@literal null} */ public SshParameters(KeyLength keyLength) { + super(keyLength); Assert.notNull(keyLength, "keyLength must not be null"); - this.keyLength = keyLength; this.sshComment = null; } @@ -66,21 +66,12 @@ public class SshParameters { * @param sshComment comment for the generated SSH key; must not be {@literal null} */ public SshParameters(KeyLength keyLength, String sshComment) { + super(keyLength); Assert.notNull(keyLength, "keyLength must not be null"); Assert.notNull(sshComment, "sshComment must not be null"); - this.keyLength = keyLength; this.sshComment = sshComment; } - /** - * Get the value of the key length parameter. - * - * @return the value of the parameter; will be {@literal null} if not explicitly set - */ - public Integer getKeyLength() { - return keyLength == null ? null : keyLength.getLength(); - } - /** * Get the value of the ssh comment parameter. * diff --git a/spring-credhub-core/src/test/java/org/springframework/credhub/core/CredHubTemplateDetailCertificateUnitTests.java b/spring-credhub-core/src/test/java/org/springframework/credhub/core/CredHubTemplateDetailCertificateUnitTests.java index 6b0a179..feb04d6 100644 --- a/spring-credhub-core/src/test/java/org/springframework/credhub/core/CredHubTemplateDetailCertificateUnitTests.java +++ b/spring-credhub-core/src/test/java/org/springframework/credhub/core/CredHubTemplateDetailCertificateUnitTests.java @@ -28,15 +28,22 @@ import org.springframework.credhub.support.CredentialDetails; import org.springframework.credhub.support.CredentialDetailsData; import org.springframework.credhub.support.CredentialRequest; import org.springframework.credhub.support.CredentialType; +import org.springframework.credhub.support.ParametersRequest; import org.springframework.credhub.support.certificate.CertificateCredential; import org.springframework.credhub.support.certificate.CertificateCredentialRequest; +import org.springframework.credhub.support.certificate.CertificateParameters; +import org.springframework.credhub.support.certificate.CertificateParametersRequest; import org.springframework.http.ResponseEntity; @RunWith(Theories.class) public class CredHubTemplateDetailCertificateUnitTests - extends CredHubTemplateDetailUnitTestsBase { + extends CredHubTemplateDetailUnitTestsBase { private static final CertificateCredential CREDENTIAL = new CertificateCredential("certificate", "authority", "private-key"); + private static final CertificateParameters PARAMETERS = CertificateParameters.builder() + .commonName("common") + .credential("credential") + .build(); @DataPoints("detail-responses") public static List>> buildDetailResponses() { @@ -56,6 +63,14 @@ public class CredHubTemplateDetailCertificateUnitTests .build(); } + @Override + public ParametersRequest getGenerateRequest() { + return CertificateParametersRequest.builder() + .name(NAME) + .parameters(PARAMETERS) + .build(); + } + @Override public Class getType() { return CertificateCredential.class; @@ -67,6 +82,12 @@ public class CredHubTemplateDetailCertificateUnitTests verifyWrite(expectedResponse); } + @Theory + public void generate(@FromDataPoints("detail-responses") + ResponseEntity> expectedResponse) { + verifyGenerate(expectedResponse); + } + @Theory public void getById(@FromDataPoints("detail-responses") ResponseEntity> expectedResponse) { diff --git a/spring-credhub-core/src/test/java/org/springframework/credhub/support/certificate/CertificateParametersRequestUnitTests.java b/spring-credhub-core/src/test/java/org/springframework/credhub/support/certificate/CertificateParametersRequestUnitTests.java new file mode 100644 index 0000000..37fb0e5 --- /dev/null +++ b/spring-credhub-core/src/test/java/org/springframework/credhub/support/certificate/CertificateParametersRequestUnitTests.java @@ -0,0 +1,132 @@ +/* + * Copyright 2016-2017 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.credhub.support.certificate; + +import org.junit.Test; + +import org.springframework.credhub.support.KeyLength; +import org.springframework.credhub.support.ParametersRequestUnitTestsBase; +import org.springframework.credhub.support.SimpleCredentialName; +import org.springframework.credhub.support.certificate.CertificateParametersRequest.CertificateParametersRequestBuilder; + +import static org.hamcrest.CoreMatchers.allOf; +import static org.hamcrest.CoreMatchers.equalTo; +import static org.junit.Assert.assertThat; +import static org.valid4j.matchers.jsonpath.JsonPathMatchers.hasJsonPath; +import static org.valid4j.matchers.jsonpath.JsonPathMatchers.hasNoJsonPath; + +public class CertificateParametersRequestUnitTests extends ParametersRequestUnitTestsBase { + @Test + public void serializeWithParameters() throws Exception { + CertificateParametersRequestBuilder requestBuilder = CertificateParametersRequest.builder() + .name(new SimpleCredentialName("example", "credential")) + .overwrite(true) + .parameters(CertificateParameters.builder() + .keyLength(KeyLength.LENGTH_2048) + .commonName("common") + .alternateNames("alt1", "alt2") + .organization("org") + .organizationUnit("dev") + .locality("city") + .state("state") + .country("country") + .duration(1234) + .credential("credential") + .certificateAuthority(true) + .selfSign(false) + .build()); + + String jsonValue = serializeToJson(requestBuilder); + + assertCommonRequestFields(jsonValue, true, "/example/credential", "certificate"); + assertThat(jsonValue, + allOf(hasJsonPath("$.parameters.key_length", equalTo(2048)), + hasJsonPath("$.parameters.common_name", equalTo("common")), + hasJsonPath("$.parameters.alternative_names[0]", equalTo("alt1")), + hasJsonPath("$.parameters.alternative_names[1]", equalTo("alt2")), + hasJsonPath("$.parameters.organization", equalTo("org")), + hasJsonPath("$.parameters.organization_unit", equalTo("dev")), + hasJsonPath("$.parameters.locality", equalTo("city")), + hasJsonPath("$.parameters.state", equalTo("state")), + hasJsonPath("$.parameters.country", equalTo("country")), + hasJsonPath("$.parameters.duration", equalTo(1234)), + hasJsonPath("$.parameters.credential", equalTo("credential")), + hasJsonPath("$.parameters.is_ca", equalTo(true)), + hasJsonPath("$.parameters.self_sign", equalTo(false)))); + } + + @Test + public void serializeWithMinimalParameters() throws Exception { + CertificateParametersRequestBuilder requestBuilder = CertificateParametersRequest.builder() + .name(new SimpleCredentialName("example", "credential")) + .overwrite(true) + .parameters(CertificateParameters.builder() + .commonName("common") + .credential("credential") + .build()); + + String jsonValue = serializeToJson(requestBuilder); + + assertCommonRequestFields(jsonValue, true, "/example/credential", "certificate"); + assertThat(jsonValue, + allOf(hasNoJsonPath("$.parameters.key_length"), + hasJsonPath("$.parameters.common_name", equalTo("common")), + hasJsonPath("$.parameters.credential", equalTo("credential")), + hasNoJsonPath("$.parameters.alternative_names"), + hasNoJsonPath("$.parameters.organization"), + hasNoJsonPath("$.parameters.organization_unit"), + hasNoJsonPath("$.parameters.locality"), + hasNoJsonPath("$.parameters.state"), + hasNoJsonPath("$.parameters.country"), + hasNoJsonPath("$.parameters.duration"), + hasNoJsonPath("$.parameters.is_ca"), + hasNoJsonPath("$.parameters.self_sign"))); + } + + @Test + public void serializeWithNoParameters() throws Exception { + CertificateParametersRequestBuilder requestBuilder = CertificateParametersRequest.builder() + .name(new SimpleCredentialName("example", "credential")) + .overwrite(true); + + String jsonValue = serializeToJson(requestBuilder); + + assertCommonRequestFields(jsonValue, true, "/example/credential", "certificate"); + assertParametersNotSet(jsonValue); + } + + @Test(expected = IllegalArgumentException.class) + public void serializeWithEmptyParameters() throws Exception { + CertificateParametersRequestBuilder requestBuilder = CertificateParametersRequest.builder() + .name(new SimpleCredentialName("example", "credential")) + .overwrite(true) + .parameters(CertificateParameters.builder() + .keyLength(KeyLength.LENGTH_2048) + .build()); + + String jsonValue = serializeToJson(requestBuilder); + } + + private void assertParametersNotSet(String jsonValue) { + assertThat(jsonValue, + allOf(hasNoJsonPath("$.parameters.key_length"), + hasNoJsonPath("$.parameters.exclude_lower"), + hasNoJsonPath("$.parameters.exclude_upper"), + hasNoJsonPath("$.parameters.exclude_number"), + hasNoJsonPath("$.parameters.include_special"))); + } +} \ No newline at end of file