From 05425549844f8e222b62ee01de1bd5c69b64c9ca Mon Sep 17 00:00:00 2001 From: Sebastian Schuster Date: Wed, 13 Mar 2024 17:42:01 +0100 Subject: [PATCH] 12671 querying by user attribute no longer forces case insensitivity for keys Signed-off-by: Sebastian Schuster --- docs/documentation/release_notes/topics/25_0_0.adoc | 6 +++++- .../upgrading/topics/changes/changes-25_0_0.adoc | 4 ++++ .../main/java/org/keycloak/models/jpa/JpaUserProvider.java | 5 ++--- .../test/java/org/keycloak/testsuite/admin/UserTest.java | 2 +- 4 files changed, 12 insertions(+), 5 deletions(-) diff --git a/docs/documentation/release_notes/topics/25_0_0.adoc b/docs/documentation/release_notes/topics/25_0_0.adoc index a2f306da4c..6f9226dc93 100644 --- a/docs/documentation/release_notes/topics/25_0_0.adoc +++ b/docs/documentation/release_notes/topics/25_0_0.adoc @@ -4,4 +4,8 @@ The following methods for setting custom cookies have been removed: * `LocaleSelectorProvider.KEYCLOAK_LOCALE` - replaced by `CookieType.LOCALE` * `HttpCookie` - replaced by `NewCookie.Builder` -* `HttpResponse.setCookieIfAbsent(HttpCookie cookie)` - replaced by `HttpResponse.setCookieIfAbsent(NewCookie cookie)` \ No newline at end of file +* `HttpResponse.setCookieIfAbsent(HttpCookie cookie)` - replaced by `HttpResponse.setCookieIfAbsent(NewCookie cookie)` + += Searching by user attribute no longer case insensitive + +When searching for users by user attribute, Keycloak no longer searches for user attribute names forcing lower case comparisons. The goal of this change was to speed up searches by using Keycloak's native index on the user attribute table. If your database collation is case-insensitive, your search results will stay the same. If your database collation is case-sensitive, you might see less search results than before. diff --git a/docs/documentation/upgrading/topics/changes/changes-25_0_0.adoc b/docs/documentation/upgrading/topics/changes/changes-25_0_0.adoc index 6d9e4d8ebf..0d80e09de3 100644 --- a/docs/documentation/upgrading/topics/changes/changes-25_0_0.adoc +++ b/docs/documentation/upgrading/topics/changes/changes-25_0_0.adoc @@ -30,3 +30,7 @@ The module `org.keycloak:keycloak-model-legacy` module was deprecated in a previ = Removed offline session preloading The old behavior to preload offline sessions at startup is now removed after it has been deprecated in the previous release. + += Removing custom user attribute indexes + +When searching for users by user attribute, Keycloak no longer searches for user attribute names forcing lower case comparisons. This means Keycloak's native index on the user attribute table will now be used when searching. If you have created your own index based on `lower(name)`to speed up searches, you can now remove it. diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/JpaUserProvider.java b/model/jpa/src/main/java/org/keycloak/models/jpa/JpaUserProvider.java index 6138049375..907d6cf35f 100755 --- a/model/jpa/src/main/java/org/keycloak/models/jpa/JpaUserProvider.java +++ b/model/jpa/src/main/java/org/keycloak/models/jpa/JpaUserProvider.java @@ -1001,15 +1001,14 @@ public class JpaUserProvider implements UserProvider, UserCredentialStore { // All unknown attributes will be assumed as custom attributes default: Join attributesJoin = root.join("attributes", JoinType.LEFT); - if (value.length() > 255) { customLongValueSearchAttributes.put(key, value); attributePredicates.add(builder.and( - builder.equal(builder.lower(attributesJoin.get("name")), key.toLowerCase()), + builder.equal(attributesJoin.get("name"), key), builder.equal(attributesJoin.get("longValueHashLowerCase"), JpaHashUtils.hashForAttributeValueLowerCase(value)))); } else { attributePredicates.add(builder.and( - builder.equal(builder.lower(attributesJoin.get("name")), key.toLowerCase()), + builder.equal(attributesJoin.get("name"), key), builder.equal(builder.lower(attributesJoin.get("value")), value.toLowerCase()))); } break; diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/UserTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/UserTest.java index 7b7f56dcf9..78f533ed8a 100755 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/UserTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/UserTest.java @@ -927,7 +927,7 @@ public class UserTest extends AbstractAdminTest { createUsers(); Map attributes = new HashMap<>(); - attributes.put("attr", "common"); + attributes.put("attr", "Common"); for (int i = 1; i < 10; i++) { List users = realm.users().searchByAttributes(i - 1, 1, null, false, mapToSearchQuery(attributes)); assertEquals(1, users.size());