From 8f0286f6f45deeea97e3503e8032b9c157f9303f Mon Sep 17 00:00:00 2001 From: Scott Frederick Date: Thu, 29 Nov 2018 20:00:14 -0600 Subject: [PATCH] Add integration tests for reactive operations. --- .../ReactiveCredHubCertificateTemplate.java | 13 +- .../ReactiveCredHubPermissionTemplate.java | 3 +- .../PermissionIntegrationTests.java | 50 +++- .../ReactiveCertificateIntegrationTests.java | 259 ++++++++++++++++++ .../ReactiveCredHubIntegrationTests.java | 10 +- .../ReactiveCredentialIntegrationTests.java | 8 +- .../ReactiveInfoIntegrationTests.java | 40 +++ ...ReactiveInterpolationIntegrationTests.java | 114 ++++++++ .../ReactivePermissionIntegrationTests.java | 165 +++++++++++ .../ReactivePermissionV2IntegrationTests.java | 176 ++++++++++++ 10 files changed, 818 insertions(+), 20 deletions(-) create mode 100644 spring-credhub-integration-tests/src/test/java/org/springframework/credhub/integration/ReactiveCertificateIntegrationTests.java create mode 100644 spring-credhub-integration-tests/src/test/java/org/springframework/credhub/integration/ReactiveInfoIntegrationTests.java create mode 100644 spring-credhub-integration-tests/src/test/java/org/springframework/credhub/integration/ReactiveInterpolationIntegrationTests.java create mode 100644 spring-credhub-integration-tests/src/test/java/org/springframework/credhub/integration/ReactivePermissionIntegrationTests.java create mode 100644 spring-credhub-integration-tests/src/test/java/org/springframework/credhub/integration/ReactivePermissionV2IntegrationTests.java diff --git a/spring-credhub-core/src/main/java/org/springframework/credhub/core/certificate/ReactiveCredHubCertificateTemplate.java b/spring-credhub-core/src/main/java/org/springframework/credhub/core/certificate/ReactiveCredHubCertificateTemplate.java index 7b08c54..4e853a8 100644 --- a/spring-credhub-core/src/main/java/org/springframework/credhub/core/certificate/ReactiveCredHubCertificateTemplate.java +++ b/spring-credhub-core/src/main/java/org/springframework/credhub/core/certificate/ReactiveCredHubCertificateTemplate.java @@ -22,6 +22,7 @@ import org.springframework.credhub.core.ReactiveCredHubOperations; import org.springframework.credhub.support.CredentialName; import org.springframework.credhub.support.certificate.CertificateCredentialDetails; import org.springframework.credhub.support.certificate.CertificateSummary; +import org.springframework.credhub.support.certificate.CertificateSummaryData; import org.springframework.http.HttpStatus; import org.springframework.util.Assert; import reactor.core.publisher.Flux; @@ -67,7 +68,8 @@ public class ReactiveCredHubCertificateTemplate implements ReactiveCredHubCertif .uri(BASE_URL_PATH) .retrieve() .onStatus(HttpStatus::isError, ExceptionUtils::buildError) - .bodyToFlux(CertificateSummary.class)); + .bodyToMono(CertificateSummaryData.class) + .flatMapMany(data -> Flux.fromIterable(data.getCertificates()))); } @Override @@ -79,8 +81,9 @@ public class ReactiveCredHubCertificateTemplate implements ReactiveCredHubCertif .uri(NAME_URL_QUERY, name.getName()) .retrieve() .onStatus(HttpStatus::isError, ExceptionUtils::buildError) - .bodyToFlux(CertificateSummary.class) - .single()); + .bodyToMono(CertificateSummaryData.class) + .flatMapMany(data -> Flux.fromIterable(data.getCertificates()))) + .single(); } @Override @@ -94,7 +97,7 @@ public class ReactiveCredHubCertificateTemplate implements ReactiveCredHubCertif request.put(TRANSITIONAL_REQUEST_FIELD, setAsTransitional); return credHubOperations.doWithWebClient(webClient -> webClient - .put() + .post() .uri(REGENERATE_URL_PATH, id) .syncBody(request) .retrieve() @@ -113,7 +116,7 @@ public class ReactiveCredHubCertificateTemplate implements ReactiveCredHubCertif request.put(SIGNED_BY_REQUEST_FIELD, certificateName.getName()); return credHubOperations.doWithWebClient(webClient -> webClient - .put() + .post() .uri(BULK_REGENERATE_URL_PATH) .syncBody(request) .retrieve() diff --git a/spring-credhub-core/src/main/java/org/springframework/credhub/core/permission/ReactiveCredHubPermissionTemplate.java b/spring-credhub-core/src/main/java/org/springframework/credhub/core/permission/ReactiveCredHubPermissionTemplate.java index e2abd25..68e8960 100644 --- a/spring-credhub-core/src/main/java/org/springframework/credhub/core/permission/ReactiveCredHubPermissionTemplate.java +++ b/spring-credhub-core/src/main/java/org/springframework/credhub/core/permission/ReactiveCredHubPermissionTemplate.java @@ -58,7 +58,8 @@ public class ReactiveCredHubPermissionTemplate implements ReactiveCredHubPermiss .uri(PERMISSIONS_URL_QUERY, name.getName()) .retrieve() .onStatus(HttpStatus::isError, ExceptionUtils::buildError) - .bodyToFlux(Permission.class)); + .bodyToMono(CredentialPermissions.class) + .flatMapMany(data -> Flux.fromIterable(data.getPermissions()))); } @Override diff --git a/spring-credhub-integration-tests/src/test/java/org/springframework/credhub/integration/PermissionIntegrationTests.java b/spring-credhub-integration-tests/src/test/java/org/springframework/credhub/integration/PermissionIntegrationTests.java index 972981f..7d8340a 100644 --- a/spring-credhub-integration-tests/src/test/java/org/springframework/credhub/integration/PermissionIntegrationTests.java +++ b/spring-credhub-integration-tests/src/test/java/org/springframework/credhub/integration/PermissionIntegrationTests.java @@ -30,6 +30,7 @@ import org.springframework.credhub.support.value.ValueCredentialRequest; import java.util.List; import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.Assume.assumeTrue; public class PermissionIntegrationTests extends CredHubIntegrationTests { private static final SimpleCredentialName CREDENTIAL_NAME = @@ -53,7 +54,9 @@ public class PermissionIntegrationTests extends CredHubIntegrationTests { } @Test - public void managePermissions() { + public void managePermissionsServerV1() { + assumeTrue(serverApiIsV1()); + credentials.write(ValueCredentialRequest.builder() .name(CREDENTIAL_NAME) .value(CREDENTIAL_VALUE) @@ -79,8 +82,7 @@ public class PermissionIntegrationTests extends CredHubIntegrationTests { List retrievedPermissions = permissions.getPermissions(CREDENTIAL_NAME); // CredHub 1.x will automatically add a permission for the authenticated user; - // CredHub 2.x will not - assertThat(retrievedPermissions.size()).isBetween(3, 4); + assertThat(retrievedPermissions.size()).isEqualTo(4); assertThat(retrievedPermissions).contains(appPermission, userPermission, clientPermission); @@ -89,6 +91,46 @@ public class PermissionIntegrationTests extends CredHubIntegrationTests { permissions.deletePermission(CREDENTIAL_NAME, Actor.client("client1")); List afterDelete = permissions.getPermissions(CREDENTIAL_NAME); - assertThat(afterDelete.size()).isBetween(0, 1); + assertThat(afterDelete.size()).isEqualTo(1); + } + + @Test + public void managePermissionsServerV2() { + assumeTrue(serverApiIsV2()); + + credentials.write(ValueCredentialRequest.builder() + .name(CREDENTIAL_NAME) + .value(CREDENTIAL_VALUE) + .build()); + + Permission appPermission = Permission.builder() + .app("app1") + .operation(Operation.READ) + .build(); + Permission userPermission = Permission.builder() + .user("user1") + .operations(Operation.READ, Operation.WRITE, Operation.DELETE) + .build(); + Permission clientPermission = Permission.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.size()).isEqualTo(3); + + assertThat(retrievedPermissions).contains(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.size()).isEqualTo(0); } } diff --git a/spring-credhub-integration-tests/src/test/java/org/springframework/credhub/integration/ReactiveCertificateIntegrationTests.java b/spring-credhub-integration-tests/src/test/java/org/springframework/credhub/integration/ReactiveCertificateIntegrationTests.java new file mode 100644 index 0000000..17d3334 --- /dev/null +++ b/spring-credhub-integration-tests/src/test/java/org/springframework/credhub/integration/ReactiveCertificateIntegrationTests.java @@ -0,0 +1,259 @@ +/* + * 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.integration; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.springframework.credhub.core.certificate.ReactiveCredHubCertificateOperations; +import org.springframework.credhub.core.credential.ReactiveCredHubCredentialOperations; +import org.springframework.credhub.support.CredentialType; +import org.springframework.credhub.support.SimpleCredentialName; +import org.springframework.credhub.support.certificate.CertificateCredential; +import org.springframework.credhub.support.certificate.CertificateParameters; +import org.springframework.credhub.support.certificate.CertificateParametersRequest; +import reactor.test.StepVerifier; + +import java.util.concurrent.atomic.AtomicReference; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.Assume.assumeTrue; + +public class ReactiveCertificateIntegrationTests extends ReactiveCredHubIntegrationTests { + private static final SimpleCredentialName TEST_CERT_NAME = + new SimpleCredentialName("spring-credhub", "integration-test", "test-certificate"); + private static final SimpleCredentialName ROOT_CERT_NAME = + new SimpleCredentialName("spring-credhub", "integration-test", "root-certificate"); + + private ReactiveCredHubCredentialOperations credentials; + private ReactiveCredHubCertificateOperations certificates; + + @Before + public void setUp() { + credentials = operations.credentials(); + certificates = operations.certificates(); + + deleteCredentialIfExists(TEST_CERT_NAME); + deleteCredentialIfExists(ROOT_CERT_NAME); + } + + @After + public void tearDown() { + deleteCredentialIfExists(TEST_CERT_NAME); + deleteCredentialIfExists(ROOT_CERT_NAME); + } + + @Test + public void generateCertificate() { + assumeTrue(serverApiIsV2()); + + StepVerifier.create(credentials.generate(CertificateParametersRequest.builder() + .name(TEST_CERT_NAME) + .parameters(CertificateParameters.builder() + .commonName("example.com") + .selfSign(true) + .build()) + .build(), + CertificateCredential.class)) + .assertNext(response -> { + assertThat(response.getName().getName()).isEqualTo(TEST_CERT_NAME.getName()); + assertThat(response.getCredentialType()).isEqualTo(CredentialType.CERTIFICATE); + assertThat(response.getId()).isNotNull(); + assertThat(response.getValue().getCertificate()).isNotNull(); + assertThat(response.getValue().getCertificateAuthority()).isNotNull(); + assertThat(response.getValue().getPrivateKey()).isNotNull(); + }) + .verifyComplete(); + + StepVerifier.create(certificates.getByName(TEST_CERT_NAME)) + .assertNext(response -> { + assertThat(response.getName()).isEqualTo(TEST_CERT_NAME.getName()); + assertThat(response.getId()).isNotNull(); + }) + .verifyComplete(); + + StepVerifier.create(certificates.getAll()) + .assertNext(response -> assertThat(response.getName()).isEqualTo(TEST_CERT_NAME.getName())) + .verifyComplete(); + } + + @Test + public void regenerateCertificate() { + assumeTrue(serverApiIsV2()); + + AtomicReference certificate = new AtomicReference<>(); + AtomicReference certificateId = new AtomicReference<>(); + + StepVerifier.create(credentials.generate(CertificateParametersRequest.builder() + .name(TEST_CERT_NAME) + .parameters(CertificateParameters.builder() + .commonName("example.com") + .selfSign(true) + .build()) + .build(), + CertificateCredential.class)) + .assertNext(response -> { + assertThat(response.getName().getName()).isEqualTo(TEST_CERT_NAME.getName()); + + certificate.set(response.getValue()); + }) + .verifyComplete(); + + StepVerifier.create(certificates.getByName(TEST_CERT_NAME)) + .assertNext(response -> { + assertThat(response.getName()).isEqualTo(TEST_CERT_NAME.getName()); + assertThat(response.getId()).isNotNull(); + + certificateId.set(response.getId()); + }) + .verifyComplete(); + + StepVerifier.create(certificates.regenerate(certificateId.get(), true)) + .assertNext(response -> { + assertThat(response.getName().getName()).isEqualTo(TEST_CERT_NAME.getName()); + assertThat(response.isTransitional()).isTrue(); + assertThat(response.getValue().getCertificate()) + .isNotEqualTo(certificate.get().getCertificate()); + assertThat(response.getValue().getCertificateAuthority()) + .isNotEqualTo(certificate.get().getCertificateAuthority()); + assertThat(response.getValue().getPrivateKey()) + .isNotEqualTo(certificate.get().getPrivateKey()); + }) + .verifyComplete(); + } + + @Test + public void rotateCertificate() { + assumeTrue(serverApiIsV2()); + + AtomicReference certificate = new AtomicReference<>(); + AtomicReference credentialVersion0Id = new AtomicReference<>(); + AtomicReference credentialVersion1Id = new AtomicReference<>(); + AtomicReference certificateId = new AtomicReference<>(); + + StepVerifier.create(credentials.generate(CertificateParametersRequest.builder() + .name(TEST_CERT_NAME) + .parameters(CertificateParameters.builder() + .commonName("example.com") + .selfSign(true) + .build()) + .build(), CertificateCredential.class)) + .assertNext(response -> { + assertThat(response.getName().getName()).isEqualTo(TEST_CERT_NAME.getName()); + + certificate.set(response.getValue()); + credentialVersion0Id.set(response.getId()); + }) + .verifyComplete(); + + StepVerifier.create(credentials.getByNameWithHistory(TEST_CERT_NAME, CertificateCredential.class)) + .assertNext(response -> assertThat(response.getId()).isEqualTo(credentialVersion0Id.get())) + .verifyComplete(); + + StepVerifier.create(certificates.getByName(TEST_CERT_NAME)) + .assertNext(response -> { + assertThat(response.getName()).isEqualTo(TEST_CERT_NAME.getName()); + assertThat(response.getId()).isNotNull(); + + certificateId.set(response.getId()); + }) + .verifyComplete(); + + StepVerifier.create(certificates.regenerate(certificateId.get(), true)) + .assertNext(response -> { + assertThat(response.getName().getName()).isEqualTo(TEST_CERT_NAME.getName()); + assertThat(response.getValue().getCertificate()) + .isNotEqualTo(certificate.get().getCertificate()); + assertThat(response.getValue().getCertificateAuthority()) + .isNotEqualTo(certificate.get().getCertificateAuthority()); + assertThat(response.getValue().getPrivateKey()) + .isNotEqualTo(certificate.get().getPrivateKey()); + + credentialVersion1Id.set(response.getId()); + }) + .verifyComplete(); + + StepVerifier.create(credentials.getByNameWithHistory(TEST_CERT_NAME, CertificateCredential.class)) + .assertNext(response -> assertThat(response.getId()).isEqualTo(credentialVersion1Id.get())) + .assertNext(response -> assertThat(response.getId()).isEqualTo(credentialVersion0Id.get())) + .verifyComplete(); + + StepVerifier.create(certificates.updateTransitionalVersion(certificateId.get(), credentialVersion0Id.get())) + .assertNext(response -> { + assertThat(response.getId()).isEqualTo(credentialVersion1Id.get()); + assertThat(response.isTransitional()).isFalse(); + }) + .assertNext(response -> { + assertThat(response.getId()).isEqualTo(credentialVersion0Id.get()); + assertThat(response.isTransitional()).isTrue(); + }) + .verifyComplete(); + + StepVerifier.create(certificates.updateTransitionalVersion(certificateId.get(), null)) + .assertNext(response -> { + assertThat(response.getId()).isEqualTo(credentialVersion1Id.get()); + assertThat(response.isTransitional()).isFalse(); + }) + .verifyComplete(); + } + + @Test + public void bulkRegenerateCertificates() { + AtomicReference rootCertificate = new AtomicReference<>(); + AtomicReference signedCertificateId = new AtomicReference<>(); + + StepVerifier.create(credentials.generate(CertificateParametersRequest.builder() + .name(ROOT_CERT_NAME) + .parameters(CertificateParameters.builder() + .commonName("example.com") + .certificateAuthority(true) + .selfSign(true) + .build()) + .build(), + CertificateCredential.class)) + .assertNext(response -> { + assertThat(response.getName().getName()).isEqualTo(ROOT_CERT_NAME.getName()); + + rootCertificate.set(response.getValue()); + }) + .verifyComplete(); + + StepVerifier.create(credentials.generate(CertificateParametersRequest.builder() + .name(TEST_CERT_NAME) + .parameters(CertificateParameters.builder() + .commonName("example.com") + .certificateAuthorityCredential(ROOT_CERT_NAME) + .build()) + .build(), + CertificateCredential.class)) + .assertNext(response -> { + assertThat(response.getValue().getCertificateAuthority()) + .isEqualTo(rootCertificate.get().getCertificate()); + + signedCertificateId.set(response.getId()); + }) + .verifyComplete(); + + StepVerifier.create(credentials.getByNameWithHistory(TEST_CERT_NAME, CertificateCredential.class)) + .assertNext(response -> assertThat(response.getId()).isEqualTo(signedCertificateId.get())) + .verifyComplete(); + + StepVerifier.create(certificates.regenerate(ROOT_CERT_NAME)) + .assertNext(response -> assertThat(response).isEqualTo(TEST_CERT_NAME)) + .verifyComplete(); + } +} diff --git a/spring-credhub-integration-tests/src/test/java/org/springframework/credhub/integration/ReactiveCredHubIntegrationTests.java b/spring-credhub-integration-tests/src/test/java/org/springframework/credhub/integration/ReactiveCredHubIntegrationTests.java index 2ede8fa..5823422 100644 --- a/spring-credhub-integration-tests/src/test/java/org/springframework/credhub/integration/ReactiveCredHubIntegrationTests.java +++ b/spring-credhub-integration-tests/src/test/java/org/springframework/credhub/integration/ReactiveCredHubIntegrationTests.java @@ -22,12 +22,12 @@ 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.CredHubException; import org.springframework.credhub.core.ReactiveCredHubOperations; import org.springframework.credhub.support.CredentialName; import org.springframework.credhub.support.info.VersionInfo; import org.springframework.test.context.ActiveProfiles; import org.springframework.test.context.junit4.SpringRunner; +import reactor.core.publisher.Mono; @RunWith(SpringRunner.class) @SpringBootTest(classes = {TestApplication.class, @@ -53,10 +53,8 @@ public abstract class ReactiveCredHubIntegrationTests { } void deleteCredentialIfExists(CredentialName credentialName) { - try { - operations.credentials().deleteByName(credentialName).block(); - } catch (CredHubException e) { - // ignore failing deletes on cleanup - } + operations.credentials().deleteByName(credentialName) + .onErrorResume(e -> Mono.empty()) + .block(); } } diff --git a/spring-credhub-integration-tests/src/test/java/org/springframework/credhub/integration/ReactiveCredentialIntegrationTests.java b/spring-credhub-integration-tests/src/test/java/org/springframework/credhub/integration/ReactiveCredentialIntegrationTests.java index 1d9ec01..a015984 100644 --- a/spring-credhub-integration-tests/src/test/java/org/springframework/credhub/integration/ReactiveCredentialIntegrationTests.java +++ b/spring-credhub-integration-tests/src/test/java/org/springframework/credhub/integration/ReactiveCredentialIntegrationTests.java @@ -95,10 +95,10 @@ public class ReactiveCredentialIntegrationTests extends ReactiveCredHubIntegrati .verifyComplete(); StepVerifier.create(credentials.getByName(CREDENTIAL_NAME, ValueCredential.class)) - .assertNext(byName -> { - assertThat(byName.getName().getName()).isEqualTo(CREDENTIAL_NAME.getName()); - assertThat(byName.getValue().getValue()).isEqualTo(CREDENTIAL_VALUE); - assertThat(byName.getCredentialType()).isEqualTo(CredentialType.VALUE); + .assertNext(response -> { + assertThat(response.getName().getName()).isEqualTo(CREDENTIAL_NAME.getName()); + assertThat(response.getValue().getValue()).isEqualTo(CREDENTIAL_VALUE); + assertThat(response.getCredentialType()).isEqualTo(CredentialType.VALUE); }) .verifyComplete(); diff --git a/spring-credhub-integration-tests/src/test/java/org/springframework/credhub/integration/ReactiveInfoIntegrationTests.java b/spring-credhub-integration-tests/src/test/java/org/springframework/credhub/integration/ReactiveInfoIntegrationTests.java new file mode 100644 index 0000000..c24aa13 --- /dev/null +++ b/spring-credhub-integration-tests/src/test/java/org/springframework/credhub/integration/ReactiveInfoIntegrationTests.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.integration; + +import org.junit.Before; +import org.junit.Test; +import org.springframework.credhub.core.info.ReactiveCredHubInfoOperations; +import reactor.test.StepVerifier; + +import static org.assertj.core.api.Assertions.assertThat; + +public class ReactiveInfoIntegrationTests extends ReactiveCredHubIntegrationTests { + private ReactiveCredHubInfoOperations info; + + @Before + public void setUp() { + info = operations.info(); + } + + @Test + public void getInfo() { + StepVerifier.create(info.version()) + .assertNext(response -> assertThat(response.getVersion()).isNotNull()) + .verifyComplete(); + } +} diff --git a/spring-credhub-integration-tests/src/test/java/org/springframework/credhub/integration/ReactiveInterpolationIntegrationTests.java b/spring-credhub-integration-tests/src/test/java/org/springframework/credhub/integration/ReactiveInterpolationIntegrationTests.java new file mode 100644 index 0000000..92031c6 --- /dev/null +++ b/spring-credhub-integration-tests/src/test/java/org/springframework/credhub/integration/ReactiveInterpolationIntegrationTests.java @@ -0,0 +1,114 @@ +/* + * 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.integration; + +import com.fasterxml.jackson.databind.ObjectMapper; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.springframework.credhub.core.credential.ReactiveCredHubCredentialOperations; +import org.springframework.credhub.core.interpolation.ReactiveCredHubInterpolationOperations; +import org.springframework.credhub.support.CredentialType; +import org.springframework.credhub.support.ServicesData; +import org.springframework.credhub.support.SimpleCredentialName; +import org.springframework.credhub.support.json.JsonCredentialRequest; +import org.springframework.credhub.support.utils.JsonUtils; +import reactor.test.StepVerifier; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; + +import static org.assertj.core.api.Assertions.assertThat; + +public class ReactiveInterpolationIntegrationTests extends ReactiveCredHubIntegrationTests { + private static final SimpleCredentialName CREDENTIAL_NAME = + new SimpleCredentialName("spring-credhub", "integration-test", "interpolation-credential"); + + private ReactiveCredHubInterpolationOperations interpolation; + private ReactiveCredHubCredentialOperations credentials; + + @Before + public void setUp() { + this.interpolation = operations.interpolation(); + this.credentials = operations.credentials(); + } + + @After + public void tearDown() { + deleteCredentialIfExists(CREDENTIAL_NAME); + } + + @Test + @SuppressWarnings("unchecked") + public void interpolate() throws IOException { + Map json = new HashMap() {{ + put("url", "https://example.com"); + put("username", "user"); + put("password", "secret"); + }}; + + StepVerifier.create(credentials.write(JsonCredentialRequest.builder() + .name(CREDENTIAL_NAME) + .value(json) + .build())) + .assertNext(response -> { + assertThat(response.getName().getName()).isEqualTo(CREDENTIAL_NAME.getName()); + assertThat(response.getValue()).isEqualTo(json); + assertThat(response.getCredentialType()).isEqualTo(CredentialType.JSON); + assertThat(response.getId()).isNotNull(); + }) + .verifyComplete(); + + StepVerifier.create(interpolation.interpolateServiceData(buildVcapServices(CREDENTIAL_NAME.getName()))) + .assertNext(servicesData -> { + assertThat(servicesData).containsKey("service-offering"); + assertThat(servicesData.get("service-offering")).hasSize(1); + assertThat(servicesData.get("service-offering").get(0)).containsKey("credentials"); + + Map credentials = + (Map) servicesData.get("service-offering").get(0).get("credentials"); + assertThat(credentials) + .containsEntry("url", "https://example.com") + .containsEntry("username", "user") + .containsEntry("password", "secret"); + }) + .verifyComplete(); + } + + private ServicesData buildVcapServices(String credHubReferenceName) throws IOException { + String vcapServices = "{" + + " \"service-offering\": [" + + " {" + + " \"credentials\": {" + + " \"credhub-ref\": \"((" + credHubReferenceName + "))\"" + + " }," + + " \"label\": \"service-offering\"," + + " \"name\": \"service-instance\"," + + " \"plan\": \"standard\"," + + " \"tags\": [" + + " \"cloud-service\"" + + " ]," + + " \"volume_mounts\": []" + + " }" + + " ]" + + "}"; + + ObjectMapper mapper = JsonUtils.buildObjectMapper(); + return mapper.readValue(vcapServices, ServicesData.class); + } +} diff --git a/spring-credhub-integration-tests/src/test/java/org/springframework/credhub/integration/ReactivePermissionIntegrationTests.java b/spring-credhub-integration-tests/src/test/java/org/springframework/credhub/integration/ReactivePermissionIntegrationTests.java new file mode 100644 index 0000000..c617974 --- /dev/null +++ b/spring-credhub-integration-tests/src/test/java/org/springframework/credhub/integration/ReactivePermissionIntegrationTests.java @@ -0,0 +1,165 @@ +/* + * 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.integration; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.springframework.credhub.core.credential.ReactiveCredHubCredentialOperations; +import org.springframework.credhub.core.permission.ReactiveCredHubPermissionOperations; +import org.springframework.credhub.support.SimpleCredentialName; +import org.springframework.credhub.support.permissions.Actor; +import org.springframework.credhub.support.permissions.ActorType; +import org.springframework.credhub.support.permissions.Operation; +import org.springframework.credhub.support.permissions.Permission; +import org.springframework.credhub.support.value.ValueCredentialRequest; +import reactor.core.publisher.Mono; +import reactor.test.StepVerifier; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.Assume.assumeTrue; + +public class ReactivePermissionIntegrationTests extends ReactiveCredHubIntegrationTests { + private static final SimpleCredentialName CREDENTIAL_NAME = + new SimpleCredentialName("spring-credhub", "integration-test", "test-permissions-credential"); + private static final String CREDENTIAL_VALUE = "test-value"; + + private ReactiveCredHubCredentialOperations credentials; + private ReactiveCredHubPermissionOperations permissions; + + @Before + public void setUp() { + credentials = operations.credentials(); + permissions = operations.permissions(); + + deleteCredentialIfExists(CREDENTIAL_NAME); + deletePermissionsIfExist(); + } + + @After + public void tearDown() { + deleteCredentialIfExists(CREDENTIAL_NAME); + deletePermissionsIfExist(); + } + + @Test + public void managePermissionsServerV1() { + assumeTrue(serverApiIsV1()); + + StepVerifier.create(credentials.write(ValueCredentialRequest.builder() + .name(CREDENTIAL_NAME) + .value(CREDENTIAL_VALUE) + .build())) + .assertNext(response -> { + assertThat(response.getName()).isEqualTo(CREDENTIAL_NAME); + assertThat(response.getId()).isNotNull(); + }) + .verifyComplete(); + + Permission appPermission = Permission.builder() + .app("app1") + .operation(Operation.READ) + .build(); + Permission userPermission = Permission.builder() + .user("user1") + .operations(Operation.READ, Operation.WRITE, Operation.DELETE) + .build(); + Permission clientPermission = Permission.builder() + .client("client1") + .operations(Operation.READ_ACL, Operation.WRITE_ACL) + .build(); + + StepVerifier.create(permissions.addPermissions(CREDENTIAL_NAME, + appPermission, + userPermission, + clientPermission)) + .expectComplete() + .verify(); + + StepVerifier.create(permissions.getPermissions(CREDENTIAL_NAME)) + .assertNext(response -> assertThat(response.getActor().getAuthType()).isEqualTo(ActorType.OAUTH_CLIENT)) + .assertNext(response -> assertThat(response).isEqualTo(appPermission)) + .assertNext(response -> assertThat(response).isEqualTo(userPermission)) + .assertNext(response -> assertThat(response).isEqualTo(clientPermission)) + .verifyComplete(); + + deletePermissionsIfExist(); + + StepVerifier.create(permissions.getPermissions(CREDENTIAL_NAME)) + .assertNext(response -> assertThat(response.getActor().getAuthType()).isEqualTo(ActorType.OAUTH_CLIENT)) + .verifyComplete(); + } + + @Test + public void managePermissionsServerV2() { + assumeTrue(serverApiIsV2()); + + StepVerifier.create(credentials.write(ValueCredentialRequest.builder() + .name(CREDENTIAL_NAME) + .value(CREDENTIAL_VALUE) + .build())) + .assertNext(response -> { + assertThat(response.getName()).isEqualTo(CREDENTIAL_NAME); + assertThat(response.getId()).isNotNull(); + }) + .verifyComplete(); + + Permission appPermission = Permission.builder() + .app("app1") + .operation(Operation.READ) + .build(); + Permission userPermission = Permission.builder() + .user("user1") + .operations(Operation.READ, Operation.WRITE, Operation.DELETE) + .build(); + Permission clientPermission = Permission.builder() + .client("client1") + .operations(Operation.READ_ACL, Operation.WRITE_ACL) + .build(); + + StepVerifier.create(permissions.addPermissions(CREDENTIAL_NAME, + appPermission, + userPermission, + clientPermission)) + .expectComplete() + .verify(); + + StepVerifier.create(permissions.getPermissions(CREDENTIAL_NAME)) + .assertNext(response -> assertThat(response).isEqualTo(appPermission)) + .assertNext(response -> assertThat(response).isEqualTo(userPermission)) + .assertNext(response -> assertThat(response).isEqualTo(clientPermission)) + .verifyComplete(); + + deletePermissionsIfExist(); + + StepVerifier.create(permissions.getPermissions(CREDENTIAL_NAME)) + .expectComplete() + .verify(); + } + + private void deletePermissionsIfExist() { + permissions.deletePermission(CREDENTIAL_NAME, Actor.app("app1")) + .onErrorResume(e -> Mono.empty()) + .block(); + permissions.deletePermission(CREDENTIAL_NAME, Actor.user("user1")) + .onErrorResume(e -> Mono.empty()) + .block(); + permissions.deletePermission(CREDENTIAL_NAME, Actor.client("client1")) + .onErrorResume(e -> Mono.empty()) + .block(); + } +} diff --git a/spring-credhub-integration-tests/src/test/java/org/springframework/credhub/integration/ReactivePermissionV2IntegrationTests.java b/spring-credhub-integration-tests/src/test/java/org/springframework/credhub/integration/ReactivePermissionV2IntegrationTests.java new file mode 100644 index 0000000..34b8719 --- /dev/null +++ b/spring-credhub-integration-tests/src/test/java/org/springframework/credhub/integration/ReactivePermissionV2IntegrationTests.java @@ -0,0 +1,176 @@ +/* + * 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.integration; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.springframework.credhub.core.credential.ReactiveCredHubCredentialOperations; +import org.springframework.credhub.core.permissionV2.ReactiveCredHubPermissionV2Operations; +import org.springframework.credhub.support.CredentialPermission; +import org.springframework.credhub.support.SimpleCredentialName; +import org.springframework.credhub.support.permissions.Actor; +import org.springframework.credhub.support.permissions.ActorType; +import org.springframework.credhub.support.permissions.Operation; +import org.springframework.credhub.support.permissions.Permission; +import org.springframework.credhub.support.value.ValueCredentialRequest; +import reactor.test.StepVerifier; + +import java.util.List; +import java.util.concurrent.atomic.AtomicReference; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.Assume.assumeTrue; +import static org.springframework.credhub.support.permissions.ActorType.OAUTH_CLIENT; + +public class ReactivePermissionV2IntegrationTests extends ReactiveCredHubIntegrationTests { + private static final SimpleCredentialName CREDENTIAL_NAME = + new SimpleCredentialName("spring-credhub", "integration-test", "test-permissionsV2-credential"); + private static final String CREDENTIAL_VALUE = "test-value"; + + private ReactiveCredHubCredentialOperations credentials; + private ReactiveCredHubPermissionV2Operations permissions; + + @Before + public void setUp() { + credentials = operations.credentials(); + permissions = operations.permissionsV2(); + + deleteCredentialIfExists(CREDENTIAL_NAME); + } + + @After + public void tearDown() { + deleteCredentialIfExists(CREDENTIAL_NAME); + } + + @Test + public void managePermissions() { + assumeTrue(serverApiIsV2()); + + AtomicReference permissionId = new AtomicReference<>(); + + StepVerifier.create(credentials.write(ValueCredentialRequest.builder() + .name(CREDENTIAL_NAME) + .value(CREDENTIAL_VALUE) + .build())) + .assertNext(response -> { + assertThat(response.getName()).isEqualTo(CREDENTIAL_NAME); + assertThat(response.getId()).isNotNull(); + }) + .verifyComplete(); + + Permission clientPermission = Permission.builder() + .client("client1") + .operations(Operation.READ, Operation.WRITE, Operation.DELETE) + .build(); + + StepVerifier.create(permissions.addPermissions(CREDENTIAL_NAME, clientPermission)) + .assertNext(response -> { + assertThat(response.getId()).isNotNull(); + assertThat(response.getPath()).isEqualTo(CREDENTIAL_NAME.getName()); + assertPermissions(response, OAUTH_CLIENT, "client1", + Operation.READ, Operation.WRITE, Operation.DELETE); + + permissionId.set(response.getId()); + }) + .verifyComplete(); + + StepVerifier.create(permissions.getPermissions(permissionId.get())) + .assertNext(response -> { + assertThat(response.getId()).isEqualTo(permissionId.get()); + assertThat(response.getPath()).isEqualTo(CREDENTIAL_NAME.getName()); + assertPermissions(response, OAUTH_CLIENT, "client1", + Operation.READ, Operation.WRITE, Operation.DELETE); + }) + .verifyComplete(); + + StepVerifier.create(permissions.deletePermission(permissionId.get())) + .expectComplete() + .verify(); + } + + @Test + public void updatePermissions() { + assumeTrue(serverApiIsV2()); + + AtomicReference permissionId = new AtomicReference<>(); + + StepVerifier.create(credentials.write(ValueCredentialRequest.builder() + .name(CREDENTIAL_NAME) + .value(CREDENTIAL_VALUE) + .build())) + .assertNext(response -> { + assertThat(response.getName()).isEqualTo(CREDENTIAL_NAME); + assertThat(response.getId()).isNotNull(); + }) + .verifyComplete(); + + Permission clientPermission = Permission.builder() + .client("client1") + .operations(Operation.READ, Operation.WRITE, Operation.DELETE) + .build(); + + StepVerifier.create(permissions.addPermissions(CREDENTIAL_NAME, clientPermission)) + .assertNext(response -> { + assertThat(response.getId()).isNotNull(); + assertThat(response.getPath()).isEqualTo(CREDENTIAL_NAME.getName()); + assertPermissions(response, OAUTH_CLIENT, "client1", + Operation.READ, Operation.WRITE, Operation.DELETE); + + permissionId.set(response.getId()); + }) + .verifyComplete(); + + Permission newPermission = Permission.builder() + .client("client1") + .operations(Operation.READ_ACL, Operation.WRITE_ACL) + .build(); + + StepVerifier.create(permissions.updatePermissions(permissionId.get(), CREDENTIAL_NAME, newPermission)) + .assertNext(response -> { + assertThat(response.getId()).isEqualTo(permissionId.get()); + assertThat(response.getPath()).isEqualTo(CREDENTIAL_NAME.getName()); + assertPermissions(response, OAUTH_CLIENT, "client1", + Operation.READ_ACL, Operation.WRITE_ACL); + }) + .verifyComplete(); + + StepVerifier.create(permissions.getPermissions(permissionId.get())) + .assertNext(response -> { + assertThat(response.getId()).isEqualTo(permissionId.get()); + assertThat(response.getPath()).isEqualTo(CREDENTIAL_NAME.getName()); + assertPermissions(response, OAUTH_CLIENT, "client1", + Operation.READ_ACL, Operation.WRITE_ACL); + }) + .verifyComplete(); + + StepVerifier.create(permissions.deletePermission(permissionId.get())) + .expectComplete() + .verify(); + } + + private void assertPermissions(CredentialPermission credentialPermission, + ActorType actorType, String actorId, Operation... operations) { + Actor actor = credentialPermission.getPermission().getActor(); + assertThat(actor.getAuthType()).isEqualTo(actorType); + assertThat(actor.getPrimaryIdentifier()).isEqualTo(actorId); + + List ops = credentialPermission.getPermission().getOperations(); + assertThat(ops).containsExactlyInAnyOrder(operations); + } +}