Roles admin REST API: Don't expand composite roles

Additionally:
- Import clean-up
- Added requireMapComposite as in RoleResource.addComposites

Closes #26951

Signed-off-by: synth3 <19573241+synth3@users.noreply.github.com>
This commit is contained in:
Andy 2024-02-10 16:46:27 +01:00 committed by Pedro Igor
parent 4e5ed3ebef
commit 137907f5ef
2 changed files with 14 additions and 8 deletions

View file

@ -33,10 +33,7 @@ import org.keycloak.models.ModelDuplicateException;
import org.keycloak.models.RealmModel;
import org.keycloak.models.RoleContainerModel;
import org.keycloak.models.RoleModel;
import org.keycloak.models.UserModel;
import org.keycloak.models.utils.KeycloakModelUtils;
import org.keycloak.models.utils.ModelToRepresentation;
import org.keycloak.models.utils.RoleUtils;
import org.keycloak.representations.idm.GroupRepresentation;
import org.keycloak.representations.idm.ManagementPermissionReference;
import org.keycloak.representations.idm.RoleRepresentation;
@ -67,9 +64,7 @@ import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.keycloak.services.ErrorResponseException;
/**
* @resource Roles
@ -179,7 +174,7 @@ public class RoleContainerResource extends RoleResource {
}
realmRoles.add(realmRole);
}
RoleUtils.expandCompositeRoles(realmRoles).forEach(role::addCompositeRole);
realmRoles.stream().peek(auth.roles()::requireMapComposite).forEach(role::addCompositeRole);
}
Map<String, List<String>> compositeClientRoles = composites.getClient();
@ -200,7 +195,7 @@ public class RoleContainerResource extends RoleResource {
}
clientRoles.add(clientRole);
}
RoleUtils.expandCompositeRoles(clientRoles).forEach(role::addCompositeRole);
clientRoles.stream().peek(auth.roles()::requireMapComposite).forEach(role::addCompositeRole);
}
}
}

View file

@ -67,6 +67,10 @@ public class RoleByIdResourceTest extends AbstractAdminTest {
public void before() {
adminClient.realm(REALM_NAME).roles().create(RoleBuilder.create().name("role-a").description("Role A").build());
adminClient.realm(REALM_NAME).roles().create(RoleBuilder.create().name("role-b").description("Role B").build());
// add a role that is a composite role
RoleRepresentation roleD = RoleBuilder.create().name("role-d").description("Role D").build();
adminClient.realm(REALM_NAME).roles().create(roleD);
adminClient.realm(REALM_NAME).roles().create(RoleBuilder.create().name("composite-role-with-d").description("Composite Role with Role D").composite().realmComposite(roleD).build());
clientId = "client-a";
Response response = adminClient.realm(REALM_NAME).clients().create(ClientBuilder.create().clientId(clientId).build());
@ -86,6 +90,8 @@ public class RoleByIdResourceTest extends AbstractAdminTest {
getCleanup().addRoleId(ids.get("role-a"));
getCleanup().addRoleId(ids.get("role-b"));
getCleanup().addRoleId(ids.get("role-c"));
getCleanup().addRoleId(ids.get("role-d"));
getCleanup().addRoleId(ids.get("composite-role-with-d"));
resource = adminClient.realm(REALM_NAME).rolesById();
@ -184,7 +190,7 @@ public class RoleByIdResourceTest extends AbstractAdminTest {
@Test
public void createNewMixedRealmCompositeRole() {
RoleRepresentation newRoleComp = RoleBuilder.create().name("role-mixed-comp").composite().realmComposite("role-a").clientComposite(clientId, "role-c").build();
RoleRepresentation newRoleComp = RoleBuilder.create().name("role-mixed-comp").composite().realmComposite("role-a").realmComposite("composite-role-with-d").clientComposite(clientId, "role-c").build();
adminClient.realm(REALM_NAME).roles().create(newRoleComp);
RoleRepresentation roleMixedComp = adminClient.realm(REALM_NAME).roles().get(newRoleComp.getName()).toRepresentation();
@ -196,10 +202,15 @@ public class RoleByIdResourceTest extends AbstractAdminTest {
Set<RoleRepresentation> containedRealmRoles = roleComposites.stream().filter(isClientRole.negate()).collect(Collectors.toSet());
assertFalse(containedRealmRoles.isEmpty());
assertTrue(containedRealmRoles.stream().anyMatch(r -> r.getName().equals("role-a")));
assertTrue(containedRealmRoles.stream().anyMatch(r -> r.getName().equals("composite-role-with-d")));
Set<RoleRepresentation> containedClientRoles = roleComposites.stream().filter(isClientRole).collect(Collectors.toSet());
assertFalse(containedClientRoles.isEmpty());
assertTrue(containedClientRoles.stream().anyMatch(r -> r.getContainerId().equals(clientUuid) && r.getName().equals("role-c")));
// check that there are no unexpected roles contained
int expectedCompositeCount = newRoleComp.getComposites().getRealm().size() + newRoleComp.getComposites().getClient().size();
assertEquals(expectedCompositeCount, roleComposites.size());
}
/**