[KEYCLOAK-10705] - Return full resource representation when querying policies by id
This commit is contained in:
parent
9fd7ab81f0
commit
709cbfd4b7
11 changed files with 123 additions and 26 deletions
|
@ -21,6 +21,8 @@ import java.util.HashSet;
|
|||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
|
||||
*/
|
||||
|
@ -36,6 +38,12 @@ public class AbstractPolicyRepresentation {
|
|||
private Logic logic = Logic.POSITIVE;
|
||||
private DecisionStrategy decisionStrategy = DecisionStrategy.UNANIMOUS;
|
||||
private String owner;
|
||||
|
||||
@JsonInclude(JsonInclude.Include.NON_EMPTY)
|
||||
private Set<ResourceRepresentation> resourcesData;
|
||||
|
||||
@JsonInclude(JsonInclude.Include.NON_EMPTY)
|
||||
private Set<ScopeRepresentation> scopesData;
|
||||
|
||||
public String getId() {
|
||||
return this.id;
|
||||
|
@ -162,4 +170,20 @@ public class AbstractPolicyRepresentation {
|
|||
public int hashCode() {
|
||||
return Objects.hash(getId());
|
||||
}
|
||||
|
||||
public <R> void setResourcesData(Set<ResourceRepresentation> resources) {
|
||||
this.resourcesData = resources;
|
||||
}
|
||||
|
||||
public Set<ResourceRepresentation> getResourcesData() {
|
||||
return resourcesData;
|
||||
}
|
||||
|
||||
public void setScopesData(Set<ScopeRepresentation> scopesData) {
|
||||
this.scopesData = scopesData;
|
||||
}
|
||||
|
||||
public Set<ScopeRepresentation> getScopesData() {
|
||||
return scopesData;
|
||||
}
|
||||
}
|
|
@ -57,6 +57,20 @@ public interface PoliciesResource {
|
|||
@NoCache
|
||||
List<PolicyRepresentation> policies();
|
||||
|
||||
@GET
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@NoCache
|
||||
List<PolicyRepresentation> policies(@QueryParam("policyId") String id,
|
||||
@QueryParam("name") String name,
|
||||
@QueryParam("type") String type,
|
||||
@QueryParam("resource") String resource,
|
||||
@QueryParam("scope") String scope,
|
||||
@QueryParam("permission") Boolean permission,
|
||||
@QueryParam("owner") String owner,
|
||||
@QueryParam("fields") String fields,
|
||||
@QueryParam("first") Integer firstResult,
|
||||
@QueryParam("max") Integer maxResult);
|
||||
|
||||
@Path("providers")
|
||||
@GET
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
|
|
|
@ -24,6 +24,7 @@ import javax.ws.rs.GET;
|
|||
import javax.ws.rs.PUT;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.Produces;
|
||||
import javax.ws.rs.QueryParam;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
|
||||
import org.jboss.resteasy.annotations.cache.NoCache;
|
||||
|
@ -41,6 +42,11 @@ public interface PolicyResource {
|
|||
@NoCache
|
||||
PolicyRepresentation toRepresentation();
|
||||
|
||||
@GET
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@NoCache
|
||||
PolicyRepresentation toRepresentation(@QueryParam("fields") String fields);
|
||||
|
||||
@PUT
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
void update(PolicyRepresentation representation);
|
||||
|
|
|
@ -817,6 +817,10 @@ public class ModelToRepresentation {
|
|||
}
|
||||
|
||||
public static <R extends AbstractPolicyRepresentation> R toRepresentation(Policy policy, AuthorizationProvider authorization, boolean genericRepresentation, boolean export) {
|
||||
return toRepresentation(policy, authorization, genericRepresentation, export, false);
|
||||
}
|
||||
|
||||
public static <R extends AbstractPolicyRepresentation> R toRepresentation(Policy policy, AuthorizationProvider authorization, boolean genericRepresentation, boolean export, boolean allFields) {
|
||||
PolicyProviderFactory providerFactory = authorization.getProviderFactory(policy.getType());
|
||||
R representation;
|
||||
|
||||
|
@ -840,6 +844,13 @@ public class ModelToRepresentation {
|
|||
representation.setType(policy.getType());
|
||||
representation.setDecisionStrategy(policy.getDecisionStrategy());
|
||||
representation.setLogic(policy.getLogic());
|
||||
|
||||
if (allFields) {
|
||||
representation.setResourcesData(policy.getResources().stream().map(
|
||||
resource -> toRepresentation(resource, resource.getResourceServer(), authorization, true)).collect(Collectors.toSet()));
|
||||
representation.setScopesData(policy.getScopes().stream().map(
|
||||
resource -> toRepresentation(resource)).collect(Collectors.toSet()));
|
||||
}
|
||||
|
||||
return representation;
|
||||
}
|
||||
|
|
|
@ -45,22 +45,22 @@ public class PermissionService extends PolicyService {
|
|||
protected PolicyTypeService doCreatePolicyTypeResource(String type) {
|
||||
return new PolicyTypeService(type, resourceServer, authorization, auth, adminEvent) {
|
||||
@Override
|
||||
protected List<Object> doSearch(Integer firstResult, Integer maxResult, Map<String, String[]> filters) {
|
||||
protected List<Object> doSearch(Integer firstResult, Integer maxResult, String fields, Map<String, String[]> filters) {
|
||||
filters.put("permission", new String[] {Boolean.TRUE.toString()});
|
||||
filters.put("type", new String[] {type});
|
||||
return super.doSearch(firstResult, maxResult, filters);
|
||||
return super.doSearch(firstResult, maxResult, fields, filters);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<Object> doSearch(Integer firstResult, Integer maxResult, Map<String, String[]> filters) {
|
||||
protected List<Object> doSearch(Integer firstResult, Integer maxResult, String fields, Map<String, String[]> filters) {
|
||||
filters.put("permission", new String[] {Boolean.TRUE.toString()});
|
||||
return super.doSearch(firstResult, maxResult, filters);
|
||||
return super.doSearch(firstResult, maxResult, fields, filters);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected AbstractPolicyRepresentation toRepresentation(Policy policy, AuthorizationProvider authorization) {
|
||||
return ModelToRepresentation.toRepresentation(policy, authorization, false, false);
|
||||
protected AbstractPolicyRepresentation toRepresentation(Policy policy, String fields, AuthorizationProvider authorization) {
|
||||
return ModelToRepresentation.toRepresentation(policy, authorization, false, false, fields != null && fields.equals("*"));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@ import javax.ws.rs.GET;
|
|||
import javax.ws.rs.PUT;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.Produces;
|
||||
import javax.ws.rs.QueryParam;
|
||||
import javax.ws.rs.core.Response;
|
||||
import javax.ws.rs.core.Response.Status;
|
||||
|
||||
|
@ -121,7 +122,7 @@ public class PolicyResourceService {
|
|||
@GET
|
||||
@Produces("application/json")
|
||||
@NoCache
|
||||
public Response findById() {
|
||||
public Response findById(@QueryParam("fields") String fields) {
|
||||
if (auth != null) {
|
||||
this.auth.realm().requireViewAuthorization();
|
||||
}
|
||||
|
@ -130,11 +131,15 @@ public class PolicyResourceService {
|
|||
return Response.status(Status.NOT_FOUND).build();
|
||||
}
|
||||
|
||||
return Response.ok(toRepresentation(policy, authorization)).build();
|
||||
return Response.ok(toRepresentation(policy, fields, authorization)).build();
|
||||
}
|
||||
|
||||
protected AbstractPolicyRepresentation toRepresentation(Policy policy, AuthorizationProvider authorization) {
|
||||
return ModelToRepresentation.toRepresentation(policy, authorization, true, false);
|
||||
private AbstractPolicyRepresentation toRepresentation(Policy policy, AuthorizationProvider authorization) {
|
||||
return toRepresentation(policy, null, authorization);
|
||||
}
|
||||
|
||||
protected AbstractPolicyRepresentation toRepresentation(Policy policy, String fields, AuthorizationProvider authorization) {
|
||||
return ModelToRepresentation.toRepresentation(policy, authorization, true, false, fields != null && fields.equals("*"));
|
||||
}
|
||||
|
||||
@Path("/dependentPolicies")
|
||||
|
|
|
@ -146,7 +146,7 @@ public class PolicyService {
|
|||
@GET
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@NoCache
|
||||
public Response findByName(@QueryParam("name") String name) {
|
||||
public Response findByName(@QueryParam("name") String name, @QueryParam("fields") String fields) {
|
||||
if (auth != null) {
|
||||
this.auth.realm().requireViewAuthorization();
|
||||
}
|
||||
|
@ -163,7 +163,7 @@ public class PolicyService {
|
|||
return Response.status(Status.OK).build();
|
||||
}
|
||||
|
||||
return Response.ok(toRepresentation(model, authorization)).build();
|
||||
return Response.ok(toRepresentation(model, fields, authorization)).build();
|
||||
}
|
||||
|
||||
@GET
|
||||
|
@ -176,6 +176,7 @@ public class PolicyService {
|
|||
@QueryParam("scope") String scope,
|
||||
@QueryParam("permission") Boolean permission,
|
||||
@QueryParam("owner") String owner,
|
||||
@QueryParam("fields") String fields,
|
||||
@QueryParam("first") Integer firstResult,
|
||||
@QueryParam("max") Integer maxResult) {
|
||||
if (auth != null) {
|
||||
|
@ -253,18 +254,18 @@ public class PolicyService {
|
|||
}
|
||||
|
||||
return Response.ok(
|
||||
doSearch(firstResult, maxResult, search))
|
||||
doSearch(firstResult, maxResult, fields, search))
|
||||
.build();
|
||||
}
|
||||
|
||||
protected AbstractPolicyRepresentation toRepresentation(Policy model, AuthorizationProvider authorization) {
|
||||
return ModelToRepresentation.toRepresentation(model, authorization, true, false);
|
||||
protected AbstractPolicyRepresentation toRepresentation(Policy model, String fields, AuthorizationProvider authorization) {
|
||||
return ModelToRepresentation.toRepresentation(model, authorization, true, false, fields != null && fields.equals("*"));
|
||||
}
|
||||
|
||||
protected List<Object> doSearch(Integer firstResult, Integer maxResult, Map<String, String[]> filters) {
|
||||
protected List<Object> doSearch(Integer firstResult, Integer maxResult, String fields, Map<String, String[]> filters) {
|
||||
PolicyStore policyStore = authorization.getStoreFactory().getPolicyStore();
|
||||
return policyStore.findByResourceServer(filters, resourceServer.getId(), firstResult != null ? firstResult : -1, maxResult != null ? maxResult : Constants.DEFAULT_MAX_RESULTS).stream()
|
||||
.map(policy -> toRepresentation(policy, authorization))
|
||||
.map(policy -> toRepresentation(policy, fields, authorization))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
|
|
|
@ -58,8 +58,7 @@ public class PolicyTypeResourceService extends PolicyResourceService {
|
|||
return representation;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected AbstractPolicyRepresentation toRepresentation(Policy policy, AuthorizationProvider authorization) {
|
||||
return ModelToRepresentation.toRepresentation(policy, authorization, false, false);
|
||||
protected AbstractPolicyRepresentation toRepresentation(Policy policy, String fields, AuthorizationProvider authorization) {
|
||||
return ModelToRepresentation.toRepresentation(policy, authorization, false, false, fields != null && fields.equals("*"));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -87,13 +87,13 @@ public class PolicyTypeService extends PolicyService {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected AbstractPolicyRepresentation toRepresentation(Policy policy, AuthorizationProvider authorization) {
|
||||
protected AbstractPolicyRepresentation toRepresentation(Policy policy, String fields, AuthorizationProvider authorization) {
|
||||
return ModelToRepresentation.toRepresentation(policy, authorization, false, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<Object> doSearch(Integer firstResult, Integer maxResult, Map<String, String[]> filters) {
|
||||
protected List<Object> doSearch(Integer firstResult, Integer maxResult, String fields, Map<String, String[]> filters) {
|
||||
filters.put("type", new String[] {type});
|
||||
return super.doSearch(firstResult, maxResult, filters);
|
||||
return super.doSearch(firstResult, maxResult, fields, filters);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -117,7 +117,7 @@ public class UserManagedPermissionService {
|
|||
@Produces("application/json")
|
||||
public Response findById(@PathParam("policyId") String policyId) {
|
||||
checkRequest(getAssociatedResourceId(policyId), null);
|
||||
return PolicyTypeResourceService.class.cast(delegate.getResource(policyId)).findById();
|
||||
return PolicyTypeResourceService.class.cast(delegate.getResource(policyId)).findById(null);
|
||||
}
|
||||
|
||||
@GET
|
||||
|
@ -128,7 +128,7 @@ public class UserManagedPermissionService {
|
|||
@QueryParam("scope") String scope,
|
||||
@QueryParam("first") Integer firstResult,
|
||||
@QueryParam("max") Integer maxResult) {
|
||||
return delegate.findAll(null, name, "uma", resource, scope, true, identity.getId(), firstResult, maxResult);
|
||||
return delegate.findAll(null, name, "uma", resource, scope, true, identity.getId(), null, firstResult, maxResult);
|
||||
}
|
||||
|
||||
private Policy getPolicy(@PathParam("policyId") String policyId) {
|
||||
|
|
|
@ -18,17 +18,18 @@
|
|||
package org.keycloak.testsuite.admin.client.authorization;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.keycloak.admin.client.resource.AuthorizationResource;
|
||||
import org.keycloak.admin.client.resource.PoliciesResource;
|
||||
import org.keycloak.admin.client.resource.PolicyResource;
|
||||
import org.keycloak.admin.client.resource.ResourceResource;
|
||||
import org.keycloak.admin.client.resource.ResourceScopeResource;
|
||||
import org.keycloak.admin.client.resource.ResourceScopesResource;
|
||||
import org.keycloak.admin.client.resource.ResourcesResource;
|
||||
import org.keycloak.common.Profile;
|
||||
import org.keycloak.representations.idm.authorization.DecisionStrategy;
|
||||
import org.keycloak.representations.idm.authorization.Logic;
|
||||
import org.keycloak.representations.idm.authorization.PolicyProviderRepresentation;
|
||||
import org.keycloak.representations.idm.authorization.PolicyRepresentation;
|
||||
import org.keycloak.representations.idm.authorization.ResourcePermissionRepresentation;
|
||||
import org.keycloak.representations.idm.authorization.ResourceRepresentation;
|
||||
import org.keycloak.representations.idm.authorization.ScopeRepresentation;
|
||||
|
||||
|
@ -38,6 +39,7 @@ import java.util.Arrays;
|
|||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
|
@ -147,6 +149,41 @@ public class GenericPolicyManagementTest extends AbstractAuthorizationTest {
|
|||
assertTrue(providers.containsAll(expected));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testQueryPolicyByIdAllFields() {
|
||||
PolicyResource policy = createTestingPolicy();
|
||||
PolicyRepresentation representation = policy.toRepresentation("*");
|
||||
Set<ResourceRepresentation> resources = representation.getResourcesData();
|
||||
|
||||
assertEquals(3, resources.size());
|
||||
|
||||
representation = policy.toRepresentation();
|
||||
assertNull(representation.getResourcesData());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testQueryPolicyAllFields() {
|
||||
AuthorizationResource authorization = getClientResource().authorization();
|
||||
|
||||
authorization.resources().create(new ResourceRepresentation("Resource A"));
|
||||
ResourcePermissionRepresentation permission = new ResourcePermissionRepresentation();
|
||||
permission.setName("Permission A");
|
||||
permission.addResource("Resource A");
|
||||
authorization.permissions().resource().create(permission);
|
||||
|
||||
List<PolicyRepresentation> policies = authorization.policies()
|
||||
.policies(null, "Permission A", null, null, null, true, null, "*", -1, -1);
|
||||
|
||||
assertEquals(1, policies.size());
|
||||
assertEquals(1, policies.get(0).getResourcesData().size());
|
||||
|
||||
policies = authorization.policies()
|
||||
.policies(null, "Permission A", null, null, null, true, null, null, -1, -1);
|
||||
|
||||
assertEquals(1, policies.size());
|
||||
assertNull(policies.get(0).getResourcesData());
|
||||
}
|
||||
|
||||
private PolicyResource createTestingPolicy() {
|
||||
Map<String, String> config = new HashMap<>();
|
||||
|
||||
|
|
Loading…
Reference in a new issue