keycloak-memoizeit
Changes
testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/AbstractBrokerTest.java 2(+1 -1)
testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/AbstractUserAttributeMapperTest.java 341(+341 -0)
testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/KcOidcBrokerConfiguration.java 39(+39 -0)
testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/KcSamlBrokerConfiguration.java 58(+43 -15)
Details
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/AbstractBrokerTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/AbstractBrokerTest.java
index bfc04a6..b32b94c 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/AbstractBrokerTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/AbstractBrokerTest.java
@@ -140,7 +140,7 @@ public abstract class AbstractBrokerTest extends AbstractKeycloakTest {
driver.getCurrentUrl().contains("/auth/realms/" + bc.consumerRealmName() + "/"));
log.debug("Updating info on updateAccount page");
- updateAccountInformationPage.updateAccountInformation("Firstname", "Lastname");
+ updateAccountInformationPage.updateAccountInformation(bc.getUserLogin(), bc.getUserEmail(), "Firstname", "Lastname");
UsersResource consumerUsers = adminClient.realm(bc.consumerRealmName()).users();
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/AbstractUserAttributeMapperTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/AbstractUserAttributeMapperTest.java
new file mode 100644
index 0000000..fb74fce
--- /dev/null
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/AbstractUserAttributeMapperTest.java
@@ -0,0 +1,341 @@
+package org.keycloak.testsuite.broker;
+
+import org.keycloak.admin.client.resource.IdentityProviderResource;
+import org.keycloak.admin.client.resource.RealmResource;
+import org.keycloak.admin.client.resource.UsersResource;
+import org.keycloak.representations.idm.ClientRepresentation;
+import org.keycloak.representations.idm.IdentityProviderMapperRepresentation;
+import org.keycloak.representations.idm.IdentityProviderRepresentation;
+import org.keycloak.representations.idm.RealmRepresentation;
+import org.keycloak.representations.idm.UserRepresentation;
+import org.keycloak.testsuite.AbstractKeycloakTest;
+import org.keycloak.testsuite.Assert;
+import org.keycloak.testsuite.Retry;
+import org.keycloak.testsuite.pages.AccountPasswordPage;
+import org.keycloak.testsuite.pages.ErrorPage;
+import org.keycloak.testsuite.pages.IdpConfirmLinkPage;
+import org.keycloak.testsuite.pages.LoginPage;
+import org.keycloak.testsuite.pages.UpdateAccountInformationPage;
+import org.keycloak.testsuite.util.UserBuilder;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+import javax.ws.rs.core.Response;
+import org.jboss.arquillian.graphene.page.Page;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.openqa.selenium.TimeoutException;
+
+import static org.junit.Assert.*;
+import static org.hamcrest.Matchers.*;
+import static org.keycloak.testsuite.admin.ApiUtil.*;
+import static org.keycloak.testsuite.broker.BrokerTestTools.encodeUrl;
+import static org.keycloak.testsuite.broker.BrokerTestTools.waitForPage;
+
+/**
+ *
+ * @author hmlnarik
+ */
+public abstract class AbstractUserAttributeMapperTest extends AbstractKeycloakTest {
+
+ protected static final String MAPPED_ATTRIBUTE_NAME = "mapped-user-attribute";
+ protected static final String MAPPED_ATTRIBUTE_FRIENDLY_NAME = "mapped-user-attribute-friendly";
+ protected static final String ATTRIBUTE_TO_MAP_NAME = "user-attribute";
+ protected static final String ATTRIBUTE_TO_MAP_FRIENDLY_NAME = "user-attribute-friendly";
+
+ private static final Set<String> PROTECTED_NAMES = ImmutableSet.<String>builder().add("email").add("lastName").add("firstName").build();
+ private static final Map<String, String> ATTRIBUTE_NAME_TRANSLATION = ImmutableMap.<String, String>builder()
+ .put(ATTRIBUTE_TO_MAP_FRIENDLY_NAME, MAPPED_ATTRIBUTE_FRIENDLY_NAME)
+ .put(ATTRIBUTE_TO_MAP_NAME, MAPPED_ATTRIBUTE_NAME)
+ .build();
+
+ @Page
+ protected LoginPage accountLoginPage;
+
+ @Page
+ protected UpdateAccountInformationPage updateAccountInformationPage;
+
+ @Page
+ protected AccountPasswordPage accountPasswordPage;
+
+ @Page
+ protected ErrorPage errorPage;
+
+ @Page
+ protected IdpConfirmLinkPage idpConfirmLinkPage;
+
+ protected BrokerConfiguration bc = getBrokerConfiguration();
+
+ protected String userId;
+
+ /**
+ * Returns a broker configuration. Return value should not change between calls.
+ * @return
+ */
+ protected abstract BrokerConfiguration getBrokerConfiguration();
+
+ protected abstract Iterable<IdentityProviderMapperRepresentation> createIdentityProviderMappers();
+
+ @Override
+ public void addTestRealms(List<RealmRepresentation> testRealms) {
+ RealmRepresentation providerRealm = bc.createProviderRealm();
+ RealmRepresentation consumerRealm = bc.createConsumerRealm();
+
+ testRealms.add(providerRealm);
+ testRealms.add(consumerRealm);
+ }
+
+ @Before
+ public void addIdentityProviderToConsumerRealm() {
+ log.debug("adding identity provider to realm " + bc.consumerRealmName());
+
+ RealmResource realm = adminClient.realm(bc.consumerRealmName());
+ final IdentityProviderRepresentation idp = bc.setUpIdentityProvider(suiteContext);
+ realm.identityProviders().create(idp);
+
+ IdentityProviderResource idpResource = realm.identityProviders().get(idp.getAlias());
+ for (IdentityProviderMapperRepresentation mapper : createIdentityProviderMappers()) {
+ mapper.setIdentityProviderAlias(bc.getIDPAlias());
+ Response resp = idpResource.addMapper(mapper);
+ resp.close();
+ }
+ }
+
+ @Before
+ public void addClients() {
+ List<ClientRepresentation> clients = bc.createProviderClients(suiteContext);
+ if (clients != null) {
+ RealmResource providerRealm = adminClient.realm(bc.providerRealmName());
+ for (ClientRepresentation client : clients) {
+ log.debug("adding client " + client.getName() + " to realm " + bc.providerRealmName());
+
+ providerRealm.clients().create(client);
+ }
+ }
+
+ clients = bc.createConsumerClients(suiteContext);
+ if (clients != null) {
+ RealmResource consumerRealm = adminClient.realm(bc.consumerRealmName());
+ for (ClientRepresentation client : clients) {
+ log.debug("adding client " + client.getName() + " to realm " + bc.consumerRealmName());
+
+ consumerRealm.clients().create(client);
+ }
+ }
+ }
+
+ protected void createUserInProviderRealm(Map<String, List<String>> attributes) {
+ log.debug("creating user in realm " + bc.providerRealmName());
+
+ UserRepresentation user = UserBuilder.create()
+ .username(bc.getUserLogin())
+ .email(bc.getUserEmail())
+ .build();
+ user.setEmailVerified(true);
+ user.setAttributes(attributes);
+ this.userId = createUserAndResetPasswordWithAdminClient(adminClient.realm(bc.providerRealmName()), user, bc.getUserPassword());
+ }
+
+ private void logInAsUserInIDP() {
+ driver.navigate().to(getAccountUrl(bc.consumerRealmName()));
+
+ log.debug("Clicking social " + bc.getIDPAlias());
+ accountLoginPage.clickSocial(bc.getIDPAlias());
+
+ waitForPage(driver, "log in to");
+
+ Assert.assertTrue("Driver should be on the provider realm page right now",
+ driver.getCurrentUrl().contains("/auth/realms/" + bc.providerRealmName() + "/"));
+
+ log.debug("Logging in");
+ accountLoginPage.login(bc.getUserLogin(), bc.getUserPassword());
+ }
+
+ /** Logs in the IDP and updates account information */
+ private void logInAsUserInIDPForFirstTime() {
+ logInAsUserInIDP();
+
+ waitForPage(driver, "update account information");
+
+ Assert.assertTrue(updateAccountInformationPage.isCurrent());
+ Assert.assertTrue("We must be on correct realm right now",
+ driver.getCurrentUrl().contains("/auth/realms/" + bc.consumerRealmName() + "/"));
+
+ log.debug("Updating info on updateAccount page");
+ updateAccountInformationPage.updateAccountInformation(bc.getUserLogin(), bc.getUserEmail(), "Firstname", "Lastname");
+ }
+
+ private String getAccountUrl(String realmName) {
+ return BrokerTestTools.getAuthRoot(suiteContext) + "/auth/realms/" + realmName + "/account";
+ }
+
+ private void logoutFromRealm(String realm) {
+ driver.navigate().to(BrokerTestTools.getAuthRoot(suiteContext)
+ + "/auth/realms/" + realm
+ + "/protocol/" + "openid-connect"
+ + "/logout?redirect_uri=" + encodeUrl(getAccountUrl(realm)));
+
+ try {
+ Retry.execute(() -> {
+ try {
+ waitForPage(driver, "log in to " + realm);
+ } catch (TimeoutException ex) {
+ driver.navigate().refresh();
+ log.debug("[Retriable] Timed out waiting for login page");
+ throw ex;
+ }
+ }, 10, 100);
+ } catch (TimeoutException e) {
+ log.debug(driver.getTitle());
+ log.debug(driver.getPageSource());
+ Assert.fail("Timeout while waiting for login page");
+ }
+ }
+
+ private UserRepresentation findUser(String realm, String userName, String email) {
+ UsersResource consumerUsers = adminClient.realm(realm).users();
+
+ int userCount = consumerUsers.count();
+ assertThat("There must be at least one user", userCount, greaterThan(0));
+
+ List<UserRepresentation> users = consumerUsers.search("", 0, userCount);
+
+ for (UserRepresentation user : users) {
+ if (user.getUsername().equals(userName) && user.getEmail().equals(email)) {
+ return user;
+ }
+ }
+
+ fail("User " + userName + " not found in " + realm + " realm");
+ return null;
+ }
+
+ private void assertUserAttributes(Map<String, List<String>> attrs, UserRepresentation userRep) {
+ Set<String> mappedAttrNames = attrs.entrySet().stream()
+ .filter(me -> me.getValue() != null && ! me.getValue().isEmpty())
+ .map(me -> me.getKey())
+ .filter(a -> ! PROTECTED_NAMES.contains(a))
+ .map(ATTRIBUTE_NAME_TRANSLATION::get)
+ .collect(Collectors.toSet());
+
+ if (mappedAttrNames.isEmpty()) {
+ assertThat("No attributes are expected to be present", userRep.getAttributes(), nullValue());
+ } else {
+ assertThat(userRep.getAttributes(), notNullValue());
+ assertThat(userRep.getAttributes().keySet(), equalTo(mappedAttrNames));
+ for (Map.Entry<String, List<String>> me : attrs.entrySet()) {
+ String mappedAttrName = ATTRIBUTE_NAME_TRANSLATION.get(me.getKey());
+ if (mappedAttrNames.contains(mappedAttrName)) {
+ assertThat(userRep.getAttributes().get(mappedAttrName), equalTo(me.getValue()));
+ }
+ }
+ }
+
+ if (attrs.containsKey("email")) {
+ assertThat(userRep.getEmail(), equalTo(attrs.get("email").get(0)));
+ }
+ if (attrs.containsKey("firstName")) {
+ assertThat(userRep.getFirstName(), equalTo(attrs.get("firstName").get(0)));
+ }
+ if (attrs.containsKey("lastName")) {
+ assertThat(userRep.getLastName(), equalTo(attrs.get("lastName").get(0)));
+ }
+ }
+
+ protected void testValueMapping(Map<String, List<String>> initialUserAttributes, Map<String, List<String>> modifiedUserAttributes) {
+ String email = bc.getUserEmail();
+ createUserInProviderRealm(initialUserAttributes);
+
+ logInAsUserInIDPForFirstTime();
+ UserRepresentation userRep = findUser(bc.consumerRealmName(), bc.getUserLogin(), email);
+
+ assertUserAttributes(initialUserAttributes, userRep);
+
+ logoutFromRealm(bc.consumerRealmName());
+
+ // update user in provider realm
+ UserRepresentation userRepProvider = findUser(bc.providerRealmName(), bc.getUserLogin(), email);
+ Map<String, List<String>> modifiedWithoutSpecialKeys = modifiedUserAttributes.entrySet().stream()
+ .filter(a -> ! PROTECTED_NAMES.contains(a.getKey()))
+ .filter(a -> a.getValue() != null) // Remove empty attributes
+ .collect(Collectors.toMap(p -> p.getKey(), p -> p.getValue()));
+ userRepProvider.setAttributes(modifiedWithoutSpecialKeys);
+ if (modifiedUserAttributes.containsKey("email")) {
+ userRepProvider.setEmail(modifiedUserAttributes.get("email").get(0));
+ email = modifiedUserAttributes.get("email").get(0);
+ }
+ if (modifiedUserAttributes.containsKey("firstName")) {
+ userRepProvider.setFirstName(modifiedUserAttributes.get("firstName").get(0));
+ }
+ if (modifiedUserAttributes.containsKey("lastName")) {
+ userRepProvider.setLastName(modifiedUserAttributes.get("lastName").get(0));
+ }
+ adminClient.realm(bc.providerRealmName()).users().get(userRepProvider.getId()).update(userRepProvider);
+
+ logInAsUserInIDP();
+ userRep = findUser(bc.consumerRealmName(), bc.getUserLogin(), email);
+
+ assertUserAttributes(modifiedUserAttributes, userRep);
+ }
+
+ @Test
+ public void testBasicMappingSingleValue() {
+ testValueMapping(ImmutableMap.<String, List<String>>builder()
+ .put(ATTRIBUTE_TO_MAP_NAME, ImmutableList.<String>builder().add("value 1").build())
+ .build(),
+ ImmutableMap.<String, List<String>>builder()
+ .put(ATTRIBUTE_TO_MAP_NAME, ImmutableList.<String>builder().add("second value").build())
+ .build()
+ );
+ }
+
+ @Test
+ public void testBasicMappingEmail() {
+ testValueMapping(ImmutableMap.<String, List<String>>builder()
+ .put("email", ImmutableList.<String>builder().add(bc.getUserEmail()).build())
+ .build(),
+ ImmutableMap.<String, List<String>>builder()
+ .put("email", ImmutableList.<String>builder().add("other_email@redhat.com").build())
+ .build()
+ );
+ }
+
+ @Test
+ public void testBasicMappingClearValue() {
+ testValueMapping(ImmutableMap.<String, List<String>>builder()
+ .put(ATTRIBUTE_TO_MAP_NAME, ImmutableList.<String>builder().add("value 1").build())
+ .build(),
+ ImmutableMap.<String, List<String>>builder()
+ .put(ATTRIBUTE_TO_MAP_NAME, ImmutableList.<String>builder().build())
+ .build()
+ );
+ }
+
+ @Test
+ public void testBasicMappingRemoveValue() {
+ testValueMapping(ImmutableMap.<String, List<String>>builder()
+ .put(ATTRIBUTE_TO_MAP_NAME, ImmutableList.<String>builder().add("value 1").build())
+ .build(),
+ ImmutableMap.<String, List<String>>builder()
+ .build()
+ );
+ }
+
+ @Test
+ @Ignore("Unignore to test KEYCLOAK-3648")
+ public void testBasicMappingMultipleValues() {
+ testValueMapping(ImmutableMap.<String, List<String>>builder()
+ .put(ATTRIBUTE_TO_MAP_NAME, ImmutableList.<String>builder().add("value 1").add("value 2").build())
+ .build(),
+ ImmutableMap.<String, List<String>>builder()
+ .put(ATTRIBUTE_TO_MAP_NAME, ImmutableList.<String>builder().add("second value").add("second value 2").build())
+ .build()
+ );
+ }
+}
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/KcOidcBrokerConfiguration.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/KcOidcBrokerConfiguration.java
index b316314..1fdb896 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/KcOidcBrokerConfiguration.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/KcOidcBrokerConfiguration.java
@@ -1,10 +1,18 @@
package org.keycloak.testsuite.broker;
+import org.keycloak.protocol.ProtocolMapperUtils;
+import org.keycloak.protocol.oidc.OIDCLoginProtocol;
+import org.keycloak.protocol.oidc.mappers.OIDCAttributeMapperHelper;
+import org.keycloak.protocol.oidc.mappers.UserAttributeMapper;
+import org.keycloak.protocol.oidc.mappers.UserPropertyMapper;
+import org.keycloak.provider.ProviderConfigProperty;
import org.keycloak.representations.idm.ClientRepresentation;
import org.keycloak.representations.idm.IdentityProviderRepresentation;
+import org.keycloak.representations.idm.ProtocolMapperRepresentation;
import org.keycloak.representations.idm.RealmRepresentation;
import org.keycloak.testsuite.arquillian.SuiteContext;
+import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
@@ -52,6 +60,37 @@ public class KcOidcBrokerConfiguration implements BrokerConfiguration {
client.setAdminUrl(getAuthRoot(suiteContext) +
"/auth/realms/" + REALM_CONS_NAME + "/broker/" + IDP_OIDC_ALIAS + "/endpoint");
+ ProtocolMapperRepresentation emailMapper = new ProtocolMapperRepresentation();
+ emailMapper.setName("email");
+ emailMapper.setProtocol(OIDCLoginProtocol.LOGIN_PROTOCOL);
+ emailMapper.setProtocolMapper(UserPropertyMapper.PROVIDER_ID);
+ emailMapper.setConsentRequired(false);
+
+ Map<String, String> emailMapperConfig = emailMapper.getConfig();
+ emailMapperConfig.put(ProtocolMapperUtils.USER_ATTRIBUTE, "email");
+ emailMapperConfig.put(OIDCAttributeMapperHelper.TOKEN_CLAIM_NAME, "email");
+ emailMapperConfig.put(OIDCAttributeMapperHelper.JSON_TYPE, ProviderConfigProperty.STRING_TYPE);
+ emailMapperConfig.put(OIDCAttributeMapperHelper.INCLUDE_IN_ACCESS_TOKEN, "true");
+ emailMapperConfig.put(OIDCAttributeMapperHelper.INCLUDE_IN_ID_TOKEN, "true");
+ emailMapperConfig.put(OIDCAttributeMapperHelper.INCLUDE_IN_USERINFO, "true");
+
+ ProtocolMapperRepresentation userAttrMapper = new ProtocolMapperRepresentation();
+ userAttrMapper.setName("attribute - name");
+ userAttrMapper.setProtocol(OIDCLoginProtocol.LOGIN_PROTOCOL);
+ userAttrMapper.setProtocolMapper(UserAttributeMapper.PROVIDER_ID);
+ userAttrMapper.setConsentRequired(false);
+
+ Map<String, String> userAttrMapperConfig = userAttrMapper.getConfig();
+ userAttrMapperConfig.put(ProtocolMapperUtils.USER_ATTRIBUTE, AbstractUserAttributeMapperTest.ATTRIBUTE_TO_MAP_NAME);
+ userAttrMapperConfig.put(OIDCAttributeMapperHelper.TOKEN_CLAIM_NAME, AbstractUserAttributeMapperTest.ATTRIBUTE_TO_MAP_NAME);
+ userAttrMapperConfig.put(OIDCAttributeMapperHelper.JSON_TYPE, ProviderConfigProperty.STRING_TYPE);
+ userAttrMapperConfig.put(OIDCAttributeMapperHelper.INCLUDE_IN_ACCESS_TOKEN, "true");
+ userAttrMapperConfig.put(OIDCAttributeMapperHelper.INCLUDE_IN_ID_TOKEN, "true");
+ userAttrMapperConfig.put(OIDCAttributeMapperHelper.INCLUDE_IN_USERINFO, "true");
+// userAttrMapperConfig.put(ProtocolMapperUtils.MULTIVALUED, "true");
+
+ client.setProtocolMappers(Arrays.asList(emailMapper, userAttrMapper));
+
return Collections.singletonList(client);
}
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/KcSamlBrokerConfiguration.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/KcSamlBrokerConfiguration.java
index eabc329..7da71ad 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/KcSamlBrokerConfiguration.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/KcSamlBrokerConfiguration.java
@@ -5,12 +5,18 @@
*/
package org.keycloak.testsuite.broker;
+import org.keycloak.protocol.ProtocolMapperUtils;
+import org.keycloak.protocol.saml.SamlProtocol;
+import org.keycloak.protocol.saml.mappers.AttributeStatementHelper;
+import org.keycloak.protocol.saml.mappers.UserAttributeStatementMapper;
+import org.keycloak.protocol.saml.mappers.UserPropertyAttributeStatementMapper;
import org.keycloak.representations.idm.ClientRepresentation;
import org.keycloak.representations.idm.IdentityProviderRepresentation;
import org.keycloak.representations.idm.ProtocolMapperRepresentation;
import org.keycloak.representations.idm.RealmRepresentation;
import org.keycloak.testsuite.arquillian.SuiteContext;
+import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
@@ -71,21 +77,43 @@ public class KcSamlBrokerConfiguration implements BrokerConfiguration {
client.setAttributes(attributes);
- ProtocolMapperRepresentation mapper = new ProtocolMapperRepresentation();
- mapper.setName("email");
- mapper.setProtocol("saml");
- mapper.setProtocolMapper("saml-user-property-mapper");
- mapper.setConsentRequired(false);
-
- Map<String, String> mapperConfig = mapper.getConfig();
- mapperConfig.put("user.attribute", "email");
- mapperConfig.put("attribute.name", "urn:oid:1.2.840.113549.1.9.1");
- mapperConfig.put("attribute.nameformat", "urn:oasis:names:tc:SAML:2.0:attrname-format:uri");
- mapperConfig.put("friendly.name", "email");
-
- client.setProtocolMappers(Collections.singletonList(
- mapper
- ));
+ ProtocolMapperRepresentation emailMapper = new ProtocolMapperRepresentation();
+ emailMapper.setName("email");
+ emailMapper.setProtocol(SamlProtocol.LOGIN_PROTOCOL);
+ emailMapper.setProtocolMapper(UserPropertyAttributeStatementMapper.PROVIDER_ID);
+ emailMapper.setConsentRequired(false);
+
+ Map<String, String> emailMapperConfig = emailMapper.getConfig();
+ emailMapperConfig.put(ProtocolMapperUtils.USER_ATTRIBUTE, "email");
+ emailMapperConfig.put(AttributeStatementHelper.SAML_ATTRIBUTE_NAME, "urn:oid:1.2.840.113549.1.9.1");
+ emailMapperConfig.put(AttributeStatementHelper.SAML_ATTRIBUTE_NAMEFORMAT, "urn:oasis:names:tc:SAML:2.0:attrname-format:uri");
+ emailMapperConfig.put(AttributeStatementHelper.FRIENDLY_NAME, "email");
+
+ ProtocolMapperRepresentation userAttrMapper = new ProtocolMapperRepresentation();
+ userAttrMapper.setName("attribute - name");
+ userAttrMapper.setProtocol(SamlProtocol.LOGIN_PROTOCOL);
+ userAttrMapper.setProtocolMapper(UserAttributeStatementMapper.PROVIDER_ID);
+ userAttrMapper.setConsentRequired(false);
+
+ Map<String, String> userAttrMapperConfig = userAttrMapper.getConfig();
+ userAttrMapperConfig.put(ProtocolMapperUtils.USER_ATTRIBUTE, AbstractUserAttributeMapperTest.ATTRIBUTE_TO_MAP_NAME);
+ userAttrMapperConfig.put(AttributeStatementHelper.SAML_ATTRIBUTE_NAME, AbstractUserAttributeMapperTest.ATTRIBUTE_TO_MAP_NAME);
+ userAttrMapperConfig.put(AttributeStatementHelper.SAML_ATTRIBUTE_NAMEFORMAT, AttributeStatementHelper.BASIC);
+ userAttrMapperConfig.put(AttributeStatementHelper.FRIENDLY_NAME, "");
+
+ ProtocolMapperRepresentation userFriendlyAttrMapper = new ProtocolMapperRepresentation();
+ userFriendlyAttrMapper.setName("attribute - friendly name");
+ userFriendlyAttrMapper.setProtocol(SamlProtocol.LOGIN_PROTOCOL);
+ userFriendlyAttrMapper.setProtocolMapper(UserAttributeStatementMapper.PROVIDER_ID);
+ userFriendlyAttrMapper.setConsentRequired(false);
+
+ Map<String, String> userFriendlyAttrMapperConfig = userFriendlyAttrMapper.getConfig();
+ userFriendlyAttrMapperConfig.put(ProtocolMapperUtils.USER_ATTRIBUTE, AbstractUserAttributeMapperTest.ATTRIBUTE_TO_MAP_FRIENDLY_NAME);
+ userFriendlyAttrMapperConfig.put(AttributeStatementHelper.SAML_ATTRIBUTE_NAME, "");
+ userFriendlyAttrMapperConfig.put(AttributeStatementHelper.SAML_ATTRIBUTE_NAMEFORMAT, AttributeStatementHelper.BASIC);
+ userFriendlyAttrMapperConfig.put(AttributeStatementHelper.FRIENDLY_NAME, AbstractUserAttributeMapperTest.ATTRIBUTE_TO_MAP_FRIENDLY_NAME);
+
+ client.setProtocolMappers(Arrays.asList(emailMapper, userAttrMapper, userFriendlyAttrMapper));
return Collections.singletonList(client);
}
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/OidcUserAttributeMapperTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/OidcUserAttributeMapperTest.java
new file mode 100644
index 0000000..0927a86
--- /dev/null
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/OidcUserAttributeMapperTest.java
@@ -0,0 +1,38 @@
+package org.keycloak.testsuite.broker;
+
+import org.keycloak.broker.oidc.mappers.UserAttributeMapper;
+import org.keycloak.representations.idm.IdentityProviderMapperRepresentation;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Lists;
+
+
+public class OidcUserAttributeMapperTest extends AbstractUserAttributeMapperTest {
+
+ @Override
+ protected BrokerConfiguration getBrokerConfiguration() {
+ return KcOidcBrokerConfiguration.INSTANCE;
+ }
+
+ @Override
+ protected Iterable<IdentityProviderMapperRepresentation> createIdentityProviderMappers() {
+ IdentityProviderMapperRepresentation attrMapper1 = new IdentityProviderMapperRepresentation();
+ attrMapper1.setName("attribute-mapper");
+ attrMapper1.setIdentityProviderMapper(UserAttributeMapper.PROVIDER_ID);
+ attrMapper1.setConfig(ImmutableMap.<String,String>builder()
+ .put(UserAttributeMapper.CLAIM, ATTRIBUTE_TO_MAP_NAME)
+ .put(UserAttributeMapper.USER_ATTRIBUTE, MAPPED_ATTRIBUTE_NAME)
+ .build());
+
+ IdentityProviderMapperRepresentation emailAttrMapper = new IdentityProviderMapperRepresentation();
+ emailAttrMapper.setName("attribute-mapper-email");
+ emailAttrMapper.setIdentityProviderMapper(UserAttributeMapper.PROVIDER_ID);
+ emailAttrMapper.setConfig(ImmutableMap.<String,String>builder()
+ .put(UserAttributeMapper.CLAIM, "email")
+ .put(UserAttributeMapper.USER_ATTRIBUTE, "email")
+ .build());
+
+ return Lists.newArrayList(attrMapper1, emailAttrMapper);
+ }
+
+}
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/SamlUserAttributeMapperTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/SamlUserAttributeMapperTest.java
new file mode 100644
index 0000000..7184ef8
--- /dev/null
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/SamlUserAttributeMapperTest.java
@@ -0,0 +1,46 @@
+package org.keycloak.testsuite.broker;
+
+import org.keycloak.broker.saml.mappers.UserAttributeMapper;
+import org.keycloak.representations.idm.IdentityProviderMapperRepresentation;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Lists;
+
+
+public class SamlUserAttributeMapperTest extends AbstractUserAttributeMapperTest {
+
+ @Override
+ protected BrokerConfiguration getBrokerConfiguration() {
+ return KcSamlBrokerConfiguration.INSTANCE;
+ }
+
+ @Override
+ protected Iterable<IdentityProviderMapperRepresentation> createIdentityProviderMappers() {
+ IdentityProviderMapperRepresentation attrMapperEmail = new IdentityProviderMapperRepresentation();
+ attrMapperEmail.setName("attribute-mapper-email");
+ attrMapperEmail.setIdentityProviderMapper(UserAttributeMapper.PROVIDER_ID);
+ attrMapperEmail.setConfig(ImmutableMap.<String,String>builder()
+ .put(UserAttributeMapper.ATTRIBUTE_FRIENDLY_NAME, "email")
+ .put(UserAttributeMapper.USER_ATTRIBUTE, "email")
+ .build());
+
+ IdentityProviderMapperRepresentation attrMapper1 = new IdentityProviderMapperRepresentation();
+ attrMapper1.setName("attribute-mapper");
+ attrMapper1.setIdentityProviderMapper(UserAttributeMapper.PROVIDER_ID);
+ attrMapper1.setConfig(ImmutableMap.<String,String>builder()
+ .put(UserAttributeMapper.ATTRIBUTE_NAME, ATTRIBUTE_TO_MAP_NAME)
+ .put(UserAttributeMapper.USER_ATTRIBUTE, MAPPED_ATTRIBUTE_NAME)
+ .build());
+
+ IdentityProviderMapperRepresentation attrMapper2 = new IdentityProviderMapperRepresentation();
+ attrMapper2.setName("attribute-mapper-friendly");
+ attrMapper2.setIdentityProviderMapper(UserAttributeMapper.PROVIDER_ID);
+ attrMapper2.setConfig(ImmutableMap.<String,String>builder()
+ .put(UserAttributeMapper.ATTRIBUTE_FRIENDLY_NAME, ATTRIBUTE_TO_MAP_FRIENDLY_NAME)
+ .put(UserAttributeMapper.USER_ATTRIBUTE, MAPPED_ATTRIBUTE_FRIENDLY_NAME)
+ .build());
+
+ return Lists.newArrayList(attrMapperEmail, attrMapper1, attrMapper2);
+ }
+
+}