[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.Objects;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
|
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
|
||||||
*/
|
*/
|
||||||
|
@ -36,6 +38,12 @@ public class AbstractPolicyRepresentation {
|
||||||
private Logic logic = Logic.POSITIVE;
|
private Logic logic = Logic.POSITIVE;
|
||||||
private DecisionStrategy decisionStrategy = DecisionStrategy.UNANIMOUS;
|
private DecisionStrategy decisionStrategy = DecisionStrategy.UNANIMOUS;
|
||||||
private String owner;
|
private String owner;
|
||||||
|
|
||||||
|
@JsonInclude(JsonInclude.Include.NON_EMPTY)
|
||||||
|
private Set<ResourceRepresentation> resourcesData;
|
||||||
|
|
||||||
|
@JsonInclude(JsonInclude.Include.NON_EMPTY)
|
||||||
|
private Set<ScopeRepresentation> scopesData;
|
||||||
|
|
||||||
public String getId() {
|
public String getId() {
|
||||||
return this.id;
|
return this.id;
|
||||||
|
@ -162,4 +170,20 @@ public class AbstractPolicyRepresentation {
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
return Objects.hash(getId());
|
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
|
@NoCache
|
||||||
List<PolicyRepresentation> policies();
|
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")
|
@Path("providers")
|
||||||
@GET
|
@GET
|
||||||
@Produces(MediaType.APPLICATION_JSON)
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
|
|
|
@ -24,6 +24,7 @@ import javax.ws.rs.GET;
|
||||||
import javax.ws.rs.PUT;
|
import javax.ws.rs.PUT;
|
||||||
import javax.ws.rs.Path;
|
import javax.ws.rs.Path;
|
||||||
import javax.ws.rs.Produces;
|
import javax.ws.rs.Produces;
|
||||||
|
import javax.ws.rs.QueryParam;
|
||||||
import javax.ws.rs.core.MediaType;
|
import javax.ws.rs.core.MediaType;
|
||||||
|
|
||||||
import org.jboss.resteasy.annotations.cache.NoCache;
|
import org.jboss.resteasy.annotations.cache.NoCache;
|
||||||
|
@ -41,6 +42,11 @@ public interface PolicyResource {
|
||||||
@NoCache
|
@NoCache
|
||||||
PolicyRepresentation toRepresentation();
|
PolicyRepresentation toRepresentation();
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
|
@NoCache
|
||||||
|
PolicyRepresentation toRepresentation(@QueryParam("fields") String fields);
|
||||||
|
|
||||||
@PUT
|
@PUT
|
||||||
@Consumes(MediaType.APPLICATION_JSON)
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
void update(PolicyRepresentation representation);
|
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) {
|
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());
|
PolicyProviderFactory providerFactory = authorization.getProviderFactory(policy.getType());
|
||||||
R representation;
|
R representation;
|
||||||
|
|
||||||
|
@ -840,6 +844,13 @@ public class ModelToRepresentation {
|
||||||
representation.setType(policy.getType());
|
representation.setType(policy.getType());
|
||||||
representation.setDecisionStrategy(policy.getDecisionStrategy());
|
representation.setDecisionStrategy(policy.getDecisionStrategy());
|
||||||
representation.setLogic(policy.getLogic());
|
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;
|
return representation;
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,22 +45,22 @@ public class PermissionService extends PolicyService {
|
||||||
protected PolicyTypeService doCreatePolicyTypeResource(String type) {
|
protected PolicyTypeService doCreatePolicyTypeResource(String type) {
|
||||||
return new PolicyTypeService(type, resourceServer, authorization, auth, adminEvent) {
|
return new PolicyTypeService(type, resourceServer, authorization, auth, adminEvent) {
|
||||||
@Override
|
@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("permission", new String[] {Boolean.TRUE.toString()});
|
||||||
filters.put("type", new String[] {type});
|
filters.put("type", new String[] {type});
|
||||||
return super.doSearch(firstResult, maxResult, filters);
|
return super.doSearch(firstResult, maxResult, fields, filters);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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("permission", new String[] {Boolean.TRUE.toString()});
|
||||||
return super.doSearch(firstResult, maxResult, filters);
|
return super.doSearch(firstResult, maxResult, fields, filters);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected AbstractPolicyRepresentation toRepresentation(Policy policy, AuthorizationProvider authorization) {
|
protected AbstractPolicyRepresentation toRepresentation(Policy policy, String fields, AuthorizationProvider authorization) {
|
||||||
return ModelToRepresentation.toRepresentation(policy, authorization, false, false);
|
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.PUT;
|
||||||
import javax.ws.rs.Path;
|
import javax.ws.rs.Path;
|
||||||
import javax.ws.rs.Produces;
|
import javax.ws.rs.Produces;
|
||||||
|
import javax.ws.rs.QueryParam;
|
||||||
import javax.ws.rs.core.Response;
|
import javax.ws.rs.core.Response;
|
||||||
import javax.ws.rs.core.Response.Status;
|
import javax.ws.rs.core.Response.Status;
|
||||||
|
|
||||||
|
@ -121,7 +122,7 @@ public class PolicyResourceService {
|
||||||
@GET
|
@GET
|
||||||
@Produces("application/json")
|
@Produces("application/json")
|
||||||
@NoCache
|
@NoCache
|
||||||
public Response findById() {
|
public Response findById(@QueryParam("fields") String fields) {
|
||||||
if (auth != null) {
|
if (auth != null) {
|
||||||
this.auth.realm().requireViewAuthorization();
|
this.auth.realm().requireViewAuthorization();
|
||||||
}
|
}
|
||||||
|
@ -130,11 +131,15 @@ public class PolicyResourceService {
|
||||||
return Response.status(Status.NOT_FOUND).build();
|
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) {
|
private AbstractPolicyRepresentation toRepresentation(Policy policy, AuthorizationProvider authorization) {
|
||||||
return ModelToRepresentation.toRepresentation(policy, authorization, true, false);
|
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")
|
@Path("/dependentPolicies")
|
||||||
|
|
|
@ -146,7 +146,7 @@ public class PolicyService {
|
||||||
@GET
|
@GET
|
||||||
@Produces(MediaType.APPLICATION_JSON)
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
@NoCache
|
@NoCache
|
||||||
public Response findByName(@QueryParam("name") String name) {
|
public Response findByName(@QueryParam("name") String name, @QueryParam("fields") String fields) {
|
||||||
if (auth != null) {
|
if (auth != null) {
|
||||||
this.auth.realm().requireViewAuthorization();
|
this.auth.realm().requireViewAuthorization();
|
||||||
}
|
}
|
||||||
|
@ -163,7 +163,7 @@ public class PolicyService {
|
||||||
return Response.status(Status.OK).build();
|
return Response.status(Status.OK).build();
|
||||||
}
|
}
|
||||||
|
|
||||||
return Response.ok(toRepresentation(model, authorization)).build();
|
return Response.ok(toRepresentation(model, fields, authorization)).build();
|
||||||
}
|
}
|
||||||
|
|
||||||
@GET
|
@GET
|
||||||
|
@ -176,6 +176,7 @@ public class PolicyService {
|
||||||
@QueryParam("scope") String scope,
|
@QueryParam("scope") String scope,
|
||||||
@QueryParam("permission") Boolean permission,
|
@QueryParam("permission") Boolean permission,
|
||||||
@QueryParam("owner") String owner,
|
@QueryParam("owner") String owner,
|
||||||
|
@QueryParam("fields") String fields,
|
||||||
@QueryParam("first") Integer firstResult,
|
@QueryParam("first") Integer firstResult,
|
||||||
@QueryParam("max") Integer maxResult) {
|
@QueryParam("max") Integer maxResult) {
|
||||||
if (auth != null) {
|
if (auth != null) {
|
||||||
|
@ -253,18 +254,18 @@ public class PolicyService {
|
||||||
}
|
}
|
||||||
|
|
||||||
return Response.ok(
|
return Response.ok(
|
||||||
doSearch(firstResult, maxResult, search))
|
doSearch(firstResult, maxResult, fields, search))
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected AbstractPolicyRepresentation toRepresentation(Policy model, AuthorizationProvider authorization) {
|
protected AbstractPolicyRepresentation toRepresentation(Policy model, String fields, AuthorizationProvider authorization) {
|
||||||
return ModelToRepresentation.toRepresentation(model, authorization, true, false);
|
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();
|
PolicyStore policyStore = authorization.getStoreFactory().getPolicyStore();
|
||||||
return policyStore.findByResourceServer(filters, resourceServer.getId(), firstResult != null ? firstResult : -1, maxResult != null ? maxResult : Constants.DEFAULT_MAX_RESULTS).stream()
|
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());
|
.collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -58,8 +58,7 @@ public class PolicyTypeResourceService extends PolicyResourceService {
|
||||||
return representation;
|
return representation;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
protected AbstractPolicyRepresentation toRepresentation(Policy policy, String fields, AuthorizationProvider authorization) {
|
||||||
protected AbstractPolicyRepresentation toRepresentation(Policy policy, AuthorizationProvider authorization) {
|
return ModelToRepresentation.toRepresentation(policy, authorization, false, false, fields != null && fields.equals("*"));
|
||||||
return ModelToRepresentation.toRepresentation(policy, authorization, false, false);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -87,13 +87,13 @@ public class PolicyTypeService extends PolicyService {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected AbstractPolicyRepresentation toRepresentation(Policy policy, AuthorizationProvider authorization) {
|
protected AbstractPolicyRepresentation toRepresentation(Policy policy, String fields, AuthorizationProvider authorization) {
|
||||||
return ModelToRepresentation.toRepresentation(policy, authorization, false, false);
|
return ModelToRepresentation.toRepresentation(policy, authorization, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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});
|
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")
|
@Produces("application/json")
|
||||||
public Response findById(@PathParam("policyId") String policyId) {
|
public Response findById(@PathParam("policyId") String policyId) {
|
||||||
checkRequest(getAssociatedResourceId(policyId), null);
|
checkRequest(getAssociatedResourceId(policyId), null);
|
||||||
return PolicyTypeResourceService.class.cast(delegate.getResource(policyId)).findById();
|
return PolicyTypeResourceService.class.cast(delegate.getResource(policyId)).findById(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@GET
|
@GET
|
||||||
|
@ -128,7 +128,7 @@ public class UserManagedPermissionService {
|
||||||
@QueryParam("scope") String scope,
|
@QueryParam("scope") String scope,
|
||||||
@QueryParam("first") Integer firstResult,
|
@QueryParam("first") Integer firstResult,
|
||||||
@QueryParam("max") Integer maxResult) {
|
@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) {
|
private Policy getPolicy(@PathParam("policyId") String policyId) {
|
||||||
|
|
|
@ -18,17 +18,18 @@
|
||||||
package org.keycloak.testsuite.admin.client.authorization;
|
package org.keycloak.testsuite.admin.client.authorization;
|
||||||
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
import org.keycloak.admin.client.resource.AuthorizationResource;
|
||||||
import org.keycloak.admin.client.resource.PoliciesResource;
|
import org.keycloak.admin.client.resource.PoliciesResource;
|
||||||
import org.keycloak.admin.client.resource.PolicyResource;
|
import org.keycloak.admin.client.resource.PolicyResource;
|
||||||
import org.keycloak.admin.client.resource.ResourceResource;
|
import org.keycloak.admin.client.resource.ResourceResource;
|
||||||
import org.keycloak.admin.client.resource.ResourceScopeResource;
|
import org.keycloak.admin.client.resource.ResourceScopeResource;
|
||||||
import org.keycloak.admin.client.resource.ResourceScopesResource;
|
import org.keycloak.admin.client.resource.ResourceScopesResource;
|
||||||
import org.keycloak.admin.client.resource.ResourcesResource;
|
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.DecisionStrategy;
|
||||||
import org.keycloak.representations.idm.authorization.Logic;
|
import org.keycloak.representations.idm.authorization.Logic;
|
||||||
import org.keycloak.representations.idm.authorization.PolicyProviderRepresentation;
|
import org.keycloak.representations.idm.authorization.PolicyProviderRepresentation;
|
||||||
import org.keycloak.representations.idm.authorization.PolicyRepresentation;
|
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.ResourceRepresentation;
|
||||||
import org.keycloak.representations.idm.authorization.ScopeRepresentation;
|
import org.keycloak.representations.idm.authorization.ScopeRepresentation;
|
||||||
|
|
||||||
|
@ -38,6 +39,7 @@ import java.util.Arrays;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
@ -147,6 +149,41 @@ public class GenericPolicyManagementTest extends AbstractAuthorizationTest {
|
||||||
assertTrue(providers.containsAll(expected));
|
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() {
|
private PolicyResource createTestingPolicy() {
|
||||||
Map<String, String> config = new HashMap<>();
|
Map<String, String> config = new HashMap<>();
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue