Deprecate RoleModel.SearchableFields.IS_CLIENT_ROLE field

Closes #17144
This commit is contained in:
Michal Hajas 2023-02-16 15:44:13 +01:00 committed by Hynek Mlnařík
parent 0972edd6a5
commit 1c79a5666d
6 changed files with 30 additions and 66 deletions

View file

@ -71,7 +71,6 @@ public class IckleQueryWhereClauses {
WHERE_CLAUSE_PRODUCER_OVERRIDES.put(Policy.SearchableFields.CONFIG, IckleQueryWhereClauses::whereClauseForPolicyConfig); 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(Event.SearchableFields.EVENT_TYPE, IckleQueryWhereClauses::whereClauseForEnumWithStableIndex);
WHERE_CLAUSE_PRODUCER_OVERRIDES.put(AdminEvent.SearchableFields.OPERATION_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 @FunctionalInterface
@ -170,30 +169,6 @@ public class IckleQueryWhereClauses {
return IckleQueryOperators.combineExpressions(ModelCriteriaBuilder.Operator.LIKE, getFieldName(UserModel.SearchableFields.CONSENT_FOR_CLIENT), new String[] {providerId + "%"}, parameters); 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<String, Object> 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<String, Object> parameters) { private static String whereClauseForCorrespondingSessionId(String modelFieldName, ModelCriteriaBuilder.Operator op, Object[] values, Map<String, Object> parameters) {
if (op != ModelCriteriaBuilder.Operator.EQ) { if (op != ModelCriteriaBuilder.Operator.EQ) {
throw new CriterionNotSupportedException(UserSessionModel.SearchableFields.CORRESPONDING_SESSION_ID, op); throw new CriterionNotSupportedException(UserSessionModel.SearchableFields.CORRESPONDING_SESSION_ID, op);

View file

@ -76,17 +76,6 @@ public class JpaRoleModelCriteriaBuilder extends JpaModelCriteriaBuilder<JpaRole
} else { } else {
throw new CriterionNotSupportedException(modelField, op); throw new CriterionNotSupportedException(modelField, op);
} }
case NE:
if (modelField == SearchableFields.IS_CLIENT_ROLE) {
validateValue(value, modelField, op, Boolean.class);
return new JpaRoleModelCriteriaBuilder((cb, query, root) ->
((Boolean) value[0]) ? cb.isNull(root.get("clientId")) : cb.isNotNull(root.get("clientId"))
);
} else {
throw new CriterionNotSupportedException(modelField, op);
}
case IN: case IN:
if (modelField == SearchableFields.ID) { if (modelField == SearchableFields.ID) {
@ -114,6 +103,13 @@ public class JpaRoleModelCriteriaBuilder extends JpaModelCriteriaBuilder<JpaRole
} else { } else {
throw new CriterionNotSupportedException(modelField, op); throw new CriterionNotSupportedException(modelField, op);
} }
case NOT_EXISTS:
if (modelField == SearchableFields.CLIENT_ID) {
return new JpaRoleModelCriteriaBuilder((cb, query, root) -> cb.isNull(root.get("clientId")));
} else {
throw new CriterionNotSupportedException(modelField, op);
}
default: default:
throw new CriterionNotSupportedException(modelField, op); throw new CriterionNotSupportedException(modelField, op);
} }

View file

@ -123,11 +123,7 @@ public class LdapRoleModelCriteriaBuilder extends LdapModelCriteriaBuilder<LdapR
public LdapRoleModelCriteriaBuilder compare(SearchableModelField<? super RoleModel> modelField, Operator op, Object... value) { public LdapRoleModelCriteriaBuilder compare(SearchableModelField<? super RoleModel> modelField, Operator op, Object... value) {
switch (op) { switch (op) {
case EQ: case EQ:
if (modelField == RoleModel.SearchableFields.IS_CLIENT_ROLE) { if (modelField == RoleModel.SearchableFields.CLIENT_ID) {
LdapRoleModelCriteriaBuilder result = new LdapRoleModelCriteriaBuilder(roleMapperConfig, StringBuilder::new);
result.isClientRole = (boolean) value[0];
return result;
} else if (modelField == RoleModel.SearchableFields.CLIENT_ID) {
LdapRoleModelCriteriaBuilder result = new LdapRoleModelCriteriaBuilder(roleMapperConfig, StringBuilder::new); LdapRoleModelCriteriaBuilder result = new LdapRoleModelCriteriaBuilder(roleMapperConfig, StringBuilder::new);
result.clientId = (String) value[0]; result.clientId = (String) value[0];
return result; return result;
@ -148,11 +144,7 @@ public class LdapRoleModelCriteriaBuilder extends LdapModelCriteriaBuilder<LdapR
} }
case NE: case NE:
if (modelField == RoleModel.SearchableFields.IS_CLIENT_ROLE) { if (modelField == RoleModel.SearchableFields.NAME) {
LdapRoleModelCriteriaBuilder result = new LdapRoleModelCriteriaBuilder(roleMapperConfig, StringBuilder::new);
result.isClientRole = !((boolean) value[0]);
return result;
} else if (modelField == RoleModel.SearchableFields.NAME) {
// validateValue(value, modelField, op, String.class); // validateValue(value, modelField, op, String.class);
String field = modelFieldNameToLdap(roleMapperConfig, modelField); String field = modelFieldNameToLdap(roleMapperConfig, modelField);
return not(new LdapRoleModelCriteriaBuilder(roleMapperConfig, return not(new LdapRoleModelCriteriaBuilder(roleMapperConfig,
@ -201,6 +193,13 @@ public class LdapRoleModelCriteriaBuilder extends LdapModelCriteriaBuilder<LdapR
} else { } else {
throw new CriterionNotSupportedException(modelField, op); throw new CriterionNotSupportedException(modelField, op);
} }
case EXISTS:
case NOT_EXISTS:
if (modelField == RoleModel.SearchableFields.CLIENT_ID) {
LdapRoleModelCriteriaBuilder result = new LdapRoleModelCriteriaBuilder(roleMapperConfig, StringBuilder::new);
result.isClientRole = op == Operator.EXISTS;
return result;
}
default: default:
throw new CriterionNotSupportedException(modelField, op); throw new CriterionNotSupportedException(modelField, op);

View file

@ -91,7 +91,8 @@ public class MapRoleProvider implements RoleProvider {
public Stream<RoleModel> getRealmRolesStream(RealmModel realm, Integer first, Integer max) { public Stream<RoleModel> getRealmRolesStream(RealmModel realm, Integer first, Integer max) {
DefaultModelCriteria<RoleModel> mcb = criteria(); DefaultModelCriteria<RoleModel> mcb = criteria();
mcb = mcb.compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId()) 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)) return txInRealm(realm).read(withCriteria(mcb).pagination(first, max, SearchableFields.NAME))
.map(entityToAdapterFunc(realm)); .map(entityToAdapterFunc(realm));
@ -118,7 +119,8 @@ public class MapRoleProvider implements RoleProvider {
public Stream<RoleModel> getRealmRolesStream(RealmModel realm) { public Stream<RoleModel> getRealmRolesStream(RealmModel realm) {
DefaultModelCriteria<RoleModel> mcb = criteria(); DefaultModelCriteria<RoleModel> mcb = criteria();
mcb = mcb.compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId()) 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)) return txInRealm(realm).read(withCriteria(mcb).orderBy(SearchableFields.NAME, ASCENDING))
.map(entityToAdapterFunc(realm)); .map(entityToAdapterFunc(realm));
@ -200,7 +202,8 @@ public class MapRoleProvider implements RoleProvider {
DefaultModelCriteria<RoleModel> mcb = criteria(); DefaultModelCriteria<RoleModel> mcb = criteria();
mcb = mcb.compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId()) 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); .compare(SearchableFields.NAME, Operator.EQ, name);
return txInRealm(realm).read(withCriteria(mcb)) return txInRealm(realm).read(withCriteria(mcb))
@ -251,7 +254,8 @@ public class MapRoleProvider implements RoleProvider {
} }
DefaultModelCriteria<RoleModel> mcb = criteria(); DefaultModelCriteria<RoleModel> mcb = criteria();
mcb = mcb.compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId()) 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( .or(
mcb.compare(SearchableFields.NAME, Operator.ILIKE, "%" + search + "%"), mcb.compare(SearchableFields.NAME, Operator.ILIKE, "%" + search + "%"),
mcb.compare(SearchableFields.DESCRIPTION, Operator.ILIKE, "%" + search + "%") mcb.compare(SearchableFields.DESCRIPTION, Operator.ILIKE, "%" + search + "%")

View file

@ -129,7 +129,6 @@ public class MapFieldPredicates {
put(ROLE_PREDICATES, RoleModel.SearchableFields.CLIENT_ID, MapRoleEntity::getClientId); put(ROLE_PREDICATES, RoleModel.SearchableFields.CLIENT_ID, MapRoleEntity::getClientId);
put(ROLE_PREDICATES, RoleModel.SearchableFields.DESCRIPTION, MapRoleEntity::getDescription); put(ROLE_PREDICATES, RoleModel.SearchableFields.DESCRIPTION, MapRoleEntity::getDescription);
put(ROLE_PREDICATES, RoleModel.SearchableFields.NAME, MapRoleEntity::getName); 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(ROLE_PREDICATES, RoleModel.SearchableFields.COMPOSITE_ROLE, MapFieldPredicates::checkCompositeRoles);
put(USER_PREDICATES, UserModel.SearchableFields.REALM_ID, MapUserEntity::getRealmId); put(USER_PREDICATES, UserModel.SearchableFields.REALM_ID, MapUserEntity::getRealmId);
@ -389,18 +388,6 @@ public class MapFieldPredicates {
return mcb.fieldCompare(Boolean.TRUE::equals, getter); return mcb.fieldCompare(Boolean.TRUE::equals, getter);
} }
private static MapModelCriteriaBuilder<Object, MapRoleEntity, RoleModel> isClientRole(MapModelCriteriaBuilder<Object, MapRoleEntity, RoleModel> 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<MapRoleEntity, Boolean> getter;
Predicate<Object> valueComparator = CriteriaOperator.predicateFor(op, values);
getter = re -> re.getClientId() != null;
return mcb.fieldCompare(valueComparator, getter);
}
private static MapModelCriteriaBuilder<Object, MapRoleEntity, RoleModel> checkCompositeRoles(MapModelCriteriaBuilder<Object, MapRoleEntity, RoleModel> mcb, Operator op, Object[] values) { private static MapModelCriteriaBuilder<Object, MapRoleEntity, RoleModel> checkCompositeRoles(MapModelCriteriaBuilder<Object, MapRoleEntity, RoleModel> mcb, Operator op, Object[] values) {
String roleIdS = ensureEqSingleValue(RoleModel.SearchableFields.COMPOSITE_ROLE, "composite_role_id", op, values); String roleIdS = ensureEqSingleValue(RoleModel.SearchableFields.COMPOSITE_ROLE, "composite_role_id", op, values);
Function<MapRoleEntity, ?> getter; Function<MapRoleEntity, ?> getter;

View file

@ -21,8 +21,6 @@ import org.keycloak.provider.ProviderEvent;
import org.keycloak.storage.SearchableModelField; import org.keycloak.storage.SearchableModelField;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream; import java.util.stream.Stream;
/** /**
@ -38,6 +36,11 @@ public interface RoleModel {
public static final SearchableModelField<RoleModel> CLIENT_ID = new SearchableModelField<>("clientId", String.class); public static final SearchableModelField<RoleModel> CLIENT_ID = new SearchableModelField<>("clientId", String.class);
public static final SearchableModelField<RoleModel> NAME = new SearchableModelField<>("name", String.class); public static final SearchableModelField<RoleModel> NAME = new SearchableModelField<>("name", String.class);
public static final SearchableModelField<RoleModel> DESCRIPTION = new SearchableModelField<>("description", String.class); public static final SearchableModelField<RoleModel> 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<RoleModel> IS_CLIENT_ROLE = new SearchableModelField<>("isClientRole", Boolean.class); public static final SearchableModelField<RoleModel> IS_CLIENT_ROLE = new SearchableModelField<>("isClientRole", Boolean.class);
public static final SearchableModelField<RoleModel> COMPOSITE_ROLE = new SearchableModelField<>("compositeRoles", Boolean.class); public static final SearchableModelField<RoleModel> COMPOSITE_ROLE = new SearchableModelField<>("compositeRoles", Boolean.class);
} }