diff --git a/build.gradle b/build.gradle index d11c857..ea67316 100644 --- a/build.gradle +++ b/build.gradle @@ -147,6 +147,8 @@ configure(rootProject) { project.sourceSets.main.compileClasspath }) + exclude '**/spring-credhub-integration-tests/**' + maxMemory = "1024m" destinationDir = new File(buildDir, "api") } diff --git a/settings.gradle b/settings.gradle index c696461..1ec6a73 100644 --- a/settings.gradle +++ b/settings.gradle @@ -3,7 +3,9 @@ rootProject.name = 'spring-credhub' include ':spring-credhub-core' include ':spring-credhub-cloud-connector' include ':spring-credhub-starter' +include ':spring-credhub-integration-tests' project(':spring-credhub-core').projectDir = "$rootDir/spring-credhub-core" as File project(':spring-credhub-cloud-connector').projectDir = "$rootDir/spring-credhub-cloud-connector" as File project(':spring-credhub-starter').projectDir = "$rootDir/spring-credhub-starter" as File +project(':spring-credhub-integration-tests').projectDir = "$rootDir/spring-credhub-integration-tests" as File diff --git a/spring-credhub-core/src/main/java/org/springframework/credhub/configuration/CredHubTemplateFactory.java b/spring-credhub-core/src/main/java/org/springframework/credhub/configuration/CredHubTemplateFactory.java index a3de7bb..d1d88ff 100644 --- a/spring-credhub-core/src/main/java/org/springframework/credhub/configuration/CredHubTemplateFactory.java +++ b/spring-credhub-core/src/main/java/org/springframework/credhub/configuration/CredHubTemplateFactory.java @@ -45,6 +45,17 @@ public class CredHubTemplateFactory { return ClientHttpRequestFactoryFactory.create(clientOptions()); } + /** + * Create a {@link ClientHttpRequestFactory}. + * + * @return the {@link ClientHttpRequestFactory} instance. + * + * @param clientOptions options for creating the client connection + */ + public ClientHttpRequestFactory clientHttpRequestFactoryWrapper(ClientOptions clientOptions) { + return ClientHttpRequestFactoryFactory.create(clientOptions); + } + /** * Create the default {@link ClientOptions} to configure communication parameters. * diff --git a/spring-credhub-core/src/main/java/org/springframework/credhub/support/ClientOptions.java b/spring-credhub-core/src/main/java/org/springframework/credhub/support/ClientOptions.java index 112d141..1ebe785 100644 --- a/spring-credhub-core/src/main/java/org/springframework/credhub/support/ClientOptions.java +++ b/spring-credhub-core/src/main/java/org/springframework/credhub/support/ClientOptions.java @@ -25,36 +25,38 @@ import java.util.concurrent.TimeUnit; * @author Scott Frederick */ public class ClientOptions { + private Integer connectionTimeout; + + private Integer readTimeout; + + private boolean trustSelfSignedCerts; + + private String[] caCertFiles; /** - * Connection timeout; - */ - private final Integer connectionTimeout; - - /** - * Read timeout; - */ - private final Integer readTimeout; - - /** - * Create new {@link ClientOptions} with default timeouts. + * Create new {@link ClientOptions} with default values. */ public ClientOptions() { this.connectionTimeout = null; this.readTimeout = null; + this.trustSelfSignedCerts = false; } /** * Create a {@link ClientOptions} with the provided values. * - * @param connectionTimeout connection timeout in {@link TimeUnit#MILLISECONDS}, must - * be greater {@literal 0}. - * @param readTimeout read timeout in {@link TimeUnit#MILLISECONDS}, must be greater - * {@literal 0}. + * @param connectionTimeout connection timeout in {@link TimeUnit#MILLISECONDS}, must + * be greater {@literal 0} + * @param readTimeout read timeout in {@link TimeUnit#MILLISECONDS}, must be greater + * {@literal 0} + * @param trustSelfSignedCerts trust self-signed SSL certficates */ - public ClientOptions(int connectionTimeout, int readTimeout) { + public ClientOptions(int connectionTimeout, int readTimeout, boolean trustSelfSignedCerts, + String[] caCertFiles) { this.connectionTimeout = connectionTimeout; this.readTimeout = readTimeout; + this.trustSelfSignedCerts = trustSelfSignedCerts; + this.caCertFiles = caCertFiles; } /** @@ -63,7 +65,11 @@ public class ClientOptions { * @return the connection timeout; can be {@literal null if not explicitly set} */ public Integer getConnectionTimeout() { - return connectionTimeout; + return this.connectionTimeout; + } + + public void setConnectionTimeout(Integer connectionTimeout) { + this.connectionTimeout = connectionTimeout; } /** @@ -72,7 +78,26 @@ public class ClientOptions { * @return the read timeout; can be {@literal null if not explicitly set} */ public Integer getReadTimeout() { - return readTimeout; + return this.readTimeout; } + public void setReadTimeout(Integer readTimeout) { + this.readTimeout = readTimeout; + } + + public boolean isTrustSelfSignedCerts() { + return this.trustSelfSignedCerts; + } + + public void setTrustSelfSignedCerts(boolean trustSelfSignedCerts) { + this.trustSelfSignedCerts = trustSelfSignedCerts; + } + + public String[] getCaCertFiles() { + return caCertFiles; + } + + public void setCaCertFiles(String[] caCertFiles) { + this.caCertFiles = caCertFiles; + } } \ No newline at end of file diff --git a/spring-credhub-core/src/main/java/org/springframework/credhub/support/CredHubRequest.java b/spring-credhub-core/src/main/java/org/springframework/credhub/support/CredHubRequest.java index eb635d8..96c5b7f 100644 --- a/spring-credhub-core/src/main/java/org/springframework/credhub/support/CredHubRequest.java +++ b/spring-credhub-core/src/main/java/org/springframework/credhub/support/CredHubRequest.java @@ -33,7 +33,7 @@ import java.util.Objects; */ @SuppressWarnings("WeakerAccess") public class CredHubRequest { - protected boolean overwrite; + protected Boolean overwrite; protected WriteMode mode; protected CredentialName name; protected CredentialType credentialType; @@ -51,7 +51,7 @@ public class CredHubRequest { * @return the {@literal boolean} overwrite value * @deprecated as of CredHub 1.6, use {@link #mode} */ - public boolean isOverwrite() { + public Boolean isOverwrite() { return this.overwrite; } diff --git a/spring-credhub-core/src/test/java/org/springframework/credhub/support/CredHubRequestUnitTestsBase.java b/spring-credhub-core/src/test/java/org/springframework/credhub/support/CredHubRequestUnitTestsBase.java index f8b569b..4681744 100644 --- a/spring-credhub-core/src/test/java/org/springframework/credhub/support/CredHubRequestUnitTestsBase.java +++ b/spring-credhub-core/src/test/java/org/springframework/credhub/support/CredHubRequestUnitTestsBase.java @@ -98,9 +98,13 @@ public abstract class CredHubRequestUnitTestsBase { return JsonTestUtils.toJsonPath(requestBuilder.build()); } - protected void assertCommonRequestFields(DocumentContext json, boolean overwrite, WriteMode writeMode, + protected void assertCommonRequestFields(DocumentContext json, Boolean overwrite, WriteMode writeMode, String name, String type) { - assertThat(json).hasPath("$.overwrite").isEqualTo(overwrite); + if (overwrite == null) { + assertThat(json).hasNoPath("$.overwrite"); + } else { + assertThat(json).hasPath("$.overwrite").isEqualTo(overwrite); + } assertThat(json).hasPath("$.mode").isEqualTo(writeMode.getMode()); assertThat(json).hasPath("$.name").isEqualTo(name); assertThat(json).hasPath("$.type").isEqualTo(type); diff --git a/spring-credhub-core/src/test/java/org/springframework/credhub/support/json/JsonCredentialRequestUnitTests.java b/spring-credhub-core/src/test/java/org/springframework/credhub/support/json/JsonCredentialRequestUnitTests.java index cb126e2..b79666c 100644 --- a/spring-credhub-core/src/test/java/org/springframework/credhub/support/json/JsonCredentialRequestUnitTests.java +++ b/spring-credhub-core/src/test/java/org/springframework/credhub/support/json/JsonCredentialRequestUnitTests.java @@ -45,7 +45,7 @@ public class JsonCredentialRequestUnitTests extends CredHubRequestUnitTestsBase public void serializeWithJsonValue() { DocumentContext json = toJsonPath(requestBuilder); - assertCommonRequestFields(json, false, WriteMode.OVERWRITE, "/example/credential", "json"); + assertCommonRequestFields(json, null, WriteMode.OVERWRITE, "/example/credential", "json"); assertThat(json).hasPath("$.value.data").isEqualTo("value"); assertThat(json).hasPath("$.value.test").isEqualTo(true); diff --git a/spring-credhub-integration-tests/build.gradle b/spring-credhub-integration-tests/build.gradle new file mode 100644 index 0000000..6a82767 --- /dev/null +++ b/spring-credhub-integration-tests/build.gradle @@ -0,0 +1,68 @@ +/* + * 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. + */ + +description = 'Spring CredHub Integration Tests' + +buildscript { + ext { + springBootVersion = "1.5.8.RELEASE" + } + + dependencies { + classpath 'io.spring.gradle:propdeps-plugin:0.0.10.RELEASE' + classpath 'io.spring.gradle:spring-io-plugin:0.0.8.RELEASE' + classpath "org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}" + } + + repositories { + mavenCentral() + maven { url "https://repo.spring.io/plugins-release" } + } +} + +apply plugin: 'java' +apply plugin: 'maven' +apply plugin: 'eclipse' + +apply plugin: 'propdeps' +apply plugin: 'propdeps-maven' +apply plugin: 'propdeps-idea' +apply plugin: 'propdeps-eclipse' +apply plugin: 'org.springframework.boot' + +dependencies { + compile project(":spring-credhub-starter") + compile("org.springframework.boot:spring-boot-starter") + compile("org.springframework.security.oauth:spring-security-oauth2") + compile("org.apache.httpcomponents:httpclient:4.5.3") { + exclude(group: 'commons-logging', module: 'commons-logging') + } + + testCompile("org.springframework.boot:spring-boot-starter-test") + testCompile("org.assertj:assertj-core:${assertJVersion}") +} + +test { + onlyIf { + project.hasProperty("integrationTests") + } +} + +configurations.archives.artifacts.clear() + +repositories { + mavenCentral() +} \ No newline at end of file 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 new file mode 100644 index 0000000..05a9eae --- /dev/null +++ b/spring-credhub-integration-tests/src/test/java/org/springframework/credhub/integration/CredentialIntegrationTests.java @@ -0,0 +1,81 @@ +package org.springframework.credhub.integration; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.credhub.autoconfig.CredHubAutoConfiguration; +import org.springframework.credhub.autoconfig.CredHubOAuth2TemplateAutoConfiguration; +import org.springframework.credhub.autoconfig.CredHubTemplateAutoConfiguration; +import org.springframework.credhub.core.CredHubCredentialsOperations; +import org.springframework.credhub.core.CredHubOperations; +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.value.ValueCredential; +import org.springframework.credhub.support.value.ValueCredentialRequest; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.junit4.SpringRunner; + +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = {TestApplication.class, + CredHubAutoConfiguration.class, + CredHubTemplateAutoConfiguration.class, + CredHubOAuth2TemplateAutoConfiguration.class}) +@ActiveProfiles("test") +public class CredentialIntegrationTests { + private static final SimpleCredentialName CREDENTIAL_NAME = + new SimpleCredentialName("spring-credhub", "integration-test", "test-value-credential"); + private static final String CREDENTIAL_VALUE = "test-value"; + + @Autowired + private CredHubOperations operations; + + private CredHubCredentialsOperations credentials; + + @Before + public void setUp() { + credentials = operations.credentials(); + } + + @Test + public void writeCredential() { + 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 byId = credentials.getById(written.getId(), ValueCredential.class); + assertThat(byId.getName().getName()).isEqualTo(CREDENTIAL_NAME.getName()); + assertThat(byId.getValue().getValue()).isEqualTo(CREDENTIAL_VALUE); + assertThat(byId.getCredentialType()).isEqualTo(CredentialType.VALUE); + + CredentialDetails byName = credentials.getByName(CREDENTIAL_NAME, ValueCredential.class); + assertThat(byName.getName().getName()).isEqualTo(CREDENTIAL_NAME.getName()); + assertThat(byName.getValue().getValue()).isEqualTo(CREDENTIAL_VALUE); + assertThat(byName.getCredentialType()).isEqualTo(CredentialType.VALUE); + + List foundByName = credentials.findByName(new SimpleCredentialName("/test")); + assertThat(foundByName).hasSize(1); + assertThat(foundByName).extracting("name").extracting("name").containsExactly(CREDENTIAL_NAME.getName()); + + List foundByPath = credentials.findByPath("/spring-credhub/integration-test"); + assertThat(foundByPath).hasSize(1); + assertThat(foundByPath).extracting("name").extracting("name").containsExactly(CREDENTIAL_NAME.getName()); + + credentials.deleteByName(CREDENTIAL_NAME); + + List afterDelete = credentials.findByName(CREDENTIAL_NAME); + assertThat(afterDelete).hasSize(0); + } +} diff --git a/spring-credhub-integration-tests/src/test/java/org/springframework/credhub/integration/PermissionsIntegrationTests.java b/spring-credhub-integration-tests/src/test/java/org/springframework/credhub/integration/PermissionsIntegrationTests.java new file mode 100644 index 0000000..a9aba06 --- /dev/null +++ b/spring-credhub-integration-tests/src/test/java/org/springframework/credhub/integration/PermissionsIntegrationTests.java @@ -0,0 +1,88 @@ +package org.springframework.credhub.integration; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.credhub.autoconfig.CredHubAutoConfiguration; +import org.springframework.credhub.autoconfig.CredHubOAuth2TemplateAutoConfiguration; +import org.springframework.credhub.autoconfig.CredHubTemplateAutoConfiguration; +import org.springframework.credhub.core.CredHubCredentialsOperations; +import org.springframework.credhub.core.CredHubOperations; +import org.springframework.credhub.core.CredHubPermissionsOperations; +import org.springframework.credhub.support.SimpleCredentialName; +import org.springframework.credhub.support.permissions.Actor; +import org.springframework.credhub.support.permissions.CredentialPermission; +import org.springframework.credhub.support.permissions.Operation; +import org.springframework.credhub.support.value.ValueCredentialRequest; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.junit4.SpringRunner; + +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = {TestApplication.class, + CredHubAutoConfiguration.class, + CredHubTemplateAutoConfiguration.class, + CredHubOAuth2TemplateAutoConfiguration.class}) +@ActiveProfiles("test") +public class PermissionsIntegrationTests { + private static final SimpleCredentialName CREDENTIAL_NAME = + new SimpleCredentialName("spring-credhub", "integration-test", "test-permissions-credential"); + private static final String CREDENTIAL_VALUE = "test-value"; + + @Autowired + private CredHubOperations operations; + + private CredHubCredentialsOperations credentials; + private CredHubPermissionsOperations permissions; + + @Before + public void setUp() { + credentials = operations.credentials(); + permissions = operations.permissions(); + } + + @Test + public void managePermissions() { + credentials.write(ValueCredentialRequest.builder() + .name(CREDENTIAL_NAME) + .value(CREDENTIAL_VALUE) + .build()); + + CredentialPermission appPermission = CredentialPermission.builder() + .app("app1") + .operation(Operation.READ) + .build(); + CredentialPermission userPermission = CredentialPermission.builder() + .user("user1") + .operations(Operation.READ, Operation.WRITE, Operation.DELETE) + .build(); + CredentialPermission clientPermission = CredentialPermission.builder() + .client("client1") + .operations(Operation.READ_ACL, Operation.WRITE_ACL) + .build(); + + permissions.addPermissions(CREDENTIAL_NAME, + appPermission, + userPermission, + clientPermission); + + List retrievedPermissions = permissions.getPermissions(CREDENTIAL_NAME); + assertThat(retrievedPermissions).hasSize(3); + + assertThat(retrievedPermissions).containsExactlyInAnyOrder(appPermission, userPermission, clientPermission); + + permissions.deletePermission(CREDENTIAL_NAME, Actor.app("app1")); + permissions.deletePermission(CREDENTIAL_NAME, Actor.user("user1")); + permissions.deletePermission(CREDENTIAL_NAME, Actor.client("client1")); + + List afterDelete = permissions.getPermissions(CREDENTIAL_NAME); + assertThat(afterDelete).hasSize(0); + + operations.credentials().deleteByName(CREDENTIAL_NAME); + } +} diff --git a/spring-credhub-integration-tests/src/test/java/org/springframework/credhub/integration/TestApplication.java b/spring-credhub-integration-tests/src/test/java/org/springframework/credhub/integration/TestApplication.java new file mode 100644 index 0000000..b784b28 --- /dev/null +++ b/spring-credhub-integration-tests/src/test/java/org/springframework/credhub/integration/TestApplication.java @@ -0,0 +1,11 @@ +package org.springframework.credhub.integration; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class TestApplication { + public static void main(String[] args) { + SpringApplication.run(TestApplication.class, args); + } +} diff --git a/spring-credhub-starter/src/main/java/org/springframework/credhub/autoconfig/CredHubAutoConfiguration.java b/spring-credhub-starter/src/main/java/org/springframework/credhub/autoconfig/CredHubAutoConfiguration.java index 6707e9f..4f004c0 100644 --- a/spring-credhub-starter/src/main/java/org/springframework/credhub/autoconfig/CredHubAutoConfiguration.java +++ b/spring-credhub-starter/src/main/java/org/springframework/credhub/autoconfig/CredHubAutoConfiguration.java @@ -42,7 +42,7 @@ public class CredHubAutoConfiguration { private final CredHubTemplateFactory credHubTemplateFactory = new CredHubTemplateFactory(); /** - * Configuration properties for CredHub + * Create a {@link CredHubProperties} bean and populate it from properties. * * @return a {@link CredHubProperties} bean */ @@ -52,6 +52,17 @@ public class CredHubAutoConfiguration { return new CredHubProperties(); } + /** + * Create a {@link ClientOptions} bean and populate it from properties. + * + * @return a {@link ClientOptions} bean + */ + @Bean + @ConfigurationProperties(prefix = "spring.credhub") + public ClientOptions clientOptions() { + return new ClientOptions(); + } + /** * Create a {@link ClientFactoryWrapper} containing a * {@link ClientHttpRequestFactory}. {@link ClientHttpRequestFactory} is not exposed @@ -59,13 +70,14 @@ public class CredHubAutoConfiguration { * {@link ClientOptions} which are not necessarily applicable for the whole * application. * + * @param clientOptions the populated {@link ClientOptions} bean * @return the {@link ClientFactoryWrapper} to wrap a {@link ClientHttpRequestFactory} * instance */ @Bean - public ClientFactoryWrapper clientHttpRequestFactoryWrapper() { + public ClientFactoryWrapper clientHttpRequestFactoryWrapper(ClientOptions clientOptions) { return new ClientFactoryWrapper( - credHubTemplateFactory.clientHttpRequestFactoryWrapper()); + credHubTemplateFactory.clientHttpRequestFactoryWrapper(clientOptions)); } /**