diff --git a/settings.gradle b/settings.gradle index fd156d2..44cab50 100644 --- a/settings.gradle +++ b/settings.gradle @@ -4,6 +4,7 @@ include ':spring-credhub-core' include ':spring-credhub-cloud-connector' include ':spring-credhub-starter' include ':spring-credhub-integration-tests' +include ':spring-credhub-reactive-integration-tests' include ':spring-credhub-docs' project(':spring-credhub-core').projectDir = "$rootDir/spring-credhub-core" as File diff --git a/spring-credhub-core/src/main/java/org/springframework/credhub/core/permissionV2/CredHubPermissionV2Operations.java b/spring-credhub-core/src/main/java/org/springframework/credhub/core/permissionV2/CredHubPermissionV2Operations.java index 2e91018..b3c4bb8 100644 --- a/spring-credhub-core/src/main/java/org/springframework/credhub/core/permissionV2/CredHubPermissionV2Operations.java +++ b/spring-credhub-core/src/main/java/org/springframework/credhub/core/permissionV2/CredHubPermissionV2Operations.java @@ -18,12 +18,14 @@ package org.springframework.credhub.core.permissionV2; import org.springframework.credhub.support.CredentialName; import org.springframework.credhub.support.CredentialPermission; +import org.springframework.credhub.support.permissions.Actor; import org.springframework.credhub.support.permissions.Permission; /** * Specifies the interactions with CredHub to add, retrieve, and delete permissions. * * @author Scott Frederick + * @author Alberto C. Ríos */ public interface CredHubPermissionV2Operations { /** @@ -34,6 +36,16 @@ public interface CredHubPermissionV2Operations { */ CredentialPermission getPermissions(final String id); + /** + * Get a permission by path and actor. + * @since API 2.1 + * + * @param path the path of the credentials; must not be {@literal null} + * @param actor the actor of the credentials; must not be {@literal null} + * @return the details if the specified permission + */ + CredentialPermission getPermissionsByPathAndActor(final CredentialName path, final Actor actor); + /** * Add permissions to an credential path. * diff --git a/spring-credhub-core/src/main/java/org/springframework/credhub/core/permissionV2/CredHubPermissionV2Template.java b/spring-credhub-core/src/main/java/org/springframework/credhub/core/permissionV2/CredHubPermissionV2Template.java index 4d1e5c9..21aeac9 100644 --- a/spring-credhub-core/src/main/java/org/springframework/credhub/core/permissionV2/CredHubPermissionV2Template.java +++ b/spring-credhub-core/src/main/java/org/springframework/credhub/core/permissionV2/CredHubPermissionV2Template.java @@ -19,6 +19,7 @@ package org.springframework.credhub.core.permissionV2; import org.springframework.credhub.core.CredHubOperations; import org.springframework.credhub.support.CredentialName; import org.springframework.credhub.support.CredentialPermission; +import org.springframework.credhub.support.permissions.Actor; import org.springframework.credhub.support.permissions.Permission; import org.springframework.http.HttpEntity; import org.springframework.http.HttpMethod; @@ -30,10 +31,12 @@ import org.springframework.util.Assert; * and delete permissions. * * @author Scott Frederick + * @author Alberto C. Ríos */ public class CredHubPermissionV2Template implements CredHubPermissionV2Operations { static final String PERMISSIONS_URL_PATH = "/api/v2/permissions"; static final String PERMISSIONS_ID_URL_PATH = PERMISSIONS_URL_PATH + "/{id}"; + static final String PERMISSIONS_PATH_ACTOR_URL_QUERY = PERMISSIONS_URL_PATH + "?path={path}&actor={actor}"; private CredHubOperations credHubOperations; @@ -58,6 +61,19 @@ public class CredHubPermissionV2Template implements CredHubPermissionV2Operation }); } + @Override + public CredentialPermission getPermissionsByPathAndActor(final CredentialName path, final Actor actor) { + Assert.notNull(path, "credential path must not be null"); + Assert.notNull(actor, "credential actor must not be null"); + + return credHubOperations.doWithRest(restOperations -> { + ResponseEntity response = + restOperations.getForEntity(PERMISSIONS_PATH_ACTOR_URL_QUERY, + CredentialPermission.class, path.getName(), actor.getIdentity()); + return response.getBody(); + }); + } + @Override public CredentialPermission addPermissions(final CredentialName path, final Permission permission) { diff --git a/spring-credhub-core/src/main/java/org/springframework/credhub/core/permissionV2/ReactiveCredHubPermissionV2Operations.java b/spring-credhub-core/src/main/java/org/springframework/credhub/core/permissionV2/ReactiveCredHubPermissionV2Operations.java index 287517e..f2e3df3 100644 --- a/spring-credhub-core/src/main/java/org/springframework/credhub/core/permissionV2/ReactiveCredHubPermissionV2Operations.java +++ b/spring-credhub-core/src/main/java/org/springframework/credhub/core/permissionV2/ReactiveCredHubPermissionV2Operations.java @@ -18,6 +18,7 @@ package org.springframework.credhub.core.permissionV2; import org.springframework.credhub.support.CredentialName; import org.springframework.credhub.support.CredentialPermission; +import org.springframework.credhub.support.permissions.Actor; import org.springframework.credhub.support.permissions.Permission; import reactor.core.publisher.Mono; @@ -25,6 +26,7 @@ import reactor.core.publisher.Mono; * Specifies the interactions with CredHub to add, retrieve, and delete permissions. * * @author Scott Frederick + * @author Alberto C. Ríos */ public interface ReactiveCredHubPermissionV2Operations { /** @@ -35,6 +37,16 @@ public interface ReactiveCredHubPermissionV2Operations { */ Mono getPermissions(final String id); + /** + * Get a permission by path and actor. + * @since API 2.1 + * + * @param path the path of the credentials; must not be {@literal null} + * @param actor the actor of the credentials; must not be {@literal null} + * @return the details if the specified permission + */ + Mono getPermissionsByPathAndActor(final CredentialName path, final Actor actor); + /** * Add permissions to an credential path. * diff --git a/spring-credhub-core/src/main/java/org/springframework/credhub/core/permissionV2/ReactiveCredHubPermissionV2Template.java b/spring-credhub-core/src/main/java/org/springframework/credhub/core/permissionV2/ReactiveCredHubPermissionV2Template.java index de37b9a..7f02f7d 100644 --- a/spring-credhub-core/src/main/java/org/springframework/credhub/core/permissionV2/ReactiveCredHubPermissionV2Template.java +++ b/spring-credhub-core/src/main/java/org/springframework/credhub/core/permissionV2/ReactiveCredHubPermissionV2Template.java @@ -16,24 +16,28 @@ package org.springframework.credhub.core.permissionV2; +import reactor.core.publisher.Mono; + import org.springframework.credhub.core.ExceptionUtils; import org.springframework.credhub.core.ReactiveCredHubOperations; import org.springframework.credhub.support.CredentialName; import org.springframework.credhub.support.CredentialPermission; +import org.springframework.credhub.support.permissions.Actor; import org.springframework.credhub.support.permissions.Permission; import org.springframework.http.HttpStatus; import org.springframework.util.Assert; -import reactor.core.publisher.Mono; /** * Implements the main interaction with CredHub to add, retrieve, * and delete permissions. * * @author Scott Frederick + * @author Alberto C. Ríos */ public class ReactiveCredHubPermissionV2Template implements ReactiveCredHubPermissionV2Operations { private static final String PERMISSIONS_URL_PATH = "/api/v2/permissions"; private static final String PERMISSIONS_ID_URL_PATH = PERMISSIONS_URL_PATH + "/{id}"; + static final String PERMISSIONS_PATH_ACTOR_URL_QUERY = PERMISSIONS_URL_PATH + "?path={path}&actor={actor}"; private ReactiveCredHubOperations credHubOperations; @@ -74,6 +78,19 @@ public class ReactiveCredHubPermissionV2Template implements ReactiveCredHubPermi .bodyToMono(CredentialPermission.class)); } + @Override + public Mono getPermissionsByPathAndActor(final CredentialName path, final Actor actor) { + Assert.notNull(path, "credential path must not be null"); + Assert.notNull(actor, "credential actor must not be null"); + + return credHubOperations.doWithWebClient(webClient -> webClient + .get() + .uri(PERMISSIONS_PATH_ACTOR_URL_QUERY, path.getName(), actor.getIdentity()) + .retrieve() + .onStatus(HttpStatus::isError, ExceptionUtils::buildError) + .bodyToMono(CredentialPermission.class)); + } + @Override public Mono updatePermissions(final String id, final CredentialName path, final Permission permission) { diff --git a/spring-credhub-core/src/test/java/org/springframework/credhub/core/permissionV2/CredHubPermissionV2TemplateUnitTests.java b/spring-credhub-core/src/test/java/org/springframework/credhub/core/permissionV2/CredHubPermissionV2TemplateUnitTests.java index 916ca28..31059c4 100644 --- a/spring-credhub-core/src/test/java/org/springframework/credhub/core/permissionV2/CredHubPermissionV2TemplateUnitTests.java +++ b/spring-credhub-core/src/test/java/org/springframework/credhub/core/permissionV2/CredHubPermissionV2TemplateUnitTests.java @@ -21,9 +21,11 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; + import org.springframework.credhub.core.CredHubTemplate; 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.Operation; import org.springframework.credhub.support.permissions.Permission; import org.springframework.http.HttpEntity; @@ -33,9 +35,11 @@ import org.springframework.web.client.RestTemplate; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import static org.springframework.credhub.core.permissionV2.CredHubPermissionV2Template.PERMISSIONS_PATH_ACTOR_URL_QUERY; import static org.springframework.credhub.core.permissionV2.CredHubPermissionV2Template.PERMISSIONS_ID_URL_PATH; import static org.springframework.credhub.core.permissionV2.CredHubPermissionV2Template.PERMISSIONS_URL_PATH; import static org.springframework.credhub.support.permissions.ActorType.APP; +import static org.springframework.credhub.support.permissions.ActorType.OAUTH_CLIENT; import static org.springframework.http.HttpMethod.POST; import static org.springframework.http.HttpMethod.PUT; import static org.springframework.http.HttpStatus.OK; @@ -78,6 +82,31 @@ public class CredHubPermissionV2TemplateUnitTests { assertThat(response.getPermission().getOperations()).contains(Operation.READ, Operation.WRITE); } + @Test + public void getPermissionsByPathAndActor() { + String clientId = "client-id"; + + CredentialPermission expectedResponse = new CredentialPermission( + PATH, + Permission.builder() + .operation(Operation.READ) + .operation(Operation.WRITE) + .client(clientId) + .build()); + + String actor = OAUTH_CLIENT + ":" + clientId; + when(restTemplate.getForEntity(PERMISSIONS_PATH_ACTOR_URL_QUERY, CredentialPermission.class, PATH.getName(), actor)) + .thenReturn(new ResponseEntity<>(expectedResponse, OK)); + + CredentialPermission response = credHubTemplate.getPermissionsByPathAndActor(PATH, Actor.client(clientId)); + + assertThat(response).isNotNull(); + assertThat(response.getPath()).isEqualTo(PATH.getName()); + assertThat(response.getPermission().getActor().getAuthType()).isEqualTo(OAUTH_CLIENT); + assertThat(response.getPermission().getActor().getPrimaryIdentifier()).isEqualTo(clientId); + assertThat(response.getPermission().getOperations()).contains(Operation.READ, Operation.WRITE); + } + @Test public void addPermissions() { Permission permission = Permission.builder() @@ -130,4 +159,4 @@ public class CredHubPermissionV2TemplateUnitTests { verify(restTemplate).delete(PERMISSIONS_ID_URL_PATH, "uuid"); } -} \ No newline at end of file +}