Merge pull request #3785 from mposolda/master
KEYCLOAK-4274 Fix recursive composite role mappings
This commit is contained in:
commit
8717cd0090
5 changed files with 38 additions and 11 deletions
|
@ -176,7 +176,7 @@ public class RoleAdapter implements RoleModel {
|
|||
|
||||
@Override
|
||||
public boolean hasRole(RoleModel role) {
|
||||
return this.equals(role) || KeycloakModelUtils.searchFor(role, this);
|
||||
return this.equals(role) || KeycloakModelUtils.searchFor(role, this, new HashSet<>());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -128,7 +128,7 @@ public class RoleAdapter implements RoleModel, JpaModel<RoleEntity> {
|
|||
|
||||
@Override
|
||||
public boolean hasRole(RoleModel role) {
|
||||
return this.equals(role) || KeycloakModelUtils.searchFor(role, this);
|
||||
return this.equals(role) || KeycloakModelUtils.searchFor(role, this, new HashSet<>());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -172,7 +172,7 @@ public class RoleAdapter extends AbstractMongoAdapter<MongoRoleEntity> implement
|
|||
|
||||
@Override
|
||||
public boolean hasRole(RoleModel role) {
|
||||
return this.equals(role) || KeycloakModelUtils.searchFor(role, this);
|
||||
return this.equals(role) || KeycloakModelUtils.searchFor(role, this, new HashSet<>());
|
||||
}
|
||||
|
||||
public MongoRoleEntity getRole() {
|
||||
|
|
|
@ -177,14 +177,23 @@ public final class KeycloakModelUtils {
|
|||
* @param visited set of already visited roles (used for recursion)
|
||||
* @return true if "role" is descendant of "composite"
|
||||
*/
|
||||
public static boolean searchFor(RoleModel role, RoleModel composite) {
|
||||
return composite.isComposite() && (
|
||||
composite.getComposites().contains(role) ||
|
||||
composite.getComposites().stream()
|
||||
.filter(x -> x.isComposite() && x.hasRole(role))
|
||||
public static boolean searchFor(RoleModel role, RoleModel composite, Set<String> visited) {
|
||||
if (visited.contains(composite.getId())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
visited.add(composite.getId());
|
||||
|
||||
if (!composite.isComposite()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Set<RoleModel> compositeRoles = composite.getComposites();
|
||||
return compositeRoles.contains(role) ||
|
||||
compositeRoles.stream()
|
||||
.filter(x -> x.isComposite() && searchFor(role, x, visited))
|
||||
.findFirst()
|
||||
.isPresent()
|
||||
);
|
||||
.isPresent();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
package org.keycloak.testsuite.composites;
|
||||
|
||||
import org.jboss.arquillian.graphene.page.Page;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.keycloak.OAuth2Constants;
|
||||
|
@ -28,6 +27,7 @@ import org.keycloak.common.enums.SslRequired;
|
|||
import org.keycloak.representations.AccessToken;
|
||||
import org.keycloak.representations.idm.RealmRepresentation;
|
||||
import org.keycloak.representations.idm.RoleRepresentation;
|
||||
import org.keycloak.testsuite.Assert;
|
||||
import org.keycloak.testsuite.admin.ApiUtil;
|
||||
import org.keycloak.testsuite.pages.LoginPage;
|
||||
import org.keycloak.testsuite.util.ClientBuilder;
|
||||
|
@ -345,4 +345,22 @@ public class CompositeRoleTest extends AbstractCompositeKeycloakTest {
|
|||
Assert.assertEquals(200, refreshResponse.getStatusCode());
|
||||
}
|
||||
|
||||
|
||||
// KEYCLOAK-4274
|
||||
@Test
|
||||
public void testRecursiveComposites() throws Exception {
|
||||
// This will create recursive composite mappings between "REALM_COMPOSITE_1" and "REALM_ROLE_1"
|
||||
RoleRepresentation realmComposite1 = testRealm().roles().get("REALM_COMPOSITE_1").toRepresentation();
|
||||
testRealm().roles().get("REALM_ROLE_1").addComposites(Collections.singletonList(realmComposite1));
|
||||
|
||||
UserResource userResource = ApiUtil.findUserByUsernameId(testRealm(), "REALM_COMPOSITE_1_USER");
|
||||
List<RoleRepresentation> realmRoles = userResource.roles().realmLevel().listEffective();
|
||||
Assert.assertNames(realmRoles, "REALM_COMPOSITE_1", "REALM_ROLE_1");
|
||||
|
||||
userResource = ApiUtil.findUserByUsernameId(testRealm(), "REALM_ROLE_1_USER");
|
||||
realmRoles = userResource.roles().realmLevel().listEffective();
|
||||
Assert.assertNames(realmRoles, "REALM_COMPOSITE_1", "REALM_ROLE_1");
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue