diff --git a/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/entities/CachedRealm.java b/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/entities/CachedRealm.java index df4097a1b9..5dbdb7f394 100755 --- a/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/entities/CachedRealm.java +++ b/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/entities/CachedRealm.java @@ -719,17 +719,17 @@ public class CachedRealm extends AbstractExtendableRevisioned { public Integer getAttribute(String name, Integer defaultValue) { String v = getAttribute(name); - return v != null ? Integer.valueOf(v) : defaultValue; + return v != null && !v.isEmpty() ? Integer.valueOf(v) : defaultValue; } public Long getAttribute(String name, Long defaultValue) { String v = getAttribute(name); - return v != null ? Long.valueOf(v) : defaultValue; + return v != null && !v.isEmpty() ? Long.valueOf(v) : defaultValue; } public Boolean getAttribute(String name, Boolean defaultValue) { String v = getAttribute(name); - return v != null ? Boolean.valueOf(v) : defaultValue; + return v != null && !v.isEmpty() ? Boolean.valueOf(v) : defaultValue; } public Map getAttributes() { diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/RealmAdapter.java b/model/jpa/src/main/java/org/keycloak/models/jpa/RealmAdapter.java index 25eeef56a8..59c5c533ad 100755 --- a/model/jpa/src/main/java/org/keycloak/models/jpa/RealmAdapter.java +++ b/model/jpa/src/main/java/org/keycloak/models/jpa/RealmAdapter.java @@ -589,6 +589,7 @@ public class RealmAdapter implements StorageProviderRealmModel, JpaModel nonNull(entry.getValue())) + .filter(entry -> !entry.getValue().isEmpty()) .filter(entry -> entry.getKey().startsWith(RealmAttributes.ACTION_TOKEN_GENERATED_BY_USER_LIFESPAN + ".")) .forEach(entry -> userActionTokens.put(entry.getKey().substring(RealmAttributes.ACTION_TOKEN_GENERATED_BY_USER_LIFESPAN.length() + 1), Integer.valueOf(entry.getValue()))); diff --git a/server-spi/src/main/java/org/keycloak/models/RealmModel.java b/server-spi/src/main/java/org/keycloak/models/RealmModel.java index 9d1e91a3f8..4dc7a57c86 100755 --- a/server-spi/src/main/java/org/keycloak/models/RealmModel.java +++ b/server-spi/src/main/java/org/keycloak/models/RealmModel.java @@ -119,15 +119,15 @@ public interface RealmModel extends RoleContainerModel { String getAttribute(String name); default Integer getAttribute(String name, Integer defaultValue) { String v = getAttribute(name); - return v != null ? Integer.valueOf(v) : defaultValue; + return v != null && !v.isEmpty() ? Integer.valueOf(v) : defaultValue; } default Long getAttribute(String name, Long defaultValue) { String v = getAttribute(name); - return v != null ? Long.valueOf(v) : defaultValue; + return v != null && !v.isEmpty() ? Long.valueOf(v) : defaultValue; } default Boolean getAttribute(String name, Boolean defaultValue) { String v = getAttribute(name); - return v != null ? Boolean.valueOf(v) : defaultValue; + return v != null && !v.isEmpty() ? Boolean.valueOf(v) : defaultValue; } Map getAttributes(); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/realm/RealmTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/realm/RealmTest.java index 9d2159b770..0810cc1094 100755 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/realm/RealmTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/realm/RealmTest.java @@ -18,6 +18,9 @@ package org.keycloak.testsuite.admin.realm; import com.google.common.collect.Sets; +import jakarta.ws.rs.BadRequestException; +import jakarta.ws.rs.NotFoundException; +import jakarta.ws.rs.core.Response; import org.apache.commons.io.IOUtils; import org.hamcrest.CoreMatchers; import org.hamcrest.Matchers; @@ -38,6 +41,10 @@ import org.keycloak.models.Constants; import org.keycloak.models.OAuth2DeviceConfig; import org.keycloak.models.OTPPolicy; import org.keycloak.models.ParConfig; +import org.keycloak.models.RealmModel; +import org.keycloak.models.RealmProvider; +import org.keycloak.models.cache.CacheRealmProvider; +import org.keycloak.models.jpa.entities.RealmAttributes; import org.keycloak.protocol.oidc.OIDCLoginProtocol; import org.keycloak.protocol.saml.SamlProtocol; import org.keycloak.representations.adapters.action.GlobalRequestResult; @@ -70,9 +77,6 @@ import org.keycloak.testsuite.utils.tls.TLSUtils; import org.keycloak.userprofile.UserProfileProvider; import org.keycloak.util.JsonSerialization; -import jakarta.ws.rs.BadRequestException; -import jakarta.ws.rs.NotFoundException; -import jakarta.ws.rs.core.Response; import java.io.IOException; import java.nio.charset.Charset; import java.util.ArrayList; @@ -997,4 +1001,43 @@ public class RealmTest extends AbstractAdminTest { // this used to return non-empty collection assertThat(adminClient.realm(realmName).components().query(null, UserProfileProvider.class.getName()), empty()); } + + @Test + public void testSetEmptyAttributeValues() { + String realmName = "testSetEmptyAttributeValues"; + RealmRepresentation rep = new RealmRepresentation(); + rep.setRealm(realmName); + rep.setAttributes(new HashMap<>()); + rep.getAttributes().put("myboolean", ""); + rep.getAttributes().put("mylong", ""); + rep.getAttributes().put("myint", ""); + rep.getAttributes().put(RealmAttributes.ACTION_TOKEN_GENERATED_BY_USER_LIFESPAN + ".something", ""); + + adminClient.realms().create(rep); + + try { + adminClient.realm(realmName); + + testingClient.server().run(session -> { + RealmModel realm = session.realms().getRealmByName(realmName); + Assert.assertTrue(realm instanceof org.keycloak.models.cache.infinispan.RealmAdapter); + + Assert.assertNull(realm.getUserActionTokenLifespans().get("something")); + Assert.assertEquals(true, realm.getAttribute("myboolean", true)); + Assert.assertEquals(Long.valueOf(123), realm.getAttribute("mylong", (long) 123)); + Assert.assertEquals(Integer.valueOf(1234), realm.getAttribute("myint", 1234)); + + RealmProvider delegate = session.getProvider(CacheRealmProvider.class).getRealmDelegate(); + RealmModel realm2 = delegate.getRealm(realm.getId()); + Assert.assertTrue(realm2 instanceof org.keycloak.models.jpa.RealmAdapter); + + Assert.assertNull(realm2.getUserActionTokenLifespans().get("something")); + Assert.assertEquals(true, realm2.getAttribute("myboolean", true)); + Assert.assertEquals(Long.valueOf(123), realm2.getAttribute("mylong", (long) 123)); + Assert.assertEquals(Integer.valueOf(1234), realm2.getAttribute("myint", 1234)); + }); + } finally { + adminClient.realm(realmName).remove(); + } + } }