keycloak-uncached
Changes
integration/admin-client/src/main/java/org/keycloak/admin/client/resource/UserFederationProviderResource.java 1(+1 -0)
services/src/main/java/org/keycloak/services/resources/admin/UserFederationProviderResource.java 1(+1 -0)
testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/java/org/keycloak/testsuite/federation/DummyUserFederationMapper.java 140(+140 -0)
testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/resources/META-INF/services/org.keycloak.mappers.UserFederationMapperFactory 52(+52 -0)
testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/LDAPRule.java 80(+80 -0)
testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/LDAPTestConfiguration.java 35(+25 -10)
testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/UserFederationLdapConnectionTest.java 64(+64 -0)
testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/UserFederationMapperTest.java 292(+292 -0)
Details
diff --git a/integration/admin-client/src/main/java/org/keycloak/admin/client/resource/UserFederationProviderResource.java b/integration/admin-client/src/main/java/org/keycloak/admin/client/resource/UserFederationProviderResource.java
index 5e1a99f..2e4543a 100644
--- a/integration/admin-client/src/main/java/org/keycloak/admin/client/resource/UserFederationProviderResource.java
+++ b/integration/admin-client/src/main/java/org/keycloak/admin/client/resource/UserFederationProviderResource.java
@@ -64,6 +64,7 @@ public interface UserFederationProviderResource {
@GET
@Path("mapper-types")
+ @Produces(MediaType.APPLICATION_JSON)
Map<String, UserFederationMapperTypeRepresentation> getMapperTypes();
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/UserFederationProviderResource.java b/services/src/main/java/org/keycloak/services/resources/admin/UserFederationProviderResource.java
index 2a56aa0..312690c 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/UserFederationProviderResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/UserFederationProviderResource.java
@@ -185,6 +185,7 @@ public class UserFederationProviderResource {
*/
@GET
@Path("mapper-types")
+ @Produces(MediaType.APPLICATION_JSON)
@NoCache
public Map<String, UserFederationMapperTypeRepresentation> getMapperTypes() {
auth.requireView();
diff --git a/testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/java/org/keycloak/testsuite/federation/DummyUserFederationMapper.java b/testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/java/org/keycloak/testsuite/federation/DummyUserFederationMapper.java
new file mode 100644
index 0000000..214c488
--- /dev/null
+++ b/testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/java/org/keycloak/testsuite/federation/DummyUserFederationMapper.java
@@ -0,0 +1,140 @@
+/*
+ * Copyright 2016 Red Hat, Inc. and/or its affiliates
+ * and other contributors as indicated by the @author tags.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.keycloak.testsuite.federation;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+import org.keycloak.Config;
+import org.keycloak.mappers.FederationConfigValidationException;
+import org.keycloak.mappers.UserFederationMapper;
+import org.keycloak.mappers.UserFederationMapperFactory;
+import org.keycloak.models.GroupModel;
+import org.keycloak.models.KeycloakSession;
+import org.keycloak.models.KeycloakSessionFactory;
+import org.keycloak.models.RealmModel;
+import org.keycloak.models.UserFederationMapperModel;
+import org.keycloak.models.UserFederationProvider;
+import org.keycloak.models.UserFederationProviderModel;
+import org.keycloak.models.UserFederationSyncResult;
+import org.keycloak.models.UserModel;
+import org.keycloak.provider.ProviderConfigProperty;
+import org.keycloak.representations.idm.UserFederationMapperSyncConfigRepresentation;
+
+/**
+ * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
+ */
+public class DummyUserFederationMapper implements UserFederationMapperFactory, UserFederationMapper {
+
+ public static final String PROVIDER_NAME = "dummy-mapper";
+
+ @Override
+ public String getFederationProviderType() {
+ return DummyUserFederationProviderFactory.PROVIDER_NAME;
+ }
+
+ @Override
+ public String getDisplayCategory() {
+ return "Dummy";
+ }
+
+ @Override
+ public String getDisplayType() {
+ return "Dummy";
+ }
+
+ @Override
+ public UserFederationMapperSyncConfigRepresentation getSyncConfig() {
+ return new UserFederationMapperSyncConfigRepresentation(true, "dummyFedToKeycloak", true, "dummyKeycloakToFed");
+ }
+
+ @Override
+ public void validateConfig(RealmModel realm, UserFederationProviderModel fedProviderModel, UserFederationMapperModel mapperModel) throws FederationConfigValidationException {
+
+ }
+
+ @Override
+ public Map<String, String> getDefaultConfig(UserFederationProviderModel providerModel) {
+ return Collections.emptyMap();
+ }
+
+ @Override
+ public String getHelpText() {
+ return "Dummy";
+ }
+
+ @Override
+ public List<ProviderConfigProperty> getConfigProperties() {
+ return Collections.emptyList();
+ }
+
+ @Override
+ public UserFederationMapper create(KeycloakSession session) {
+ return this;
+ }
+
+ @Override
+ public void init(Config.Scope config) {
+
+ }
+
+ @Override
+ public void postInit(KeycloakSessionFactory factory) {
+
+ }
+
+ @Override
+ public void close() {
+
+ }
+
+ @Override
+ public String getId() {
+ return PROVIDER_NAME;
+ }
+
+ @Override
+ public UserFederationSyncResult syncDataFromFederationProviderToKeycloak(final UserFederationMapperModel mapperModel, UserFederationProvider federationProvider, KeycloakSession session, RealmModel realm) {
+ return new UserFederationSyncResult() {
+
+ @Override
+ public String getStatus() {
+ return "dummyFedToKeycloakSuccess mapper=" + mapperModel.getName();
+ }
+
+ };
+ }
+
+ @Override
+ public UserFederationSyncResult syncDataFromKeycloakToFederationProvider(final UserFederationMapperModel mapperModel, UserFederationProvider federationProvider, KeycloakSession session, RealmModel realm) {
+ return new UserFederationSyncResult() {
+
+ @Override
+ public String getStatus() {
+ return "dummyKeycloakToFedSuccess mapper=" + mapperModel.getName();
+ }
+
+ };
+ }
+
+ @Override
+ public List<UserModel> getGroupMembers(UserFederationMapperModel mapperModel, UserFederationProvider federationProvider, RealmModel realm, GroupModel group, int firstResult, int maxResults) {
+ return Collections.emptyList();
+ }
+}
diff --git a/testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/resources/META-INF/services/org.keycloak.mappers.UserFederationMapperFactory b/testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/resources/META-INF/services/org.keycloak.mappers.UserFederationMapperFactory
new file mode 100644
index 0000000..2bc7ca8
--- /dev/null
+++ b/testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/resources/META-INF/services/org.keycloak.mappers.UserFederationMapperFactory
@@ -0,0 +1,52 @@
+#
+# Copyright 2016 Red Hat, Inc. and/or its affiliates
+# and other contributors as indicated by the @author tags.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+#
+# Copyright 2016 Red Hat, Inc. and/or its affiliates
+# and other contributors as indicated by the @author tags.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+#
+# Copyright 2016 Red Hat, Inc. and/or its affiliates
+# and other contributors as indicated by the @author tags.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+org.keycloak.testsuite.federation.DummyUserFederationMapper
\ No newline at end of file
diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/LDAPRule.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/LDAPRule.java
new file mode 100644
index 0000000..5cebe8c
--- /dev/null
+++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/LDAPRule.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright 2016 Red Hat, Inc. and/or its affiliates
+ * and other contributors as indicated by the @author tags.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.keycloak.testsuite.util;
+
+import java.util.Map;
+import java.util.Properties;
+
+import org.junit.rules.ExternalResource;
+import org.keycloak.util.ldap.LDAPEmbeddedServer;
+
+/**
+ * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
+ */
+public class LDAPRule extends ExternalResource {
+
+ public static final String LDAP_CONNECTION_PROPERTIES_LOCATION = "classpath:ldap/ldap-connection.properties";
+
+ protected LDAPTestConfiguration ldapTestConfiguration;
+ protected LDAPEmbeddedServer ldapEmbeddedServer;
+
+ @Override
+ protected void before() throws Throwable {
+ String connectionPropsLocation = getConnectionPropertiesLocation();
+ ldapTestConfiguration = LDAPTestConfiguration.readConfiguration(connectionPropsLocation);
+
+ if (ldapTestConfiguration.isStartEmbeddedLdapServer()) {
+ ldapEmbeddedServer = createServer();
+ ldapEmbeddedServer.init();
+ ldapEmbeddedServer.start();
+ }
+ }
+
+ @Override
+ protected void after() {
+ try {
+ if (ldapEmbeddedServer != null) {
+ ldapEmbeddedServer.stop();
+ ldapEmbeddedServer = null;
+ ldapTestConfiguration = null;
+ }
+ } catch (Exception e) {
+ throw new RuntimeException("Error tearDown Embedded LDAP server.", e);
+ }
+ }
+
+ protected String getConnectionPropertiesLocation() {
+ return LDAP_CONNECTION_PROPERTIES_LOCATION;
+ }
+
+ protected LDAPEmbeddedServer createServer() {
+ Properties defaultProperties = new Properties();
+ defaultProperties.setProperty(LDAPEmbeddedServer.PROPERTY_DSF, LDAPEmbeddedServer.DSF_INMEMORY);
+ defaultProperties.setProperty(LDAPEmbeddedServer.PROPERTY_LDIF_FILE, "classpath:ldap/users.ldif");
+
+ return new LDAPEmbeddedServer(defaultProperties);
+ }
+
+ public Map<String, String> getConfig() {
+ return ldapTestConfiguration.getLDAPConfig();
+ }
+
+ public int getSleepTime() {
+ return ldapTestConfiguration.getSleepTime();
+ }
+}
diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/LDAPTestConfiguration.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/LDAPTestConfiguration.java
index f4a5d50..5540c39 100644
--- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/LDAPTestConfiguration.java
+++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/LDAPTestConfiguration.java
@@ -20,13 +20,19 @@ package org.keycloak.testsuite.util;
import static org.keycloak.testsuite.util.IOUtil.PROJECT_BUILD_DIRECTORY;
import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
import java.io.InputStream;
+import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import org.apache.commons.configuration.PropertiesConfiguration;
import org.jboss.logging.Logger;
+import org.keycloak.common.constants.GenericConstants;
import org.keycloak.common.constants.KerberosConstants;
+import org.keycloak.common.util.FindFile;
import org.keycloak.models.LDAPConstants;
import org.keycloak.models.UserFederationProvider;
@@ -37,7 +43,6 @@ public class LDAPTestConfiguration {
private static final Logger log = Logger.getLogger(LDAPTestConfiguration.class);
- private String connectionPropertiesLocation;
private int sleepTime;
private boolean startEmbeddedLdapServer = true;
private Map<String, String> config;
@@ -95,8 +100,7 @@ public class LDAPTestConfiguration {
public static LDAPTestConfiguration readConfiguration(String connectionPropertiesLocation) {
LDAPTestConfiguration ldapTestConfiguration = new LDAPTestConfiguration();
- ldapTestConfiguration.setConnectionPropertiesLocation(getResource(connectionPropertiesLocation));
- ldapTestConfiguration.loadConnectionProperties();
+ ldapTestConfiguration.loadConnectionProperties(connectionPropertiesLocation);
return ldapTestConfiguration;
}
@@ -104,13 +108,28 @@ public class LDAPTestConfiguration {
return new File(PROJECT_BUILD_DIRECTORY, "dependency/kerberos/" + resourceName).getAbsolutePath();
}
- protected void loadConnectionProperties() {
+ protected void loadConnectionProperties(String connectionPropertiesLocation) {
+ // TODO: Improve and possibly use FindFile
+ InputStream is;
+ try {
+ if (connectionPropertiesLocation.startsWith(GenericConstants.PROTOCOL_CLASSPATH)) {
+ String classPathLocation = connectionPropertiesLocation.replace(GenericConstants.PROTOCOL_CLASSPATH, "");
+ log.info("Reading LDAP configuration from classpath from: " + classPathLocation);
+ is = LDAPTestConfiguration.class.getClassLoader().getResourceAsStream(classPathLocation);
+ } else {
+ String file = getResource(connectionPropertiesLocation);
+ log.info("Reading LDAP configuration from: " + connectionPropertiesLocation);
+ is = new FileInputStream(file);
+ }
+ } catch (IOException ioe) {
+ throw new RuntimeException(ioe);
+ }
+
PropertiesConfiguration p;
try {
- log.info("Reading LDAP configuration from: " + connectionPropertiesLocation);
p = new PropertiesConfiguration();
p.setDelimiterParsingDisabled(true);
- p.load(connectionPropertiesLocation);
+ p.load(is);
}
catch (Exception e) {
throw new RuntimeException(e);
@@ -139,10 +158,6 @@ public class LDAPTestConfiguration {
return config;
}
- public void setConnectionPropertiesLocation(String connectionPropertiesLocation) {
- this.connectionPropertiesLocation = connectionPropertiesLocation;
- }
-
public boolean isStartEmbeddedLdapServer() {
return startEmbeddedLdapServer;
}
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/UserFederationLdapConnectionTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/UserFederationLdapConnectionTest.java
new file mode 100644
index 0000000..041d58c
--- /dev/null
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/UserFederationLdapConnectionTest.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2016 Red Hat, Inc. and/or its affiliates
+ * and other contributors as indicated by the @author tags.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.keycloak.testsuite.admin;
+
+import javax.ws.rs.core.Response;
+
+import org.junit.ClassRule;
+import org.junit.Test;
+import org.keycloak.services.managers.LDAPConnectionTestManager;
+import org.keycloak.testsuite.Assert;
+import org.keycloak.testsuite.util.LDAPRule;
+
+/**
+ * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
+ */
+public class UserFederationLdapConnectionTest extends AbstractAdminTest {
+
+ @ClassRule
+ public static LDAPRule ldapRule = new LDAPRule();
+
+ @Test
+ public void testLdapConnections1() {
+ // Unknown action
+ Response response = realm.testLDAPConnection("unknown", "ldap://localhost:10389", "foo", "bar", "false");
+ assertStatus(response, 400);
+
+ // Bad host
+ response = realm.testLDAPConnection(LDAPConnectionTestManager.TEST_CONNECTION, "ldap://localhostt:10389", "foo", "bar", "false");
+ assertStatus(response, 400);
+
+ // Connection success
+ response = realm.testLDAPConnection(LDAPConnectionTestManager.TEST_CONNECTION, "ldap://localhost:10389", "foo", "bar", "false");
+ assertStatus(response, 204);
+
+ // Bad authentication
+ response = realm.testLDAPConnection(LDAPConnectionTestManager.TEST_AUTHENTICATION, "ldap://localhost:10389", "foo", "bar", "false");
+ assertStatus(response, 400);
+
+ // Authentication success
+ response = realm.testLDAPConnection(LDAPConnectionTestManager.TEST_AUTHENTICATION, "ldap://localhost:10389", "uid=admin,ou=system", "secret", "false");
+ assertStatus(response, 204);
+
+ }
+
+ private void assertStatus(Response response, int status) {
+ Assert.assertEquals(status, response.getStatus());
+ response.close();
+ }
+}
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/UserFederationMapperTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/UserFederationMapperTest.java
new file mode 100644
index 0000000..72989a5
--- /dev/null
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/UserFederationMapperTest.java
@@ -0,0 +1,292 @@
+/*
+ * Copyright 2016 Red Hat, Inc. and/or its affiliates
+ * and other contributors as indicated by the @author tags.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.keycloak.testsuite.admin;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.ws.rs.BadRequestException;
+import javax.ws.rs.NotFoundException;
+import javax.ws.rs.core.Response;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.keycloak.admin.client.resource.UserFederationProviderResource;
+import org.keycloak.federation.ldap.mappers.UserAttributeLDAPFederationMapper;
+import org.keycloak.federation.ldap.mappers.UserAttributeLDAPFederationMapperFactory;
+import org.keycloak.federation.ldap.mappers.membership.role.RoleLDAPFederationMapperFactory;
+import org.keycloak.federation.ldap.mappers.membership.role.RoleMapperConfig;
+import org.keycloak.representations.idm.ConfigPropertyRepresentation;
+import org.keycloak.representations.idm.UserFederationMapperRepresentation;
+import org.keycloak.representations.idm.UserFederationMapperTypeRepresentation;
+import org.keycloak.representations.idm.UserFederationProviderRepresentation;
+import org.keycloak.representations.idm.UserFederationSyncResultRepresentation;
+import org.keycloak.testsuite.Assert;
+import org.keycloak.testsuite.federation.DummyUserFederationMapper;
+import org.keycloak.testsuite.util.UserFederationProviderBuilder;
+
+/**
+ * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
+ */
+public class UserFederationMapperTest extends AbstractAdminTest {
+
+ private String ldapProviderId;
+ private String dummyProviderId;
+
+ @Before
+ public void initFederationProviders() {
+ UserFederationProviderRepresentation ldapRep = UserFederationProviderBuilder.create()
+ .displayName("ldap-1")
+ .providerName("ldap")
+ .priority(1)
+ .build();
+ Response resp = realm.userFederation().create(ldapRep);
+ this.ldapProviderId = ApiUtil.getCreatedId(resp);
+ resp.close();
+
+ UserFederationProviderRepresentation dummyRep = UserFederationProviderBuilder.create()
+ .displayName("dummy-1")
+ .providerName("dummy")
+ .priority(2)
+ .build();
+ resp = realm.userFederation().create(dummyRep);
+ this.dummyProviderId = ApiUtil.getCreatedId(resp);
+ resp.close();
+ }
+
+ @After
+ public void cleanFederationProviders() {
+ realm.userFederation().get(ldapProviderId).remove();
+ realm.userFederation().get(dummyProviderId).remove();
+ }
+
+
+ @Test
+ public void testProviderFactories() {
+ // Test dummy mapper
+ Map<String, UserFederationMapperTypeRepresentation> mapperTypes = realm.userFederation().get(dummyProviderId).getMapperTypes();
+ Assert.assertEquals(1, mapperTypes.size());
+ Assert.assertEquals("Dummy", mapperTypes.get("dummy-mapper").getName());
+
+
+ // Test LDAP mappers
+ mapperTypes = ldapProviderResource().getMapperTypes();
+ Assert.assertTrue(mapperTypes.keySet().containsAll(Arrays.asList("user-attribute-ldap-mapper", "full-name-ldap-mapper", "role-ldap-mapper")));
+
+ UserFederationMapperTypeRepresentation attrMapper = mapperTypes.get("user-attribute-ldap-mapper");
+ Assert.assertEquals("User Attribute", attrMapper.getName());
+ Assert.assertFalse(attrMapper.getSyncConfig().isFedToKeycloakSyncSupported());
+ Assert.assertFalse(attrMapper.getSyncConfig().isKeycloakToFedSyncSupported());
+ Set<String> propNames = getConfigPropertyNames(attrMapper);
+ Assert.assertTrue(propNames.containsAll(Arrays.asList("user.model.attribute", "ldap.attribute", "read.only")));
+ Assert.assertEquals("false", attrMapper.getDefaultConfig().get("always.read.value.from.ldap"));
+
+ UserFederationMapperTypeRepresentation roleMapper = mapperTypes.get("role-ldap-mapper");
+ Assert.assertEquals("Role mappings", roleMapper.getName());
+ Assert.assertTrue(roleMapper.getSyncConfig().isFedToKeycloakSyncSupported());
+ Assert.assertTrue(roleMapper.getSyncConfig().isKeycloakToFedSyncSupported());
+ Assert.assertEquals("sync-ldap-roles-to-keycloak", roleMapper.getSyncConfig().getFedToKeycloakSyncMessage());
+ Assert.assertEquals("sync-keycloak-roles-to-ldap", roleMapper.getSyncConfig().getKeycloakToFedSyncMessage());
+ propNames = getConfigPropertyNames(roleMapper);
+ Assert.assertTrue(propNames.containsAll(Arrays.asList("roles.dn", "role.name.ldap.attribute", "role.object.classes")));
+ Assert.assertEquals("cn", roleMapper.getDefaultConfig().get("role.name.ldap.attribute"));
+ }
+
+ private Set<String> getConfigPropertyNames(UserFederationMapperTypeRepresentation mapper) {
+ List<ConfigPropertyRepresentation> cfg = mapper.getProperties();
+ Set<String> result = new HashSet<>();
+ for (ConfigPropertyRepresentation rep : cfg) {
+ result.add(rep.getName());
+ }
+ return result;
+
+ }
+
+
+ @Test
+ public void testUserAttributeMapperCRUD() {
+ // Test create fails with invalid config
+ UserFederationMapperRepresentation attrMapper = createMapperRep("email-mapper", UserAttributeLDAPFederationMapperFactory.PROVIDER_ID);
+ Response response = ldapProviderResource().addMapper(attrMapper);
+ Assert.assertEquals(400, response.getStatus());
+ response.close();
+
+ attrMapper.getConfig().put(UserAttributeLDAPFederationMapper.USER_MODEL_ATTRIBUTE, "email");
+ response = ldapProviderResource().addMapper(attrMapper);
+ Assert.assertEquals(400, response.getStatus());
+ response.close();
+
+ // Test create success when all mandatory attributes available
+ attrMapper.getConfig().put(UserAttributeLDAPFederationMapper.LDAP_ATTRIBUTE, "mail");
+ String mapperId = createMapper(attrMapper);
+
+ // Test get
+ UserFederationMapperRepresentation mapperRep = ldapProviderResource().getMapperById(mapperId);
+ assertMapper(mapperRep, mapperId, "email-mapper", UserAttributeLDAPFederationMapperFactory.PROVIDER_ID, UserAttributeLDAPFederationMapper.USER_MODEL_ATTRIBUTE, "email", UserAttributeLDAPFederationMapper.LDAP_ATTRIBUTE, "mail");
+
+ // Test update fails with invalid config
+ mapperRep.getConfig().put(UserAttributeLDAPFederationMapper.LDAP_ATTRIBUTE, "mail-updated");
+ mapperRep.getConfig().remove(UserAttributeLDAPFederationMapper.USER_MODEL_ATTRIBUTE);
+ try {
+ ldapProviderResource().updateMapper(mapperId, mapperRep);
+ Assert.fail("Not expected update to success");
+ } catch (BadRequestException bre) {
+ // Expected
+ }
+
+ // Test not updated
+ mapperRep = ldapProviderResource().getMapperById(mapperId);
+ assertMapper(mapperRep, mapperId, "email-mapper", UserAttributeLDAPFederationMapperFactory.PROVIDER_ID, UserAttributeLDAPFederationMapper.USER_MODEL_ATTRIBUTE, "email", UserAttributeLDAPFederationMapper.LDAP_ATTRIBUTE, "mail");
+
+ // Test update success
+ mapperRep.getConfig().put(UserAttributeLDAPFederationMapper.USER_MODEL_ATTRIBUTE, "email-updated");
+ mapperRep.getConfig().put(UserAttributeLDAPFederationMapper.LDAP_ATTRIBUTE, "mail-updated");
+ ldapProviderResource().updateMapper(mapperId, mapperRep);
+
+ mapperRep = ldapProviderResource().getMapperById(mapperId);
+ assertMapper(mapperRep, mapperId, "email-mapper", UserAttributeLDAPFederationMapperFactory.PROVIDER_ID, UserAttributeLDAPFederationMapper.USER_MODEL_ATTRIBUTE, "email-updated", UserAttributeLDAPFederationMapper.LDAP_ATTRIBUTE, "mail-updated");
+
+ // Test removed successfully
+ ldapProviderResource().removeMapper(mapperId);
+ try {
+ ldapProviderResource().getMapperById(mapperId);
+ Assert.fail("Not expected find to success as mapper was removed");
+ } catch (NotFoundException nfe) {
+ // Expected
+ }
+ }
+
+ private String createMapper(UserFederationMapperRepresentation mapper) {
+ Response response = ldapProviderResource().addMapper(mapper);
+ Assert.assertEquals(201, response.getStatus());
+ response.close();
+ return ApiUtil.getCreatedId(response);
+ }
+
+
+ @Test
+ public void testRoleMapper() {
+ // Create role mapper will fail
+ UserFederationMapperRepresentation roleMapper = createMapperRep("role-mapper", RoleLDAPFederationMapperFactory.PROVIDER_ID,
+ RoleMapperConfig.ROLES_DN, "ou=roles,dc=keycloak,dc=org",
+ RoleMapperConfig.MODE, "READ_ONLY");
+ Response response = ldapProviderResource().addMapper(roleMapper);
+ Assert.assertEquals(400, response.getStatus());
+ response.close();
+
+ // Fix config and create successfully
+ roleMapper.getConfig().put(RoleMapperConfig.USE_REALM_ROLES_MAPPING, "true");
+ String roleMapperId = createMapper(roleMapper);
+
+ // Assert builtin mappers
+ List<UserFederationMapperRepresentation> mappers = ldapProviderResource().getMappers();
+ Assert.assertNotNull(findMapperByName(mappers, "email"));
+ Assert.assertNotNull(findMapperByName(mappers, "first name"));
+ Assert.assertNull(findMapperByName(mappers, "non-existent"));
+
+ roleMapper = findMapperByName(mappers, "role-mapper");
+ assertMapper(roleMapper, roleMapperId, "role-mapper", RoleLDAPFederationMapperFactory.PROVIDER_ID,
+ RoleMapperConfig.ROLES_DN, "ou=roles,dc=keycloak,dc=org",
+ RoleMapperConfig.MODE, "READ_ONLY",
+ RoleMapperConfig.USE_REALM_ROLES_MAPPING, "true");
+
+
+ // Remove role mapper and assert not found anymore
+ ldapProviderResource().removeMapper(roleMapperId);
+ mappers = ldapProviderResource().getMappers();
+ Assert.assertNull(findMapperByName(mappers, "role-mapper"));
+ }
+
+
+ @Test
+ public void testSyncMapper() {
+ // Create dummy mapper
+ UserFederationMapperRepresentation dummyMapperRep = new UserFederationMapperRepresentation();
+ dummyMapperRep.setName("some-dummy");
+ dummyMapperRep.setFederationMapperType(DummyUserFederationMapper.PROVIDER_NAME);
+ dummyMapperRep.setFederationProviderDisplayName("dummy-1");
+ String mapperId = createMapper(dummyMapperRep);
+
+ // Try to sync with unknown action - fail
+ try {
+ realm.userFederation().get(dummyProviderId).syncMapperData(mapperId, "unknown");
+ Assert.fail("Not expected to pass");
+ } catch (NotFoundException nfe) {
+ // Expected
+ }
+
+ // Try fed To Keycloak sync
+ UserFederationSyncResultRepresentation result = realm.userFederation().get(dummyProviderId).syncMapperData(mapperId, "fedToKeycloak");
+ Assert.assertEquals("dummyFedToKeycloakSuccess mapper=some-dummy", result.getStatus());
+
+ // Try keycloak to fed
+ result = realm.userFederation().get(dummyProviderId).syncMapperData(mapperId, "keycloakToFed");
+ Assert.assertEquals("dummyKeycloakToFedSuccess mapper=some-dummy", result.getStatus());
+
+ }
+
+
+ private UserFederationProviderResource ldapProviderResource() {
+ return realm.userFederation().get(ldapProviderId);
+ }
+
+ private UserFederationMapperRepresentation createMapperRep(String name, String type, String... config) {
+ UserFederationMapperRepresentation rep = new UserFederationMapperRepresentation();
+ rep.setName(name);
+ rep.setFederationMapperType(type);
+ rep.setFederationProviderDisplayName("ldap-1");
+
+ Map<String, String> cfg = new HashMap<>();
+ for (int i=0 ; i<config.length ; i+=2) {
+ cfg.put(config[i], config[i+1]);
+ }
+ rep.setConfig(cfg);
+ return rep;
+ }
+
+ private void assertMapper(UserFederationMapperRepresentation rep, String id, String name, String federationMapperType, String... config) {
+ Assert.assertEquals(id, rep.getId());
+ Assert.assertEquals(name, rep.getName());
+ Assert.assertEquals("ldap-1", rep.getFederationProviderDisplayName());
+ Assert.assertEquals(federationMapperType, rep.getFederationMapperType());
+
+ if (config == null) {
+ config = new String[] {};
+ }
+ Assert.assertEquals(rep.getConfig().size() * 2, config.length);
+ for (int i=0 ; i<config.length ; i+=2) {
+ String key = config[i];
+ String value = config[i+1];
+ Assert.assertEquals(value, rep.getConfig().get(key));
+ }
+ }
+
+ private UserFederationMapperRepresentation findMapperByName(List<UserFederationMapperRepresentation> mappers, String name) {
+ for (UserFederationMapperRepresentation rep : mappers) {
+ if (rep.getName().equals(name)) {
+ return rep;
+ }
+ }
+ return null;
+ }
+}
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/UserFederationTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/UserFederationTest.java
index 0cd3508..7e702a0 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/UserFederationTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/UserFederationTest.java
@@ -22,7 +22,6 @@ import java.util.List;
import javax.ws.rs.BadRequestException;
import javax.ws.rs.NotFoundException;
-import javax.ws.rs.core.GenericType;
import javax.ws.rs.core.Response;
import org.junit.Test;
@@ -73,7 +72,7 @@ public class UserFederationTest extends AbstractAdminTest {
userFederation().getProviderFactory("not-existent");
Assert.fail("Not expected to find not-existent provider");
} catch (NotFoundException nfe) {
- nfe.getResponse().close();
+ // Expected
}
}
@@ -205,7 +204,7 @@ public class UserFederationTest extends AbstractAdminTest {
userFederation().get(id).update(ldapRep);
Assert.fail("Not expected to successfull update");
} catch (BadRequestException bre) {
- bre.getResponse().close();
+ // Expected
}
// Assert nothing was updated
@@ -291,7 +290,7 @@ public class UserFederationTest extends AbstractAdminTest {
userFederation().get(id1).syncUsers("unknown");
Assert.fail("Not expected to sync with unknown action");
} catch (NotFoundException nfe) {
- nfe.getResponse().close();
+ // Expected
}
// Assert sync didn't happen
diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/ldap/ldap-connection.properties b/testsuite/integration-arquillian/tests/base/src/test/resources/ldap/ldap-connection.properties
new file mode 100644
index 0000000..610312c
--- /dev/null
+++ b/testsuite/integration-arquillian/tests/base/src/test/resources/ldap/ldap-connection.properties
@@ -0,0 +1,26 @@
+#
+# Copyright 2016 Red Hat, Inc. and/or its affiliates
+# and other contributors as indicated by the @author tags.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+idm.test.ldap.connection.url=ldap\://localhost\:10389
+idm.test.ldap.base.dn=dc\=keycloak,dc\=org
+idm.test.ldap.user.dn.suffix=ou\=People,dc\=keycloak,dc\=org
+idm.test.ldap.start.embedded.ldap.server=true
+idm.test.ldap.bind.dn=uid\=admin,ou\=system
+idm.test.ldap.bind.credential=secret
+idm.test.ldap.connection.pooling=true
+idm.test.ldap.pagination=true
+idm.test.ldap.batch.size.for.sync=3
\ No newline at end of file