Add support for generation of RSA and SSH credentials.

This commit is contained in:
Scott Frederick
2017-05-26 15:18:08 -05:00
parent e1e23bced2
commit cfae43a34f
13 changed files with 545 additions and 32 deletions

View File

@@ -45,7 +45,7 @@ public class JsonUtils {
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_EMPTY);
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
configureCredentialDetailcredentialTypeMapping(objectMapper);
configureCredentialDetailTypeMapping(objectMapper);
return objectMapper;
}
@@ -56,7 +56,7 @@ public class JsonUtils {
*
* @param objectMapper the {@link ObjectMapper} to configure
*/
private static void configureCredentialDetailcredentialTypeMapping(ObjectMapper objectMapper) {
private static void configureCredentialDetailTypeMapping(ObjectMapper objectMapper) {
List<NamedType> subtypes = new ArrayList<NamedType>();
for (CredentialType type : CredentialType.values()) {
subtypes.add(new NamedType(type.getModelClass(), type.getValueType()));

View File

@@ -0,0 +1,51 @@
/*
* 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;
import com.fasterxml.jackson.annotation.JsonCreator;
public enum KeyLength {
LENGTH_2048(2048),
LENGTH_3072(3072),
LENGTH_4096(4096);
private final int length;
KeyLength(int length) {
this.length = length;
}
public int getLength() {
return length;
}
/**
* Convert an integer value to its enum value.
*
* @param length the integer value to convert to enum value
* @return the enum value
*/
@JsonCreator
public static KeyLength getTypeByString(int length) {
for (KeyLength value : KeyLength.values()) {
if (value.getLength() == length) {
return value;
}
}
return null;
}
}

View File

@@ -91,14 +91,14 @@ public class ParametersRequest<T> extends CredHubRequest {
* A builder that provides a fluent API for constructing {@link ParametersRequest}s.
*/
@SuppressWarnings("unchecked")
protected static abstract class GenerateCredentialRequestBuilder<T, R extends ParametersRequest<T>, B extends GenerateCredentialRequestBuilder<T, R, B>> {
protected static abstract class ParametersRequestBuilder<T, R extends ParametersRequest<T>, B extends ParametersRequestBuilder<T, R, B>> {
private final B thisObj;
protected final R targetObj;
/**
* Create a {@link GenerateCredentialRequestBuilder}. Intended for internal use.
* Create a {@link ParametersRequestBuilder}. Intended for internal use.
*/
protected GenerateCredentialRequestBuilder() {
protected ParametersRequestBuilder() {
this.thisObj = createBuilder();
this.targetObj = createTarget();
}

View File

@@ -17,7 +17,7 @@
package org.springframework.credhub.support.password;
/**
* Parameters for generating a new password value. All parameters are optional; if not specified,
* Parameters for generating a new password credential. All parameters are optional; if not specified,
* CredHub-provided defaults will be used.
*
* @author Scott Frederick
@@ -43,7 +43,7 @@ public class PasswordParameters {
/**
* Create a {@link PasswordParameters} using the specified values.
*
* @param length length of generated credential value
* @param length length of generated password value
* @param excludeUpper {@literal true} to exclude upper case alpha characters from generated credential value
* @param excludeLower {@literal true} to exclude lower case alpha characters from generated credential value
* @param excludeNumber {@literal true} to exclude numeric characters from generated credential value

View File

@@ -40,22 +40,22 @@ public class PasswordParametersRequest extends ParametersRequest<PasswordParamet
*
* @return a builder
*/
public static PasswordGenerateRequestBuilder builder() {
return new PasswordGenerateRequestBuilder();
public static PasswordParametersRequestBuilder builder() {
return new PasswordParametersRequestBuilder();
}
/**
* A builder that provides a fluent API for constructing {@link PasswordParametersRequest}s.
*/
public static class PasswordGenerateRequestBuilder
extends GenerateCredentialRequestBuilder<PasswordParameters, PasswordParametersRequest, PasswordGenerateRequestBuilder> {
public static class PasswordParametersRequestBuilder
extends ParametersRequestBuilder<PasswordParameters, PasswordParametersRequest, PasswordParametersRequestBuilder> {
@Override
protected PasswordParametersRequest createTarget() {
return new PasswordParametersRequest();
}
@Override
protected PasswordGenerateRequestBuilder createBuilder() {
protected PasswordParametersRequestBuilder createBuilder() {
return this;
}
@@ -65,11 +65,10 @@ public class PasswordParametersRequest extends ParametersRequest<PasswordParamet
* @param parameters the generation parameters; must not be {@literal null}
* @return the builder
*/
public PasswordGenerateRequestBuilder parameters(PasswordParameters parameters) {
public PasswordParametersRequestBuilder parameters(PasswordParameters parameters) {
Assert.notNull(parameters, "parameters must not be null");
targetObj.setParameters(parameters);
return this;
}
}
}

View File

@@ -0,0 +1,56 @@
/*
* 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;
import org.springframework.util.Assert;
/**
* Parameters for generating a new RSA credential. All parameters are optional; if not specified,
* CredHub-provided defaults will be used.
*
* @author Scott Frederick
*/
public class RsaParameters {
private final KeyLength keyLength;
/**
* Create a {@link RsaParameters} using defaults for all parameter values.
*/
private RsaParameters() {
keyLength = null;
}
/**
* Create a {@link RsaParameters} using the specified values.
*
* @param keyLength length of generated RSA key; must not be {@literal null}
*/
public RsaParameters(KeyLength 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();
}
}

View File

@@ -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.rsa;
import org.springframework.credhub.support.ParametersRequest;
import org.springframework.util.Assert;
import static org.springframework.credhub.support.CredentialType.RSA;
/**
* The details of a request to generate a new {@link RsaCredential} in CredHub.
*
* @author Scott Frederick
*/
public class RsaParametersRequest extends ParametersRequest<RsaParameters> {
/**
* Create a {@link RsaParametersRequest}.
*/
RsaParametersRequest() {
super(RSA);
}
/**
* Create a builder that provides a fluent API for providing the values required
* to construct a {@link RsaParametersRequest}.
*
* @return a builder
*/
public static RsaParametersRequestBuilder builder() {
return new RsaParametersRequestBuilder();
}
/**
* A builder that provides a fluent API for constructing {@link RsaParametersRequest}s.
*/
public static class RsaParametersRequestBuilder
extends ParametersRequestBuilder<RsaParameters, RsaParametersRequest, RsaParametersRequestBuilder> {
@Override
protected RsaParametersRequest createTarget() {
return new RsaParametersRequest();
}
@Override
protected RsaParametersRequestBuilder createBuilder() {
return this;
}
/**
* Set the parameters for generation of an RSA credential.
*
* @param parameters the generation parameters; must not be {@literal null}
* @return the builder
*/
public RsaParametersRequestBuilder parameters(RsaParameters parameters) {
Assert.notNull(parameters, "parameters must not be null");
targetObj.setParameters(parameters);
return this;
}
}
}

View File

@@ -0,0 +1,92 @@
/*
* 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.ssh;
import org.springframework.credhub.support.KeyLength;
import org.springframework.util.Assert;
/**
* Parameters for generating a new SSH credential. All parameters are optional; if not specified,
* CredHub-provided defaults will be used.
*
* @author Scott Frederick
*/
public class SshParameters {
private final KeyLength keyLength;
private final String sshComment;
/**
* Create a {@link SshParameters} using defaults for all parameter values.
*/
private SshParameters() {
keyLength = null;
sshComment = null;
}
/**
* Create a {@link SshParameters} using the specified values.
*
* @param sshComment comment for the generated SSH key; must not be {@literal null}
*/
public SshParameters(String sshComment) {
Assert.notNull(sshComment, "sshComment must not be null");
this.keyLength = null;
this.sshComment = sshComment;
}
/**
* Create a {@link SshParameters} using the specified values.
*
* @param keyLength length of generated SSH key; must not be {@literal null}
*/
public SshParameters(KeyLength keyLength) {
Assert.notNull(keyLength, "keyLength must not be null");
this.keyLength = keyLength;
this.sshComment = null;
}
/**
* Create a {@link SshParameters} using the specified values.
*
* @param keyLength length of generated SSH key; must not be {@literal null}
* @param sshComment comment for the generated SSH key; must not be {@literal null}
*/
public SshParameters(KeyLength keyLength, String sshComment) {
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.
*
* @return the value of the parameter; will be {@literal null} if not explicitly set
*/
public String getSshComment() {
return sshComment;
}
}

View File

@@ -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.ssh;
import org.springframework.credhub.support.ParametersRequest;
import org.springframework.util.Assert;
import static org.springframework.credhub.support.CredentialType.SSH;
/**
* The details of a request to generate a new {@link SshCredential} in CredHub.
*
* @author Scott Frederick
*/
public class SshParametersRequest extends ParametersRequest<SshParameters> {
/**
* Create a {@link SshParametersRequest}.
*/
SshParametersRequest() {
super(SSH);
}
/**
* Create a builder that provides a fluent API for providing the values required
* to construct a {@link SshParametersRequest}.
*
* @return a builder
*/
public static SshParametersRequestBuilder builder() {
return new SshParametersRequestBuilder();
}
/**
* A builder that provides a fluent API for constructing {@link SshParametersRequest}s.
*/
public static class SshParametersRequestBuilder
extends ParametersRequestBuilder<SshParameters, SshParametersRequest, SshParametersRequestBuilder> {
@Override
protected SshParametersRequest createTarget() {
return new SshParametersRequest();
}
@Override
protected SshParametersRequestBuilder createBuilder() {
return this;
}
/**
* Set the parameters for generation of an SSH credential.
*
* @param parameters the generation parameters; must not be {@literal null}
* @return the builder
*/
public SshParametersRequestBuilder parameters(SshParameters parameters) {
Assert.notNull(parameters, "parameters must not be null");
targetObj.setParameters(parameters);
return this;
}
}
}

View File

@@ -20,9 +20,13 @@ import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.Before;
import org.springframework.credhub.support.ParametersRequest.GenerateCredentialRequestBuilder;
import org.springframework.credhub.support.ParametersRequest.ParametersRequestBuilder;
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;
import static org.valid4j.matchers.jsonpath.JsonPathMatchers.isJson;
public abstract class ParametersRequestUnitTestsBase {
@@ -33,10 +37,18 @@ public abstract class ParametersRequestUnitTestsBase {
mapper = JsonUtils.buildObjectMapper();
}
protected <T extends GenerateCredentialRequestBuilder> String serializeToJson(T requestBuilder)
protected <T extends ParametersRequestBuilder> String serializeToJson(T requestBuilder)
throws JsonProcessingException {
String jsonValue = mapper.writeValueAsString(requestBuilder.build());
assertThat(jsonValue, isJson());
return jsonValue;
}
protected void assertCommonRequestFields(String jsonValue, boolean overwrite, String name, String type) {
assertThat(jsonValue,
allOf(hasJsonPath("$.overwrite", equalTo(overwrite)),
hasJsonPath("$.name", equalTo(name)),
hasJsonPath("$.type", equalTo(type))));
assertThat(jsonValue, hasNoJsonPath("$.additional_permissions"));
}
}

View File

@@ -20,7 +20,7 @@ import org.junit.Test;
import org.springframework.credhub.support.ParametersRequestUnitTestsBase;
import org.springframework.credhub.support.SimpleCredentialName;
import org.springframework.credhub.support.password.PasswordParametersRequest.PasswordGenerateRequestBuilder;
import org.springframework.credhub.support.password.PasswordParametersRequest.PasswordParametersRequestBuilder;
import static org.hamcrest.CoreMatchers.allOf;
import static org.hamcrest.CoreMatchers.equalTo;
@@ -31,7 +31,7 @@ import static org.valid4j.matchers.jsonpath.JsonPathMatchers.hasNoJsonPath;
public class PasswordParametersRequestUnitTests extends ParametersRequestUnitTestsBase {
@Test
public void serializeWithParameters() throws Exception {
PasswordGenerateRequestBuilder requestBuilder = PasswordParametersRequest.builder()
PasswordParametersRequestBuilder requestBuilder = PasswordParametersRequest.builder()
.name(new SimpleCredentialName("example", "credential"))
.overwrite(true)
.parameters(PasswordParameters.builder()
@@ -44,38 +44,46 @@ public class PasswordParametersRequestUnitTests extends ParametersRequestUnitTes
String jsonValue = serializeToJson(requestBuilder);
assertCommonRequestFields(jsonValue, true, "/example/credential", "password");
assertThat(jsonValue,
allOf(hasJsonPath("$.overwrite", equalTo(true)),
hasJsonPath("$.name", equalTo("/example/credential")),
hasJsonPath("$.type", equalTo("password")),
hasJsonPath("$.parameters.length", equalTo(20)),
allOf(hasJsonPath("$.parameters.length", equalTo(20)),
hasJsonPath("$.parameters.exclude_lower", equalTo(true)),
hasJsonPath("$.parameters.exclude_upper", equalTo(false)),
hasJsonPath("$.parameters.exclude_number", equalTo(true)),
hasJsonPath("$.parameters.include_special", equalTo(false))));
assertThat(jsonValue, hasNoJsonPath("$.additional_permissions"));
}
@Test
public void serializeWithDefaults() throws Exception {
PasswordGenerateRequestBuilder requestBuilder = PasswordParametersRequest.builder()
public void serializeWithEmptyParameters() throws Exception {
PasswordParametersRequestBuilder requestBuilder = PasswordParametersRequest.builder()
.name(new SimpleCredentialName("example", "credential"))
.overwrite(true)
.parameters(new PasswordParameters());
String jsonValue = serializeToJson(requestBuilder);
assertCommonRequestFields(jsonValue, true, "/example/credential", "password");
assertParametersNotSet(jsonValue);
}
@Test
public void serializeWithNoParameters() throws Exception {
PasswordParametersRequestBuilder requestBuilder = PasswordParametersRequest.builder()
.name(new SimpleCredentialName("example", "credential"))
.overwrite(true);
String jsonValue = serializeToJson(requestBuilder);
assertCommonRequestFields(jsonValue, true, "/example/credential", "password");
assertParametersNotSet(jsonValue);
}
private void assertParametersNotSet(String jsonValue) {
assertThat(jsonValue,
allOf(hasJsonPath("$.overwrite", equalTo(true)),
hasJsonPath("$.name", equalTo("/example/credential")),
hasJsonPath("$.type", equalTo("password")),
hasNoJsonPath("$.parameters.length"),
allOf(hasNoJsonPath("$.parameters.length"),
hasNoJsonPath("$.parameters.exclude_lower"),
hasNoJsonPath("$.parameters.exclude_upper"),
hasNoJsonPath("$.parameters.exclude_number"),
hasNoJsonPath("$.parameters.include_special")));
assertThat(jsonValue, hasNoJsonPath("$.additional_permissions"));
}
}

View File

@@ -0,0 +1,56 @@
/*
* 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.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.rsa.RsaParametersRequest.RsaParametersRequestBuilder;
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 RsaParametersRequestUnitTests extends ParametersRequestUnitTestsBase {
@Test
public void serializeWithParameters() throws Exception {
RsaParametersRequestBuilder requestBuilder = RsaParametersRequest.builder()
.name(new SimpleCredentialName("example", "credential"))
.overwrite(true)
.parameters(new RsaParameters(KeyLength.LENGTH_4096));
String jsonValue = serializeToJson(requestBuilder);
assertCommonRequestFields(jsonValue, true, "/example/credential", "rsa");
assertThat(jsonValue, hasJsonPath("$.parameters.key_length", equalTo(4096)));
}
@Test
public void serializeWithNoParameters() throws Exception {
RsaParametersRequestBuilder requestBuilder = RsaParametersRequest.builder()
.name(new SimpleCredentialName("example", "credential"))
.overwrite(true);
String jsonValue = serializeToJson(requestBuilder);
assertCommonRequestFields(jsonValue, true, "/example/credential", "rsa");
assertThat(jsonValue, hasNoJsonPath("$.parameters.key_length"));
}
}

View File

@@ -0,0 +1,91 @@
/*
* 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.ssh;
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.ssh.SshParametersRequest.SshParametersRequestBuilder;
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 SshParametersRequestUnitTests extends ParametersRequestUnitTestsBase {
@Test
public void serializeWithParameters() throws Exception {
SshParametersRequestBuilder requestBuilder = SshParametersRequest.builder()
.name(new SimpleCredentialName("example", "credential"))
.overwrite(true)
.parameters(new SshParameters(KeyLength.LENGTH_2048, "ssh comment"));
String jsonValue = serializeToJson(requestBuilder);
assertCommonRequestFields(jsonValue, true, "/example/credential", "ssh");
assertThat(jsonValue,
allOf(hasJsonPath("$.parameters.key_length", equalTo(2048)),
hasJsonPath("$.parameters.ssh_comment", equalTo("ssh comment"))));
}
@Test
public void serializeWithLengthParameter() throws Exception {
SshParametersRequestBuilder requestBuilder = SshParametersRequest.builder()
.name(new SimpleCredentialName("example", "credential"))
.overwrite(true)
.parameters(new SshParameters(KeyLength.LENGTH_2048));
String jsonValue = serializeToJson(requestBuilder);
assertCommonRequestFields(jsonValue, true, "/example/credential", "ssh");
assertThat(jsonValue,
allOf(hasJsonPath("$.parameters.key_length", equalTo(2048)),
hasNoJsonPath("$.parameters.ssh_comment")));
}
@Test
public void serializeWithCommentParameter() throws Exception {
SshParametersRequestBuilder requestBuilder = SshParametersRequest.builder()
.name(new SimpleCredentialName("example", "credential"))
.overwrite(true)
.parameters(new SshParameters("ssh comment"));
String jsonValue = serializeToJson(requestBuilder);
assertCommonRequestFields(jsonValue, true, "/example/credential", "ssh");
assertThat(jsonValue,
allOf(hasNoJsonPath("$.parameters.key_length"),
hasJsonPath("$.parameters.ssh_comment", equalTo("ssh comment"))));
}
@Test
public void serializeWithNoParameters() throws Exception {
SshParametersRequestBuilder requestBuilder = SshParametersRequest.builder()
.name(new SimpleCredentialName("example", "credential"))
.overwrite(true);
String jsonValue = serializeToJson(requestBuilder);
assertCommonRequestFields(jsonValue, true, "/example/credential", "ssh");
assertThat(jsonValue,
allOf(hasNoJsonPath("$.parameters.key_length"),
hasNoJsonPath("$.parameters.ssh_comment")));
}
}