diff --git a/spring-credhub-cloud-connector/src/main/java/org/springframework/credhub/cloud/CredHubInterpolationServiceDataPostProcessor.java b/spring-credhub-cloud-connector/src/main/java/org/springframework/credhub/cloud/CredHubInterpolationServiceDataPostProcessor.java index 5820efe..c9f0210 100644 --- a/spring-credhub-cloud-connector/src/main/java/org/springframework/credhub/cloud/CredHubInterpolationServiceDataPostProcessor.java +++ b/spring-credhub-cloud-connector/src/main/java/org/springframework/credhub/cloud/CredHubInterpolationServiceDataPostProcessor.java @@ -22,6 +22,7 @@ import java.util.logging.Logger; import org.springframework.cloud.cloudfoundry.CloudFoundryRawServiceData; import org.springframework.cloud.cloudfoundry.ServiceDataPostProcessor; import org.springframework.credhub.configuration.CredHubTemplateFactory; +import org.springframework.credhub.core.CredHubInterpolationOperations; import org.springframework.credhub.core.CredHubOperations; import org.springframework.credhub.core.CredHubProperties; import org.springframework.credhub.support.ServicesData; @@ -38,7 +39,7 @@ public class CredHubInterpolationServiceDataPostProcessor private Logger logger = Logger .getLogger(CredHubInterpolationServiceDataPostProcessor.class.getName()); - private CredHubOperations credHubOperations; + private CredHubInterpolationOperations credHubOperations; /** * Initialize the service data post-processor. @@ -54,7 +55,8 @@ public class CredHubInterpolationServiceDataPostProcessor && !credHubProperties.getUrl().isEmpty()) { credHubOperations = credHubTemplateFactroy.credHubTemplate( credHubProperties, - credHubTemplateFactroy.clientHttpRequestFactoryWrapper()); + credHubTemplateFactroy.clientHttpRequestFactoryWrapper()) + .interpolation(); } else { logger.log(Level.WARNING, @@ -73,14 +75,14 @@ public class CredHubInterpolationServiceDataPostProcessor * * @param credHubOperations the CredHubOperations to use */ - CredHubInterpolationServiceDataPostProcessor(CredHubOperations credHubOperations) { + CredHubInterpolationServiceDataPostProcessor(CredHubInterpolationOperations credHubOperations) { this.credHubOperations = credHubOperations; } /** * Process the provided {@literal serviceData} parsed from {@literal VCAP_SERVICES} by * Spring Cloud Connectors using the - * {@link CredHubOperations#interpolateServiceData(ServicesData)} API. + * {@link org.springframework.credhub.core.CredHubInterpolationOperations#interpolateServiceData(ServicesData)} API. * * @param serviceData raw service data parsed from {@literal VCAP_SERVICES} * @return serviceData with CredHub references replaced by stored credentials diff --git a/spring-credhub-cloud-connector/src/test/java/org/springframework/credhub/cloud/CredHubInterpolationServiceDataPostProcessorTests.java b/spring-credhub-cloud-connector/src/test/java/org/springframework/credhub/cloud/CredHubInterpolationServiceDataPostProcessorTests.java index 33aa8cf..df11683 100644 --- a/spring-credhub-cloud-connector/src/test/java/org/springframework/credhub/cloud/CredHubInterpolationServiceDataPostProcessorTests.java +++ b/spring-credhub-cloud-connector/src/test/java/org/springframework/credhub/cloud/CredHubInterpolationServiceDataPostProcessorTests.java @@ -32,7 +32,7 @@ import org.mockito.junit.MockitoJUnitRunner; import org.springframework.cloud.cloudfoundry.CloudFoundryRawServiceData; import org.springframework.credhub.core.CredHubException; -import org.springframework.credhub.core.CredHubOperations; +import org.springframework.credhub.core.CredHubInterpolationOperations; import org.springframework.credhub.support.ServicesData; import org.springframework.http.HttpStatus; @@ -45,7 +45,7 @@ import static org.mockito.Mockito.when; @RunWith(MockitoJUnitRunner.class) public class CredHubInterpolationServiceDataPostProcessorTests { @Mock - private CredHubOperations credHubOperations; + private CredHubInterpolationOperations credHubOperations; @Test public void processServiceData() { diff --git a/spring-credhub-core/src/main/java/org/springframework/credhub/core/CredHubCredentialsOperations.java b/spring-credhub-core/src/main/java/org/springframework/credhub/core/CredHubCredentialsOperations.java new file mode 100644 index 0000000..6325dcf --- /dev/null +++ b/spring-credhub-core/src/main/java/org/springframework/credhub/core/CredHubCredentialsOperations.java @@ -0,0 +1,135 @@ +/* + * 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.core; + +import org.springframework.credhub.support.CredentialDetails; +import org.springframework.credhub.support.CredentialName; +import org.springframework.credhub.support.CredentialRequest; +import org.springframework.credhub.support.CredentialSummary; +import org.springframework.credhub.support.ParametersRequest; + +import java.util.List; + +/** + * Specifies the interactions with CredHub to save, generate, retrieve, + * and delete credentials. + * + * @author Scott Frederick + */ +public interface CredHubCredentialsOperations { + /** + * Write a new credential to CredHub, or overwrite an existing credential with a new + * value. + * + * @param credentialRequest the credential to write to CredHub; must not be {@literal null} + * @param the credential implementation type + * @return the details of the written credential + */ + CredentialDetails write(final CredentialRequest credentialRequest); + + /** + * Generate a new credential in CredHub, or overwrite an existing credential with a new + * generated value. + * + * @param parametersRequest the parameters of the new credential to generate in CredHub; + * must not be {@literal null} + * @param the credential implementation type + * @param

the credential parameter implementation type + * @return the details of the generated credential + */ + CredentialDetails generate(final ParametersRequest

parametersRequest); + + /** + * Regenerate a credential in CredHub. Only credentials that were previously generated can be + * re-generated. + * + * @param name the name of the credential; must not be {@literal null} + * @param the credential implementation type + * @return the details of the regenerated credential + */ + CredentialDetails regenerate(final CredentialName name); + + /** + * Retrieve a credential using its ID, as returned in a write request. + * + * @param id the ID of the credential; must not be {@literal null} + * @param credentialType the type of the credential to be retrieved; must not be {@literal null} + * @param the credential implementation type + * @return the details of the retrieved credential + */ + CredentialDetails getById(final String id, final Class credentialType); + + /** + * Retrieve a credential using its name, as passed to a write request. + * Only the current credential value will be returned. + * + * @param name the name of the credential; must not be {@literal null} + * @param credentialType the type of credential expected to be returned + * @param the credential implementation type + * @return the details of the retrieved credential + */ + CredentialDetails getByName(final CredentialName name, final Class credentialType); + + /** + * Retrieve a credential using its name, as passed to a write request. + * A collection of all stored values for the named credential will be returned, + * including historical values. + * + * @param name the name of the credential; must not be {@literal null} + * @param credentialType the type of credential expected to be returned + * @param the credential implementation type + * @return the details of the retrieved credential, including history + */ + List> getByNameWithHistory(final CredentialName name, final Class credentialType); + + /** + * Retrieve a credential using its name, as passed to a write request. + * A collection of stored values for the named credential will be returned, + * with the specified number of historical values. + * + * @param name the name of the credential; must not be {@literal null} + * @param versions the number of historical versions to retrieve + * @param credentialType the type of credential expected to be returned + * @param the credential implementation type + * @return the details of the retrieved credential, including history + */ + List> getByNameWithHistory(final CredentialName name, int versions, + final Class credentialType); + + /** + * Find a credential using a full or partial name. + * + * @param name the name of the credential; must not be {@literal null} + * @return a summary of the credential search results + */ + List findByName(final CredentialName name); + + /** + * Find a credential using a path. + * + * @param path the path to the credential; must not be {@literal null} + * @return a summary of the credential search results + */ + List findByPath(final String path); + + /** + * Delete a credential by its full name. + * + * @param name the name of the credential; must not be {@literal null} + */ + void deleteByName(final CredentialName name); +} diff --git a/spring-credhub-core/src/main/java/org/springframework/credhub/core/CredHubCredentialsTemplate.java b/spring-credhub-core/src/main/java/org/springframework/credhub/core/CredHubCredentialsTemplate.java new file mode 100644 index 0000000..3c101a8 --- /dev/null +++ b/spring-credhub-core/src/main/java/org/springframework/credhub/core/CredHubCredentialsTemplate.java @@ -0,0 +1,286 @@ +/* + * 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.core; + +import org.springframework.core.ParameterizedTypeReference; +import org.springframework.credhub.support.CredentialDetails; +import org.springframework.credhub.support.CredentialDetailsData; +import org.springframework.credhub.support.CredentialName; +import org.springframework.credhub.support.CredentialRequest; +import org.springframework.credhub.support.CredentialSummary; +import org.springframework.credhub.support.CredentialSummaryData; +import org.springframework.credhub.support.ParametersRequest; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.util.Assert; +import org.springframework.web.client.RestOperations; +import org.springframework.web.client.RestTemplate; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import static org.springframework.http.HttpMethod.GET; +import static org.springframework.http.HttpMethod.POST; +import static org.springframework.http.HttpMethod.PUT; + +/** + * Implements the interactions with CredHub to save, retrieve, + * and delete credentials. + * + * @author Scott Frederick + */ +public class CredHubCredentialsTemplate implements CredHubCredentialsOperations { + static final String BASE_URL_PATH = "/api/v1/data"; + static final String ID_URL_PATH = BASE_URL_PATH + "/{id}"; + static final String NAME_URL_QUERY = BASE_URL_PATH + "?name={name}"; + static final String NAME_URL_QUERY_CURRENT = NAME_URL_QUERY + "¤t=true"; + static final String NAME_URL_QUERY_VERSIONS = NAME_URL_QUERY + "&versions={versions}"; + static final String NAME_LIKE_URL_QUERY = BASE_URL_PATH + "?name-like={name}"; + static final String PATH_URL_QUERY = BASE_URL_PATH + "?path={path}"; + static final String REGENERATE_URL_PATH = "/api/v1/regenerate"; + + private CredHubOperations credHubOperations; + + /** + * Create a new {@link CredHubCredentialsTemplate}. + * + * @param credHubOperations the {@link CredHubOperations} to use for interactions with CredHub + */ + CredHubCredentialsTemplate(CredHubOperations credHubOperations) { + this.credHubOperations = credHubOperations; + } + + @Override + public CredentialDetails write(final CredentialRequest credentialRequest) { + Assert.notNull(credentialRequest, "credentialRequest must not be null"); + + final ParameterizedTypeReference> ref = + new ParameterizedTypeReference>() {}; + + return credHubOperations.doWithRest(new RestOperationsCallback>() { + @Override + public CredentialDetails doWithRestOperations(RestOperations restOperations) { + ResponseEntity> response = + restOperations.exchange(BASE_URL_PATH, PUT, + new HttpEntity<>(credentialRequest), ref); + + throwExceptionOnError(response); + + return response.getBody(); + } + }); + } + + @Override + public CredentialDetails generate(final ParametersRequest

parametersRequest) { + Assert.notNull(parametersRequest, "parametersRequest must not be null"); + + final ParameterizedTypeReference> ref = + new ParameterizedTypeReference>() {}; + + return credHubOperations.doWithRest(new RestOperationsCallback>() { + @Override + public CredentialDetails doWithRestOperations(RestOperations restOperations) { + ResponseEntity> response = + restOperations.exchange(BASE_URL_PATH, POST, + new HttpEntity<>(parametersRequest), ref); + + throwExceptionOnError(response); + + return response.getBody(); + } + }); + } + + @Override + public CredentialDetails regenerate(final CredentialName name) { + Assert.notNull(name, "credential name must not be null"); + + final ParameterizedTypeReference> ref = + new ParameterizedTypeReference>() {}; + + return credHubOperations.doWithRest(new RestOperationsCallback>() { + @Override + public CredentialDetails doWithRestOperations(RestOperations restOperations) { + Map request = new HashMap<>(1); + request.put("name", name.getName()); + + ResponseEntity> response = + restOperations.exchange(REGENERATE_URL_PATH, POST, + new HttpEntity<>(request), ref); + + throwExceptionOnError(response); + + return response.getBody(); + } + }); + } + + @Override + public CredentialDetails getById(final String id, final Class credentialType) { + Assert.notNull(id, "credential id must not be null"); + Assert.notNull(credentialType, "credential type must not be null"); + + final ParameterizedTypeReference> ref = + new ParameterizedTypeReference>() {}; + + return credHubOperations.doWithRest(new RestOperationsCallback>() { + @Override + public CredentialDetails doWithRestOperations(RestOperations restOperations) { + ResponseEntity> response = + restOperations.exchange(ID_URL_PATH, GET, null, ref, id); + + throwExceptionOnError(response); + + return response.getBody(); + } + }); + } + + @Override + public CredentialDetails getByName(final CredentialName name, final Class credentialType) { + Assert.notNull(name, "credential name must not be null"); + Assert.notNull(credentialType, "credential type must not be null"); + + final ParameterizedTypeReference> ref = + new ParameterizedTypeReference>() {}; + + return credHubOperations.doWithRest(new RestOperationsCallback>() { + @Override + public CredentialDetails doWithRestOperations(RestOperations restOperations) { + ResponseEntity> response = + restOperations.exchange(NAME_URL_QUERY_CURRENT, GET, null, ref, name.getName()); + + throwExceptionOnError(response); + + return response.getBody().getData().get(0); + } + }); + } + + @Override + public List> getByNameWithHistory(final CredentialName name, final Class credentialType) { + Assert.notNull(name, "credential name must not be null"); + Assert.notNull(credentialType, "credential type must not be null"); + + final ParameterizedTypeReference> ref = + new ParameterizedTypeReference>() {}; + + return credHubOperations.doWithRest(new RestOperationsCallback>>() { + @Override + public List> doWithRestOperations(RestOperations restOperations) { + ResponseEntity> response = + restOperations.exchange(NAME_URL_QUERY, GET, null, ref, name.getName()); + + throwExceptionOnError(response); + + return response.getBody().getData(); + } + }); + } + + @Override + public List> getByNameWithHistory(final CredentialName name, final int versions, + final Class credentialType) { + Assert.notNull(name, "credential name must not be null"); + Assert.notNull(credentialType, "credential type must not be null"); + + final ParameterizedTypeReference> ref = + new ParameterizedTypeReference>() {}; + + return credHubOperations.doWithRest(new RestOperationsCallback>>() { + @Override + public List> doWithRestOperations(RestOperations restOperations) { + ResponseEntity> response = + restOperations.exchange(NAME_URL_QUERY_VERSIONS, GET, null, ref, + name.getName(), versions); + + throwExceptionOnError(response); + + return response.getBody().getData(); + } + }); + } + + @Override + public List findByName(final CredentialName name) { + Assert.notNull(name, "credential name must not be null"); + + return credHubOperations.doWithRest(new RestOperationsCallback>() { + @Override + public List doWithRestOperations( + RestOperations restOperations) { + ResponseEntity response = restOperations + .getForEntity(NAME_LIKE_URL_QUERY, + CredentialSummaryData.class, name.getName()); + + throwExceptionOnError(response); + + return response.getBody().getCredentials(); + } + }); + } + + @Override + public List findByPath(final String path) { + Assert.notNull(path, "credential path must not be null"); + + return credHubOperations.doWithRest(new RestOperationsCallback>() { + @Override + public List doWithRestOperations( + RestOperations restOperations) { + ResponseEntity response = restOperations + .getForEntity(PATH_URL_QUERY, CredentialSummaryData.class, + path); + + throwExceptionOnError(response); + + return response.getBody().getCredentials(); + } + }); + } + + @Override + public void deleteByName(final CredentialName name) { + Assert.notNull(name, "credential name must not be null"); + + final String name1 = name.getName(); + Assert.notNull(name1, "credential name must not be null"); + + credHubOperations.doWithRest(new RestOperationsCallback() { + @Override + public Void doWithRestOperations(RestOperations restOperations) { + restOperations.delete(NAME_URL_QUERY, name1); + return null; + } + }); + } + + /** + * Helper method to throw an appropriate exception if a request to CredHub + * returns with an error code. + * + * @param response a {@link ResponseEntity} returned from {@link RestTemplate} + */ + private void throwExceptionOnError(ResponseEntity response) { + if (!response.getStatusCode().equals(HttpStatus.OK)) { + throw new CredHubException(response.getStatusCode()); + } + } +} diff --git a/spring-credhub-core/src/main/java/org/springframework/credhub/core/CredHubInterpolationOperations.java b/spring-credhub-core/src/main/java/org/springframework/credhub/core/CredHubInterpolationOperations.java new file mode 100644 index 0000000..d0a9cb3 --- /dev/null +++ b/spring-credhub-core/src/main/java/org/springframework/credhub/core/CredHubInterpolationOperations.java @@ -0,0 +1,88 @@ +/* + * 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.core; + +import org.springframework.credhub.support.ServicesData; + +/** + * Specifies the interactions with CredHub to interpolate service binding credentials. + * + * @author Scott Frederick + */ +public interface CredHubInterpolationOperations { + /** + * Search the provided data structure of bound service credentials, looking for + * references to CredHub credentials. Any CredHub credentials found in the data + * structure will be replaced by the credential value stored in CredHub. + * + * Example: + * + * A JSON data structure parsed from a {@literal VCAP_SERVICES} environment + * variable might look like this if the service broker that provided the binding + * is integrated with CredHub: + * + *

+	 * {@code
+	 * {
+	 *    "service-offering": [{
+	 *      "credentials": {
+	 *        "credhub-ref": "((/c/service-broker/service-offering/1111-2222-3333-4444/credentials))"
+	 *      }
+	 *      "label": "service-offering",
+	 *      "name": "service-instance",
+	 *      "plan": "standard",
+	 *      "tags": ["
+	 *        "cloud-service"
+	 *      ]
+	 *    }]
+	 * }
+	 * }
+	 * 
+ * + * Assuming that CredHub has a credential with the name + * {@literal /c/service-broker/service-offering/1111-2222-3333-4444/credentials}, + * passing the data structure above to this method would result in the + * {@literal credhub-ref} field being replaced by the credentials stored in CredHub: + * + *
+	 * {@code
+	 * {
+	 *    "service-offering": [{
+	 *      "credentials": {
+	 *        "url": "https://servicehost.example.com/",
+	 *        "username": "someuser",
+	 *        "password": "secret"
+	 *      }
+	 *      "label": "service-offering",
+	 *      "name": "service-instance",
+	 *      "plan": "standard",
+	 *      "tags": ["
+	 *        "cloud-service"
+	 *      ]
+	 *    }]
+	 * }
+	 * }
+	 * 
+ * + * @param serviceData a data structure of bound service credentials, as would be + * parsed from the {@literal VCAP_SERVICES} environment variable provided to + * applications running on Cloud Foundry + * @return the serviceData structure with CredHub references replaced by stored + * credential values + */ + ServicesData interpolateServiceData(final ServicesData serviceData); +} diff --git a/spring-credhub-core/src/main/java/org/springframework/credhub/core/CredHubInterpolationTemplate.java b/spring-credhub-core/src/main/java/org/springframework/credhub/core/CredHubInterpolationTemplate.java new file mode 100644 index 0000000..ad85c78 --- /dev/null +++ b/spring-credhub-core/src/main/java/org/springframework/credhub/core/CredHubInterpolationTemplate.java @@ -0,0 +1,76 @@ +/* + * 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.core; + +import org.springframework.credhub.support.ServicesData; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.util.Assert; +import org.springframework.web.client.RestOperations; +import org.springframework.web.client.RestTemplate; + +import static org.springframework.http.HttpMethod.POST; + +/** + * Implements the main interaction with CredHub to interpolate service binding credentials. + * + * @author Scott Frederick + */ +public class CredHubInterpolationTemplate implements CredHubInterpolationOperations { + static final String INTERPOLATE_URL_PATH = "/api/v1/interpolate"; + + private CredHubOperations credHubOperations; + + /** + * Create a new {@link CredHubInterpolationTemplate}. + * + * @param credHubOperations the {@link CredHubOperations} to use for interactions with CredHub + */ + CredHubInterpolationTemplate(CredHubOperations credHubOperations) { + this.credHubOperations = credHubOperations; + } + + @Override + public ServicesData interpolateServiceData(final ServicesData serviceData) { + Assert.notNull(serviceData, "serviceData must not be null"); + + return credHubOperations.doWithRest(new RestOperationsCallback() { + @Override + public ServicesData doWithRestOperations(RestOperations restOperations) { + ResponseEntity response = restOperations + .exchange(INTERPOLATE_URL_PATH, POST, + new HttpEntity<>(serviceData), ServicesData.class); + + throwExceptionOnError(response); + + return response.getBody(); + } + }); + } + /** + * Helper method to throw an appropriate exception if a request to CredHub + * returns with an error code. + * + * @param response a {@link ResponseEntity} returned from {@link RestTemplate} + */ + private void throwExceptionOnError(ResponseEntity response) { + if (!response.getStatusCode().equals(HttpStatus.OK)) { + throw new CredHubException(response.getStatusCode()); + } + } +} diff --git a/spring-credhub-core/src/main/java/org/springframework/credhub/core/CredHubOperations.java b/spring-credhub-core/src/main/java/org/springframework/credhub/core/CredHubOperations.java index 9b243cd..527eb04 100644 --- a/spring-credhub-core/src/main/java/org/springframework/credhub/core/CredHubOperations.java +++ b/spring-credhub-core/src/main/java/org/springframework/credhub/core/CredHubOperations.java @@ -16,213 +16,34 @@ package org.springframework.credhub.core; -import java.util.List; - -import org.springframework.credhub.support.permissions.Actor; -import org.springframework.credhub.support.permissions.CredentialPermission; -import org.springframework.credhub.support.CredentialDetails; -import org.springframework.credhub.support.CredentialName; -import org.springframework.credhub.support.CredentialSummary; -import org.springframework.credhub.support.ParametersRequest; -import org.springframework.credhub.support.ServicesData; -import org.springframework.credhub.support.CredentialRequest; import org.springframework.web.client.RestTemplate; /** - * Specifies the main interaction with CredHub to save, generate, retrieve, - * and delete credentials. + * Specifies the main interaction with CredHub. * * @author Scott Frederick */ public interface CredHubOperations { /** - * Write a new credential to CredHub, or overwrite an existing credential with a new - * value. + * Get the operations for saving, retrieving, and deleting credentials. * - * @param credentialRequest the credential to write to CredHub; must not be {@literal null} - * @param the credential implementation type - * @return the details of the written credential + * @return the credentials operations */ - CredentialDetails write(final CredentialRequest credentialRequest); + CredHubCredentialsOperations credentials(); /** - * Generate a new credential in CredHub, or overwrite an existing credential with a new - * generated value. + * Get the operations for adding, retrieving, and deleting credential permissions. * - * @param parametersRequest the parameters of the new credential to generate in CredHub; - * must not be {@literal null} - * @param the credential implementation type - * @param

the credential parameter implementation type - * @return the details of the generated credential + * @return the permissions operations */ - CredentialDetails generate(final ParametersRequest

parametersRequest); + CredHubPermissionsOperations permissions(); /** - * Regenerate a credential in CredHub. Only credentials that were previously generated can be - * re-generated. + * Get the operations interpolating service binding credentials. * - * @param name the name of the credential; must not be {@literal null} - * @param the credential implementation type - * @return the details of the regenerated credential + * @return the interpolation operations */ - CredentialDetails regenerate(final CredentialName name); - - /** - * Retrieve a credential using its ID, as returned in a write request. - * - * @param id the ID of the credential; must not be {@literal null} - * @param credentialType the type of the credential to be retrieved; must not be {@literal null} - * @param the credential implementation type - * @return the details of the retrieved credential - */ - CredentialDetails getById(final String id, final Class credentialType); - - /** - * Retrieve a credential using its name, as passed to a write request. - * Only the current credential value will be returned. - * - * @param name the name of the credential; must not be {@literal null} - * @param credentialType the type of credential expected to be returned - * @param the credential implementation type - * @return the details of the retrieved credential - */ - CredentialDetails getByName(final CredentialName name, final Class credentialType); - - /** - * Retrieve a credential using its name, as passed to a write request. - * A collection of all stored values for the named credential will be returned, - * including historical values. - * - * @param name the name of the credential; must not be {@literal null} - * @param credentialType the type of credential expected to be returned - * @param the credential implementation type - * @return the details of the retrieved credential, including history - */ - List> getByNameWithHistory(final CredentialName name, final Class credentialType); - - /** - * Retrieve a credential using its name, as passed to a write request. - * A collection of stored values for the named credential will be returned, - * with the specified number of historical values. - * - * @param name the name of the credential; must not be {@literal null} - * @param versions the number of historical versions to retrieve - * @param credentialType the type of credential expected to be returned - * @param the credential implementation type - * @return the details of the retrieved credential, including history - */ - List> getByNameWithHistory(final CredentialName name, int versions, - final Class credentialType); - - /** - * Find a credential using a full or partial name. - * - * @param name the name of the credential; must not be {@literal null} - * @return a summary of the credential search results - */ - List findByName(final CredentialName name); - - /** - * Find a credential using a path. - * - * @param path the path to the credential; must not be {@literal null} - * @return a summary of the credential search results - */ - List findByPath(final String path); - - /** - * Delete a credential by its full name. - * - * @param name the name of the credential; must not be {@literal null} - */ - void deleteByName(final CredentialName name); - - /** - * Get the permissions associated with a credential. - * - * @param name the name of the credential; must not be {@literal null} - * @return the collection of permissions associated with the credential - */ - List getPermissions(final CredentialName name); - - /** - * Add permissions to an existing credential. - * - * @param name the name of the credential; must not be {@literal null} - * @param permissions a collection of permissions to add - * @return the collection of permissions associated with the credential - */ - List addPermissions(final CredentialName name, final CredentialPermission... permissions); - - /** - * Delete a permission associated with a credential. - * - * @param name the name of the credential; must not be {@literal null} - * @param actor the actor of the permission; must not be {@literal null} - */ - void deletePermission(final CredentialName name, final Actor actor); - - /** - * Search the provided data structure of bound service credentials, looking for - * references to CredHub credentials. Any CredHub credentials found in the data - * structure will be replaced by the credential value stored in CredHub. - * - * Example: - * - * A JSON data structure parsed from a {@literal VCAP_SERVICES} environment - * variable might look like this if the service broker that provided the binding - * is integrated with CredHub: - * - *

-	 * {@code
-	 * {
-	 *    "service-offering": [{
-	 *      "credentials": {
-	 *        "credhub-ref": "((/c/service-broker/service-offering/1111-2222-3333-4444/credentials))"
-	 *      }
-	 *      "label": "service-offering",
-	 *      "name": "service-instance",
-	 *      "plan": "standard",
-	 *      "tags": ["
-	 *        "cloud-service"
-	 *      ]
-	 *    }]
-	 * }
-	 * }
-	 * 
- * - * Assuming that CredHub has a credential with the name - * {@literal /c/service-broker/service-offering/1111-2222-3333-4444/credentials}, - * passing the data structure above to this method would result in the - * {@literal credhub-ref} field being replaced by the credentials stored in CredHub: - * - *
-	 * {@code
-	 * {
-	 *    "service-offering": [{
-	 *      "credentials": {
-	 *        "url": "https://servicehost.example.com/",
-	 *        "username": "someuser",
-	 *        "password": "secret"
-	 *      }
-	 *      "label": "service-offering",
-	 *      "name": "service-instance",
-	 *      "plan": "standard",
-	 *      "tags": ["
-	 *        "cloud-service"
-	 *      ]
-	 *    }]
-	 * }
-	 * }
-	 * 
- * - * @param serviceData a data structure of bound service credentials, as would be - * parsed from the {@literal VCAP_SERVICES} environment variable provided to - * applications running on Cloud Foundry - * @return the serviceData structure with CredHub references replaced by stored - * credential values - */ - ServicesData interpolateServiceData(final ServicesData serviceData); + CredHubInterpolationOperations interpolation(); /** * Allow interaction with the configured {@link RestTemplate} not provided diff --git a/spring-credhub-core/src/main/java/org/springframework/credhub/core/CredHubPermissionsOperations.java b/spring-credhub-core/src/main/java/org/springframework/credhub/core/CredHubPermissionsOperations.java new file mode 100644 index 0000000..e637f90 --- /dev/null +++ b/spring-credhub-core/src/main/java/org/springframework/credhub/core/CredHubPermissionsOperations.java @@ -0,0 +1,55 @@ +/* + * 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.core; + +import org.springframework.credhub.support.CredentialName; +import org.springframework.credhub.support.permissions.Actor; +import org.springframework.credhub.support.permissions.CredentialPermission; + +import java.util.List; + +/** + * Specifies the interactions with CredHub to add, retrieve, and delete permissions. + * + * @author Scott Frederick + */ +public interface CredHubPermissionsOperations { + /** + * Get the permissions associated with a credential. + * + * @param name the name of the credential; must not be {@literal null} + * @return the collection of permissions associated with the credential + */ + List getPermissions(final CredentialName name); + + /** + * Add permissions to an existing credential. + * + * @param name the name of the credential; must not be {@literal null} + * @param permissions a collection of permissions to add + * @return the collection of permissions associated with the credential + */ + List addPermissions(final CredentialName name, final CredentialPermission... permissions); + + /** + * Delete a permission associated with a credential. + * + * @param name the name of the credential; must not be {@literal null} + * @param actor the actor of the permission; must not be {@literal null} + */ + void deletePermission(final CredentialName name, final Actor actor); +} diff --git a/spring-credhub-core/src/main/java/org/springframework/credhub/core/CredHubPermissionsTemplate.java b/spring-credhub-core/src/main/java/org/springframework/credhub/core/CredHubPermissionsTemplate.java new file mode 100644 index 0000000..93221f9 --- /dev/null +++ b/spring-credhub-core/src/main/java/org/springframework/credhub/core/CredHubPermissionsTemplate.java @@ -0,0 +1,102 @@ +/* + * 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.core; + +import org.springframework.credhub.support.CredentialName; +import org.springframework.credhub.support.CredentialPermissions; +import org.springframework.credhub.support.permissions.Actor; +import org.springframework.credhub.support.permissions.CredentialPermission; +import org.springframework.http.HttpEntity; +import org.springframework.http.ResponseEntity; +import org.springframework.util.Assert; +import org.springframework.web.client.RestOperations; + +import java.util.List; + +import static org.springframework.http.HttpMethod.POST; + +/** + * Implements the main interaction with CredHub to add, retrieve, + * and delete permissions. + * + * @author Scott Frederick + */ +public class CredHubPermissionsTemplate implements CredHubPermissionsOperations { + static final String PERMISSIONS_URL_PATH = "/api/v1/permissions"; + static final String PERMISSIONS_URL_QUERY = PERMISSIONS_URL_PATH + "?credential_name={name}"; + static final String PERMISSIONS_ACTOR_URL_QUERY = PERMISSIONS_URL_QUERY + "&actor={actor}"; + + private CredHubOperations credHubOperations; + + /** + * Create a new {@link CredHubPermissionsTemplate}. + * + * @param credHubOperations the {@link CredHubOperations} to use for interactions with CredHub + */ + CredHubPermissionsTemplate(CredHubOperations credHubOperations) { + this.credHubOperations = credHubOperations; + } + + @Override + public List getPermissions(final CredentialName name) { + Assert.notNull(name, "credential name must not be null"); + + return credHubOperations.doWithRest(new RestOperationsCallback>() { + @Override + public List doWithRestOperations(RestOperations restOperations) { + ResponseEntity response = + restOperations.getForEntity(PERMISSIONS_URL_QUERY, + CredentialPermissions.class, name.getName()); + return response.getBody().getPermissions(); + } + }); + } + + @Override + public List addPermissions(final CredentialName name, + final CredentialPermission... permissions) { + Assert.notNull(name, "credential name must not be null"); + + final CredentialPermissions credentialPermissions = new CredentialPermissions(name, permissions); + + return credHubOperations.doWithRest(new RestOperationsCallback>() { + @Override + public List doWithRestOperations(RestOperations restOperations) { + ResponseEntity response = + restOperations.exchange(PERMISSIONS_URL_PATH, POST, + new HttpEntity<>(credentialPermissions), + CredentialPermissions.class); + + return response.getBody().getPermissions(); + } + }); + } + + @Override + public void deletePermission(final CredentialName name, final Actor actor) { + Assert.notNull(name, "credential name must not be null"); + Assert.notNull(actor, "actor must not be null"); + + credHubOperations.doWithRest(new RestOperationsCallback() { + @Override + public Void doWithRestOperations(RestOperations restOperations) { + restOperations.delete(PERMISSIONS_ACTOR_URL_QUERY, name.getName(), actor.getIdentity()); + return null; + } + }); + } +} diff --git a/spring-credhub-core/src/main/java/org/springframework/credhub/core/CredHubTemplate.java b/spring-credhub-core/src/main/java/org/springframework/credhub/core/CredHubTemplate.java index e9c6a94..8309112 100644 --- a/spring-credhub-core/src/main/java/org/springframework/credhub/core/CredHubTemplate.java +++ b/spring-credhub-core/src/main/java/org/springframework/credhub/core/CredHubTemplate.java @@ -16,57 +16,17 @@ package org.springframework.credhub.core; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.springframework.core.ParameterizedTypeReference; -import org.springframework.credhub.support.CredentialDetails; -import org.springframework.credhub.support.CredentialDetailsData; -import org.springframework.credhub.support.CredentialName; -import org.springframework.credhub.support.CredentialPermissions; -import org.springframework.credhub.support.CredentialRequest; -import org.springframework.credhub.support.CredentialSummary; -import org.springframework.credhub.support.CredentialSummaryData; -import org.springframework.credhub.support.ParametersRequest; -import org.springframework.credhub.support.ServicesData; -import org.springframework.credhub.support.permissions.Actor; -import org.springframework.credhub.support.permissions.CredentialPermission; -import org.springframework.http.HttpEntity; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; import org.springframework.http.client.ClientHttpRequestFactory; import org.springframework.util.Assert; import org.springframework.web.client.HttpStatusCodeException; -import org.springframework.web.client.RestOperations; import org.springframework.web.client.RestTemplate; -import static org.springframework.http.HttpMethod.GET; -import static org.springframework.http.HttpMethod.POST; -import static org.springframework.http.HttpMethod.PUT; - /** - * Implements the main interaction with CredHub to save, retrieve, - * and delete credentials. + * Implements the main interaction with CredHub. * * @author Scott Frederick */ public class CredHubTemplate implements CredHubOperations { - static final String BASE_URL_PATH = "/api/v1/data"; - static final String ID_URL_PATH = BASE_URL_PATH + "/{id}"; - static final String NAME_URL_QUERY = BASE_URL_PATH + "?name={name}"; - static final String NAME_URL_QUERY_CURRENT = NAME_URL_QUERY + "¤t=true"; - static final String NAME_URL_QUERY_VERSIONS = NAME_URL_QUERY + "&versions={versions}"; - static final String NAME_LIKE_URL_QUERY = BASE_URL_PATH + "?name-like={name}"; - static final String PATH_URL_QUERY = BASE_URL_PATH + "?path={path}"; - - static final String PERMISSIONS_URL_PATH = "/api/v1/permissions"; - static final String PERMISSIONS_URL_QUERY = PERMISSIONS_URL_PATH + "?credential_name={name}"; - static final String PERMISSIONS_ACTOR_URL_QUERY = PERMISSIONS_URL_QUERY + "&actor={actor}"; - - static final String INTERPOLATE_URL_PATH = "/api/v1/interpolate"; - static final String REGENERATE_URL_PATH = "/api/v1/regenerate"; - private final RestTemplate restTemplate; /** @@ -98,279 +58,44 @@ public class CredHubTemplate implements CredHubOperations { clientHttpRequestFactory); } + /** + * Get the operations for saving, retrieving, and deleting credentials. + * + * @return the credentials operations + */ @Override - public CredentialDetails write(final CredentialRequest credentialRequest) { - Assert.notNull(credentialRequest, "credentialRequest must not be null"); - - final ParameterizedTypeReference> ref = - new ParameterizedTypeReference>() {}; - - return doWithRest(new RestOperationsCallback>() { - @Override - public CredentialDetails doWithRestOperations(RestOperations restOperations) { - ResponseEntity> response = - restOperations.exchange(BASE_URL_PATH, PUT, - new HttpEntity<>(credentialRequest), ref); - - throwExceptionOnError(response); - - return response.getBody(); - } - }); + public CredHubCredentialsOperations credentials() { + return new CredHubCredentialsTemplate(this); } + /** + * Get the operations for adding, retrieving, and deleting permissions from a credential. + * + * @return the permissions operations + */ @Override - public CredentialDetails generate(final ParametersRequest

parametersRequest) { - Assert.notNull(parametersRequest, "parametersRequest must not be null"); - - final ParameterizedTypeReference> ref = - new ParameterizedTypeReference>() {}; - - return doWithRest(new RestOperationsCallback>() { - @Override - public CredentialDetails doWithRestOperations(RestOperations restOperations) { - ResponseEntity> response = - restOperations.exchange(BASE_URL_PATH, POST, - new HttpEntity<>(parametersRequest), ref); - - throwExceptionOnError(response); - - return response.getBody(); - } - }); + public CredHubPermissionsOperations permissions() { + return new CredHubPermissionsTemplate(this); } + /** + * Get the operations interpolating service binding credentials. + * + * @return the interpolation operations + */ @Override - public CredentialDetails regenerate(final CredentialName name) { - Assert.notNull(name, "credential name must not be null"); - - final ParameterizedTypeReference> ref = - new ParameterizedTypeReference>() {}; - - return doWithRest(new RestOperationsCallback>() { - @Override - public CredentialDetails doWithRestOperations(RestOperations restOperations) { - Map request = new HashMap<>(1); - request.put("name", name.getName()); - - ResponseEntity> response = - restOperations.exchange(REGENERATE_URL_PATH, POST, - new HttpEntity<>(request), ref); - - throwExceptionOnError(response); - - return response.getBody(); - } - }); - } - - @Override - public CredentialDetails getById(final String id, final Class credentialType) { - Assert.notNull(id, "credential id must not be null"); - Assert.notNull(credentialType, "credential type must not be null"); - - final ParameterizedTypeReference> ref = - new ParameterizedTypeReference>() {}; - - return doWithRest(new RestOperationsCallback>() { - @Override - public CredentialDetails doWithRestOperations(RestOperations restOperations) { - ResponseEntity> response = - restOperations.exchange(ID_URL_PATH, GET, null, ref, id); - - throwExceptionOnError(response); - - return response.getBody(); - } - }); - } - - @Override - public CredentialDetails getByName(final CredentialName name, final Class credentialType) { - Assert.notNull(name, "credential name must not be null"); - Assert.notNull(credentialType, "credential type must not be null"); - - final ParameterizedTypeReference> ref = - new ParameterizedTypeReference>() {}; - - return doWithRest(new RestOperationsCallback>() { - @Override - public CredentialDetails doWithRestOperations(RestOperations restOperations) { - ResponseEntity> response = - restOperations.exchange(NAME_URL_QUERY_CURRENT, GET, null, ref, name.getName()); - - throwExceptionOnError(response); - - return response.getBody().getData().get(0); - } - }); - } - - @Override - public List> getByNameWithHistory(final CredentialName name, final Class credentialType) { - Assert.notNull(name, "credential name must not be null"); - Assert.notNull(credentialType, "credential type must not be null"); - - final ParameterizedTypeReference> ref = - new ParameterizedTypeReference>() {}; - - return doWithRest(new RestOperationsCallback>>() { - @Override - public List> doWithRestOperations(RestOperations restOperations) { - ResponseEntity> response = - restOperations.exchange(NAME_URL_QUERY, GET, null, ref, name.getName()); - - throwExceptionOnError(response); - - return response.getBody().getData(); - } - }); - } - - @Override - public List> getByNameWithHistory(final CredentialName name, final int versions, - final Class credentialType) { - Assert.notNull(name, "credential name must not be null"); - Assert.notNull(credentialType, "credential type must not be null"); - - final ParameterizedTypeReference> ref = - new ParameterizedTypeReference>() {}; - - return doWithRest(new RestOperationsCallback>>() { - @Override - public List> doWithRestOperations(RestOperations restOperations) { - ResponseEntity> response = - restOperations.exchange(NAME_URL_QUERY_VERSIONS, GET, null, ref, - name.getName(), versions); - - throwExceptionOnError(response); - - return response.getBody().getData(); - } - }); - } - - @Override - public List findByName(final CredentialName name) { - Assert.notNull(name, "credential name must not be null"); - - return doWithRest(new RestOperationsCallback>() { - @Override - public List doWithRestOperations( - RestOperations restOperations) { - ResponseEntity response = restOperations - .getForEntity(NAME_LIKE_URL_QUERY, - CredentialSummaryData.class, name.getName()); - - throwExceptionOnError(response); - - return response.getBody().getCredentials(); - } - }); - } - - @Override - public List findByPath(final String path) { - Assert.notNull(path, "credential path must not be null"); - - return doWithRest(new RestOperationsCallback>() { - @Override - public List doWithRestOperations( - RestOperations restOperations) { - ResponseEntity response = restOperations - .getForEntity(PATH_URL_QUERY, CredentialSummaryData.class, - path); - - throwExceptionOnError(response); - - return response.getBody().getCredentials(); - } - }); - } - - @Override - public void deleteByName(final CredentialName name) { - Assert.notNull(name, "credential name must not be null"); - - final String name1 = name.getName(); - Assert.notNull(name1, "credential name must not be null"); - - doWithRest(new RestOperationsCallback() { - @Override - public Void doWithRestOperations(RestOperations restOperations) { - restOperations.delete(NAME_URL_QUERY, name1); - return null; - } - }); - } - - @Override - public List getPermissions(final CredentialName name) { - Assert.notNull(name, "credential name must not be null"); - - return doWithRest(new RestOperationsCallback>() { - @Override - public List doWithRestOperations(RestOperations restOperations) { - ResponseEntity response = - restOperations.getForEntity(PERMISSIONS_URL_QUERY, - CredentialPermissions.class, name.getName()); - return response.getBody().getPermissions(); - } - }); - } - - @Override - public List addPermissions(final CredentialName name, - final CredentialPermission... permissions) { - Assert.notNull(name, "credential name must not be null"); - - final CredentialPermissions credentialPermissions = new CredentialPermissions(name, permissions); - - return doWithRest(new RestOperationsCallback>() { - @Override - public List doWithRestOperations(RestOperations restOperations) { - ResponseEntity response = - restOperations.exchange(PERMISSIONS_URL_PATH, POST, - new HttpEntity<>(credentialPermissions), - CredentialPermissions.class); - - return response.getBody().getPermissions(); - } - }); - } - - @Override - public void deletePermission(final CredentialName name, final Actor actor) { - Assert.notNull(name, "credential name must not be null"); - Assert.notNull(actor, "actor must not be null"); - - doWithRest(new RestOperationsCallback() { - @Override - public Void doWithRestOperations(RestOperations restOperations) { - restOperations.delete(PERMISSIONS_ACTOR_URL_QUERY, name.getName(), actor.getIdentity()); - return null; - } - }); - } - - @Override - public ServicesData interpolateServiceData(final ServicesData serviceData) { - Assert.notNull(serviceData, "serviceData must not be null"); - - return doWithRest(new RestOperationsCallback() { - @Override - public ServicesData doWithRestOperations(RestOperations restOperations) { - ResponseEntity response = restOperations - .exchange(INTERPOLATE_URL_PATH, POST, - new HttpEntity<>(serviceData), ServicesData.class); - - throwExceptionOnError(response); - - return response.getBody(); - } - }); + public CredHubInterpolationOperations interpolation() { + return new CredHubInterpolationTemplate(this); } + /** + * Allow interaction with the configured {@link RestTemplate} not provided + * by other methods. + * + * @param callback wrapper for the callback method + * @param the credential implementation type + * @return the return value from the callback method + */ @Override public T doWithRest(RestOperationsCallback callback) { Assert.notNull(callback, "callback must not be null"); @@ -382,16 +107,4 @@ public class CredHubTemplate implements CredHubOperations { throw new CredHubException(e); } } - - /** - * Helper method to throw an appropriate exception if a request to CredHub - * returns with an error code. - * - * @param response a {@link ResponseEntity} returned from {@link RestTemplate} - */ - private void throwExceptionOnError(ResponseEntity response) { - if (!response.getStatusCode().equals(HttpStatus.OK)) { - throw new CredHubException(response.getStatusCode()); - } - } } diff --git a/spring-credhub-core/src/test/java/org/springframework/credhub/core/CredHubClientUnitTests.java b/spring-credhub-core/src/test/java/org/springframework/credhub/core/CredHubClientUnitTests.java index 392560d..aab49a3 100644 --- a/spring-credhub-core/src/test/java/org/springframework/credhub/core/CredHubClientUnitTests.java +++ b/spring-credhub-core/src/test/java/org/springframework/credhub/core/CredHubClientUnitTests.java @@ -39,7 +39,7 @@ public class CredHubClientUnitTests { private ClientHttpRequestFactory clientHttpRequestFactory; @Test - public void restTemplateIsCreated() throws Exception { + public void restTemplateIsCreated() { RestTemplate restTemplate = CredHubClient.createRestTemplate(CREDHUB_URI, clientHttpRequestFactory); diff --git a/spring-credhub-core/src/test/java/org/springframework/credhub/core/CredHubTemplateSummaryResponseUnitTests.java b/spring-credhub-core/src/test/java/org/springframework/credhub/core/CredHubCredentialsTemplateSummaryUnitTests.java similarity index 92% rename from spring-credhub-core/src/test/java/org/springframework/credhub/core/CredHubTemplateSummaryResponseUnitTests.java rename to spring-credhub-core/src/test/java/org/springframework/credhub/core/CredHubCredentialsTemplateSummaryUnitTests.java index 8b14ba2..8fa5127 100644 --- a/spring-credhub-core/src/test/java/org/springframework/credhub/core/CredHubTemplateSummaryResponseUnitTests.java +++ b/spring-credhub-core/src/test/java/org/springframework/credhub/core/CredHubCredentialsTemplateSummaryUnitTests.java @@ -34,13 +34,13 @@ import static org.hamcrest.Matchers.notNullValue; import static org.junit.Assert.assertThat; import static org.junit.Assert.fail; import static org.mockito.Mockito.when; -import static org.springframework.credhub.core.CredHubTemplate.NAME_LIKE_URL_QUERY; -import static org.springframework.credhub.core.CredHubTemplate.PATH_URL_QUERY; +import static org.springframework.credhub.core.CredHubCredentialsTemplate.NAME_LIKE_URL_QUERY; +import static org.springframework.credhub.core.CredHubCredentialsTemplate.PATH_URL_QUERY; import static org.springframework.http.HttpStatus.OK; import static org.springframework.http.HttpStatus.UNAUTHORIZED; @RunWith(Theories.class) -public class CredHubTemplateSummaryResponseUnitTests extends CredHubTemplateUnitTestsBase { +public class CredHubCredentialsTemplateSummaryUnitTests extends CredHubCredentialsTemplateUnitTestsBase { @DataPoint("responses") public static ResponseEntity successfulResponse = new ResponseEntity<>(new CredentialSummaryData(new CredentialSummary(NAME)), OK); diff --git a/spring-credhub-core/src/test/java/org/springframework/credhub/core/CredHubCredentialsTemplateUnitTests.java b/spring-credhub-core/src/test/java/org/springframework/credhub/core/CredHubCredentialsTemplateUnitTests.java new file mode 100644 index 0000000..f4195df --- /dev/null +++ b/spring-credhub-core/src/test/java/org/springframework/credhub/core/CredHubCredentialsTemplateUnitTests.java @@ -0,0 +1,35 @@ +/* + * 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.core; + + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.junit.MockitoJUnitRunner; + +import static org.mockito.Mockito.verify; +import static org.springframework.credhub.core.CredHubCredentialsTemplate.NAME_URL_QUERY; + +@RunWith(MockitoJUnitRunner.class) +public class CredHubCredentialsTemplateUnitTests extends CredHubCredentialsTemplateUnitTestsBase { + @Test + public void deleteByName() { + credHubTemplate.deleteByName(NAME); + + verify(restTemplate).delete(NAME_URL_QUERY, NAME.getName()); + } +} \ No newline at end of file diff --git a/spring-credhub-core/src/test/java/org/springframework/credhub/core/CredHubTemplateUnitTestsBase.java b/spring-credhub-core/src/test/java/org/springframework/credhub/core/CredHubCredentialsTemplateUnitTestsBase.java similarity index 87% rename from spring-credhub-core/src/test/java/org/springframework/credhub/core/CredHubTemplateUnitTestsBase.java rename to spring-credhub-core/src/test/java/org/springframework/credhub/core/CredHubCredentialsTemplateUnitTestsBase.java index adfccef..bbdf6f7 100644 --- a/spring-credhub-core/src/test/java/org/springframework/credhub/core/CredHubTemplateUnitTestsBase.java +++ b/spring-credhub-core/src/test/java/org/springframework/credhub/core/CredHubCredentialsTemplateUnitTestsBase.java @@ -26,7 +26,7 @@ import org.mockito.quality.Strictness; import org.springframework.credhub.support.SimpleCredentialName; import org.springframework.web.client.RestTemplate; -public abstract class CredHubTemplateUnitTestsBase { +public abstract class CredHubCredentialsTemplateUnitTestsBase { protected static final SimpleCredentialName NAME = new SimpleCredentialName("example", "credential"); @Rule @@ -35,10 +35,10 @@ public abstract class CredHubTemplateUnitTestsBase { @Mock protected RestTemplate restTemplate; - protected CredHubTemplate credHubTemplate; + protected CredHubCredentialsOperations credHubTemplate; @Before public void setUpCredHubTemplateUnitTests() { - credHubTemplate = new CredHubTemplate(restTemplate); + credHubTemplate = new CredHubTemplate(restTemplate).credentials(); } } diff --git a/spring-credhub-core/src/test/java/org/springframework/credhub/core/CredHubInterpolationTemplateUnitTests.java b/spring-credhub-core/src/test/java/org/springframework/credhub/core/CredHubInterpolationTemplateUnitTests.java new file mode 100644 index 0000000..34ad47e --- /dev/null +++ b/spring-credhub-core/src/test/java/org/springframework/credhub/core/CredHubInterpolationTemplateUnitTests.java @@ -0,0 +1,104 @@ +/* + * 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.core; + +import com.fasterxml.jackson.databind.ObjectMapper; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnit; +import org.mockito.junit.MockitoJUnitRunner; +import org.mockito.junit.MockitoRule; +import org.mockito.quality.Strictness; +import org.springframework.credhub.support.ServiceInstanceCredentialName; +import org.springframework.credhub.support.ServicesData; +import org.springframework.credhub.support.utils.JsonUtils; +import org.springframework.http.HttpEntity; +import org.springframework.http.ResponseEntity; +import org.springframework.web.client.RestTemplate; + +import java.io.IOException; + +import static org.hamcrest.Matchers.equalTo; +import static org.junit.Assert.assertThat; +import static org.mockito.Mockito.when; +import static org.springframework.credhub.core.CredHubInterpolationTemplate.INTERPOLATE_URL_PATH; +import static org.springframework.http.HttpMethod.POST; +import static org.springframework.http.HttpStatus.OK; + +@RunWith(MockitoJUnitRunner.class) +public class CredHubInterpolationTemplateUnitTests { + @Rule + public MockitoRule mockitoRule = MockitoJUnit.rule().strictness(Strictness.STRICT_STUBS); + + @Mock + private RestTemplate restTemplate; + + private CredHubInterpolationOperations credHubTemplate; + + @Before + public void setUpCredHubTemplateUnitTests() { + credHubTemplate = new CredHubTemplate(restTemplate).interpolation(); + } + + @Test + public void interpolateServiceData() throws IOException { + ServiceInstanceCredentialName credentialName = ServiceInstanceCredentialName.builder() + .serviceBrokerName("service-broker") + .serviceOfferingName("service-offering") + .serviceBindingId("1111-1111-1111-111") + .credentialName("credential_json") + .build(); + + ServicesData vcapServices = buildVcapServices(credentialName.getName()); + + ServicesData expectedResponse = new ServicesData(); + + when(restTemplate.exchange(INTERPOLATE_URL_PATH, POST, + new HttpEntity<>(vcapServices), ServicesData.class)) + .thenReturn(new ResponseEntity<>(expectedResponse, OK)); + + ServicesData response = credHubTemplate.interpolateServiceData(vcapServices); + + assertThat(response, equalTo(expectedResponse)); + } + + 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); + } + +} \ No newline at end of file diff --git a/spring-credhub-core/src/test/java/org/springframework/credhub/core/CredHubTemplateUnitTests.java b/spring-credhub-core/src/test/java/org/springframework/credhub/core/CredHubPermissionsTemplateUnitTests.java similarity index 56% rename from spring-credhub-core/src/test/java/org/springframework/credhub/core/CredHubTemplateUnitTests.java rename to spring-credhub-core/src/test/java/org/springframework/credhub/core/CredHubPermissionsTemplateUnitTests.java index cbb7461..af2e408 100644 --- a/spring-credhub-core/src/test/java/org/springframework/credhub/core/CredHubTemplateUnitTests.java +++ b/spring-credhub-core/src/test/java/org/springframework/credhub/core/CredHubPermissionsTemplateUnitTests.java @@ -16,45 +16,46 @@ package org.springframework.credhub.core; -import java.io.IOException; -import java.util.List; - -import com.fasterxml.jackson.databind.ObjectMapper; +import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; - +import org.springframework.credhub.support.CredentialPermissions; +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.CredentialPermission; -import org.springframework.credhub.support.CredentialPermissions; -import org.springframework.credhub.support.utils.JsonUtils; import org.springframework.credhub.support.permissions.Operation; -import org.springframework.credhub.support.ServiceInstanceCredentialName; -import org.springframework.credhub.support.ServicesData; import org.springframework.http.HttpEntity; import org.springframework.http.ResponseEntity; +import org.springframework.web.client.RestTemplate; + +import java.util.List; import static org.hamcrest.Matchers.equalTo; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertThat; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; -import static org.springframework.credhub.core.CredHubTemplate.INTERPOLATE_URL_PATH; -import static org.springframework.credhub.core.CredHubTemplate.NAME_URL_QUERY; -import static org.springframework.credhub.core.CredHubTemplate.PERMISSIONS_ACTOR_URL_QUERY; -import static org.springframework.credhub.core.CredHubTemplate.PERMISSIONS_URL_PATH; -import static org.springframework.credhub.core.CredHubTemplate.PERMISSIONS_URL_QUERY; +import static org.springframework.credhub.core.CredHubPermissionsTemplate.PERMISSIONS_ACTOR_URL_QUERY; +import static org.springframework.credhub.core.CredHubPermissionsTemplate.PERMISSIONS_URL_PATH; +import static org.springframework.credhub.core.CredHubPermissionsTemplate.PERMISSIONS_URL_QUERY; import static org.springframework.http.HttpMethod.POST; import static org.springframework.http.HttpStatus.OK; @RunWith(MockitoJUnitRunner.class) -public class CredHubTemplateUnitTests extends CredHubTemplateUnitTestsBase { - @Test - public void deleteByName() { - credHubTemplate.deleteByName(NAME); +public class CredHubPermissionsTemplateUnitTests { + private static final SimpleCredentialName NAME = new SimpleCredentialName("example", "credential"); - verify(restTemplate).delete(NAME_URL_QUERY, NAME.getName()); + @Mock + private RestTemplate restTemplate; + + private CredHubPermissionsOperations credHubTemplate; + + @Before + public void setUpCredHubTemplateUnitTests() { + credHubTemplate = new CredHubTemplate(restTemplate).permissions(); } @Test @@ -75,7 +76,7 @@ public class CredHubTemplateUnitTests extends CredHubTemplateUnitTestsBase { ); when(restTemplate.getForEntity(PERMISSIONS_URL_QUERY, CredentialPermissions.class, NAME.getName())) - .thenReturn(new ResponseEntity(expectedResponse, OK)); + .thenReturn(new ResponseEntity<>(expectedResponse, OK)); List response = credHubTemplate.getPermissions(NAME); @@ -102,8 +103,8 @@ public class CredHubTemplateUnitTests extends CredHubTemplateUnitTestsBase { CredentialPermissions expectedResponse = new CredentialPermissions(NAME, permission1, permission2); when(restTemplate.exchange(PERMISSIONS_URL_PATH, POST, - new HttpEntity(expectedResponse), CredentialPermissions.class)) - .thenReturn(new ResponseEntity(expectedResponse, OK)); + new HttpEntity<>(expectedResponse), CredentialPermissions.class)) + .thenReturn(new ResponseEntity<>(expectedResponse, OK)); List response = credHubTemplate.addPermissions(NAME, permission1, permission2); @@ -118,49 +119,4 @@ public class CredHubTemplateUnitTests extends CredHubTemplateUnitTestsBase { verify(restTemplate).delete(PERMISSIONS_ACTOR_URL_QUERY, NAME.getName(), ActorType.APP + ":appid1"); } - - @Test - public void interpolateServiceData() throws IOException { - ServiceInstanceCredentialName credentialName = ServiceInstanceCredentialName.builder() - .serviceBrokerName("service-broker") - .serviceOfferingName("service-offering") - .serviceBindingId("1111-1111-1111-111") - .credentialName("credential_json") - .build(); - - ServicesData vcapServices = buildVcapServices(credentialName.getName()); - - ServicesData expectedResponse = new ServicesData(); - - when(restTemplate.exchange(INTERPOLATE_URL_PATH, POST, - new HttpEntity(vcapServices), ServicesData.class)) - .thenReturn(new ResponseEntity(expectedResponse, OK)); - - ServicesData response = credHubTemplate.interpolateServiceData(vcapServices); - - assertThat(response, equalTo(expectedResponse)); - } - - 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); - } - } \ No newline at end of file diff --git a/spring-credhub-core/src/test/java/org/springframework/credhub/core/CredHubTemplateDetailUnitTestsBase.java b/spring-credhub-core/src/test/java/org/springframework/credhub/core/CredHubTemplateDetailUnitTestsBase.java index 6141fd1..ef67b84 100644 --- a/spring-credhub-core/src/test/java/org/springframework/credhub/core/CredHubTemplateDetailUnitTestsBase.java +++ b/spring-credhub-core/src/test/java/org/springframework/credhub/core/CredHubTemplateDetailUnitTestsBase.java @@ -40,12 +40,12 @@ import static org.mockito.ArgumentMatchers.eq; import static org.mockito.ArgumentMatchers.isA; import static org.mockito.ArgumentMatchers.isNull; import static org.mockito.Mockito.when; -import static org.springframework.credhub.core.CredHubTemplate.BASE_URL_PATH; -import static org.springframework.credhub.core.CredHubTemplate.ID_URL_PATH; -import static org.springframework.credhub.core.CredHubTemplate.NAME_URL_QUERY; -import static org.springframework.credhub.core.CredHubTemplate.NAME_URL_QUERY_CURRENT; -import static org.springframework.credhub.core.CredHubTemplate.NAME_URL_QUERY_VERSIONS; -import static org.springframework.credhub.core.CredHubTemplate.REGENERATE_URL_PATH; +import static org.springframework.credhub.core.CredHubCredentialsTemplate.BASE_URL_PATH; +import static org.springframework.credhub.core.CredHubCredentialsTemplate.ID_URL_PATH; +import static org.springframework.credhub.core.CredHubCredentialsTemplate.NAME_URL_QUERY; +import static org.springframework.credhub.core.CredHubCredentialsTemplate.NAME_URL_QUERY_CURRENT; +import static org.springframework.credhub.core.CredHubCredentialsTemplate.NAME_URL_QUERY_VERSIONS; +import static org.springframework.credhub.core.CredHubCredentialsTemplate.REGENERATE_URL_PATH; import static org.springframework.http.HttpMethod.GET; import static org.springframework.http.HttpMethod.POST; import static org.springframework.http.HttpMethod.PUT; @@ -53,7 +53,7 @@ import static org.springframework.http.HttpStatus.OK; import static org.springframework.http.HttpStatus.UNAUTHORIZED; @SuppressWarnings("unchecked") -public abstract class CredHubTemplateDetailUnitTestsBase extends CredHubTemplateUnitTestsBase { +public abstract class CredHubTemplateDetailUnitTestsBase extends CredHubCredentialsTemplateUnitTestsBase { private static final String CREDENTIAL_ID = "1111-1111-1111-1111"; protected abstract Class getType();