[KEYCLOAK-7804] - Option to return resource body

This commit is contained in:
Corentin Dupont 2018-08-17 17:42:07 +02:00 committed by Pedro Igor
parent d04791243c
commit b80701589c
3 changed files with 115 additions and 50 deletions

View file

@ -17,14 +17,14 @@
*/
package org.keycloak.authorization.client.resource;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.Callable;
import com.fasterxml.jackson.core.type.TypeReference;
import org.keycloak.authorization.client.Configuration;
import org.keycloak.authorization.client.representation.ServerConfiguration;
import org.keycloak.authorization.client.util.Http;
import org.keycloak.authorization.client.util.HttpMethod;
import org.keycloak.authorization.client.util.Throwables;
import org.keycloak.authorization.client.util.TokenCallable;
import org.keycloak.representations.idm.authorization.ResourceRepresentation;
@ -128,13 +128,13 @@ public class ProtectedResource {
* @return a {@link ResourceRepresentation}
*/
public ResourceRepresentation findByName(String name) {
String[] representations = find(null, name, null, configuration.getResource(), null, null, false, null, null);
List<ResourceRepresentation> representations = find(null, name, null, configuration.getResource(), null, null, false, true, null, null);
if (representations.length == 0) {
if (representations.isEmpty()) {
return null;
}
return findById(representations[0]);
return representations.get(0);
}
/**
@ -145,13 +145,13 @@ public class ProtectedResource {
* @return a {@link ResourceRepresentation}
*/
public ResourceRepresentation findByName(String name, String ownerId) {
String[] representations = find(null, name, null, ownerId, null, null, false, null, null);
List<ResourceRepresentation> representations = find(null, name, null, ownerId, null, null, false, true,null, null);
if (representations.length == 0) {
if (representations.isEmpty()) {
return null;
}
return findById(representations[0]);
return representations.get(0);
}
/**
@ -172,19 +172,7 @@ public class ProtectedResource {
Callable<String[]> callable = new Callable<String[]>() {
@Override
public String[] call() throws Exception {
return http.<String[]>get(serverConfiguration.getResourceRegistrationEndpoint())
.authorizationBearer(pat.call())
.param("_id", id)
.param("name", name)
.param("uri", uri)
.param("owner", owner)
.param("type", type)
.param("scope", scope)
.param("matchingUri", Boolean.valueOf(matchingUri).toString())
.param("deep", Boolean.FALSE.toString())
.param("first", firstResult != null ? firstResult.toString() : null)
.param("max", maxResult != null ? maxResult.toString() : null)
.response().json(String[].class).execute();
return (String[]) createFindRequest(id, name, uri, owner, type, scope, matchingUri, false, firstResult, maxResult).response().json(String[].class).execute();
}
};
try {
@ -194,6 +182,40 @@ public class ProtectedResource {
}
}
/**
* Query the server for any resource with the matching arguments.
*
* @param id the resource id
* @param name the resource name
* @param uri the resource uri
* @param owner the resource owner
* @param type the resource type
* @param scope the resource scope
* @param matchingUri the resource uri. Use this parameter to lookup a resource that best match the given uri
* @param deep if the result should be a list of resource representations with details about the resource. If false, only ids are returned
* @param firstResult the position of the first resource to retrieve
* @param maxResult the maximum number of resources to retrieve
* @return a list of resource representations or an array of strings representing resource ids, depending on the generic type
*/
public <R> R find(final String id, final String name, final String uri, final String owner, final String type, final String scope, final boolean matchingUri, final boolean deep, final Integer firstResult, final Integer maxResult) {
if (deep) {
Callable<List<ResourceRepresentation>> callable = new Callable<List<ResourceRepresentation>>() {
@Override
public List<ResourceRepresentation> call() {
return (List<ResourceRepresentation>) createFindRequest(id, name, uri, owner, type, scope, matchingUri, deep, firstResult, maxResult).response().json(new TypeReference<List<ResourceRepresentation>>() {
}).execute();
}
};
try {
return (R) callable.call();
} catch (Exception cause) {
return (R) Throwables.retryAndWrapExceptionIfNecessary(callable, pat, "Could not find resource", cause);
}
}
return (R) find(id, name, uri, owner, type, scope, matchingUri, firstResult, maxResult);
}
/**
* Query the server for all resources.
*
@ -235,19 +257,7 @@ public class ProtectedResource {
* @param uri the resource uri
*/
public List<ResourceRepresentation> findByUri(String uri) {
String[] ids = find(null, null, uri, null, null, null, false, null, null);
if (ids.length == 0) {
return Collections.emptyList();
}
List<ResourceRepresentation> representations = new ArrayList<>();
for (String id : ids) {
representations.add(findById(id));
}
return representations;
return find(null, null, uri, null, null, null, false, true, null, null);
}
/**
@ -258,18 +268,21 @@ public class ProtectedResource {
* @return a list of resources
*/
public List<ResourceRepresentation> findByMatchingUri(String uri) {
String[] ids = find(null, null, uri, null, null, null, true, null, null);
return find(null, null, uri, null, null, null, true, true,null, null);
}
if (ids.length == 0) {
return Collections.emptyList();
}
List<ResourceRepresentation> representations = new ArrayList<>();
for (String id : ids) {
representations.add(findById(id));
}
return representations;
private HttpMethod createFindRequest(String id, String name, String uri, String owner, String type, String scope, boolean matchingUri, boolean deep, Integer firstResult, Integer maxResult) {
return http.get(serverConfiguration.getResourceRegistrationEndpoint())
.authorizationBearer(pat.call())
.param("_id", id)
.param("name", name)
.param("uri", uri)
.param("owner", owner)
.param("type", type)
.param("scope", scope)
.param("matchingUri", Boolean.valueOf(matchingUri).toString())
.param("deep", Boolean.toString(deep))
.param("first", firstResult != null ? firstResult.toString() : null)
.param("max", maxResult != null ? maxResult.toString() : null);
}
}

View file

@ -128,7 +128,12 @@ public class ResourceService {
@QueryParam("deep") Boolean deep,
@QueryParam("first") Integer firstResult,
@QueryParam("max") Integer maxResult) {
return resourceManager.find(id, name, uri, owner, type, scope, matchingUri, deep, firstResult, maxResult, (BiFunction<Resource, Boolean, String>) (resource, deep1) -> resource.getId());
if(deep != null && deep) {
return resourceManager.find(id, name, uri, owner, type, scope, matchingUri, deep, firstResult, maxResult);
} else {
return resourceManager.find(id, name, uri, owner, type, scope, matchingUri, deep, firstResult, maxResult, (BiFunction<Resource, Boolean, String>) (resource, deep1) -> resource.getId());
}
}
private void checkResourceServerSettings() {
@ -136,4 +141,4 @@ public class ResourceService {
throw new ErrorResponseException("not_supported", "Remote management is disabled.", Status.BAD_REQUEST);
}
}
}
}

View file

@ -19,12 +19,22 @@ package org.keycloak.testsuite.admin.client.authorization;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import java.io.IOException;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import org.hamcrest.Matcher;
import org.hamcrest.Matchers;
import org.hamcrest.collection.IsMapContaining;
import org.junit.Test;
import org.keycloak.authorization.client.AuthzClient;
import org.keycloak.authorization.client.Configuration;
@ -96,6 +106,36 @@ public class ResourceManagementWithAuthzClientTest extends ResourceManagementTes
assertEquals("/resources/{pattern}/sub-resources/{pattern}/*", resources.get(0).getUri());
}
@Test
public void testFindDeep() {
ResourceRepresentation resource1 = new ResourceRepresentation("/*", new HashSet<>());
resource1.addScope("a", "b", "c");
resource1.setType("type");
Map<String, List<String>> attributes = new HashMap<>();
attributes.put("a", Arrays.asList("a"));
attributes.put("b", Arrays.asList("b"));
attributes.put("c", Arrays.asList("c"));
resource1.setAttributes(attributes);
resource1.setIconUri("icon");
resource1.setUris(new HashSet<>(Arrays.asList("/a", "/b", "/c")));
ResourceRepresentation resource = doCreateResource(resource1);
AuthzClient authzClient = getAuthzClient();
List<ResourceRepresentation> representations = authzClient.protection().resource().find(resource.getId(), null, null, null, null, null, false, true,null, null);
assertEquals(1, representations.size());
assertEquals(resource.getId(), representations.get(0).getId());
assertEquals(resource.getName(), representations.get(0).getName());
assertEquals(resource.getIconUri(), representations.get(0).getIconUri());
assertThat(resource.getUris(), Matchers.containsInAnyOrder(representations.get(0).getUris().toArray()));
assertThat(resource.getAttributes().entrySet(), Matchers.containsInAnyOrder(representations.get(0).getAttributes().entrySet().toArray()));
}
@Override
protected ResourceRepresentation doCreateResource(ResourceRepresentation newResource) {
ResourceRepresentation resource = toResourceRepresentation(newResource);
@ -127,7 +167,7 @@ public class ResourceManagementWithAuthzClientTest extends ResourceManagementTes
resourceRepresentation.setId(created.getId());
resourceRepresentation.setName(created.getName());
resourceRepresentation.setIconUri(created.getIconUri());
resourceRepresentation.setUri(created.getUri());
resourceRepresentation.setUris(created.getUris());
resourceRepresentation.setType(created.getType());
resourceRepresentation.setOwner(created.getOwner());
resourceRepresentation.setScopes(created.getScopes().stream().map(scopeRepresentation -> {
@ -151,7 +191,13 @@ public class ResourceManagementWithAuthzClientTest extends ResourceManagementTes
resource.setId(newResource.getId());
resource.setName(newResource.getName());
resource.setIconUri(newResource.getIconUri());
resource.setUri(newResource.getUri());
if (newResource.getUris() != null && !newResource.getUris().isEmpty()) {
resource.setUris(newResource.getUris());
} else {
resource.setUri(newResource.getUri());
}
resource.setType(newResource.getType());
if (newResource.getOwner() != null) {
@ -169,6 +215,7 @@ public class ResourceManagementWithAuthzClientTest extends ResourceManagementTes
resource.setAttributes(newResource.getAttributes());
return resource;
}