Ignore empty attribute values when retriveing boolean/int/long (#26729) (#26737)

Resolves #26597, resolves #26665

Signed-off-by: stianst <stianst@gmail.com>
This commit is contained in:
Stian Thorgersen 2024-02-06 15:29:34 +01:00 committed by GitHub
parent f0e5172b11
commit 3e08a1713b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 53 additions and 9 deletions

View file

@ -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<String, String> getAttributes() {

View file

@ -589,6 +589,7 @@ public class RealmAdapter implements StorageProviderRealmModel, JpaModel<RealmEn
getAttributes().entrySet().stream()
.filter(Objects::nonNull)
.filter(entry -> 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())));

View file

@ -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<String, String> getAttributes();

View file

@ -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();
}
}
}