diff --git a/server-spi-private/src/main/java/org/keycloak/models/utils/RepresentationToModel.java b/server-spi-private/src/main/java/org/keycloak/models/utils/RepresentationToModel.java index e2d97ec090..99faf6b8f1 100755 --- a/server-spi-private/src/main/java/org/keycloak/models/utils/RepresentationToModel.java +++ b/server-spi-private/src/main/java/org/keycloak/models/utils/RepresentationToModel.java @@ -21,6 +21,7 @@ import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; +import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.ListIterator; @@ -1689,7 +1690,7 @@ public class RepresentationToModel { model.setName(rep.getName()); model.setIdentityProviderAlias(rep.getIdentityProviderAlias()); model.setIdentityProviderMapper(rep.getIdentityProviderMapper()); - model.setConfig(rep.getConfig()); + model.setConfig(removeEmptyString(rep.getConfig())); return model; } @@ -2437,4 +2438,20 @@ public class RepresentationToModel { } } + + private static Map removeEmptyString(Map map) { + if (map == null) { + return null; + } + + Map m = new HashMap<>(map); + for (Iterator> itr = m.entrySet().iterator(); itr.hasNext(); ) { + Map.Entry e = itr.next(); + if (e.getValue() == null || e.getValue().equals("")) { + itr.remove(); + } + } + return m; + } + } diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/IdentityProviderTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/IdentityProviderTest.java index d95384783c..fdf0c14b4f 100755 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/IdentityProviderTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/IdentityProviderTest.java @@ -23,6 +23,7 @@ import org.keycloak.admin.client.resource.IdentityProviderResource; import org.keycloak.dom.saml.v2.metadata.EndpointType; import org.keycloak.dom.saml.v2.metadata.EntityDescriptorType; import org.keycloak.dom.saml.v2.metadata.IndexedEndpointType; +import org.keycloak.dom.saml.v2.metadata.KeyDescriptorType; import org.keycloak.dom.saml.v2.metadata.KeyTypes; import org.keycloak.dom.saml.v2.metadata.SPSSODescriptorType; import org.keycloak.events.admin.OperationType; @@ -30,7 +31,6 @@ import org.keycloak.events.admin.ResourceType; import org.keycloak.models.utils.StripSecretsUtils; import org.keycloak.representations.idm.AdminEventRepresentation; import org.keycloak.representations.idm.ComponentRepresentation; -import org.keycloak.representations.idm.CredentialRepresentation; import org.keycloak.representations.idm.IdentityProviderMapperRepresentation; import org.keycloak.representations.idm.IdentityProviderMapperTypeRepresentation; import org.keycloak.representations.idm.IdentityProviderRepresentation; @@ -39,10 +39,12 @@ import org.keycloak.saml.common.util.StaxParserUtil; import org.keycloak.saml.processing.core.parsers.saml.metadata.SAMLEntityDescriptorParser; import org.keycloak.testsuite.Assert; import org.keycloak.testsuite.util.AdminEventPaths; +import org.w3c.dom.NodeList; import javax.ws.rs.NotFoundException; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; +import javax.xml.crypto.dsig.XMLSignature; import java.io.ByteArrayInputStream; import java.io.IOException; import java.net.URI; @@ -57,16 +59,17 @@ import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; -import javax.xml.crypto.dsig.XMLSignature; +import static org.hamcrest.Matchers.containsInAnyOrder; +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.hasEntry; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.notNullValue; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertThat; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; -import static org.hamcrest.Matchers.*; -import org.keycloak.dom.saml.v2.metadata.KeyDescriptorType; -import org.w3c.dom.NodeList; /** * @author Stian Thorgersen @@ -449,6 +452,40 @@ public class IdentityProviderTest extends AbstractAdminTest { } } + // KEYCLOAK-4962 + @Test + public void testUpdateProtocolMappers() { + create(createRep("google", "google")); + + IdentityProviderResource provider = realm.identityProviders().get("google"); + + IdentityProviderMapperRepresentation mapper = new IdentityProviderMapperRepresentation(); + mapper.setIdentityProviderAlias("google"); + mapper.setName("my_mapper"); + mapper.setIdentityProviderMapper("oidc-hardcoded-role-idp-mapper"); + Map config = new HashMap<>(); + config.put("role", ""); + mapper.setConfig(config); + + Response response = provider.addMapper(mapper); + String mapperId = ApiUtil.getCreatedId(response); + + + List mappers = provider.getMappers(); + assertEquals(1, mappers.size()); + assertEquals(0, mappers.get(0).getConfig().size()); + + mapper = provider.getMapperById(mapperId); + mapper.getConfig().put("role", "offline_access"); + + provider.update(mapperId, mapper); + + mappers = provider.getMappers(); + assertEquals(1, mappers.size()); + assertEquals(1, mappers.get(0).getConfig().size()); + assertEquals("offline_access", mappers.get(0).getConfig().get("role")); + } + @Test public void testInstalledIdentityProviders() { Response response = realm.identityProviders().getIdentityProviders("oidc");