Skip to content

Commit

Permalink
KEYCLOAK-12687 Add briefRepresentation queryParams to get roles 'comp…
Browse files Browse the repository at this point in the history
…osite' endpoints
  • Loading branch information
Axel Messinese authored and hmlnarik committed Jul 3, 2020
1 parent 10cdc58 commit f30395d
Show file tree
Hide file tree
Showing 7 changed files with 77 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,12 @@

import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.DefaultValue;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import java.util.List;

Expand All @@ -45,6 +47,10 @@ public interface RoleScopeResource {
@GET
@Path("composite")
List<RoleRepresentation> listEffective();

@GET
@Path("composite")
List<RoleRepresentation> listEffective(@QueryParam("briefRepresentation") @DefaultValue("true") boolean briefRepresentation);

@POST
void add(List<RoleRepresentation> rolesToAdd);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,12 @@

import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.DefaultValue;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;
Expand Down Expand Up @@ -110,20 +112,23 @@ public List<RoleRepresentation> getClientRoleMappings() {
*
* This recurses any composite roles
*
* @param briefRepresentation if false, return roles with their attributes
*
* @return
*/
@Path("composite")
@GET
@Produces(MediaType.APPLICATION_JSON)
@NoCache
public List<RoleRepresentation> getCompositeClientRoleMappings() {
public List<RoleRepresentation> getCompositeClientRoleMappings(@QueryParam("briefRepresentation") @DefaultValue("true") boolean briefRepresentation) {
viewPermission.require();


Set<RoleModel> roles = client.getRoles();
List<RoleRepresentation> mapRep = new ArrayList<RoleRepresentation>();
for (RoleModel roleModel : roles) {
if (user.hasRole(roleModel)) mapRep.add(ModelToRepresentation.toBriefRepresentation(roleModel));
if (user.hasRole(roleModel)) {
mapRep.add(briefRepresentation ? ModelToRepresentation.toBriefRepresentation(roleModel) : ModelToRepresentation.toRepresentation(roleModel));
}
}
return mapRep;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,13 @@

import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.DefaultValue;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.MediaType;
Expand Down Expand Up @@ -173,20 +175,22 @@ public List<RoleRepresentation> getRealmRoleMappings() {
*
* This will recurse all composite roles to get the result.
*
* @param briefRepresentation if false, return roles with their attributes
*
* @return
*/
@Path("realm/composite")
@GET
@Produces(MediaType.APPLICATION_JSON)
@NoCache
public List<RoleRepresentation> getCompositeRealmRoleMappings() {
public List<RoleRepresentation> getCompositeRealmRoleMappings(@QueryParam("briefRepresentation") @DefaultValue("true") boolean briefRepresentation) {
viewPermission.require();

Set<RoleModel> roles = realm.getRoles();
List<RoleRepresentation> realmMappingsRep = new ArrayList<RoleRepresentation>();
for (RoleModel roleModel : roles) {
if (roleMapper.hasRole(roleModel)) {
realmMappingsRep.add(ModelToRepresentation.toBriefRepresentation(roleModel));
realmMappingsRep.add(briefRepresentation ? ModelToRepresentation.toBriefRepresentation(roleModel) : ModelToRepresentation.toRepresentation(roleModel));
}
}
return realmMappingsRep;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,12 @@

import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.DefaultValue;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import java.util.ArrayList;
import java.util.LinkedList;
Expand Down Expand Up @@ -115,17 +117,19 @@ public List<RoleRepresentation> getAvailableClientScopeMappings() {
*
* Returns the roles for the client that are associated with the client's scope.
*
* @param briefRepresentation if false, return roles with their attributes
*
* @return
*/
@Path("composite")
@GET
@Produces(MediaType.APPLICATION_JSON)
@NoCache
public List<RoleRepresentation> getCompositeClientScopeMappings() {
public List<RoleRepresentation> getCompositeClientScopeMappings(@QueryParam("briefRepresentation") @DefaultValue("true") boolean briefRepresentation) {
viewPermission.require();

Set<RoleModel> roles = scopedClient.getRoles();
return ScopeMappedResource.getComposite(scopeContainer, roles);
return ScopeMappedResource.getComposite(scopeContainer, roles, briefRepresentation);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,13 @@

import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.DefaultValue;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import java.util.ArrayList;
import java.util.HashMap;
Expand Down Expand Up @@ -186,27 +188,29 @@ public static List<RoleRepresentation> getAvailable(AdminPermissionEvaluator aut
* any composite roles associated with the client's scope and adds the roles to this lists. The method is really
* to show a comprehensive total view of realm-level roles associated with the client.
*
* @param briefRepresentation if false, return roles with their attributes
*
* @return
*/
@Path("realm/composite")
@GET
@Produces(MediaType.APPLICATION_JSON)
@NoCache
public List<RoleRepresentation> getCompositeRealmScopeMappings() {
public List<RoleRepresentation> getCompositeRealmScopeMappings(@QueryParam("briefRepresentation") @DefaultValue("true") boolean briefRepresentation) {
viewPermission.require();

if (scopeContainer == null) {
throw new NotFoundException("Could not find client");
}

Set<RoleModel> roles = realm.getRoles();
return getComposite(scopeContainer, roles);
return getComposite(scopeContainer, roles, briefRepresentation);
}

public static List<RoleRepresentation> getComposite(ScopeContainerModel client, Set<RoleModel> roles) {
public static List<RoleRepresentation> getComposite(ScopeContainerModel client, Set<RoleModel> roles, boolean briefRepresentation) {
List<RoleRepresentation> composite = new ArrayList<RoleRepresentation>();
for (RoleModel roleModel : roles) {
if (client.hasScope(roleModel)) composite.add(ModelToRepresentation.toBriefRepresentation(roleModel));
if (client.hasScope(roleModel)) composite.add(briefRepresentation ? ModelToRepresentation.toBriefRepresentation(roleModel) : ModelToRepresentation.toRepresentation(roleModel));
}
return composite;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1738,6 +1738,16 @@ public void testDefaultRequiredActionAdded() {
realm.flows().updateRequiredAction(UserModel.RequiredAction.UPDATE_PASSWORD.toString(), updatePasswordReqAction);
assertAdminEvents.assertEvent(realmId, OperationType.UPDATE, AdminEventPaths.authRequiredActionPath(UserModel.RequiredAction.UPDATE_PASSWORD.toString()), updatePasswordReqAction, ResourceType.REQUIRED_ACTION);
}

private RoleRepresentation getRoleByName(String name, List<RoleRepresentation> roles) {
for(RoleRepresentation role : roles) {
if(role.getName().equalsIgnoreCase(name)) {
return role;
}
}

return null;
}

@Test
public void roleMappings() {
Expand All @@ -1747,18 +1757,26 @@ public void roleMappings() {
RealmRepresentation realmRep = RealmBuilder.edit(realm.toRepresentation()).testEventListener().build();
realm.update(realmRep);

RoleRepresentation realmCompositeRole = RoleBuilder.create().name("realm-composite").singleAttribute("attribute1", "value1").build();

realm.roles().create(RoleBuilder.create().name("realm-role").build());
realm.roles().create(RoleBuilder.create().name("realm-composite").build());
realm.roles().create(realmCompositeRole);
realm.roles().get("realm-composite").update(realmCompositeRole);
realm.roles().create(RoleBuilder.create().name("realm-child").build());
realm.roles().get("realm-composite").addComposites(Collections.singletonList(realm.roles().get("realm-child").toRepresentation()));


Response response = realm.clients().create(ClientBuilder.create().clientId("myclient").build());
String clientUuid = ApiUtil.getCreatedId(response);
response.close();

RoleRepresentation clientCompositeRole = RoleBuilder.create().name("client-composite").singleAttribute("attribute1", "value1").build();


realm.clients().get(clientUuid).roles().create(RoleBuilder.create().name("client-role").build());
realm.clients().get(clientUuid).roles().create(RoleBuilder.create().name("client-role2").build());
realm.clients().get(clientUuid).roles().create(RoleBuilder.create().name("client-composite").build());
realm.clients().get(clientUuid).roles().create(clientCompositeRole);
realm.clients().get(clientUuid).roles().get("client-composite").update(clientCompositeRole);
realm.clients().get(clientUuid).roles().create(RoleBuilder.create().name("client-child").build());
realm.clients().get(clientUuid).roles().get("client-composite").addComposites(Collections.singletonList(realm.clients().get(clientUuid).roles().get("client-child").toRepresentation()));

Expand Down Expand Up @@ -1793,10 +1811,22 @@ public void roleMappings() {
assertNames(roles.realmLevel().listAvailable(), "admin", "customer-user-premium", "realm-composite-role", "sample-realm-role", "attribute-role");
assertNames(roles.realmLevel().listEffective(), "realm-role", "realm-composite", "realm-child", "user", "offline_access", Constants.AUTHZ_UMA_AUTHORIZATION);

// List realm effective role with full representation
List<RoleRepresentation> realmRolesFullRepresentations = roles.realmLevel().listEffective(false);
RoleRepresentation realmCompositeRoleFromList = getRoleByName("realm-composite", realmRolesFullRepresentations);
assertNotNull(realmCompositeRoleFromList);
assertTrue(realmCompositeRoleFromList.getAttributes().containsKey("attribute1"));

// List client roles
assertNames(roles.clientLevel(clientUuid).listAll(), "client-role", "client-composite");
assertNames(roles.clientLevel(clientUuid).listAvailable(), "client-role2");
assertNames(roles.clientLevel(clientUuid).listEffective(), "client-role", "client-composite", "client-child");

// List client effective role with full representation
List<RoleRepresentation> rolesFullRepresentations = roles.clientLevel(clientUuid).listEffective(false);
RoleRepresentation clientCompositeRoleFromList = getRoleByName("client-composite", rolesFullRepresentations);
assertNotNull(clientCompositeRoleFromList);
assertTrue(clientCompositeRoleFromList.getAttributes().containsKey("attribute1"));

// Get mapping representation
MappingsRepresentation all = roles.getAll();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

/**
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
Expand Down Expand Up @@ -58,6 +59,16 @@ public RoleBuilder composite() {
rep.setComposite(true);
return this;
}

public RoleBuilder attributes(Map<String, List<String>> attributes) {
rep.setAttributes(attributes);
return this;
}

public RoleBuilder singleAttribute(String name, String value) {
rep.singleAttribute(name, value);
return this;
}

private void checkCompositesNull() {
if (rep.getComposites() == null) {
Expand Down

0 comments on commit f30395d

Please sign in to comment.