diff --git a/model/map-hot-rod/src/main/java/org/keycloak/models/map/storage/hotRod/IckleQueryWhereClauses.java b/model/map-hot-rod/src/main/java/org/keycloak/models/map/storage/hotRod/IckleQueryWhereClauses.java index 252e3b8435..89bf89450f 100644 --- a/model/map-hot-rod/src/main/java/org/keycloak/models/map/storage/hotRod/IckleQueryWhereClauses.java +++ b/model/map-hot-rod/src/main/java/org/keycloak/models/map/storage/hotRod/IckleQueryWhereClauses.java @@ -71,7 +71,6 @@ public class IckleQueryWhereClauses { WHERE_CLAUSE_PRODUCER_OVERRIDES.put(Policy.SearchableFields.CONFIG, IckleQueryWhereClauses::whereClauseForPolicyConfig); WHERE_CLAUSE_PRODUCER_OVERRIDES.put(Event.SearchableFields.EVENT_TYPE, IckleQueryWhereClauses::whereClauseForEnumWithStableIndex); WHERE_CLAUSE_PRODUCER_OVERRIDES.put(AdminEvent.SearchableFields.OPERATION_TYPE, IckleQueryWhereClauses::whereClauseForEnumWithStableIndex); - WHERE_CLAUSE_PRODUCER_OVERRIDES.put(RoleModel.SearchableFields.IS_CLIENT_ROLE, IckleQueryWhereClauses::whereClauseForClientRole); } @FunctionalInterface @@ -170,30 +169,6 @@ public class IckleQueryWhereClauses { return IckleQueryOperators.combineExpressions(ModelCriteriaBuilder.Operator.LIKE, getFieldName(UserModel.SearchableFields.CONSENT_FOR_CLIENT), new String[] {providerId + "%"}, parameters); } - private static String whereClauseForClientRole(String modelFieldName, ModelCriteriaBuilder.Operator op, Object[] values, Map parameters) { - if (op != ModelCriteriaBuilder.Operator.EQ && op != ModelCriteriaBuilder.Operator.NE) { - throw new CriterionNotSupportedException(RoleModel.SearchableFields.IS_CLIENT_ROLE, op); - } - if (values == null || values.length != 1) { - throw new CriterionNotSupportedException(RoleModel.SearchableFields.IS_CLIENT_ROLE, op, "Invalid arguments, expected (boolean), got: " + Arrays.toString(values)); - } - - Boolean b = (Boolean) values[0]; - if (op == Operator.EQ) { - if (b == null || b == Boolean.FALSE) { - return IckleQueryWhereClauses.produceWhereClause(RoleModel.SearchableFields.CLIENT_ID, Operator.NOT_EXISTS, new Object[] {}, parameters); - } else { - return IckleQueryWhereClauses.produceWhereClause(RoleModel.SearchableFields.CLIENT_ID, Operator.EXISTS, new Object[] {}, parameters); - } - } else /* if (op == Operator.NE) */ { - if (b == null || b == Boolean.TRUE) { - return IckleQueryWhereClauses.produceWhereClause(RoleModel.SearchableFields.CLIENT_ID, Operator.NOT_EXISTS, new Object[] {}, parameters); - } else { - return IckleQueryWhereClauses.produceWhereClause(RoleModel.SearchableFields.CLIENT_ID, Operator.EXISTS, new Object[] {}, parameters); - } - } - } - private static String whereClauseForCorrespondingSessionId(String modelFieldName, ModelCriteriaBuilder.Operator op, Object[] values, Map parameters) { if (op != ModelCriteriaBuilder.Operator.EQ) { throw new CriterionNotSupportedException(UserSessionModel.SearchableFields.CORRESPONDING_SESSION_ID, op); diff --git a/model/map-jpa/src/main/java/org/keycloak/models/map/storage/jpa/role/JpaRoleModelCriteriaBuilder.java b/model/map-jpa/src/main/java/org/keycloak/models/map/storage/jpa/role/JpaRoleModelCriteriaBuilder.java index d338b459de..a2e9a06c78 100644 --- a/model/map-jpa/src/main/java/org/keycloak/models/map/storage/jpa/role/JpaRoleModelCriteriaBuilder.java +++ b/model/map-jpa/src/main/java/org/keycloak/models/map/storage/jpa/role/JpaRoleModelCriteriaBuilder.java @@ -76,19 +76,8 @@ public class JpaRoleModelCriteriaBuilder extends JpaModelCriteriaBuilder - ((Boolean) value[0]) ? cb.isNull(root.get("clientId")) : cb.isNotNull(root.get("clientId")) - ); - } else { - throw new CriterionNotSupportedException(modelField, op); - } case IN: - if (modelField ==SearchableFields.ID) { + if (modelField == SearchableFields.ID) { Set uuids = getUuidsForInOperator(value, modelField); @@ -114,6 +103,13 @@ public class JpaRoleModelCriteriaBuilder extends JpaModelCriteriaBuilder cb.isNull(root.get("clientId"))); + } else { + throw new CriterionNotSupportedException(modelField, op); + } + default: throw new CriterionNotSupportedException(modelField, op); } diff --git a/model/map-ldap/src/main/java/org/keycloak/models/map/storage/ldap/role/LdapRoleModelCriteriaBuilder.java b/model/map-ldap/src/main/java/org/keycloak/models/map/storage/ldap/role/LdapRoleModelCriteriaBuilder.java index f7952bf422..aff4284f93 100644 --- a/model/map-ldap/src/main/java/org/keycloak/models/map/storage/ldap/role/LdapRoleModelCriteriaBuilder.java +++ b/model/map-ldap/src/main/java/org/keycloak/models/map/storage/ldap/role/LdapRoleModelCriteriaBuilder.java @@ -123,11 +123,7 @@ public class LdapRoleModelCriteriaBuilder extends LdapModelCriteriaBuilder modelField, Operator op, Object... value) { switch (op) { case EQ: - if (modelField == RoleModel.SearchableFields.IS_CLIENT_ROLE) { - LdapRoleModelCriteriaBuilder result = new LdapRoleModelCriteriaBuilder(roleMapperConfig, StringBuilder::new); - result.isClientRole = (boolean) value[0]; - return result; - } else if (modelField == RoleModel.SearchableFields.CLIENT_ID) { + if (modelField == RoleModel.SearchableFields.CLIENT_ID) { LdapRoleModelCriteriaBuilder result = new LdapRoleModelCriteriaBuilder(roleMapperConfig, StringBuilder::new); result.clientId = (String) value[0]; return result; @@ -148,11 +144,7 @@ public class LdapRoleModelCriteriaBuilder extends LdapModelCriteriaBuilder getRealmRolesStream(RealmModel realm, Integer first, Integer max) { DefaultModelCriteria mcb = criteria(); mcb = mcb.compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId()) - .compare(SearchableFields.IS_CLIENT_ROLE, Operator.NE, true); + // filter realm roles only + .compare(SearchableFields.CLIENT_ID, Operator.NOT_EXISTS); return txInRealm(realm).read(withCriteria(mcb).pagination(first, max, SearchableFields.NAME)) .map(entityToAdapterFunc(realm)); @@ -118,7 +119,8 @@ public class MapRoleProvider implements RoleProvider { public Stream getRealmRolesStream(RealmModel realm) { DefaultModelCriteria mcb = criteria(); mcb = mcb.compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId()) - .compare(SearchableFields.IS_CLIENT_ROLE, Operator.NE, true); + // filter realm roles only + .compare(SearchableFields.CLIENT_ID, Operator.NOT_EXISTS); return txInRealm(realm).read(withCriteria(mcb).orderBy(SearchableFields.NAME, ASCENDING)) .map(entityToAdapterFunc(realm)); @@ -200,7 +202,8 @@ public class MapRoleProvider implements RoleProvider { DefaultModelCriteria mcb = criteria(); mcb = mcb.compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId()) - .compare(SearchableFields.IS_CLIENT_ROLE, Operator.NE, true) + // filter realm roles only + .compare(SearchableFields.CLIENT_ID, Operator.NOT_EXISTS) .compare(SearchableFields.NAME, Operator.EQ, name); return txInRealm(realm).read(withCriteria(mcb)) @@ -251,7 +254,8 @@ public class MapRoleProvider implements RoleProvider { } DefaultModelCriteria mcb = criteria(); mcb = mcb.compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId()) - .compare(SearchableFields.IS_CLIENT_ROLE, Operator.NE, true) + // filter realm roles only + .compare(SearchableFields.CLIENT_ID, Operator.NOT_EXISTS) .or( mcb.compare(SearchableFields.NAME, Operator.ILIKE, "%" + search + "%"), mcb.compare(SearchableFields.DESCRIPTION, Operator.ILIKE, "%" + search + "%") diff --git a/model/map/src/main/java/org/keycloak/models/map/storage/chm/MapFieldPredicates.java b/model/map/src/main/java/org/keycloak/models/map/storage/chm/MapFieldPredicates.java index 2eba137e49..a35c450209 100644 --- a/model/map/src/main/java/org/keycloak/models/map/storage/chm/MapFieldPredicates.java +++ b/model/map/src/main/java/org/keycloak/models/map/storage/chm/MapFieldPredicates.java @@ -129,7 +129,6 @@ public class MapFieldPredicates { put(ROLE_PREDICATES, RoleModel.SearchableFields.CLIENT_ID, MapRoleEntity::getClientId); put(ROLE_PREDICATES, RoleModel.SearchableFields.DESCRIPTION, MapRoleEntity::getDescription); put(ROLE_PREDICATES, RoleModel.SearchableFields.NAME, MapRoleEntity::getName); - put(ROLE_PREDICATES, RoleModel.SearchableFields.IS_CLIENT_ROLE, MapFieldPredicates::isClientRole); put(ROLE_PREDICATES, RoleModel.SearchableFields.COMPOSITE_ROLE, MapFieldPredicates::checkCompositeRoles); put(USER_PREDICATES, UserModel.SearchableFields.REALM_ID, MapUserEntity::getRealmId); @@ -389,18 +388,6 @@ public class MapFieldPredicates { return mcb.fieldCompare(Boolean.TRUE::equals, getter); } - - private static MapModelCriteriaBuilder isClientRole(MapModelCriteriaBuilder mcb, Operator op, Object[] values) { - if (values == null || values.length != 1 || ! (op == Operator.EQ || op == Operator.NE) || ! (values[0] instanceof Boolean)) { - throw new CriterionNotSupportedException(RoleModel.SearchableFields.IS_CLIENT_ROLE, op, "Invalid arguments, got: " + Arrays.toString(values)); - } - Function getter; - Predicate valueComparator = CriteriaOperator.predicateFor(op, values); - getter = re -> re.getClientId() != null; - - return mcb.fieldCompare(valueComparator, getter); - } - private static MapModelCriteriaBuilder checkCompositeRoles(MapModelCriteriaBuilder mcb, Operator op, Object[] values) { String roleIdS = ensureEqSingleValue(RoleModel.SearchableFields.COMPOSITE_ROLE, "composite_role_id", op, values); Function getter; diff --git a/server-spi/src/main/java/org/keycloak/models/RoleModel.java b/server-spi/src/main/java/org/keycloak/models/RoleModel.java index 8c7864c969..d02759fd3b 100755 --- a/server-spi/src/main/java/org/keycloak/models/RoleModel.java +++ b/server-spi/src/main/java/org/keycloak/models/RoleModel.java @@ -21,8 +21,6 @@ import org.keycloak.provider.ProviderEvent; import org.keycloak.storage.SearchableModelField; import java.util.List; import java.util.Map; -import java.util.Set; -import java.util.stream.Collectors; import java.util.stream.Stream; /** @@ -38,6 +36,11 @@ public interface RoleModel { public static final SearchableModelField CLIENT_ID = new SearchableModelField<>("clientId", String.class); public static final SearchableModelField NAME = new SearchableModelField<>("name", String.class); public static final SearchableModelField DESCRIPTION = new SearchableModelField<>("description", String.class); + /** + * @deprecated Please use {@link #CLIENT_ID} SearchableField with operators EXISTS/NOT_EXISTS to replace + * field IS_CLIENT_ROLE with operator EQ with value true/false. + */ + @Deprecated public static final SearchableModelField IS_CLIENT_ROLE = new SearchableModelField<>("isClientRole", Boolean.class); public static final SearchableModelField COMPOSITE_ROLE = new SearchableModelField<>("compositeRoles", Boolean.class); }