fix tests
This commit is contained in:
parent
4ce055cede
commit
c280634bfa
26 changed files with 125 additions and 3564 deletions
4
dependencies/server-all/pom.xml
vendored
4
dependencies/server-all/pom.xml
vendored
|
@ -67,10 +67,6 @@
|
|||
<groupId>org.keycloak</groupId>
|
||||
<artifactId>keycloak-ldap-federation</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<artifactId>keycloak-ldap-storage</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<artifactId>keycloak-kerberos-federation</artifactId>
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
</properties>
|
||||
|
||||
<resources>
|
||||
<artifact name="${org.keycloak:keycloak-ldap-storage}"/>
|
||||
<artifact name="${org.keycloak:keycloak-ldap-federation}"/>
|
||||
</resources>
|
||||
|
||||
<dependencies>
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>keycloak-ldap-storage</artifactId>
|
||||
<artifactId>keycloak-ldap-federation</artifactId>
|
||||
<name>Keycloak LDAP UserStoreProvider</name>
|
||||
<description />
|
||||
|
||||
|
|
|
@ -34,7 +34,6 @@
|
|||
|
||||
<modules>
|
||||
<module>kerberos</module>
|
||||
<module>ldap</module>
|
||||
<module>ldap2</module>
|
||||
<module>sssd</module>
|
||||
</modules>
|
||||
|
|
|
@ -501,8 +501,7 @@ public class UserCacheSession implements UserCache {
|
|||
@Override
|
||||
public UserModel getServiceAccount(ClientModel client) {
|
||||
// Just an attempt to find the user from cache by default serviceAccount username
|
||||
String username = ServiceAccountConstants.SERVICE_ACCOUNT_USER_PREFIX + client.getClientId();
|
||||
UserModel user = getUserByUsername(username, client.getRealm());
|
||||
UserModel user = findServiceAccount(client);
|
||||
if (user != null && user.getServiceAccountClientLink() != null && user.getServiceAccountClientLink().equals(client.getId())) {
|
||||
return user;
|
||||
}
|
||||
|
@ -510,6 +509,60 @@ public class UserCacheSession implements UserCache {
|
|||
return getDelegate().getServiceAccount(client);
|
||||
}
|
||||
|
||||
public UserModel findServiceAccount(ClientModel client) {
|
||||
String username = ServiceAccountConstants.SERVICE_ACCOUNT_USER_PREFIX + client.getClientId();
|
||||
logger.tracev("getServiceAccount: {0}", username);
|
||||
username = username.toLowerCase();
|
||||
RealmModel realm = client.getRealm();
|
||||
if (realmInvalidations.contains(realm.getId())) {
|
||||
logger.tracev("realmInvalidations");
|
||||
return getDelegate().getServiceAccount(client);
|
||||
}
|
||||
String cacheKey = getUserByUsernameCacheKey(realm.getId(), username);
|
||||
if (invalidations.contains(cacheKey)) {
|
||||
logger.tracev("invalidations");
|
||||
return getDelegate().getServiceAccount(client);
|
||||
}
|
||||
UserListQuery query = cache.get(cacheKey, UserListQuery.class);
|
||||
|
||||
String userId = null;
|
||||
if (query == null) {
|
||||
logger.tracev("query null");
|
||||
Long loaded = cache.getCurrentRevision(cacheKey);
|
||||
UserModel model = getDelegate().getServiceAccount(client);
|
||||
if (model == null) {
|
||||
logger.tracev("model from delegate null");
|
||||
return null;
|
||||
}
|
||||
userId = model.getId();
|
||||
if (invalidations.contains(userId)) return model;
|
||||
if (managedUsers.containsKey(userId)) {
|
||||
logger.tracev("return managed user");
|
||||
return managedUsers.get(userId);
|
||||
}
|
||||
|
||||
UserModel adapter = getUserAdapter(realm, userId, loaded, model);
|
||||
if (adapter instanceof UserAdapter) { // this was cached, so we can cache query too
|
||||
query = new UserListQuery(loaded, cacheKey, realm, model.getId());
|
||||
cache.addRevisioned(query, startupRevision);
|
||||
}
|
||||
managedUsers.put(userId, adapter);
|
||||
return adapter;
|
||||
} else {
|
||||
userId = query.getUsers().iterator().next();
|
||||
if (invalidations.contains(userId)) {
|
||||
logger.tracev("invalidated cache return delegate");
|
||||
return getDelegate().getUserByUsername(username, realm);
|
||||
|
||||
}
|
||||
logger.trace("return getUserById");
|
||||
return getUserById(userId, realm);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public List<UserModel> getUsers(RealmModel realm, boolean includeServiceAccounts) {
|
||||
return getDelegate().getUsers(realm, includeServiceAccounts);
|
||||
|
|
5
pom.xml
5
pom.xml
|
@ -711,11 +711,6 @@
|
|||
<artifactId>keycloak-ldap-federation</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<artifactId>keycloak-ldap-storage</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<artifactId>keycloak-dependencies-server-min</artifactId>
|
||||
|
|
|
@ -65,7 +65,7 @@
|
|||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<artifactId>keycloak-ldap-storage</artifactId>
|
||||
<artifactId>keycloak-ldap-federation</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
|
|
|
@ -92,11 +92,13 @@ public class DefaultKeycloakTransactionManager implements KeycloakTransactionMan
|
|||
|
||||
if (jtaPolicy == JTAPolicy.REQUIRES_NEW) {
|
||||
JtaTransactionManagerLookup jtaLookup = session.getProvider(JtaTransactionManagerLookup.class);
|
||||
if (jtaLookup != null) {
|
||||
TransactionManager tm = jtaLookup.getTransactionManager();
|
||||
if (tm != null) {
|
||||
enlist(new JtaTransactionWrapper(tm));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (KeycloakTransaction tx : transactions) {
|
||||
tx.begin();
|
||||
|
|
|
@ -1,129 +0,0 @@
|
|||
/*
|
||||
* 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.adapter.federation;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.keycloak.events.Details;
|
||||
import org.keycloak.federation.kerberos.CommonKerberosConfig;
|
||||
import org.keycloak.federation.ldap.LDAPFederationProviderFactory;
|
||||
import org.keycloak.federation.ldap.kerberos.LDAPProviderKerberosConfig;
|
||||
import org.keycloak.models.UserFederationProvider;
|
||||
import org.keycloak.models.UserFederationProviderModel;
|
||||
import org.keycloak.representations.idm.RealmRepresentation;
|
||||
import org.keycloak.representations.idm.UserFederationProviderRepresentation;
|
||||
import org.keycloak.representations.idm.UserRepresentation;
|
||||
import org.keycloak.testsuite.admin.ApiUtil;
|
||||
|
||||
import javax.ws.rs.core.Response;
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Test of LDAPFederationProvider (Kerberos backed by LDAP)
|
||||
*
|
||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||
*/
|
||||
public abstract class AbstractKerberosLdapAdapterTest extends AbstractKerberosAdapterTest {
|
||||
|
||||
private static final String PROVIDER_CONFIG_LOCATION = "kerberos-ldap-connection.properties";
|
||||
|
||||
@Before
|
||||
public void init() throws Exception{
|
||||
Map<String,String> ldapConfig = getConfig();
|
||||
UserFederationProviderRepresentation userFederationProviderRepresentation = new UserFederationProviderRepresentation();
|
||||
userFederationProviderRepresentation.setProviderName(LDAPFederationProviderFactory.PROVIDER_NAME);
|
||||
userFederationProviderRepresentation.setConfig(ldapConfig);
|
||||
userFederationProviderRepresentation.setPriority(0);
|
||||
userFederationProviderRepresentation.setDisplayName("kerberos-ldap");
|
||||
userFederationProviderRepresentation.setFullSyncPeriod(-1);
|
||||
userFederationProviderRepresentation.setChangedSyncPeriod(-1);
|
||||
userFederationProviderRepresentation.setLastSync(0);
|
||||
RealmRepresentation realmRepresentation = testRealmResource().toRepresentation();
|
||||
realmRepresentation.setUserFederationProviders(Arrays.asList(userFederationProviderRepresentation));
|
||||
realmRepresentation.setEventsEnabled(true);
|
||||
testRealmResource().update(realmRepresentation);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected CommonKerberosConfig getKerberosConfig(UserFederationProviderModel model) {
|
||||
return new LDAPProviderKerberosConfig(model);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void spnegoLoginTest() throws Exception {
|
||||
spnegoLoginTestImpl();
|
||||
// Assert user was imported and hasn't any required action on him. Profile info is synced from LDAP
|
||||
assertUser("hnelson", "hnelson@keycloak.org", "Horatio", "Nelson", false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void writableEditModeTest() throws Exception {
|
||||
|
||||
// Change editMode to WRITABLE
|
||||
updateProviderEditMode(UserFederationProvider.EditMode.WRITABLE);
|
||||
|
||||
// Login with username/password from kerberos
|
||||
changePasswordPage.navigateTo();
|
||||
loginPage.isCurrent();
|
||||
loginPage.form().login("jduke", "theduke");
|
||||
changePasswordPage.isCurrent();
|
||||
|
||||
// Successfully change password now
|
||||
changePasswordPage.changePasswords("theduke", "newPass", "newPass");
|
||||
Assert.assertTrue(driver.getPageSource().contains("Your password has been updated."));
|
||||
changePasswordPage.logOut();
|
||||
|
||||
// Login with old password doesn't work, but with new password works
|
||||
loginPage.form().login("jduke", "theduke");
|
||||
loginPage.isCurrent();
|
||||
loginPage.form().login("jduke", "newPass");
|
||||
changePasswordPage.isCurrent();
|
||||
changePasswordPage.logOut();
|
||||
|
||||
// Assert SPNEGO login with the new password as mode is writable
|
||||
events.clear();
|
||||
Response spnegoResponse = spnegoLogin("jduke", "newPass");
|
||||
Assert.assertEquals(302, spnegoResponse.getStatus());
|
||||
UserRepresentation user = ApiUtil.findUserByUsername(testRealmResource(), "jduke");
|
||||
events.expectLogin()
|
||||
.client("kerberos-app")
|
||||
.user(user != null ? user.getId() : null)
|
||||
.detail(Details.REDIRECT_URI, kerberosPortal.toString())
|
||||
//.detail(Details.AUTH_METHOD, "spnego")
|
||||
.detail(Details.USERNAME, "jduke")
|
||||
.assertEvent();
|
||||
|
||||
// Change password back
|
||||
changePasswordPage.navigateTo();;
|
||||
|
||||
loginPage.form().login("jduke", "newPass");
|
||||
changePasswordPage.isCurrent();
|
||||
changePasswordPage.changePasswords("newPass", "theduke", "theduke");
|
||||
Assert.assertTrue(driver.getPageSource().contains("Your password has been updated."));
|
||||
changePasswordPage.logOut();
|
||||
|
||||
spnegoResponse.close();
|
||||
events.clear();
|
||||
}
|
||||
|
||||
protected String getConnectionPropertiesLocation() {
|
||||
return PROVIDER_CONFIG_LOCATION;
|
||||
}
|
||||
}
|
|
@ -1508,77 +1508,6 @@ public class PermissionsTest extends AbstractKeycloakTest {
|
|||
}, Resource.IDENTITY_PROVIDER, true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void userFederation() {
|
||||
invoke(new Invocation() {
|
||||
public void invoke(RealmResource realm) {
|
||||
realm.userFederation().getProviderInstances();
|
||||
}
|
||||
}, Resource.REALM, false);
|
||||
invoke(new Invocation() {
|
||||
public void invoke(RealmResource realm) {
|
||||
realm.userFederation().getProviderFactories();
|
||||
}
|
||||
}, Resource.REALM, false);
|
||||
invoke(new Invocation() {
|
||||
public void invoke(RealmResource realm) {
|
||||
realm.userFederation().getProviderFactory("nosuch");
|
||||
}
|
||||
}, Resource.REALM, false);
|
||||
invoke(new InvocationWithResponse() {
|
||||
public void invoke(RealmResource realm, AtomicReference<Response> response) {
|
||||
UserFederationProviderRepresentation rep = new UserFederationProviderRepresentation();
|
||||
rep.setProviderName("ldap");
|
||||
response.set(realm.userFederation().create(rep));
|
||||
}
|
||||
}, Resource.REALM, true);
|
||||
invoke(new Invocation() {
|
||||
public void invoke(RealmResource realm) {
|
||||
realm.userFederation().get("nosuch").toRepresentation();
|
||||
}
|
||||
}, Resource.REALM, false);
|
||||
invoke(new Invocation() {
|
||||
public void invoke(RealmResource realm) {
|
||||
realm.userFederation().get("nosuch").update(new UserFederationProviderRepresentation());
|
||||
}
|
||||
}, Resource.REALM, true);
|
||||
invoke(new Invocation() {
|
||||
public void invoke(RealmResource realm) {
|
||||
realm.userFederation().get("nosuch").remove();
|
||||
}
|
||||
}, Resource.REALM, true);
|
||||
invoke(new Invocation() {
|
||||
public void invoke(RealmResource realm) {
|
||||
realm.userFederation().get("nosuch").syncUsers("nosuch");
|
||||
}
|
||||
}, Resource.REALM, true);
|
||||
invoke(new Invocation() {
|
||||
public void invoke(RealmResource realm) {
|
||||
realm.userFederation().get("nosuch").getMapperTypes();
|
||||
}
|
||||
}, Resource.REALM, false);
|
||||
invoke(new Invocation() {
|
||||
public void invoke(RealmResource realm) {
|
||||
realm.userFederation().get("nosuch").getMappers();
|
||||
}
|
||||
}, Resource.REALM, false);
|
||||
invoke(new InvocationWithResponse() {
|
||||
public void invoke(RealmResource realm, AtomicReference<Response> response) {
|
||||
response.set(realm.userFederation().get("nosuch").addMapper(new UserFederationMapperRepresentation()));
|
||||
}
|
||||
}, Resource.REALM, true);
|
||||
invoke(new Invocation() {
|
||||
public void invoke(RealmResource realm) {
|
||||
realm.userFederation().get("nosuch").getMapperById("nosuch");
|
||||
}
|
||||
}, Resource.REALM, false);
|
||||
invoke(new Invocation() {
|
||||
public void invoke(RealmResource realm) {
|
||||
realm.userFederation().get("nosuch").syncMapperData("nosuch", "nosuch");
|
||||
}
|
||||
}, Resource.REALM, true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void components() {
|
||||
invoke(new Invocation() {
|
||||
|
|
|
@ -19,14 +19,11 @@ package org.keycloak.testsuite.admin;
|
|||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import org.keycloak.admin.client.resource.UserFederationProviderResource;
|
||||
import org.keycloak.events.admin.OperationType;
|
||||
import org.keycloak.events.admin.ResourceType;
|
||||
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;
|
||||
|
@ -50,10 +47,12 @@ import java.util.Set;
|
|||
/**
|
||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||
*/
|
||||
public class UserFederationMapperTest extends AbstractAdminTest {
|
||||
@Ignore
|
||||
public class UserStorageMapperTest extends AbstractAdminTest {
|
||||
|
||||
private String ldapProviderId;
|
||||
private String dummyProviderId;
|
||||
/*
|
||||
|
||||
@Before
|
||||
public void initFederationProviders() {
|
||||
|
@ -304,4 +303,5 @@ public class UserFederationMapperTest extends AbstractAdminTest {
|
|||
}
|
||||
return null;
|
||||
}
|
||||
*/
|
||||
}
|
|
@ -17,6 +17,7 @@
|
|||
|
||||
package org.keycloak.testsuite.admin;
|
||||
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import org.keycloak.admin.client.resource.UserFederationProvidersResource;
|
||||
import org.keycloak.common.constants.KerberosConstants;
|
||||
|
@ -45,7 +46,8 @@ import java.util.Map;
|
|||
/**
|
||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||
*/
|
||||
public class UserFederationTest extends AbstractAdminTest {
|
||||
@Ignore
|
||||
public class UserStorageRestTest extends AbstractAdminTest {
|
||||
|
||||
@Test
|
||||
public void testProviderFactories() {
|
|
@ -25,10 +25,11 @@ import org.keycloak.admin.client.resource.ClientTemplateResource;
|
|||
import org.keycloak.admin.client.resource.RealmResource;
|
||||
import org.keycloak.admin.client.resource.UserResource;
|
||||
import org.keycloak.common.constants.KerberosConstants;
|
||||
import org.keycloak.federation.ldap.mappers.FullNameLDAPFederationMapper;
|
||||
import org.keycloak.federation.ldap.mappers.FullNameLDAPFederationMapperFactory;
|
||||
import org.keycloak.component.ComponentModel;
|
||||
import org.keycloak.models.Constants;
|
||||
import org.keycloak.models.LDAPConstants;
|
||||
import org.keycloak.models.UserFederationMapperModel;
|
||||
import org.keycloak.models.UserFederationProviderModel;
|
||||
import org.keycloak.models.utils.DefaultAuthenticationFlows;
|
||||
import org.keycloak.protocol.oidc.OIDCLoginProtocol;
|
||||
import org.keycloak.protocol.oidc.mappers.OIDCAttributeMapperHelper;
|
||||
|
@ -37,6 +38,8 @@ import org.keycloak.representations.idm.AuthenticationFlowRepresentation;
|
|||
import org.keycloak.representations.idm.ClientMappingsRepresentation;
|
||||
import org.keycloak.representations.idm.ClientRepresentation;
|
||||
import org.keycloak.representations.idm.ClientTemplateRepresentation;
|
||||
import org.keycloak.representations.idm.ComponentExportRepresentation;
|
||||
import org.keycloak.representations.idm.ComponentRepresentation;
|
||||
import org.keycloak.representations.idm.FederatedIdentityRepresentation;
|
||||
import org.keycloak.representations.idm.IdentityProviderRepresentation;
|
||||
import org.keycloak.representations.idm.ProtocolMapperRepresentation;
|
||||
|
@ -49,6 +52,11 @@ import org.keycloak.representations.idm.authorization.PolicyRepresentation;
|
|||
import org.keycloak.representations.idm.authorization.ResourceRepresentation;
|
||||
import org.keycloak.representations.idm.authorization.ResourceServerRepresentation;
|
||||
import org.keycloak.representations.idm.authorization.ScopeRepresentation;
|
||||
import org.keycloak.storage.UserStorageProvider;
|
||||
import org.keycloak.storage.UserStorageProviderModel;
|
||||
import org.keycloak.storage.ldap.mappers.FullNameLDAPStorageMapper;
|
||||
import org.keycloak.storage.ldap.mappers.FullNameLDAPStorageMapperFactory;
|
||||
import org.keycloak.storage.ldap.mappers.LDAPStorageMapper;
|
||||
import org.keycloak.testsuite.admin.ApiUtil;
|
||||
import org.keycloak.testsuite.client.KeycloakTestingClient;
|
||||
import org.keycloak.testsuite.util.RealmRepUtil;
|
||||
|
@ -260,33 +268,34 @@ public class ExportImportUtil {
|
|||
Assert.assertEquals("googleId", google.getConfig().get("clientId"));
|
||||
Assert.assertEquals("googleSecret", google.getConfig().get("clientSecret"));
|
||||
|
||||
//////////////////
|
||||
// Test federation providers
|
||||
// on import should convert UserfederationProviderRepresentation to Component model
|
||||
List<UserFederationProviderRepresentation> fedProviders = realm.getUserFederationProviders();
|
||||
Assert.assertTrue(fedProviders.size() == 2);
|
||||
UserFederationProviderRepresentation ldap1 = fedProviders.get(0);
|
||||
Assert.assertEquals("MyLDAPProvider1", ldap1.getDisplayName());
|
||||
Assert.assertEquals("ldap", ldap1.getProviderName());
|
||||
Assert.assertEquals(1, ldap1.getPriority());
|
||||
Assert.assertEquals("ldap://foo", ldap1.getConfig().get(LDAPConstants.CONNECTION_URL));
|
||||
Assert.assertTrue(fedProviders == null || fedProviders.size() == 0);
|
||||
List<ComponentRepresentation> storageProviders = realmRsc.components().query(realm.getId(), UserStorageProvider.class.getName());
|
||||
Assert.assertTrue(storageProviders.size() == 2);
|
||||
ComponentRepresentation ldap1 = storageProviders.get(0);
|
||||
ComponentRepresentation ldap2 = storageProviders.get(1);
|
||||
if (!"MyLDAPProvider1".equals(ldap1.getName())) {
|
||||
ldap2 = ldap1;
|
||||
ldap1 = storageProviders.get(1);
|
||||
}
|
||||
Assert.assertEquals("MyLDAPProvider1", ldap1.getName());
|
||||
Assert.assertEquals("ldap", ldap1.getProviderId());
|
||||
Assert.assertEquals("1", ldap1.getConfig().getFirst("priority"));
|
||||
Assert.assertEquals("ldap://foo", ldap1.getConfig().getFirst(LDAPConstants.CONNECTION_URL));
|
||||
|
||||
UserFederationProviderRepresentation ldap2 = fedProviders.get(1);
|
||||
Assert.assertEquals("MyLDAPProvider2", ldap2.getDisplayName());
|
||||
Assert.assertEquals("ldap://bar", ldap2.getConfig().get(LDAPConstants.CONNECTION_URL));
|
||||
Assert.assertEquals("MyLDAPProvider2", ldap2.getName());
|
||||
Assert.assertEquals("ldap://bar", ldap2.getConfig().getFirst(LDAPConstants.CONNECTION_URL));
|
||||
|
||||
// Test federation mappers
|
||||
List<UserFederationMapperRepresentation> fedMappers1 = realmRsc.userFederation().get(ldap1.getId()).getMappers();
|
||||
Assert.assertTrue(fedMappers1.size() == 1);
|
||||
UserFederationMapperRepresentation fullNameMapper = fedMappers1.iterator().next();
|
||||
List<ComponentRepresentation> fedMappers1 = realmRsc.components().query(ldap1.getId(), LDAPStorageMapper.class.getName());
|
||||
ComponentRepresentation fullNameMapper = fedMappers1.iterator().next();
|
||||
Assert.assertEquals("FullNameMapper", fullNameMapper.getName());
|
||||
Assert.assertEquals(FullNameLDAPFederationMapperFactory.PROVIDER_ID, fullNameMapper.getFederationMapperType());
|
||||
//Assert.assertEquals(ldap1.getId(), fullNameMapper.getFederationProviderId());
|
||||
Assert.assertEquals("cn", fullNameMapper.getConfig().get(FullNameLDAPFederationMapper.LDAP_FULL_NAME_ATTRIBUTE));
|
||||
|
||||
// All builtin LDAP mappers should be here
|
||||
List<UserFederationMapperRepresentation> fedMappers2 = realmRsc.userFederation().get(ldap2.getId()).getMappers();
|
||||
Assert.assertTrue(fedMappers2.size() > 3);
|
||||
List<UserFederationMapperRepresentation> allMappers = realm.getUserFederationMappers();
|
||||
Assert.assertEquals(allMappers.size(), fedMappers1.size() + fedMappers2.size());
|
||||
Assert.assertEquals(FullNameLDAPStorageMapperFactory.PROVIDER_ID, fullNameMapper.getProviderId());
|
||||
Assert.assertEquals("cn", fullNameMapper.getConfig().getFirst(FullNameLDAPStorageMapper.LDAP_FULL_NAME_ATTRIBUTE));
|
||||
/////////////////
|
||||
|
||||
// Assert that federation link wasn't created during import
|
||||
Assert.assertNull(testingClient.testing().getUserByUsernameFromFedProviderFactory(realm.getRealm(), "wburke"));
|
||||
|
|
|
@ -158,7 +158,7 @@ public class ClientAuthSignedJWTTest extends AbstractKeycloakTest {
|
|||
|
||||
defaultUser = UserBuilder.create()
|
||||
.id(KeycloakModelUtils.generateId())
|
||||
.serviceAccountId(app1.getClientId())
|
||||
//.serviceAccountId(app1.getClientId())
|
||||
.username("test-user@localhost")
|
||||
.password("password")
|
||||
.build();
|
||||
|
|
|
@ -126,10 +126,6 @@
|
|||
<groupId>org.keycloak</groupId>
|
||||
<artifactId>keycloak-ldap-federation</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<artifactId>keycloak-ldap-storage</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<artifactId>keycloak-kerberos-federation</artifactId>
|
||||
|
|
|
@ -1,186 +0,0 @@
|
|||
/*
|
||||
* 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 org.junit.Assert;
|
||||
import org.junit.ClassRule;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.RuleChain;
|
||||
import org.junit.rules.TestRule;
|
||||
import org.keycloak.events.Details;
|
||||
import org.keycloak.federation.kerberos.CommonKerberosConfig;
|
||||
import org.keycloak.federation.ldap.LDAPFederationProviderFactory;
|
||||
import org.keycloak.federation.ldap.kerberos.LDAPProviderKerberosConfig;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.models.UserFederationProvider;
|
||||
import org.keycloak.models.UserFederationProviderModel;
|
||||
import org.keycloak.representations.idm.CredentialRepresentation;
|
||||
import org.keycloak.services.managers.RealmManager;
|
||||
import org.keycloak.testsuite.AssertEvents;
|
||||
import org.keycloak.testsuite.rule.KerberosRule;
|
||||
import org.keycloak.testsuite.rule.KeycloakRule;
|
||||
import org.keycloak.testsuite.rule.WebRule;
|
||||
import org.keycloak.utils.CredentialHelper;
|
||||
|
||||
import javax.ws.rs.core.Response;
|
||||
import java.net.URL;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Test of LDAPFederationProvider (Kerberos backed by LDAP)
|
||||
*
|
||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||
*/
|
||||
public class KerberosLdapTest extends AbstractKerberosTest {
|
||||
|
||||
private static final String PROVIDER_CONFIG_LOCATION = "kerberos/kerberos-ldap-connection.properties";
|
||||
|
||||
private static UserFederationProviderModel ldapModel = null;
|
||||
|
||||
private static KerberosRule kerberosRule = new KerberosRule(PROVIDER_CONFIG_LOCATION);
|
||||
|
||||
private static KeycloakRule keycloakRule = new KeycloakRule(new KeycloakRule.KeycloakSetup() {
|
||||
|
||||
@Override
|
||||
public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
|
||||
CredentialHelper.setAlternativeCredential(manager.getSession(), CredentialRepresentation.KERBEROS, appRealm);
|
||||
URL url = getClass().getResource("/kerberos-test/kerberos-app-keycloak.json");
|
||||
keycloakRule.createApplicationDeployment()
|
||||
.name("kerberos-portal").contextPath("/kerberos-portal")
|
||||
.servletClass(KerberosCredDelegServlet.class).adapterConfigPath(url.getPath())
|
||||
.role("user").deployApplication();
|
||||
|
||||
Map<String,String> ldapConfig = kerberosRule.getConfig();
|
||||
ldapModel = appRealm.addUserFederationProvider(LDAPFederationProviderFactory.PROVIDER_NAME, ldapConfig, 0, "kerberos-ldap", -1, -1, 0);
|
||||
}
|
||||
}) {
|
||||
|
||||
@Override
|
||||
protected void importRealm() {
|
||||
server.importRealm(getClass().getResourceAsStream("/kerberos-test/kerberosrealm.json"));
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
@ClassRule
|
||||
public static TestRule chain = RuleChain
|
||||
.outerRule(kerberosRule)
|
||||
.around(keycloakRule);
|
||||
|
||||
@Rule
|
||||
public WebRule webRule = new WebRule(this);
|
||||
|
||||
@Rule
|
||||
public AssertEvents events = new AssertEvents(keycloakRule);
|
||||
|
||||
@Override
|
||||
protected CommonKerberosConfig getKerberosConfig() {
|
||||
return new LDAPProviderKerberosConfig(ldapModel);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected KeycloakRule getKeycloakRule() {
|
||||
return keycloakRule;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected AssertEvents getAssertEvents() {
|
||||
return events;
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void spnegoLoginTest() throws Exception {
|
||||
spnegoLoginTestImpl();
|
||||
|
||||
// Assert user was imported and hasn't any required action on him. Profile info is synced from LDAP
|
||||
assertUser("hnelson", "hnelson@keycloak.org", "Horatio", "Nelson", false);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Override
|
||||
public void usernamePasswordLoginTest() throws Exception {
|
||||
super.usernamePasswordLoginTest();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void writableEditModeTest() throws Exception {
|
||||
KeycloakRule keycloakRule = getKeycloakRule();
|
||||
AssertEvents events = getAssertEvents();
|
||||
|
||||
// Change editMode to WRITABLE
|
||||
updateProviderEditMode(UserFederationProvider.EditMode.WRITABLE);
|
||||
|
||||
// Login with username/password from kerberos
|
||||
changePasswordPage.open();
|
||||
// Only needed if you are providing a click thru to bypass kerberos. Currently there is a javascript
|
||||
// to forward the user if kerberos isn't enabled.
|
||||
//bypassPage.isCurrent();
|
||||
//bypassPage.clickContinue();
|
||||
loginPage.assertCurrent();
|
||||
loginPage.login("jduke", "theduke");
|
||||
changePasswordPage.assertCurrent();
|
||||
|
||||
// Successfully change password now
|
||||
changePasswordPage.changePassword("theduke", "newPass", "newPass");
|
||||
Assert.assertTrue(driver.getPageSource().contains("Your password has been updated."));
|
||||
changePasswordPage.logout();
|
||||
|
||||
// Only needed if you are providing a click thru to bypass kerberos. Currently there is a javascript
|
||||
// to forward the user if kerberos isn't enabled.
|
||||
//bypassPage.isCurrent();
|
||||
//bypassPage.clickContinue();
|
||||
|
||||
// Login with old password doesn't work, but with new password works
|
||||
loginPage.login("jduke", "theduke");
|
||||
loginPage.assertCurrent();
|
||||
loginPage.login("jduke", "newPass");
|
||||
changePasswordPage.assertCurrent();
|
||||
changePasswordPage.logout();
|
||||
|
||||
// Assert SPNEGO login with the new password as mode is writable
|
||||
events.clear();
|
||||
Response spnegoResponse = spnegoLogin("jduke", "newPass");
|
||||
Assert.assertEquals(302, spnegoResponse.getStatus());
|
||||
events.expectLogin()
|
||||
.client("kerberos-app")
|
||||
.user(keycloakRule.getUser("test", "jduke").getId())
|
||||
.detail(Details.REDIRECT_URI, KERBEROS_APP_URL)
|
||||
//.detail(Details.AUTH_METHOD, "spnego")
|
||||
.detail(Details.USERNAME, "jduke")
|
||||
.assertEvent();
|
||||
|
||||
// Change password back
|
||||
changePasswordPage.open();
|
||||
// Only needed if you are providing a click thru to bypass kerberos. Currently there is a javascript
|
||||
// to forward the user if kerberos isn't enabled.
|
||||
//bypassPage.isCurrent();
|
||||
//bypassPage.clickContinue();
|
||||
|
||||
loginPage.login("jduke", "newPass");
|
||||
changePasswordPage.assertCurrent();
|
||||
changePasswordPage.changePassword("newPass", "theduke", "theduke");
|
||||
Assert.assertTrue(driver.getPageSource().contains("Your password has been updated."));
|
||||
changePasswordPage.logout();
|
||||
|
||||
spnegoResponse.close();
|
||||
events.clear();
|
||||
}
|
||||
|
||||
}
|
|
@ -1,287 +0,0 @@
|
|||
/*
|
||||
* 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.ldap;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.keycloak.federation.ldap.LDAPFederationProvider;
|
||||
import org.keycloak.federation.ldap.LDAPFederationProviderFactory;
|
||||
import org.keycloak.federation.ldap.LDAPUtils;
|
||||
import org.keycloak.federation.ldap.idm.model.LDAPObject;
|
||||
import org.keycloak.federation.ldap.idm.query.internal.LDAPQuery;
|
||||
import org.keycloak.federation.ldap.idm.store.ldap.LDAPIdentityStore;
|
||||
import org.keycloak.federation.ldap.mappers.UserAttributeLDAPFederationMapper;
|
||||
import org.keycloak.federation.ldap.mappers.UserAttributeLDAPFederationMapperFactory;
|
||||
import org.keycloak.federation.ldap.mappers.membership.LDAPGroupMapperMode;
|
||||
import org.keycloak.federation.ldap.mappers.membership.group.GroupLDAPFederationMapper;
|
||||
import org.keycloak.federation.ldap.mappers.membership.group.GroupLDAPFederationMapperFactory;
|
||||
import org.keycloak.federation.ldap.mappers.membership.group.GroupMapperConfig;
|
||||
import org.keycloak.federation.ldap.mappers.membership.role.RoleLDAPFederationMapper;
|
||||
import org.keycloak.federation.ldap.mappers.membership.role.RoleLDAPFederationMapperFactory;
|
||||
import org.keycloak.federation.ldap.mappers.membership.role.RoleMapperConfig;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.LDAPConstants;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.models.UserCredentialModel;
|
||||
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.models.UserProvider;
|
||||
import org.keycloak.models.utils.KeycloakModelUtils;
|
||||
import org.keycloak.models.utils.UserModelDelegate;
|
||||
import org.keycloak.representations.idm.CredentialRepresentation;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||
*/
|
||||
public class FederationTestUtils {
|
||||
|
||||
public static UserModel addLocalUser(KeycloakSession session, RealmModel realm, String username, String email, String password) {
|
||||
UserModel user = session.userStorage().addUser(realm, username);
|
||||
user.setEmail(email);
|
||||
user.setEnabled(true);
|
||||
|
||||
UserCredentialModel creds = new UserCredentialModel();
|
||||
creds.setType(CredentialRepresentation.PASSWORD);
|
||||
creds.setValue(password);
|
||||
|
||||
session.userCredentialManager().updateCredential(realm, user, creds);
|
||||
return user;
|
||||
}
|
||||
|
||||
public static LDAPObject addLDAPUser(LDAPFederationProvider ldapProvider, RealmModel realm, final String username,
|
||||
final String firstName, final String lastName, final String email, final String street, final String... postalCode) {
|
||||
UserModel helperUser = new UserModelDelegate(null) {
|
||||
|
||||
@Override
|
||||
public String getUsername() {
|
||||
return username;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFirstName() {
|
||||
return firstName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLastName() {
|
||||
return lastName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getEmail() {
|
||||
return email;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getAttribute(String name) {
|
||||
if ("postal_code".equals(name) && postalCode != null && postalCode.length > 0) {
|
||||
return Arrays.asList(postalCode);
|
||||
} else if ("street".equals(name) && street != null) {
|
||||
return Collections.singletonList(street);
|
||||
} else {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
};
|
||||
return LDAPUtils.addUserToLDAP(ldapProvider, realm, helperUser);
|
||||
}
|
||||
|
||||
public static void updateLDAPPassword(LDAPFederationProvider ldapProvider, LDAPObject ldapUser, String password) {
|
||||
ldapProvider.getLdapIdentityStore().updatePassword(ldapUser, password);
|
||||
|
||||
// Enable MSAD user through userAccountControls
|
||||
if (ldapProvider.getLdapIdentityStore().getConfig().isActiveDirectory()) {
|
||||
ldapUser.setSingleAttribute(LDAPConstants.USER_ACCOUNT_CONTROL, "512");
|
||||
ldapProvider.getLdapIdentityStore().update(ldapUser);
|
||||
}
|
||||
}
|
||||
|
||||
public static LDAPFederationProvider getLdapProvider(KeycloakSession keycloakSession, UserFederationProviderModel ldapFedModel) {
|
||||
LDAPFederationProviderFactory ldapProviderFactory = (LDAPFederationProviderFactory) keycloakSession.getKeycloakSessionFactory().getProviderFactory(UserFederationProvider.class, ldapFedModel.getProviderName());
|
||||
return ldapProviderFactory.getInstance(keycloakSession, ldapFedModel);
|
||||
}
|
||||
|
||||
public static void assertUserImported(UserProvider userProvider, RealmModel realm, String username, String expectedFirstName, String expectedLastName, String expectedEmail, String expectedPostalCode) {
|
||||
UserModel user = userProvider.getUserByUsername(username, realm);
|
||||
Assert.assertNotNull(user);
|
||||
Assert.assertEquals(expectedFirstName, user.getFirstName());
|
||||
Assert.assertEquals(expectedLastName, user.getLastName());
|
||||
Assert.assertEquals(expectedEmail, user.getEmail());
|
||||
Assert.assertEquals(expectedPostalCode, user.getFirstAttribute("postal_code"));
|
||||
}
|
||||
|
||||
|
||||
// CRUD model mappers
|
||||
|
||||
public static void addZipCodeLDAPMapper(RealmModel realm, UserFederationProviderModel providerModel) {
|
||||
addUserAttributeMapper(realm, providerModel, "zipCodeMapper", "postal_code", LDAPConstants.POSTAL_CODE);
|
||||
}
|
||||
|
||||
public static UserFederationMapperModel addUserAttributeMapper(RealmModel realm, UserFederationProviderModel providerModel, String mapperName, String userModelAttributeName, String ldapAttributeName) {
|
||||
UserFederationMapperModel mapperModel = KeycloakModelUtils.createUserFederationMapperModel(mapperName, providerModel.getId(), UserAttributeLDAPFederationMapperFactory.PROVIDER_ID,
|
||||
UserAttributeLDAPFederationMapper.USER_MODEL_ATTRIBUTE, userModelAttributeName,
|
||||
UserAttributeLDAPFederationMapper.LDAP_ATTRIBUTE, ldapAttributeName,
|
||||
UserAttributeLDAPFederationMapper.READ_ONLY, "false",
|
||||
UserAttributeLDAPFederationMapper.ALWAYS_READ_VALUE_FROM_LDAP, "false",
|
||||
UserAttributeLDAPFederationMapper.IS_MANDATORY_IN_LDAP, "false");
|
||||
return realm.addUserFederationMapper(mapperModel);
|
||||
}
|
||||
|
||||
public static void addOrUpdateRoleLDAPMappers(RealmModel realm, UserFederationProviderModel providerModel, LDAPGroupMapperMode mode) {
|
||||
UserFederationMapperModel mapperModel = realm.getUserFederationMapperByName(providerModel.getId(), "realmRolesMapper");
|
||||
if (mapperModel != null) {
|
||||
mapperModel.getConfig().put(RoleMapperConfig.MODE, mode.toString());
|
||||
realm.updateUserFederationMapper(mapperModel);
|
||||
} else {
|
||||
String baseDn = providerModel.getConfig().get(LDAPConstants.BASE_DN);
|
||||
mapperModel = KeycloakModelUtils.createUserFederationMapperModel("realmRolesMapper", providerModel.getId(), RoleLDAPFederationMapperFactory.PROVIDER_ID,
|
||||
RoleMapperConfig.ROLES_DN, "ou=RealmRoles," + baseDn,
|
||||
RoleMapperConfig.USE_REALM_ROLES_MAPPING, "true",
|
||||
RoleMapperConfig.MODE, mode.toString());
|
||||
realm.addUserFederationMapper(mapperModel);
|
||||
}
|
||||
|
||||
mapperModel = realm.getUserFederationMapperByName(providerModel.getId(), "financeRolesMapper");
|
||||
if (mapperModel != null) {
|
||||
mapperModel.getConfig().put(RoleMapperConfig.MODE, mode.toString());
|
||||
realm.updateUserFederationMapper(mapperModel);
|
||||
} else {
|
||||
String baseDn = providerModel.getConfig().get(LDAPConstants.BASE_DN);
|
||||
mapperModel = KeycloakModelUtils.createUserFederationMapperModel("financeRolesMapper", providerModel.getId(), RoleLDAPFederationMapperFactory.PROVIDER_ID,
|
||||
RoleMapperConfig.ROLES_DN, "ou=FinanceRoles," + baseDn,
|
||||
RoleMapperConfig.USE_REALM_ROLES_MAPPING, "false",
|
||||
RoleMapperConfig.CLIENT_ID, "finance",
|
||||
RoleMapperConfig.MODE, mode.toString());
|
||||
realm.addUserFederationMapper(mapperModel);
|
||||
}
|
||||
}
|
||||
|
||||
public static void addOrUpdateGroupMapper(RealmModel realm, UserFederationProviderModel providerModel, LDAPGroupMapperMode mode, String descriptionAttrName, String... otherConfigOptions) {
|
||||
UserFederationMapperModel mapperModel = realm.getUserFederationMapperByName(providerModel.getId(), "groupsMapper");
|
||||
if (mapperModel != null) {
|
||||
mapperModel.getConfig().put(GroupMapperConfig.MODE, mode.toString());
|
||||
updateGroupMapperConfigOptions(mapperModel, otherConfigOptions);
|
||||
realm.updateUserFederationMapper(mapperModel);
|
||||
} else {
|
||||
String baseDn = providerModel.getConfig().get(LDAPConstants.BASE_DN);
|
||||
mapperModel = KeycloakModelUtils.createUserFederationMapperModel("groupsMapper", providerModel.getId(), GroupLDAPFederationMapperFactory.PROVIDER_ID,
|
||||
GroupMapperConfig.GROUPS_DN, "ou=Groups," + baseDn,
|
||||
GroupMapperConfig.MAPPED_GROUP_ATTRIBUTES, descriptionAttrName,
|
||||
GroupMapperConfig.PRESERVE_GROUP_INHERITANCE, "true",
|
||||
GroupMapperConfig.MODE, mode.toString());
|
||||
updateGroupMapperConfigOptions(mapperModel, otherConfigOptions);
|
||||
realm.addUserFederationMapper(mapperModel);
|
||||
}
|
||||
}
|
||||
|
||||
public static void updateGroupMapperConfigOptions(UserFederationMapperModel mapperModel, String... configOptions) {
|
||||
for (int i=0 ; i<configOptions.length ; i+=2) {
|
||||
String cfgName = configOptions[i];
|
||||
String cfgValue = configOptions[i+1];
|
||||
mapperModel.getConfig().put(cfgName, cfgValue);
|
||||
}
|
||||
}
|
||||
|
||||
// End CRUD model mappers
|
||||
|
||||
public static void syncRolesFromLDAP(RealmModel realm, LDAPFederationProvider ldapProvider, UserFederationProviderModel providerModel) {
|
||||
UserFederationMapperModel mapperModel = realm.getUserFederationMapperByName(providerModel.getId(), "realmRolesMapper");
|
||||
RoleLDAPFederationMapper roleMapper = getRoleMapper(mapperModel, ldapProvider, realm);
|
||||
|
||||
roleMapper.syncDataFromFederationProviderToKeycloak();
|
||||
|
||||
mapperModel = realm.getUserFederationMapperByName(providerModel.getId(), "financeRolesMapper");
|
||||
roleMapper = getRoleMapper(mapperModel, ldapProvider, realm);
|
||||
roleMapper.syncDataFromFederationProviderToKeycloak();
|
||||
}
|
||||
|
||||
public static void removeAllLDAPUsers(LDAPFederationProvider ldapProvider, RealmModel realm) {
|
||||
LDAPIdentityStore ldapStore = ldapProvider.getLdapIdentityStore();
|
||||
LDAPQuery ldapQuery = LDAPUtils.createQueryForUserSearch(ldapProvider, realm);
|
||||
List<LDAPObject> allUsers = ldapQuery.getResultList();
|
||||
|
||||
for (LDAPObject ldapUser : allUsers) {
|
||||
ldapStore.remove(ldapUser);
|
||||
}
|
||||
}
|
||||
|
||||
public static void removeAllLDAPRoles(KeycloakSession session, RealmModel appRealm, UserFederationProviderModel ldapModel, String mapperName) {
|
||||
UserFederationMapperModel mapperModel = appRealm.getUserFederationMapperByName(ldapModel.getId(), mapperName);
|
||||
LDAPFederationProvider ldapProvider = FederationTestUtils.getLdapProvider(session, ldapModel);
|
||||
LDAPQuery roleQuery = getRoleMapper(mapperModel, ldapProvider, appRealm).createRoleQuery();
|
||||
List<LDAPObject> ldapRoles = roleQuery.getResultList();
|
||||
for (LDAPObject ldapRole : ldapRoles) {
|
||||
ldapProvider.getLdapIdentityStore().remove(ldapRole);
|
||||
}
|
||||
}
|
||||
|
||||
public static void removeAllLDAPGroups(KeycloakSession session, RealmModel appRealm, UserFederationProviderModel ldapModel, String mapperName) {
|
||||
UserFederationMapperModel mapperModel = appRealm.getUserFederationMapperByName(ldapModel.getId(), mapperName);
|
||||
LDAPFederationProvider ldapProvider = FederationTestUtils.getLdapProvider(session, ldapModel);
|
||||
LDAPQuery roleQuery = getGroupMapper(mapperModel, ldapProvider, appRealm).createGroupQuery();
|
||||
List<LDAPObject> ldapRoles = roleQuery.getResultList();
|
||||
for (LDAPObject ldapRole : ldapRoles) {
|
||||
ldapProvider.getLdapIdentityStore().remove(ldapRole);
|
||||
}
|
||||
}
|
||||
|
||||
public static void createLDAPRole(KeycloakSession session, RealmModel appRealm, UserFederationProviderModel ldapModel, String mapperName, String roleName) {
|
||||
UserFederationMapperModel mapperModel = appRealm.getUserFederationMapperByName(ldapModel.getId(), mapperName);
|
||||
LDAPFederationProvider ldapProvider = FederationTestUtils.getLdapProvider(session, ldapModel);
|
||||
getRoleMapper(mapperModel, ldapProvider, appRealm).createLDAPRole(roleName);
|
||||
}
|
||||
|
||||
public static LDAPObject createLDAPGroup(KeycloakSession session, RealmModel appRealm, UserFederationProviderModel ldapModel, String groupName, String... additionalAttrs) {
|
||||
UserFederationMapperModel mapperModel = appRealm.getUserFederationMapperByName(ldapModel.getId(), "groupsMapper");
|
||||
LDAPFederationProvider ldapProvider = FederationTestUtils.getLdapProvider(session, ldapModel);
|
||||
|
||||
Map<String, Set<String>> additAttrs = new HashMap<>();
|
||||
for (int i=0 ; i<additionalAttrs.length ; i+=2) {
|
||||
String attrName = additionalAttrs[i];
|
||||
String attrValue = additionalAttrs[i+1];
|
||||
additAttrs.put(attrName, Collections.singleton(attrValue));
|
||||
}
|
||||
|
||||
return getGroupMapper(mapperModel, ldapProvider, appRealm).createLDAPGroup(groupName, additAttrs);
|
||||
}
|
||||
|
||||
public static GroupLDAPFederationMapper getGroupMapper(UserFederationMapperModel mapperModel, LDAPFederationProvider ldapProvider, RealmModel realm) {
|
||||
return new GroupLDAPFederationMapper(mapperModel, ldapProvider, realm, new GroupLDAPFederationMapperFactory());
|
||||
}
|
||||
|
||||
public static RoleLDAPFederationMapper getRoleMapper(UserFederationMapperModel mapperModel, LDAPFederationProvider ldapProvider, RealmModel realm) {
|
||||
return new RoleLDAPFederationMapper(mapperModel, ldapProvider, realm, new RoleLDAPFederationMapperFactory());
|
||||
}
|
||||
|
||||
|
||||
public static void assertSyncEquals(UserFederationSyncResult syncResult, int expectedAdded, int expectedUpdated, int expectedRemoved, int expectedFailed) {
|
||||
Assert.assertEquals(expectedAdded, syncResult.getAdded());
|
||||
Assert.assertEquals(expectedUpdated, syncResult.getUpdated());
|
||||
Assert.assertEquals(expectedRemoved, syncResult.getRemoved());
|
||||
Assert.assertEquals(expectedFailed, syncResult.getFailed());
|
||||
}
|
||||
}
|
|
@ -1,63 +0,0 @@
|
|||
/*
|
||||
* 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.ldap;
|
||||
|
||||
import org.keycloak.KeycloakSecurityContext;
|
||||
import org.keycloak.representations.IDToken;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServlet;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||
*/
|
||||
public class LDAPExampleServlet extends HttpServlet {
|
||||
|
||||
|
||||
@Override
|
||||
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
|
||||
KeycloakSecurityContext securityContext = (KeycloakSecurityContext) req.getAttribute(KeycloakSecurityContext.class.getName());
|
||||
IDToken idToken = securityContext.getIdToken();
|
||||
|
||||
PrintWriter out = resp.getWriter();
|
||||
out.println("<html><head><title>LDAP Portal</title></head><body>");
|
||||
out.println("<table border><tr><th>Attribute name</th><th>Attribute values</th></tr>");
|
||||
|
||||
out.printf("<tr><td>%s</td><td>%s</td></tr>", "preferred_username", idToken.getPreferredUsername());
|
||||
out.println();
|
||||
out.printf("<tr><td>%s</td><td>%s</td></tr>", "name", idToken.getName());
|
||||
out.println();
|
||||
out.printf("<tr><td>%s</td><td>%s</td></tr>", "email", idToken.getEmail());
|
||||
out.println();
|
||||
|
||||
for (Map.Entry<String, Object> claim : idToken.getOtherClaims().entrySet()) {
|
||||
String value = claim.getValue().toString();
|
||||
out.printf("<tr><td>%s</td><td>%s</td></tr>", claim.getKey(), value);
|
||||
out.println();
|
||||
}
|
||||
|
||||
out.println("</table></body></html>");
|
||||
out.flush();
|
||||
}
|
||||
|
||||
}
|
|
@ -1,867 +0,0 @@
|
|||
/*
|
||||
* 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.ldap.base;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.ClassRule;
|
||||
import org.junit.FixMethodOrder;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.RuleChain;
|
||||
import org.junit.rules.TestRule;
|
||||
import org.junit.runners.MethodSorters;
|
||||
import org.keycloak.OAuth2Constants;
|
||||
import org.keycloak.credential.CredentialModel;
|
||||
import org.keycloak.federation.ldap.LDAPConfig;
|
||||
import org.keycloak.federation.ldap.LDAPFederationProvider;
|
||||
import org.keycloak.federation.ldap.LDAPFederationProviderFactory;
|
||||
import org.keycloak.federation.ldap.idm.model.LDAPObject;
|
||||
import org.keycloak.federation.ldap.mappers.FullNameLDAPFederationMapper;
|
||||
import org.keycloak.federation.ldap.mappers.FullNameLDAPFederationMapperFactory;
|
||||
import org.keycloak.federation.ldap.mappers.HardcodedLDAPRoleMapper;
|
||||
import org.keycloak.federation.ldap.mappers.HardcodedLDAPRoleMapperFactory;
|
||||
import org.keycloak.federation.ldap.mappers.UserAttributeLDAPFederationMapper;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.LDAPConstants;
|
||||
import org.keycloak.models.ModelException;
|
||||
import org.keycloak.models.ModelReadOnlyException;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.models.RoleModel;
|
||||
import org.keycloak.models.UserCredentialModel;
|
||||
import org.keycloak.models.UserFederationMapperModel;
|
||||
import org.keycloak.models.UserFederationProvider;
|
||||
import org.keycloak.models.UserFederationProviderModel;
|
||||
import org.keycloak.models.UserModel;
|
||||
import org.keycloak.models.utils.KeycloakModelUtils;
|
||||
import org.keycloak.models.utils.ModelToRepresentation;
|
||||
import org.keycloak.representations.AccessToken;
|
||||
import org.keycloak.representations.idm.RealmRepresentation;
|
||||
import org.keycloak.services.managers.RealmManager;
|
||||
import org.keycloak.testsuite.OAuthClient;
|
||||
import org.keycloak.testsuite.federation.ldap.FederationTestUtils;
|
||||
import org.keycloak.testsuite.pages.AccountPasswordPage;
|
||||
import org.keycloak.testsuite.pages.AccountUpdateProfilePage;
|
||||
import org.keycloak.testsuite.pages.AppPage;
|
||||
import org.keycloak.testsuite.pages.LoginPage;
|
||||
import org.keycloak.testsuite.pages.RegisterPage;
|
||||
import org.keycloak.testsuite.rule.KeycloakRule;
|
||||
import org.keycloak.testsuite.rule.LDAPRule;
|
||||
import org.keycloak.testsuite.rule.WebResource;
|
||||
import org.keycloak.testsuite.rule.WebRule;
|
||||
import org.keycloak.util.JsonSerialization;
|
||||
import org.openqa.selenium.WebDriver;
|
||||
|
||||
import java.io.FileOutputStream;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||
*/
|
||||
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
|
||||
public class FederationProvidersIntegrationTest {
|
||||
|
||||
private static LDAPRule ldapRule = new LDAPRule();
|
||||
|
||||
private static UserFederationProviderModel ldapModel = null;
|
||||
|
||||
private static KeycloakRule keycloakRule = new KeycloakRule(new KeycloakRule.KeycloakSetup() {
|
||||
|
||||
@Override
|
||||
public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
|
||||
FederationTestUtils.addLocalUser(manager.getSession(), appRealm, "marykeycloak", "mary@test.com", "password-app");
|
||||
|
||||
Map<String,String> ldapConfig = ldapRule.getConfig();
|
||||
ldapConfig.put(LDAPConstants.SYNC_REGISTRATIONS, "true");
|
||||
ldapConfig.put(LDAPConstants.EDIT_MODE, UserFederationProvider.EditMode.WRITABLE.toString());
|
||||
|
||||
ldapModel = appRealm.addUserFederationProvider(LDAPFederationProviderFactory.PROVIDER_NAME, ldapConfig, 0, "test-ldap", -1, -1, 0);
|
||||
FederationTestUtils.addZipCodeLDAPMapper(appRealm, ldapModel);
|
||||
|
||||
// Delete all LDAP users and add some new for testing
|
||||
LDAPFederationProvider ldapFedProvider = FederationTestUtils.getLdapProvider(session, ldapModel);
|
||||
FederationTestUtils.removeAllLDAPUsers(ldapFedProvider, appRealm);
|
||||
|
||||
LDAPObject john = FederationTestUtils.addLDAPUser(ldapFedProvider, appRealm, "johnkeycloak", "John", "Doe", "john@email.org", null, "1234");
|
||||
FederationTestUtils.updateLDAPPassword(ldapFedProvider, john, "Password1");
|
||||
|
||||
LDAPObject existing = FederationTestUtils.addLDAPUser(ldapFedProvider, appRealm, "existing", "Existing", "Foo", "existing@email.org", null, "5678");
|
||||
|
||||
appRealm.getClientByClientId("test-app").setDirectAccessGrantsEnabled(true);
|
||||
}
|
||||
});
|
||||
|
||||
/*
|
||||
@Test
|
||||
public void exportJson() throws Exception {
|
||||
KeycloakSession session = keycloakRule.startSession();
|
||||
FileOutputStream os = new FileOutputStream("/Users/williamburke/jboss/keycloak/p1b-repo/keycloak/fed-provider.json");
|
||||
RealmManager manager = new RealmManager(session);
|
||||
RealmModel appRealm = manager.getRealm("test");
|
||||
RealmRepresentation rep = ModelToRepresentation.toRepresentation(appRealm, true);
|
||||
JsonSerialization.writeValueToStream(os, rep);
|
||||
os.close();
|
||||
|
||||
}
|
||||
*/
|
||||
|
||||
@ClassRule
|
||||
public static TestRule chain = RuleChain
|
||||
.outerRule(ldapRule)
|
||||
.around(keycloakRule);
|
||||
|
||||
@Rule
|
||||
public WebRule webRule = new WebRule(this);
|
||||
|
||||
@WebResource
|
||||
protected OAuthClient oauth;
|
||||
|
||||
@WebResource
|
||||
protected WebDriver driver;
|
||||
|
||||
@WebResource
|
||||
protected AppPage appPage;
|
||||
|
||||
@WebResource
|
||||
protected RegisterPage registerPage;
|
||||
|
||||
@WebResource
|
||||
protected LoginPage loginPage;
|
||||
|
||||
@WebResource
|
||||
protected AccountUpdateProfilePage profilePage;
|
||||
|
||||
@WebResource
|
||||
protected AccountPasswordPage changePasswordPage;
|
||||
|
||||
// @Test
|
||||
// @Ignore
|
||||
// public void runit() throws Exception {
|
||||
// Thread.sleep(10000000);
|
||||
//
|
||||
// }
|
||||
|
||||
|
||||
@Test
|
||||
public void caseInSensitiveImport() {
|
||||
KeycloakSession session = keycloakRule.startSession();
|
||||
try {
|
||||
RealmManager manager = new RealmManager(session);
|
||||
RealmModel appRealm = manager.getRealm("test");
|
||||
LDAPFederationProvider ldapFedProvider = FederationTestUtils.getLdapProvider(session, ldapModel);
|
||||
LDAPObject jbrown2 = FederationTestUtils.addLDAPUser(ldapFedProvider, appRealm, "JBrown2", "John", "Brown2", "jbrown2@email.org", null, "1234");
|
||||
FederationTestUtils.updateLDAPPassword(ldapFedProvider, jbrown2, "Password1");
|
||||
LDAPObject jbrown3 = FederationTestUtils.addLDAPUser(ldapFedProvider, appRealm, "jbrown3", "John", "Brown3", "JBrown3@email.org", null, "1234");
|
||||
FederationTestUtils.updateLDAPPassword(ldapFedProvider, jbrown3, "Password1");
|
||||
} finally {
|
||||
keycloakRule.stopSession(session, true);
|
||||
}
|
||||
|
||||
loginSuccessAndLogout("jbrown2", "Password1");
|
||||
loginSuccessAndLogout("JBrown2", "Password1");
|
||||
loginSuccessAndLogout("jbrown2@email.org", "Password1");
|
||||
loginSuccessAndLogout("JBrown2@email.org", "Password1");
|
||||
|
||||
loginSuccessAndLogout("jbrown3", "Password1");
|
||||
loginSuccessAndLogout("JBrown3", "Password1");
|
||||
loginSuccessAndLogout("jbrown3@email.org", "Password1");
|
||||
loginSuccessAndLogout("JBrown3@email.org", "Password1");
|
||||
}
|
||||
|
||||
private void loginSuccessAndLogout(String username, String password) {
|
||||
loginPage.open();
|
||||
loginPage.login(username, password);
|
||||
Assert.assertEquals(AppPage.RequestType.AUTH_RESPONSE, appPage.getRequestType());
|
||||
Assert.assertNotNull(oauth.getCurrentQuery().get(OAuth2Constants.CODE));
|
||||
oauth.openLogout();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void caseInsensitiveSearch() {
|
||||
KeycloakSession session = keycloakRule.startSession();
|
||||
try {
|
||||
RealmManager manager = new RealmManager(session);
|
||||
RealmModel appRealm = manager.getRealm("test");
|
||||
LDAPFederationProvider ldapFedProvider = FederationTestUtils.getLdapProvider(session, ldapModel);
|
||||
LDAPObject jbrown4 = FederationTestUtils.addLDAPUser(ldapFedProvider, appRealm, "JBrown4", "John", "Brown4", "jbrown4@email.org", null, "1234");
|
||||
FederationTestUtils.updateLDAPPassword(ldapFedProvider, jbrown4, "Password1");
|
||||
LDAPObject jbrown5 = FederationTestUtils.addLDAPUser(ldapFedProvider, appRealm, "jbrown5", "John", "Brown5", "JBrown5@Email.org", null, "1234");
|
||||
FederationTestUtils.updateLDAPPassword(ldapFedProvider, jbrown5, "Password1");
|
||||
} finally {
|
||||
keycloakRule.stopSession(session, true);
|
||||
}
|
||||
|
||||
session = keycloakRule.startSession();
|
||||
try {
|
||||
RealmManager manager = new RealmManager(session);
|
||||
RealmModel appRealm = manager.getRealm("test");
|
||||
|
||||
// search by username
|
||||
List<UserModel> users = session.users().searchForUser("JBROwn4", appRealm);
|
||||
Assert.assertEquals(1, users.size());
|
||||
UserModel user4 = users.get(0);
|
||||
Assert.assertEquals("jbrown4", user4.getUsername());
|
||||
Assert.assertEquals("jbrown4@email.org", user4.getEmail());
|
||||
|
||||
// search by email
|
||||
users = session.users().searchForUser("JBROwn5@eMAil.org", appRealm);
|
||||
Assert.assertEquals(1, users.size());
|
||||
UserModel user5 = users.get(0);
|
||||
Assert.assertEquals("jbrown5", user5.getUsername());
|
||||
Assert.assertEquals("jbrown5@email.org", user5.getEmail());
|
||||
} finally {
|
||||
keycloakRule.stopSession(session, true);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void deleteFederationLink() {
|
||||
loginLdap();
|
||||
{
|
||||
KeycloakSession session = keycloakRule.startSession();
|
||||
try {
|
||||
RealmManager manager = new RealmManager(session);
|
||||
|
||||
RealmModel appRealm = manager.getRealm("test");
|
||||
appRealm.removeUserFederationProvider(ldapModel);
|
||||
Assert.assertEquals(0, appRealm.getUserFederationProviders().size());
|
||||
} finally {
|
||||
keycloakRule.stopSession(session, true);
|
||||
}
|
||||
}
|
||||
loginPage.open();
|
||||
loginPage.login("johnkeycloak", "Password1");
|
||||
loginPage.assertCurrent();
|
||||
|
||||
Assert.assertEquals("Invalid username or password.", loginPage.getError());
|
||||
|
||||
{
|
||||
KeycloakSession session = keycloakRule.startSession();
|
||||
try {
|
||||
RealmManager manager = new RealmManager(session);
|
||||
|
||||
RealmModel appRealm = manager.getRealm("test");
|
||||
ldapModel = appRealm.addUserFederationProvider(ldapModel.getProviderName(), ldapModel.getConfig(), ldapModel.getPriority(), ldapModel.getDisplayName(), -1, -1, 0);
|
||||
FederationTestUtils.addZipCodeLDAPMapper(appRealm, ldapModel);
|
||||
} finally {
|
||||
keycloakRule.stopSession(session, true);
|
||||
}
|
||||
}
|
||||
loginLdap();
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void loginClassic() {
|
||||
loginPage.open();
|
||||
loginPage.login("marykeycloak", "password-app");
|
||||
|
||||
Assert.assertEquals(AppPage.RequestType.AUTH_RESPONSE, appPage.getRequestType());
|
||||
Assert.assertNotNull(oauth.getCurrentQuery().get(OAuth2Constants.CODE));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void loginLdap() {
|
||||
loginPage.open();
|
||||
loginPage.login("johnkeycloak", "Password1");
|
||||
|
||||
Assert.assertEquals(AppPage.RequestType.AUTH_RESPONSE, appPage.getRequestType());
|
||||
Assert.assertNotNull(oauth.getCurrentQuery().get(OAuth2Constants.CODE));
|
||||
|
||||
profilePage.open();
|
||||
Assert.assertEquals("John", profilePage.getFirstName());
|
||||
Assert.assertEquals("Doe", profilePage.getLastName());
|
||||
Assert.assertEquals("john@email.org", profilePage.getEmail());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void loginLdapWithDirectGrant() throws Exception {
|
||||
OAuthClient.AccessTokenResponse response = oauth.doGrantAccessTokenRequest("password", "johnkeycloak", "Password1");
|
||||
assertEquals(200, response.getStatusCode());
|
||||
AccessToken accessToken = oauth.verifyToken(response.getAccessToken());
|
||||
|
||||
response = oauth.doGrantAccessTokenRequest("password", "johnkeycloak", "");
|
||||
assertEquals(401, response.getStatusCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void loginLdapWithEmail() {
|
||||
loginPage.open();
|
||||
loginPage.login("john@email.org", "Password1");
|
||||
|
||||
Assert.assertEquals(AppPage.RequestType.AUTH_RESPONSE, appPage.getRequestType());
|
||||
Assert.assertNotNull(oauth.getCurrentQuery().get(OAuth2Constants.CODE));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void loginLdapWithoutPassword() {
|
||||
loginPage.open();
|
||||
loginPage.login("john@email.org", "");
|
||||
Assert.assertEquals("Invalid username or password.", loginPage.getError());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void passwordChangeLdap() throws Exception {
|
||||
changePasswordPage.open();
|
||||
loginPage.login("johnkeycloak", "Password1");
|
||||
changePasswordPage.changePassword("Password1", "New-password1", "New-password1");
|
||||
|
||||
Assert.assertEquals("Your password has been updated.", profilePage.getSuccess());
|
||||
|
||||
changePasswordPage.logout();
|
||||
|
||||
loginPage.open();
|
||||
loginPage.login("johnkeycloak", "Bad-password1");
|
||||
Assert.assertEquals("Invalid username or password.", loginPage.getError());
|
||||
|
||||
loginPage.open();
|
||||
loginPage.login("johnkeycloak", "New-password1");
|
||||
Assert.assertEquals(AppPage.RequestType.AUTH_RESPONSE, appPage.getRequestType());
|
||||
|
||||
// Change password back to previous value
|
||||
changePasswordPage.open();
|
||||
changePasswordPage.changePassword("New-password1", "Password1", "Password1");
|
||||
Assert.assertEquals("Your password has been updated.", profilePage.getSuccess());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void registerExistingLdapUser() {
|
||||
loginPage.open();
|
||||
loginPage.clickRegister();
|
||||
registerPage.assertCurrent();
|
||||
|
||||
// check existing username
|
||||
registerPage.register("firstName", "lastName", "email@mail.cz", "existing", "Password1", "Password1");
|
||||
registerPage.assertCurrent();
|
||||
Assert.assertEquals("Username already exists.", registerPage.getError());
|
||||
|
||||
// Check existing email
|
||||
registerPage.register("firstName", "lastName", "existing@email.org", "nonExisting", "Password1", "Password1");
|
||||
registerPage.assertCurrent();
|
||||
Assert.assertEquals("Email already exists.", registerPage.getError());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void registerUserLdapSuccess() {
|
||||
loginPage.open();
|
||||
loginPage.clickRegister();
|
||||
registerPage.assertCurrent();
|
||||
|
||||
registerPage.register("firstName", "lastName", "email2@check.cz", "registerUserSuccess2", "Password1", "Password1");
|
||||
Assert.assertEquals(AppPage.RequestType.AUTH_RESPONSE, appPage.getRequestType());
|
||||
|
||||
KeycloakSession session = keycloakRule.startSession();
|
||||
try {
|
||||
RealmModel appRealm = session.realms().getRealmByName("test");
|
||||
UserModel user = session.users().getUserByUsername("registerUserSuccess2", appRealm);
|
||||
Assert.assertNotNull(user);
|
||||
Assert.assertNotNull(user.getFederationLink());
|
||||
Assert.assertEquals(user.getFederationLink(), ldapModel.getId());
|
||||
} finally {
|
||||
keycloakRule.stopSession(session, false);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCaseSensitiveAttributeName() {
|
||||
KeycloakSession session = keycloakRule.startSession();
|
||||
|
||||
try {
|
||||
RealmModel appRealm = new RealmManager(session).getRealmByName("test");
|
||||
|
||||
LDAPFederationProvider ldapFedProvider = FederationTestUtils.getLdapProvider(session, ldapModel);
|
||||
LDAPObject johnZip = FederationTestUtils.addLDAPUser(ldapFedProvider, appRealm, "johnzip", "John", "Zip", "johnzip@email.org", null, "12398");
|
||||
|
||||
// Remove default zipcode mapper and add the mapper for "POstalCode" to test case sensitivity
|
||||
UserFederationMapperModel currentZipMapper = appRealm.getUserFederationMapperByName(ldapModel.getId(), "zipCodeMapper");
|
||||
appRealm.removeUserFederationMapper(currentZipMapper);
|
||||
FederationTestUtils.addUserAttributeMapper(appRealm, ldapModel, "zipCodeMapper-cs", "postal_code", "POstalCode");
|
||||
|
||||
// Fetch user from LDAP and check that postalCode is filled
|
||||
UserModel user = session.users().getUserByUsername("johnzip", appRealm);
|
||||
String postalCode = user.getFirstAttribute("postal_code");
|
||||
Assert.assertEquals("12398", postalCode);
|
||||
|
||||
} finally {
|
||||
keycloakRule.stopSession(session, false);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCommaInUsername() {
|
||||
KeycloakSession session = keycloakRule.startSession();
|
||||
boolean skip = false;
|
||||
|
||||
try {
|
||||
RealmModel appRealm = new RealmManager(session).getRealmByName("test");
|
||||
LDAPFederationProvider ldapFedProvider = FederationTestUtils.getLdapProvider(session, ldapModel);
|
||||
|
||||
// Workaround as comma is not allowed in sAMAccountName on active directory. So we will skip the test for this configuration
|
||||
LDAPConfig config = ldapFedProvider.getLdapIdentityStore().getConfig();
|
||||
if (config.isActiveDirectory() && config.getUsernameLdapAttribute().equals(LDAPConstants.SAM_ACCOUNT_NAME)) {
|
||||
skip = true;
|
||||
}
|
||||
|
||||
if (!skip) {
|
||||
LDAPObject johnComma = FederationTestUtils.addLDAPUser(ldapFedProvider, appRealm, "john,comma", "John", "Comma", "johncomma@email.org", null, "12387");
|
||||
FederationTestUtils.updateLDAPPassword(ldapFedProvider, johnComma, "Password1");
|
||||
|
||||
LDAPObject johnPlus = FederationTestUtils.addLDAPUser(ldapFedProvider, appRealm, "john+plus,comma", "John", "Plus", "johnplus@email.org", null, "12387");
|
||||
FederationTestUtils.updateLDAPPassword(ldapFedProvider, johnPlus, "Password1");
|
||||
}
|
||||
} finally {
|
||||
keycloakRule.stopSession(session, false);
|
||||
}
|
||||
|
||||
if (!skip) {
|
||||
// Try to import the user with comma in username into Keycloak
|
||||
loginSuccessAndLogout("john,comma", "Password1");
|
||||
loginSuccessAndLogout("john+plus,comma", "Password1");
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDirectLDAPUpdate() {
|
||||
KeycloakSession session = keycloakRule.startSession();
|
||||
|
||||
try {
|
||||
RealmModel appRealm = new RealmManager(session).getRealmByName("test");
|
||||
|
||||
LDAPFederationProvider ldapFedProvider = FederationTestUtils.getLdapProvider(session, ldapModel);
|
||||
LDAPObject johnDirect = FederationTestUtils.addLDAPUser(ldapFedProvider, appRealm, "johndirect", "John", "Direct", "johndirect@email.org", null, "12399");
|
||||
|
||||
// Fetch user from LDAP and check that postalCode is filled
|
||||
UserModel user = session.users().getUserByUsername("johndirect", appRealm);
|
||||
String postalCode = user.getFirstAttribute("postal_code");
|
||||
Assert.assertEquals("12399", postalCode);
|
||||
|
||||
// Directly update user in LDAP
|
||||
johnDirect.setSingleAttribute(LDAPConstants.POSTAL_CODE, "12400");
|
||||
johnDirect.setSingleAttribute(LDAPConstants.SN, "DirectLDAPUpdated");
|
||||
ldapFedProvider.getLdapIdentityStore().update(johnDirect);
|
||||
|
||||
} finally {
|
||||
keycloakRule.stopSession(session, true);
|
||||
}
|
||||
|
||||
session = keycloakRule.startSession();
|
||||
try {
|
||||
RealmModel appRealm = new RealmManager(session).getRealmByName("test");
|
||||
UserModel user = session.users().getUserByUsername("johndirect", appRealm);
|
||||
|
||||
// Verify that postalCode is still the same as we read it's value from Keycloak DB
|
||||
user = session.users().getUserByUsername("johndirect", appRealm);
|
||||
String postalCode = user.getFirstAttribute("postal_code");
|
||||
Assert.assertEquals("12399", postalCode);
|
||||
|
||||
// Check user.getAttributes()
|
||||
postalCode = user.getAttributes().get("postal_code").get(0);
|
||||
Assert.assertEquals("12399", postalCode);
|
||||
|
||||
// LastName is new as lastName mapper will read the value from LDAP
|
||||
String lastName = user.getLastName();
|
||||
Assert.assertEquals("DirectLDAPUpdated", lastName);
|
||||
} finally {
|
||||
keycloakRule.stopSession(session, true);
|
||||
}
|
||||
|
||||
session = keycloakRule.startSession();
|
||||
try {
|
||||
RealmModel appRealm = new RealmManager(session).getRealmByName("test");
|
||||
|
||||
// Update postalCode mapper to always read the value from LDAP
|
||||
UserFederationMapperModel zipMapper = appRealm.getUserFederationMapperByName(ldapModel.getId(), "zipCodeMapper");
|
||||
zipMapper.getConfig().put(UserAttributeLDAPFederationMapper.ALWAYS_READ_VALUE_FROM_LDAP, "true");
|
||||
appRealm.updateUserFederationMapper(zipMapper);
|
||||
|
||||
// Update lastName mapper to read the value from Keycloak DB
|
||||
UserFederationMapperModel lastNameMapper = appRealm.getUserFederationMapperByName(ldapModel.getId(), "last name");
|
||||
lastNameMapper.getConfig().put(UserAttributeLDAPFederationMapper.ALWAYS_READ_VALUE_FROM_LDAP, "false");
|
||||
appRealm.updateUserFederationMapper(lastNameMapper);
|
||||
|
||||
// Verify that postalCode is read from LDAP now
|
||||
UserModel user = session.users().getUserByUsername("johndirect", appRealm);
|
||||
String postalCode = user.getFirstAttribute("postal_code");
|
||||
Assert.assertEquals("12400", postalCode);
|
||||
|
||||
// Check user.getAttributes()
|
||||
postalCode = user.getAttributes().get("postal_code").get(0);
|
||||
Assert.assertEquals("12400", postalCode);
|
||||
|
||||
Assert.assertFalse(user.getAttributes().containsKey(UserModel.LAST_NAME));
|
||||
|
||||
// lastName is read from Keycloak DB now
|
||||
String lastName = user.getLastName();
|
||||
Assert.assertEquals("Direct", lastName);
|
||||
|
||||
} finally {
|
||||
keycloakRule.stopSession(session, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// TODO: Rather separate test for fullNameMapper to better test all the possibilities
|
||||
@Test
|
||||
public void testFullNameMapper() {
|
||||
KeycloakSession session = keycloakRule.startSession();
|
||||
UserFederationMapperModel firstNameMapper = null;
|
||||
|
||||
try {
|
||||
RealmModel appRealm = new RealmManager(session).getRealmByName("test");
|
||||
|
||||
// assert that user "fullnameUser" is not in local DB
|
||||
Assert.assertNull(session.users().getUserByUsername("fullname", appRealm));
|
||||
|
||||
// Add the user with some fullName into LDAP directly. Ensure that fullName is saved into "cn" attribute in LDAP (currently mapped to model firstName)
|
||||
LDAPFederationProvider ldapFedProvider = FederationTestUtils.getLdapProvider(session, ldapModel);
|
||||
FederationTestUtils.addLDAPUser(ldapFedProvider, appRealm, "fullname", "James Dee", "Dee", "fullname@email.org", null, "4578");
|
||||
|
||||
// add fullname mapper to the provider and remove "firstNameMapper". For this test, we will simply map full name to the LDAP attribute, which was before firstName ( "givenName" on active directory, "cn" on other LDAP servers)
|
||||
firstNameMapper = appRealm.getUserFederationMapperByName(ldapModel.getId(), "first name");
|
||||
String ldapFirstNameAttributeName = firstNameMapper.getConfig().get(UserAttributeLDAPFederationMapper.LDAP_ATTRIBUTE);
|
||||
appRealm.removeUserFederationMapper(firstNameMapper);
|
||||
|
||||
UserFederationMapperModel fullNameMapperModel = KeycloakModelUtils.createUserFederationMapperModel("full name", ldapModel.getId(), FullNameLDAPFederationMapperFactory.PROVIDER_ID,
|
||||
FullNameLDAPFederationMapper.LDAP_FULL_NAME_ATTRIBUTE, ldapFirstNameAttributeName,
|
||||
FullNameLDAPFederationMapper.READ_ONLY, "false");
|
||||
appRealm.addUserFederationMapper(fullNameMapperModel);
|
||||
} finally {
|
||||
keycloakRule.stopSession(session, true);
|
||||
}
|
||||
|
||||
session = keycloakRule.startSession();
|
||||
try {
|
||||
RealmModel appRealm = new RealmManager(session).getRealmByName("test");
|
||||
|
||||
// Assert user is successfully imported in Keycloak DB now with correct firstName and lastName
|
||||
FederationTestUtils.assertUserImported(session.users(), appRealm, "fullname", "James", "Dee", "fullname@email.org", "4578");
|
||||
|
||||
// change mapper to writeOnly
|
||||
UserFederationMapperModel fullNameMapperModel = appRealm.getUserFederationMapperByName(ldapModel.getId(), "full name");
|
||||
fullNameMapperModel.getConfig().put(FullNameLDAPFederationMapper.WRITE_ONLY, "true");
|
||||
appRealm.updateUserFederationMapper(fullNameMapperModel);
|
||||
} finally {
|
||||
keycloakRule.stopSession(session, true);
|
||||
}
|
||||
|
||||
|
||||
// Assert changing user in Keycloak will change him in LDAP too...
|
||||
session = keycloakRule.startSession();
|
||||
try {
|
||||
RealmModel appRealm = new RealmManager(session).getRealmByName("test");
|
||||
|
||||
UserModel fullnameUser = session.users().getUserByUsername("fullname", appRealm);
|
||||
fullnameUser.setFirstName("James2");
|
||||
fullnameUser.setLastName("Dee2");
|
||||
} finally {
|
||||
keycloakRule.stopSession(session, true);
|
||||
}
|
||||
|
||||
|
||||
// Assert changed user available in Keycloak
|
||||
session = keycloakRule.startSession();
|
||||
try {
|
||||
RealmModel appRealm = new RealmManager(session).getRealmByName("test");
|
||||
|
||||
// Assert user is successfully imported in Keycloak DB now with correct firstName and lastName
|
||||
FederationTestUtils.assertUserImported(session.users(), appRealm, "fullname", "James2", "Dee2", "fullname@email.org", "4578");
|
||||
|
||||
// Remove "fullnameUser" to assert he is removed from LDAP. Revert mappers to previous state
|
||||
UserModel fullnameUser = session.users().getUserByUsername("fullname", appRealm);
|
||||
session.users().removeUser(appRealm, fullnameUser);
|
||||
|
||||
// Revert mappers
|
||||
UserFederationMapperModel fullNameMapperModel = appRealm.getUserFederationMapperByName(ldapModel.getId(), "full name");
|
||||
appRealm.removeUserFederationMapper(fullNameMapperModel);
|
||||
|
||||
firstNameMapper.setId(null);
|
||||
appRealm.addUserFederationMapper(firstNameMapper);
|
||||
} finally {
|
||||
keycloakRule.stopSession(session, true);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHardcodedRoleMapper() {
|
||||
KeycloakSession session = keycloakRule.startSession();
|
||||
UserFederationMapperModel firstNameMapper = null;
|
||||
|
||||
try {
|
||||
RealmModel appRealm = new RealmManager(session).getRealmByName("test");
|
||||
RoleModel hardcodedRole = appRealm.addRole("hardcoded-role");
|
||||
|
||||
// assert that user "johnkeycloak" doesn't have hardcoded role
|
||||
UserModel john = session.users().getUserByUsername("johnkeycloak", appRealm);
|
||||
Assert.assertFalse(john.hasRole(hardcodedRole));
|
||||
|
||||
UserFederationMapperModel hardcodedMapperModel = KeycloakModelUtils.createUserFederationMapperModel("hardcoded role", ldapModel.getId(), HardcodedLDAPRoleMapperFactory.PROVIDER_ID,
|
||||
HardcodedLDAPRoleMapper.ROLE, "hardcoded-role");
|
||||
appRealm.addUserFederationMapper(hardcodedMapperModel);
|
||||
} finally {
|
||||
keycloakRule.stopSession(session, true);
|
||||
}
|
||||
|
||||
session = keycloakRule.startSession();
|
||||
try {
|
||||
RealmModel appRealm = new RealmManager(session).getRealmByName("test");
|
||||
RoleModel hardcodedRole = appRealm.getRole("hardcoded-role");
|
||||
|
||||
// Assert user is successfully imported in Keycloak DB now with correct firstName and lastName
|
||||
UserModel john = session.users().getUserByUsername("johnkeycloak", appRealm);
|
||||
Assert.assertTrue(john.hasRole(hardcodedRole));
|
||||
|
||||
// Can't remove user from hardcoded role
|
||||
try {
|
||||
john.deleteRoleMapping(hardcodedRole);
|
||||
Assert.fail("Didn't expected to remove role mapping");
|
||||
} catch (ModelException expected) {
|
||||
}
|
||||
|
||||
// Revert mappers
|
||||
UserFederationMapperModel hardcodedMapperModel = appRealm.getUserFederationMapperByName(ldapModel.getId(), "hardcoded role");
|
||||
appRealm.removeUserFederationMapper(hardcodedMapperModel);
|
||||
} finally {
|
||||
keycloakRule.stopSession(session, true);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testImportExistingUserFromLDAP() throws Exception {
|
||||
// Add LDAP user with same email like existing model user
|
||||
keycloakRule.update(new KeycloakRule.KeycloakSetup() {
|
||||
|
||||
@Override
|
||||
public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
|
||||
LDAPFederationProvider ldapFedProvider = FederationTestUtils.getLdapProvider(session, ldapModel);
|
||||
FederationTestUtils.addLDAPUser(ldapFedProvider, appRealm, "marykeycloak", "Mary1", "Kelly1", "mary1@email.org", null, "123");
|
||||
FederationTestUtils.addLDAPUser(ldapFedProvider, appRealm, "mary-duplicatemail", "Mary2", "Kelly2", "mary@test.com", null, "123");
|
||||
LDAPObject marynoemail = FederationTestUtils.addLDAPUser(ldapFedProvider, appRealm, "marynoemail", "Mary1", "Kelly1", null, null, "123");
|
||||
FederationTestUtils.updateLDAPPassword(ldapFedProvider, marynoemail, "Password1");
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
// Try to import the duplicated LDAP user into Keycloak
|
||||
loginPage.open();
|
||||
loginPage.login("mary-duplicatemail", "password");
|
||||
Assert.assertEquals("Email already exists.", loginPage.getError());
|
||||
|
||||
loginPage.login("mary1@email.org", "password");
|
||||
Assert.assertEquals("Username already exists.", loginPage.getError());
|
||||
|
||||
loginSuccessAndLogout("marynoemail", "Password1");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReadonly() {
|
||||
KeycloakSession session = keycloakRule.startSession();
|
||||
try {
|
||||
RealmModel appRealm = session.realms().getRealmByName("test");
|
||||
|
||||
UserFederationProviderModel model = new UserFederationProviderModel(ldapModel.getId(), ldapModel.getProviderName(), ldapModel.getConfig(),
|
||||
ldapModel.getPriority(), ldapModel.getDisplayName(), -1, -1, 0);
|
||||
model.getConfig().put(LDAPConstants.EDIT_MODE, UserFederationProvider.EditMode.READ_ONLY.toString());
|
||||
appRealm.updateUserFederationProvider(model);
|
||||
UserModel user = session.users().getUserByUsername("johnkeycloak", appRealm);
|
||||
Assert.assertNotNull(user);
|
||||
Assert.assertNotNull(user.getFederationLink());
|
||||
Assert.assertEquals(user.getFederationLink(), ldapModel.getId());
|
||||
try {
|
||||
user.setEmail("error@error.com");
|
||||
Assert.fail("should fail");
|
||||
} catch (ModelReadOnlyException e) {
|
||||
|
||||
}
|
||||
try {
|
||||
user.setLastName("Berk");
|
||||
Assert.fail("should fail");
|
||||
} catch (ModelReadOnlyException e) {
|
||||
|
||||
}
|
||||
try {
|
||||
user.setFirstName("Bilbo");
|
||||
Assert.fail("should fail");
|
||||
} catch (ModelReadOnlyException e) {
|
||||
|
||||
}
|
||||
try {
|
||||
UserCredentialModel cred = UserCredentialModel.password("PoopyPoop1");
|
||||
session.userCredentialManager().updateCredential(appRealm, user, cred);
|
||||
Assert.fail("should fail");
|
||||
} catch (ModelReadOnlyException e) {
|
||||
|
||||
}
|
||||
|
||||
Assert.assertTrue(session.users().removeUser(appRealm, user));
|
||||
} finally {
|
||||
keycloakRule.stopSession(session, false);
|
||||
}
|
||||
|
||||
session = keycloakRule.startSession();
|
||||
try {
|
||||
RealmModel appRealm = session.realms().getRealmByName("test");
|
||||
Assert.assertEquals(UserFederationProvider.EditMode.WRITABLE.toString(), appRealm.getUserFederationProviders().get(0).getConfig().get(LDAPConstants.EDIT_MODE));
|
||||
} finally {
|
||||
keycloakRule.stopSession(session, false);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRemoveFederatedUser() {
|
||||
KeycloakSession session = keycloakRule.startSession();
|
||||
try {
|
||||
RealmModel appRealm = session.realms().getRealmByName("test");
|
||||
UserModel user = session.users().getUserByUsername("registerUserSuccess2", appRealm);
|
||||
Assert.assertNotNull(user);
|
||||
Assert.assertNotNull(user.getFederationLink());
|
||||
Assert.assertEquals(user.getFederationLink(), ldapModel.getId());
|
||||
|
||||
Assert.assertTrue(session.users().removeUser(appRealm, user));
|
||||
Assert.assertNull(session.users().getUserByUsername("registerUserSuccess2", appRealm));
|
||||
} finally {
|
||||
keycloakRule.stopSession(session, true);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSearch() {
|
||||
KeycloakSession session = keycloakRule.startSession();
|
||||
try {
|
||||
RealmModel appRealm = session.realms().getRealmByName("test");
|
||||
LDAPFederationProvider ldapProvider = FederationTestUtils.getLdapProvider(session, ldapModel);
|
||||
|
||||
FederationTestUtils.addLDAPUser(ldapProvider, appRealm, "username1", "John1", "Doel1", "user1@email.org", null, "121");
|
||||
FederationTestUtils.addLDAPUser(ldapProvider, appRealm, "username2", "John2", "Doel2", "user2@email.org", null, "122");
|
||||
FederationTestUtils.addLDAPUser(ldapProvider, appRealm, "username3", "John3", "Doel3", "user3@email.org", null, "123");
|
||||
FederationTestUtils.addLDAPUser(ldapProvider, appRealm, "username4", "John4", "Doel4", "user4@email.org", null, "124");
|
||||
|
||||
// Users are not at local store at this moment
|
||||
Assert.assertNull(session.userStorage().getUserByUsername("username1", appRealm));
|
||||
Assert.assertNull(session.userStorage().getUserByUsername("username2", appRealm));
|
||||
Assert.assertNull(session.userStorage().getUserByUsername("username3", appRealm));
|
||||
Assert.assertNull(session.userStorage().getUserByUsername("username4", appRealm));
|
||||
|
||||
// search by username
|
||||
session.users().searchForUser("username1", appRealm);
|
||||
FederationTestUtils.assertUserImported(session.userStorage(), appRealm, "username1", "John1", "Doel1", "user1@email.org", "121");
|
||||
|
||||
// search by email
|
||||
session.users().searchForUser("user2@email.org", appRealm);
|
||||
FederationTestUtils.assertUserImported(session.userStorage(), appRealm, "username2", "John2", "Doel2", "user2@email.org", "122");
|
||||
|
||||
// search by lastName
|
||||
session.users().searchForUser("Doel3", appRealm);
|
||||
FederationTestUtils.assertUserImported(session.userStorage(), appRealm, "username3", "John3", "Doel3", "user3@email.org", "123");
|
||||
|
||||
// search by firstName + lastName
|
||||
session.users().searchForUser("John4 Doel4", appRealm);
|
||||
FederationTestUtils.assertUserImported(session.userStorage(), appRealm, "username4", "John4", "Doel4", "user4@email.org", "124");
|
||||
} finally {
|
||||
keycloakRule.stopSession(session, true);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSearchWithCustomLDAPFilter() {
|
||||
// Add custom filter for searching users
|
||||
KeycloakSession session = keycloakRule.startSession();
|
||||
try {
|
||||
RealmModel appRealm = session.realms().getRealmByName("test");
|
||||
ldapModel.getConfig().put(LDAPConstants.CUSTOM_USER_SEARCH_FILTER, "(|(mail=user5@email.org)(mail=user6@email.org))");
|
||||
appRealm.updateUserFederationProvider(ldapModel);
|
||||
} finally {
|
||||
keycloakRule.stopSession(session, true);
|
||||
}
|
||||
|
||||
session = keycloakRule.startSession();
|
||||
try {
|
||||
LDAPFederationProvider ldapProvider = FederationTestUtils.getLdapProvider(session, ldapModel);
|
||||
RealmModel appRealm = session.realms().getRealmByName("test");
|
||||
|
||||
FederationTestUtils.addLDAPUser(ldapProvider, appRealm, "username5", "John5", "Doel5", "user5@email.org", null, "125");
|
||||
FederationTestUtils.addLDAPUser(ldapProvider, appRealm, "username6", "John6", "Doel6", "user6@email.org", null, "126");
|
||||
FederationTestUtils.addLDAPUser(ldapProvider, appRealm, "username7", "John7", "Doel7", "user7@email.org", null, "127");
|
||||
|
||||
// search by email
|
||||
session.users().searchForUser("user5@email.org", appRealm);
|
||||
FederationTestUtils.assertUserImported(session.userStorage(), appRealm, "username5", "John5", "Doel5", "user5@email.org", "125");
|
||||
|
||||
session.users().searchForUser("John6 Doel6", appRealm);
|
||||
FederationTestUtils.assertUserImported(session.userStorage(), appRealm, "username6", "John6", "Doel6", "user6@email.org", "126");
|
||||
|
||||
session.users().searchForUser("user7@email.org", appRealm);
|
||||
session.users().searchForUser("John7 Doel7", appRealm);
|
||||
Assert.assertNull(session.userStorage().getUserByUsername("username7", appRealm));
|
||||
|
||||
// Remove custom filter
|
||||
ldapModel.getConfig().remove(LDAPConstants.CUSTOM_USER_SEARCH_FILTER);
|
||||
appRealm.updateUserFederationProvider(ldapModel);
|
||||
} finally {
|
||||
keycloakRule.stopSession(session, true);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUnsynced() throws Exception {
|
||||
KeycloakSession session = keycloakRule.startSession();
|
||||
try {
|
||||
RealmModel appRealm = session.realms().getRealmByName("test");
|
||||
|
||||
UserFederationProviderModel model = new UserFederationProviderModel(ldapModel.getId(), ldapModel.getProviderName(), ldapModel.getConfig(), ldapModel.getPriority(),
|
||||
ldapModel.getDisplayName(), -1, -1, 0);
|
||||
model.getConfig().put(LDAPConstants.EDIT_MODE, UserFederationProvider.EditMode.UNSYNCED.toString());
|
||||
appRealm.updateUserFederationProvider(model);
|
||||
UserModel user = session.users().getUserByUsername("johnkeycloak", appRealm);
|
||||
Assert.assertNotNull(user);
|
||||
Assert.assertNotNull(user.getFederationLink());
|
||||
Assert.assertEquals(user.getFederationLink(), ldapModel.getId());
|
||||
|
||||
UserCredentialModel cred = UserCredentialModel.password("Candycand1");
|
||||
session.userCredentialManager().updateCredential(appRealm, user, cred);
|
||||
CredentialModel userCredentialValueModel = session.userCredentialManager().getStoredCredentialsByType(appRealm, user, CredentialModel.PASSWORD).get(0);
|
||||
Assert.assertEquals(UserCredentialModel.PASSWORD, userCredentialValueModel.getType());
|
||||
Assert.assertTrue(session.userCredentialManager().isValid(appRealm, user, cred));
|
||||
|
||||
// LDAP password is still unchanged
|
||||
LDAPFederationProvider ldapProvider = FederationTestUtils.getLdapProvider(session, model);
|
||||
LDAPObject ldapUser = ldapProvider.loadLDAPUserByUsername(appRealm, "johnkeycloak");
|
||||
ldapProvider.getLdapIdentityStore().validatePassword(ldapUser, "Password1");
|
||||
|
||||
// User is deleted just locally
|
||||
Assert.assertTrue(session.users().removeUser(appRealm, user));
|
||||
|
||||
// Assert user not available locally, but will be reimported from LDAP once searched
|
||||
Assert.assertNull(session.userStorage().getUserByUsername("johnkeycloak", appRealm));
|
||||
Assert.assertNotNull(session.users().getUserByUsername("johnkeycloak", appRealm));
|
||||
} finally {
|
||||
keycloakRule.stopSession(session, false);
|
||||
}
|
||||
|
||||
session = keycloakRule.startSession();
|
||||
try {
|
||||
RealmModel appRealm = session.realms().getRealmByName("test");
|
||||
Assert.assertEquals(UserFederationProvider.EditMode.WRITABLE.toString(), appRealm.getUserFederationProviders().get(0).getConfig().get(LDAPConstants.EDIT_MODE));
|
||||
} finally {
|
||||
keycloakRule.stopSession(session, false);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,252 +0,0 @@
|
|||
/*
|
||||
* 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.ldap.base;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.ClassRule;
|
||||
import org.junit.FixMethodOrder;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runners.MethodSorters;
|
||||
import org.keycloak.federation.ldap.LDAPFederationProvider;
|
||||
import org.keycloak.federation.ldap.LDAPFederationProviderFactory;
|
||||
import org.keycloak.federation.ldap.mappers.membership.LDAPGroupMapperMode;
|
||||
import org.keycloak.federation.ldap.mappers.membership.group.GroupLDAPFederationMapperFactory;
|
||||
import org.keycloak.federation.ldap.mappers.membership.group.GroupMapperConfig;
|
||||
import org.keycloak.models.GroupModel;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.LDAPConstants;
|
||||
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.utils.KeycloakModelUtils;
|
||||
import org.keycloak.services.managers.RealmManager;
|
||||
import org.keycloak.testsuite.federation.ldap.FederationTestUtils;
|
||||
import org.keycloak.testsuite.rule.KeycloakRule;
|
||||
import org.keycloak.testsuite.rule.LDAPRule;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||
*/
|
||||
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
|
||||
public class LDAPGroupMapper2WaySyncTest {
|
||||
|
||||
@ClassRule
|
||||
public static LDAPRule ldapRule = new LDAPRule();
|
||||
|
||||
private static UserFederationProviderModel ldapModel = null;
|
||||
private static String descriptionAttrName = null;
|
||||
|
||||
@Rule
|
||||
public KeycloakRule keycloakRule = new KeycloakRule(new KeycloakRule.KeycloakSetup() {
|
||||
|
||||
@Override
|
||||
public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
|
||||
Map<String,String> ldapConfig = ldapRule.getConfig();
|
||||
ldapConfig.put(LDAPConstants.SYNC_REGISTRATIONS, "true");
|
||||
ldapConfig.put(LDAPConstants.EDIT_MODE, UserFederationProvider.EditMode.WRITABLE.toString());
|
||||
ldapConfig.put(LDAPConstants.BATCH_SIZE_FOR_SYNC, "4"); // Issues with pagination on ApacheDS
|
||||
|
||||
ldapModel = appRealm.addUserFederationProvider(LDAPFederationProviderFactory.PROVIDER_NAME, ldapConfig, 0, "test-ldap", -1, -1, 0);
|
||||
LDAPFederationProvider ldapFedProvider = FederationTestUtils.getLdapProvider(session, ldapModel);
|
||||
descriptionAttrName = ldapFedProvider.getLdapIdentityStore().getConfig().isActiveDirectory() ? "displayName" : "description";
|
||||
|
||||
// Add group mapper
|
||||
FederationTestUtils.addOrUpdateGroupMapper(appRealm, ldapModel, LDAPGroupMapperMode.LDAP_ONLY, descriptionAttrName);
|
||||
|
||||
// Remove all LDAP groups
|
||||
FederationTestUtils.removeAllLDAPGroups(session, appRealm, ldapModel, "groupsMapper");
|
||||
|
||||
// Add some groups for testing into Keycloak
|
||||
removeAllModelGroups(appRealm);
|
||||
|
||||
GroupModel group1 = appRealm.createGroup("group1");
|
||||
appRealm.moveGroup(group1, null);
|
||||
group1.setSingleAttribute(descriptionAttrName, "group1 - description1");
|
||||
|
||||
GroupModel group11 = appRealm.createGroup("group11");
|
||||
appRealm.moveGroup(group11, group1);
|
||||
|
||||
GroupModel group12 = appRealm.createGroup("group12");
|
||||
appRealm.moveGroup(group12, group1);
|
||||
group12.setSingleAttribute(descriptionAttrName, "group12 - description12");
|
||||
|
||||
GroupModel group2 = appRealm.createGroup("group2");
|
||||
appRealm.moveGroup(group2, null);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@Test
|
||||
public void test01_syncNoPreserveGroupInheritance() throws Exception {
|
||||
KeycloakSession session = keycloakRule.startSession();
|
||||
try {
|
||||
RealmModel realm = session.realms().getRealmByName("test");
|
||||
UserFederationMapperModel mapperModel = realm.getUserFederationMapperByName(ldapModel.getId(), "groupsMapper");
|
||||
LDAPFederationProvider ldapProvider = FederationTestUtils.getLdapProvider(session, ldapModel);
|
||||
|
||||
// Update group mapper to skip preserve inheritance and check it will pass now
|
||||
FederationTestUtils.updateGroupMapperConfigOptions(mapperModel, GroupMapperConfig.PRESERVE_GROUP_INHERITANCE, "false");
|
||||
realm.updateUserFederationMapper(mapperModel);
|
||||
|
||||
// Sync from Keycloak into LDAP
|
||||
UserFederationSyncResult syncResult = new GroupLDAPFederationMapperFactory().create(session).syncDataFromKeycloakToFederationProvider(mapperModel, ldapProvider, session, realm);
|
||||
FederationTestUtils.assertSyncEquals(syncResult, 4, 0, 0, 0);
|
||||
} finally {
|
||||
keycloakRule.stopSession(session, true);
|
||||
}
|
||||
|
||||
session = keycloakRule.startSession();
|
||||
try {
|
||||
RealmModel realm = session.realms().getRealmByName("test");
|
||||
|
||||
// Delete all KC groups now
|
||||
removeAllModelGroups(realm);
|
||||
Assert.assertNull(KeycloakModelUtils.findGroupByPath(realm, "/group1"));
|
||||
Assert.assertNull(KeycloakModelUtils.findGroupByPath(realm, "/group11"));
|
||||
Assert.assertNull(KeycloakModelUtils.findGroupByPath(realm, "/group2"));
|
||||
} finally {
|
||||
keycloakRule.stopSession(session, true);
|
||||
}
|
||||
|
||||
|
||||
|
||||
session = keycloakRule.startSession();
|
||||
try {
|
||||
RealmModel realm = session.realms().getRealmByName("test");
|
||||
UserFederationMapperModel mapperModel = realm.getUserFederationMapperByName(ldapModel.getId(), "groupsMapper");
|
||||
LDAPFederationProvider ldapProvider = FederationTestUtils.getLdapProvider(session, ldapModel);
|
||||
|
||||
// Sync from LDAP back into Keycloak
|
||||
UserFederationSyncResult syncResult = new GroupLDAPFederationMapperFactory().create(session).syncDataFromFederationProviderToKeycloak(mapperModel, ldapProvider, session, realm);
|
||||
FederationTestUtils.assertSyncEquals(syncResult, 4, 0, 0, 0);
|
||||
|
||||
// Assert groups are imported to keycloak. All are at top level
|
||||
GroupModel kcGroup1 = KeycloakModelUtils.findGroupByPath(realm, "/group1");
|
||||
GroupModel kcGroup11 = KeycloakModelUtils.findGroupByPath(realm, "/group11");
|
||||
GroupModel kcGroup12 = KeycloakModelUtils.findGroupByPath(realm, "/group12");
|
||||
GroupModel kcGroup2 = KeycloakModelUtils.findGroupByPath(realm, "/group2");
|
||||
|
||||
Assert.assertEquals(0, kcGroup1.getSubGroups().size());
|
||||
|
||||
Assert.assertEquals("group1 - description1", kcGroup1.getFirstAttribute(descriptionAttrName));
|
||||
Assert.assertNull(kcGroup11.getFirstAttribute(descriptionAttrName));
|
||||
Assert.assertEquals("group12 - description12", kcGroup12.getFirstAttribute(descriptionAttrName));
|
||||
Assert.assertNull(kcGroup2.getFirstAttribute(descriptionAttrName));
|
||||
|
||||
// test drop non-existing works
|
||||
testDropNonExisting(session, realm, mapperModel, ldapProvider);
|
||||
} finally {
|
||||
keycloakRule.stopSession(session, true);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test02_syncWithGroupInheritance() throws Exception {
|
||||
KeycloakSession session = keycloakRule.startSession();
|
||||
try {
|
||||
RealmModel realm = session.realms().getRealmByName("test");
|
||||
UserFederationMapperModel mapperModel = realm.getUserFederationMapperByName(ldapModel.getId(), "groupsMapper");
|
||||
LDAPFederationProvider ldapProvider = FederationTestUtils.getLdapProvider(session, ldapModel);
|
||||
|
||||
// Update group mapper to skip preserve inheritance and check it will pass now
|
||||
FederationTestUtils.updateGroupMapperConfigOptions(mapperModel, GroupMapperConfig.PRESERVE_GROUP_INHERITANCE, "true");
|
||||
realm.updateUserFederationMapper(mapperModel);
|
||||
|
||||
// Sync from Keycloak into LDAP
|
||||
UserFederationSyncResult syncResult = new GroupLDAPFederationMapperFactory().create(session).syncDataFromKeycloakToFederationProvider(mapperModel, ldapProvider, session, realm);
|
||||
FederationTestUtils.assertSyncEquals(syncResult, 4, 0, 0, 0);
|
||||
} finally {
|
||||
keycloakRule.stopSession(session, true);
|
||||
}
|
||||
|
||||
session = keycloakRule.startSession();
|
||||
try {
|
||||
RealmModel realm = session.realms().getRealmByName("test");
|
||||
|
||||
// Delete all KC groups now
|
||||
removeAllModelGroups(realm);
|
||||
Assert.assertNull(KeycloakModelUtils.findGroupByPath(realm, "/group1"));
|
||||
Assert.assertNull(KeycloakModelUtils.findGroupByPath(realm, "/group11"));
|
||||
Assert.assertNull(KeycloakModelUtils.findGroupByPath(realm, "/group2"));
|
||||
} finally {
|
||||
keycloakRule.stopSession(session, true);
|
||||
}
|
||||
|
||||
|
||||
|
||||
session = keycloakRule.startSession();
|
||||
try {
|
||||
RealmModel realm = session.realms().getRealmByName("test");
|
||||
UserFederationMapperModel mapperModel = realm.getUserFederationMapperByName(ldapModel.getId(), "groupsMapper");
|
||||
LDAPFederationProvider ldapProvider = FederationTestUtils.getLdapProvider(session, ldapModel);
|
||||
|
||||
// Sync from LDAP back into Keycloak
|
||||
UserFederationSyncResult syncResult = new GroupLDAPFederationMapperFactory().create(session).syncDataFromFederationProviderToKeycloak(mapperModel, ldapProvider, session, realm);
|
||||
FederationTestUtils.assertSyncEquals(syncResult, 4, 0, 0, 0);
|
||||
|
||||
// Assert groups are imported to keycloak. All are at top level
|
||||
GroupModel kcGroup1 = KeycloakModelUtils.findGroupByPath(realm, "/group1");
|
||||
GroupModel kcGroup11 = KeycloakModelUtils.findGroupByPath(realm, "/group1/group11");
|
||||
GroupModel kcGroup12 = KeycloakModelUtils.findGroupByPath(realm, "/group1/group12");
|
||||
GroupModel kcGroup2 = KeycloakModelUtils.findGroupByPath(realm, "/group2");
|
||||
|
||||
Assert.assertEquals(2, kcGroup1.getSubGroups().size());
|
||||
|
||||
Assert.assertEquals("group1 - description1", kcGroup1.getFirstAttribute(descriptionAttrName));
|
||||
Assert.assertNull(kcGroup11.getFirstAttribute(descriptionAttrName));
|
||||
Assert.assertEquals("group12 - description12", kcGroup12.getFirstAttribute(descriptionAttrName));
|
||||
Assert.assertNull(kcGroup2.getFirstAttribute(descriptionAttrName));
|
||||
|
||||
// test drop non-existing works
|
||||
testDropNonExisting(session, realm, mapperModel, ldapProvider);
|
||||
} finally {
|
||||
keycloakRule.stopSession(session, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static void removeAllModelGroups(RealmModel appRealm) {
|
||||
for (GroupModel group : appRealm.getTopLevelGroups()) {
|
||||
appRealm.removeGroup(group);
|
||||
}
|
||||
}
|
||||
|
||||
private void testDropNonExisting(KeycloakSession session, RealmModel realm, UserFederationMapperModel mapperModel, LDAPFederationProvider ldapProvider) {
|
||||
// Put some group directly to LDAP
|
||||
FederationTestUtils.createLDAPGroup(session, realm, ldapModel, "group3");
|
||||
|
||||
// Sync and assert our group is still in LDAP
|
||||
UserFederationSyncResult syncResult = new GroupLDAPFederationMapperFactory().create(session).syncDataFromKeycloakToFederationProvider(mapperModel, ldapProvider, session, realm);
|
||||
FederationTestUtils.assertSyncEquals(syncResult, 0, 4, 0, 0);
|
||||
Assert.assertNotNull(FederationTestUtils.getGroupMapper(mapperModel, ldapProvider, realm).loadLDAPGroupByName("group3"));
|
||||
|
||||
// Change config to drop non-existing groups
|
||||
FederationTestUtils.updateGroupMapperConfigOptions(mapperModel, GroupMapperConfig.DROP_NON_EXISTING_GROUPS_DURING_SYNC, "true");
|
||||
realm.updateUserFederationMapper(mapperModel);
|
||||
|
||||
// Sync and assert group removed from LDAP
|
||||
syncResult = new GroupLDAPFederationMapperFactory().create(session).syncDataFromKeycloakToFederationProvider(mapperModel, ldapProvider, session, realm);
|
||||
FederationTestUtils.assertSyncEquals(syncResult, 0, 4, 1, 0);
|
||||
Assert.assertNull(FederationTestUtils.getGroupMapper(mapperModel, ldapProvider, realm).loadLDAPGroupByName("group3"));
|
||||
}
|
||||
}
|
|
@ -1,312 +0,0 @@
|
|||
/*
|
||||
* 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.ldap.base;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.ClassRule;
|
||||
import org.junit.FixMethodOrder;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.RuleChain;
|
||||
import org.junit.rules.TestRule;
|
||||
import org.junit.runners.MethodSorters;
|
||||
import org.keycloak.federation.ldap.LDAPFederationProvider;
|
||||
import org.keycloak.federation.ldap.LDAPFederationProviderFactory;
|
||||
import org.keycloak.federation.ldap.LDAPUtils;
|
||||
import org.keycloak.federation.ldap.idm.model.LDAPObject;
|
||||
import org.keycloak.federation.ldap.mappers.membership.LDAPGroupMapperMode;
|
||||
import org.keycloak.federation.ldap.mappers.membership.MembershipType;
|
||||
import org.keycloak.federation.ldap.mappers.membership.group.GroupLDAPFederationMapper;
|
||||
import org.keycloak.federation.ldap.mappers.membership.group.GroupLDAPFederationMapperFactory;
|
||||
import org.keycloak.federation.ldap.mappers.membership.group.GroupMapperConfig;
|
||||
import org.keycloak.models.GroupModel;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.LDAPConstants;
|
||||
import org.keycloak.models.ModelException;
|
||||
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.models.utils.KeycloakModelUtils;
|
||||
import org.keycloak.services.managers.RealmManager;
|
||||
import org.keycloak.testsuite.federation.ldap.FederationTestUtils;
|
||||
import org.keycloak.testsuite.rule.KeycloakRule;
|
||||
import org.keycloak.testsuite.rule.LDAPRule;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||
*/
|
||||
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
|
||||
public class LDAPGroupMapperSyncTest {
|
||||
|
||||
private static LDAPRule ldapRule = new LDAPRule();
|
||||
|
||||
private static UserFederationProviderModel ldapModel = null;
|
||||
private static String descriptionAttrName = null;
|
||||
|
||||
private static KeycloakRule keycloakRule = new KeycloakRule(new KeycloakRule.KeycloakSetup() {
|
||||
|
||||
@Override
|
||||
public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
|
||||
Map<String,String> ldapConfig = ldapRule.getConfig();
|
||||
ldapConfig.put(LDAPConstants.SYNC_REGISTRATIONS, "true");
|
||||
ldapConfig.put(LDAPConstants.EDIT_MODE, UserFederationProvider.EditMode.WRITABLE.toString());
|
||||
|
||||
ldapModel = appRealm.addUserFederationProvider(LDAPFederationProviderFactory.PROVIDER_NAME, ldapConfig, 0, "test-ldap", -1, -1, 0);
|
||||
LDAPFederationProvider ldapFedProvider = FederationTestUtils.getLdapProvider(session, ldapModel);
|
||||
descriptionAttrName = ldapFedProvider.getLdapIdentityStore().getConfig().isActiveDirectory() ? "displayName" : "description";
|
||||
|
||||
// Add group mapper
|
||||
FederationTestUtils.addOrUpdateGroupMapper(appRealm, ldapModel, LDAPGroupMapperMode.LDAP_ONLY, descriptionAttrName);
|
||||
|
||||
// Remove all LDAP groups
|
||||
FederationTestUtils.removeAllLDAPGroups(session, appRealm, ldapModel, "groupsMapper");
|
||||
|
||||
// Add some groups for testing
|
||||
LDAPObject group1 = FederationTestUtils.createLDAPGroup(manager.getSession(), appRealm, ldapModel, "group1", descriptionAttrName, "group1 - description");
|
||||
LDAPObject group11 = FederationTestUtils.createLDAPGroup(manager.getSession(), appRealm, ldapModel, "group11");
|
||||
LDAPObject group12 = FederationTestUtils.createLDAPGroup(manager.getSession(), appRealm, ldapModel, "group12", descriptionAttrName, "group12 - description");
|
||||
|
||||
LDAPUtils.addMember(ldapFedProvider, MembershipType.DN, LDAPConstants.MEMBER, group1, group11, false);
|
||||
LDAPUtils.addMember(ldapFedProvider, MembershipType.DN, LDAPConstants.MEMBER, group1, group12, true);
|
||||
}
|
||||
});
|
||||
|
||||
@ClassRule
|
||||
public static TestRule chain = RuleChain
|
||||
.outerRule(ldapRule)
|
||||
.around(keycloakRule);
|
||||
|
||||
@Before
|
||||
public void before() {
|
||||
KeycloakSession session = keycloakRule.startSession();
|
||||
try {
|
||||
RealmModel realm = session.realms().getRealmByName("test");
|
||||
List<GroupModel> kcGroups = realm.getTopLevelGroups();
|
||||
for (GroupModel kcGroup : kcGroups) {
|
||||
realm.removeGroup(kcGroup);
|
||||
}
|
||||
} finally {
|
||||
keycloakRule.stopSession(session, true);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test01_syncNoPreserveGroupInheritance() throws Exception {
|
||||
KeycloakSession session = keycloakRule.startSession();
|
||||
try {
|
||||
RealmModel realm = session.realms().getRealmByName("test");
|
||||
UserFederationMapperModel mapperModel = realm.getUserFederationMapperByName(ldapModel.getId(), "groupsMapper");
|
||||
LDAPFederationProvider ldapProvider = FederationTestUtils.getLdapProvider(session, ldapModel);
|
||||
GroupLDAPFederationMapper groupMapper = FederationTestUtils.getGroupMapper(mapperModel, ldapProvider, realm);
|
||||
|
||||
// Add recursive group mapping to LDAP. Check that sync with preserve group inheritance will fail
|
||||
LDAPObject group1 = groupMapper.loadLDAPGroupByName("group1");
|
||||
LDAPObject group12 = groupMapper.loadLDAPGroupByName("group12");
|
||||
LDAPUtils.addMember(ldapProvider, MembershipType.DN, LDAPConstants.MEMBER, group12, group1, true);
|
||||
|
||||
try {
|
||||
new GroupLDAPFederationMapperFactory().create(session).syncDataFromFederationProviderToKeycloak(mapperModel, ldapProvider, session, realm);
|
||||
Assert.fail("Not expected group sync to pass");
|
||||
} catch (ModelException expected) {
|
||||
Assert.assertTrue(expected.getMessage().contains("Recursion detected"));
|
||||
}
|
||||
|
||||
// Update group mapper to skip preserve inheritance and check it will pass now
|
||||
FederationTestUtils.updateGroupMapperConfigOptions(mapperModel, GroupMapperConfig.PRESERVE_GROUP_INHERITANCE, "false");
|
||||
realm.updateUserFederationMapper(mapperModel);
|
||||
|
||||
new GroupLDAPFederationMapperFactory().create(session).syncDataFromFederationProviderToKeycloak(mapperModel, ldapProvider, session, realm);
|
||||
|
||||
// Assert groups are imported to keycloak. All are at top level
|
||||
GroupModel kcGroup1 = KeycloakModelUtils.findGroupByPath(realm, "/group1");
|
||||
GroupModel kcGroup11 = KeycloakModelUtils.findGroupByPath(realm, "/group11");
|
||||
GroupModel kcGroup12 = KeycloakModelUtils.findGroupByPath(realm, "/group12");
|
||||
|
||||
Assert.assertEquals(0, kcGroup1.getSubGroups().size());
|
||||
|
||||
Assert.assertEquals("group1 - description", kcGroup1.getFirstAttribute(descriptionAttrName));
|
||||
Assert.assertNull(kcGroup11.getFirstAttribute(descriptionAttrName));
|
||||
Assert.assertEquals("group12 - description", kcGroup12.getFirstAttribute(descriptionAttrName));
|
||||
|
||||
// Cleanup - remove recursive mapping in LDAP
|
||||
LDAPUtils.deleteMember(ldapProvider, MembershipType.DN, LDAPConstants.MEMBER, group12, group1, true);
|
||||
|
||||
} finally {
|
||||
keycloakRule.stopSession(session, false);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test02_syncWithGroupInheritance() throws Exception {
|
||||
KeycloakSession session = keycloakRule.startSession();
|
||||
try {
|
||||
RealmModel realm = session.realms().getRealmByName("test");
|
||||
UserFederationMapperModel mapperModel = realm.getUserFederationMapperByName(ldapModel.getId(), "groupsMapper");
|
||||
LDAPFederationProvider ldapProvider = FederationTestUtils.getLdapProvider(session, ldapModel);
|
||||
GroupLDAPFederationMapper groupMapper = FederationTestUtils.getGroupMapper(mapperModel, ldapProvider, realm);
|
||||
|
||||
// Sync groups with inheritance
|
||||
UserFederationSyncResult syncResult = new GroupLDAPFederationMapperFactory().create(session).syncDataFromFederationProviderToKeycloak(mapperModel, ldapProvider, session, realm);
|
||||
FederationTestUtils.assertSyncEquals(syncResult, 3, 0, 0, 0);
|
||||
|
||||
// Assert groups are imported to keycloak including their inheritance from LDAP
|
||||
GroupModel kcGroup1 = KeycloakModelUtils.findGroupByPath(realm, "/group1");
|
||||
Assert.assertNull(KeycloakModelUtils.findGroupByPath(realm, "/group11"));
|
||||
Assert.assertNull(KeycloakModelUtils.findGroupByPath(realm, "/group12"));
|
||||
GroupModel kcGroup11 = KeycloakModelUtils.findGroupByPath(realm, "/group1/group11");
|
||||
GroupModel kcGroup12 = KeycloakModelUtils.findGroupByPath(realm, "/group1/group12");
|
||||
|
||||
Assert.assertEquals(2, kcGroup1.getSubGroups().size());
|
||||
|
||||
Assert.assertEquals("group1 - description", kcGroup1.getFirstAttribute(descriptionAttrName));
|
||||
Assert.assertNull(kcGroup11.getFirstAttribute(descriptionAttrName));
|
||||
Assert.assertEquals("group12 - description", kcGroup12.getFirstAttribute(descriptionAttrName));
|
||||
|
||||
// Update description attributes in LDAP
|
||||
LDAPObject group1 = groupMapper.loadLDAPGroupByName("group1");
|
||||
group1.setSingleAttribute(descriptionAttrName, "group1 - changed description");
|
||||
ldapProvider.getLdapIdentityStore().update(group1);
|
||||
|
||||
LDAPObject group12 = groupMapper.loadLDAPGroupByName("group12");
|
||||
group12.setAttribute(descriptionAttrName, null);
|
||||
ldapProvider.getLdapIdentityStore().update(group12);
|
||||
|
||||
// Sync and assert groups updated
|
||||
syncResult = new GroupLDAPFederationMapperFactory().create(session).syncDataFromFederationProviderToKeycloak(mapperModel, ldapProvider, session, realm);
|
||||
FederationTestUtils.assertSyncEquals(syncResult, 0, 3, 0, 0);
|
||||
|
||||
// Assert attributes changed in keycloak
|
||||
kcGroup1 = KeycloakModelUtils.findGroupByPath(realm, "/group1");
|
||||
kcGroup12 = KeycloakModelUtils.findGroupByPath(realm, "/group1/group12");
|
||||
Assert.assertEquals("group1 - changed description", kcGroup1.getFirstAttribute(descriptionAttrName));
|
||||
Assert.assertNull(kcGroup12.getFirstAttribute(descriptionAttrName));
|
||||
} finally {
|
||||
keycloakRule.stopSession(session, false);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test03_syncWithDropNonExistingGroups() throws Exception {
|
||||
KeycloakSession session = keycloakRule.startSession();
|
||||
try {
|
||||
RealmModel realm = session.realms().getRealmByName("test");
|
||||
UserFederationMapperModel mapperModel = realm.getUserFederationMapperByName(ldapModel.getId(), "groupsMapper");
|
||||
LDAPFederationProvider ldapProvider = FederationTestUtils.getLdapProvider(session, ldapModel);
|
||||
|
||||
// Sync groups with inheritance
|
||||
UserFederationSyncResult syncResult = new GroupLDAPFederationMapperFactory().create(session).syncDataFromFederationProviderToKeycloak(mapperModel, ldapProvider, session, realm);
|
||||
FederationTestUtils.assertSyncEquals(syncResult, 3, 0, 0, 0);
|
||||
|
||||
// Assert groups are imported to keycloak including their inheritance from LDAP
|
||||
GroupModel kcGroup1 = KeycloakModelUtils.findGroupByPath(realm, "/group1");
|
||||
Assert.assertNotNull(KeycloakModelUtils.findGroupByPath(realm, "/group1/group11"));
|
||||
Assert.assertNotNull(KeycloakModelUtils.findGroupByPath(realm, "/group1/group12"));
|
||||
|
||||
Assert.assertEquals(2, kcGroup1.getSubGroups().size());
|
||||
|
||||
// Create some new groups in keycloak
|
||||
GroupModel model1 = realm.createGroup("model1");
|
||||
realm.moveGroup(model1, null);
|
||||
GroupModel model2 = realm.createGroup("model2");
|
||||
kcGroup1.addChild(model2);
|
||||
|
||||
// Sync groups again from LDAP. Nothing deleted
|
||||
syncResult = new GroupLDAPFederationMapperFactory().create(session).syncDataFromFederationProviderToKeycloak(mapperModel, ldapProvider, session, realm);
|
||||
FederationTestUtils.assertSyncEquals(syncResult, 0, 3, 0, 0);
|
||||
|
||||
Assert.assertNotNull(KeycloakModelUtils.findGroupByPath(realm, "/group1/group11"));
|
||||
Assert.assertNotNull(KeycloakModelUtils.findGroupByPath(realm, "/group1/group12"));
|
||||
Assert.assertNotNull(KeycloakModelUtils.findGroupByPath(realm, "/model1"));
|
||||
Assert.assertNotNull(KeycloakModelUtils.findGroupByPath(realm, "/group1/model2"));
|
||||
|
||||
// Update group mapper to drop non-existing groups during sync
|
||||
FederationTestUtils.updateGroupMapperConfigOptions(mapperModel, GroupMapperConfig.DROP_NON_EXISTING_GROUPS_DURING_SYNC, "true");
|
||||
realm.updateUserFederationMapper(mapperModel);
|
||||
|
||||
// Sync groups again from LDAP. Assert LDAP non-existing groups deleted
|
||||
syncResult = new GroupLDAPFederationMapperFactory().create(session).syncDataFromFederationProviderToKeycloak(mapperModel, ldapProvider, session, realm);
|
||||
Assert.assertEquals(3, syncResult.getUpdated());
|
||||
Assert.assertTrue(syncResult.getRemoved() == 2);
|
||||
|
||||
// Sync and assert groups updated
|
||||
Assert.assertNotNull(KeycloakModelUtils.findGroupByPath(realm, "/group1/group11"));
|
||||
Assert.assertNotNull(KeycloakModelUtils.findGroupByPath(realm, "/group1/group12"));
|
||||
Assert.assertNull(KeycloakModelUtils.findGroupByPath(realm, "/model1"));
|
||||
Assert.assertNull(KeycloakModelUtils.findGroupByPath(realm, "/group1/model2"));
|
||||
} finally {
|
||||
keycloakRule.stopSession(session, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Test
|
||||
public void test04_syncNoPreserveGroupInheritanceWithLazySync() throws Exception {
|
||||
KeycloakSession session = keycloakRule.startSession();
|
||||
try {
|
||||
RealmModel realm = session.realms().getRealmByName("test");
|
||||
UserFederationMapperModel mapperModel = realm.getUserFederationMapperByName(ldapModel.getId(), "groupsMapper");
|
||||
LDAPFederationProvider ldapProvider = FederationTestUtils.getLdapProvider(session, ldapModel);
|
||||
GroupLDAPFederationMapper groupMapper = FederationTestUtils.getGroupMapper(mapperModel, ldapProvider, realm);
|
||||
|
||||
// Update group mapper to skip preserve inheritance
|
||||
FederationTestUtils.updateGroupMapperConfigOptions(mapperModel, GroupMapperConfig.PRESERVE_GROUP_INHERITANCE, "false");
|
||||
realm.updateUserFederationMapper(mapperModel);
|
||||
|
||||
// Add user to LDAP and put him as member of group11
|
||||
FederationTestUtils.removeAllLDAPUsers(ldapProvider, realm);
|
||||
LDAPObject johnLdap = FederationTestUtils.addLDAPUser(ldapProvider, realm, "johnkeycloak", "John", "Doe", "john@email.org", null, "1234");
|
||||
FederationTestUtils.updateLDAPPassword(ldapProvider, johnLdap, "Password1");
|
||||
groupMapper.addGroupMappingInLDAP("group11", johnLdap);
|
||||
|
||||
// Assert groups not yet imported to Keycloak DB
|
||||
Assert.assertNull(KeycloakModelUtils.findGroupByPath(realm, "/group1"));
|
||||
Assert.assertNull(KeycloakModelUtils.findGroupByPath(realm, "/group11"));
|
||||
Assert.assertNull(KeycloakModelUtils.findGroupByPath(realm, "/group12"));
|
||||
|
||||
// Load user from LDAP to Keycloak DB
|
||||
UserModel john = session.users().getUserByUsername("johnkeycloak", realm);
|
||||
Set<GroupModel> johnGroups = john.getGroups();
|
||||
|
||||
// Assert just those groups, which john was memberOf exists because they were lazily created
|
||||
GroupModel group1 = KeycloakModelUtils.findGroupByPath(realm, "/group1");
|
||||
GroupModel group11 = KeycloakModelUtils.findGroupByPath(realm, "/group11");
|
||||
GroupModel group12 = KeycloakModelUtils.findGroupByPath(realm, "/group12");
|
||||
Assert.assertNull(group1);
|
||||
Assert.assertNotNull(group11);
|
||||
Assert.assertNull(group12);
|
||||
|
||||
Assert.assertEquals(1, johnGroups.size());
|
||||
Assert.assertTrue(johnGroups.contains(group11));
|
||||
|
||||
// Delete group mapping
|
||||
john.leaveGroup(group11);
|
||||
|
||||
} finally {
|
||||
keycloakRule.stopSession(session, false);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,361 +0,0 @@
|
|||
/*
|
||||
* 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.ldap.base;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.ClassRule;
|
||||
import org.junit.FixMethodOrder;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.RuleChain;
|
||||
import org.junit.rules.TestRule;
|
||||
import org.junit.runners.MethodSorters;
|
||||
import org.keycloak.federation.ldap.LDAPConfig;
|
||||
import org.keycloak.federation.ldap.LDAPFederationProvider;
|
||||
import org.keycloak.federation.ldap.LDAPFederationProviderFactory;
|
||||
import org.keycloak.federation.ldap.LDAPUtils;
|
||||
import org.keycloak.federation.ldap.idm.model.LDAPDn;
|
||||
import org.keycloak.federation.ldap.idm.model.LDAPObject;
|
||||
import org.keycloak.federation.ldap.mappers.membership.LDAPGroupMapperMode;
|
||||
import org.keycloak.federation.ldap.mappers.membership.MembershipType;
|
||||
import org.keycloak.federation.ldap.mappers.membership.group.GroupLDAPFederationMapper;
|
||||
import org.keycloak.federation.ldap.mappers.membership.group.GroupLDAPFederationMapperFactory;
|
||||
import org.keycloak.federation.ldap.mappers.membership.group.GroupMapperConfig;
|
||||
import org.keycloak.models.GroupModel;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.LDAPConstants;
|
||||
import org.keycloak.models.ModelException;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.models.UserFederationMapperModel;
|
||||
import org.keycloak.models.UserFederationProvider;
|
||||
import org.keycloak.models.UserFederationProviderModel;
|
||||
import org.keycloak.models.UserModel;
|
||||
import org.keycloak.models.utils.KeycloakModelUtils;
|
||||
import org.keycloak.services.managers.RealmManager;
|
||||
import org.keycloak.testsuite.federation.ldap.FederationTestUtils;
|
||||
import org.keycloak.testsuite.rule.KeycloakRule;
|
||||
import org.keycloak.testsuite.rule.LDAPRule;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||
*/
|
||||
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
|
||||
public class LDAPGroupMapperTest {
|
||||
|
||||
private static LDAPRule ldapRule = new LDAPRule();
|
||||
|
||||
private static UserFederationProviderModel ldapModel = null;
|
||||
private static String descriptionAttrName = null;
|
||||
|
||||
private static KeycloakRule keycloakRule = new KeycloakRule(new KeycloakRule.KeycloakSetup() {
|
||||
|
||||
@Override
|
||||
public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
|
||||
FederationTestUtils.addLocalUser(manager.getSession(), appRealm, "mary", "mary@test.com", "password-app");
|
||||
FederationTestUtils.addLocalUser(manager.getSession(), appRealm, "john", "john@test.com", "password-app");
|
||||
|
||||
Map<String,String> ldapConfig = ldapRule.getConfig();
|
||||
ldapConfig.put(LDAPConstants.SYNC_REGISTRATIONS, "true");
|
||||
ldapConfig.put(LDAPConstants.EDIT_MODE, UserFederationProvider.EditMode.WRITABLE.toString());
|
||||
|
||||
ldapModel = appRealm.addUserFederationProvider(LDAPFederationProviderFactory.PROVIDER_NAME, ldapConfig, 0, "test-ldap", -1, -1, 0);
|
||||
LDAPFederationProvider ldapFedProvider = FederationTestUtils.getLdapProvider(session, ldapModel);
|
||||
descriptionAttrName = ldapFedProvider.getLdapIdentityStore().getConfig().isActiveDirectory() ? "displayName" : "description";
|
||||
|
||||
// Add group mapper
|
||||
FederationTestUtils.addOrUpdateGroupMapper(appRealm, ldapModel, LDAPGroupMapperMode.LDAP_ONLY, descriptionAttrName);
|
||||
|
||||
// Remove all LDAP groups
|
||||
FederationTestUtils.removeAllLDAPGroups(session, appRealm, ldapModel, "groupsMapper");
|
||||
|
||||
// Add some groups for testing
|
||||
LDAPObject group1 = FederationTestUtils.createLDAPGroup(manager.getSession(), appRealm, ldapModel, "group1", descriptionAttrName, "group1 - description");
|
||||
LDAPObject group11 = FederationTestUtils.createLDAPGroup(manager.getSession(), appRealm, ldapModel, "group11");
|
||||
LDAPObject group12 = FederationTestUtils.createLDAPGroup(manager.getSession(), appRealm, ldapModel, "group12", descriptionAttrName, "group12 - description");
|
||||
|
||||
LDAPUtils.addMember(ldapFedProvider, MembershipType.DN, LDAPConstants.MEMBER, group1, group11, false);
|
||||
LDAPUtils.addMember(ldapFedProvider, MembershipType.DN, LDAPConstants.MEMBER, group1, group12, true);
|
||||
|
||||
// Sync LDAP groups to Keycloak DB
|
||||
UserFederationMapperModel mapperModel = appRealm.getUserFederationMapperByName(ldapModel.getId(), "groupsMapper");
|
||||
new GroupLDAPFederationMapperFactory().create(session).syncDataFromFederationProviderToKeycloak(mapperModel, ldapFedProvider, session, appRealm);
|
||||
|
||||
// Delete all LDAP users
|
||||
FederationTestUtils.removeAllLDAPUsers(ldapFedProvider, appRealm);
|
||||
|
||||
// Add some LDAP users for testing
|
||||
LDAPObject john = FederationTestUtils.addLDAPUser(ldapFedProvider, appRealm, "johnkeycloak", "John", "Doe", "john@email.org", null, "1234");
|
||||
FederationTestUtils.updateLDAPPassword(ldapFedProvider, john, "Password1");
|
||||
|
||||
LDAPObject mary = FederationTestUtils.addLDAPUser(ldapFedProvider, appRealm, "marykeycloak", "Mary", "Kelly", "mary@email.org", null, "5678");
|
||||
FederationTestUtils.updateLDAPPassword(ldapFedProvider, mary, "Password1");
|
||||
|
||||
LDAPObject rob = FederationTestUtils.addLDAPUser(ldapFedProvider, appRealm, "robkeycloak", "Rob", "Brown", "rob@email.org", null, "8910");
|
||||
FederationTestUtils.updateLDAPPassword(ldapFedProvider, rob, "Password1");
|
||||
|
||||
LDAPObject james = FederationTestUtils.addLDAPUser(ldapFedProvider, appRealm, "jameskeycloak", "James", "Brown", "james@email.org", null, "8910");
|
||||
FederationTestUtils.updateLDAPPassword(ldapFedProvider, james, "Password1");
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
@ClassRule
|
||||
public static TestRule chain = RuleChain
|
||||
.outerRule(ldapRule)
|
||||
.around(keycloakRule);
|
||||
|
||||
@Test
|
||||
public void test01_ldapOnlyGroupMappings() {
|
||||
KeycloakSession session = keycloakRule.startSession();
|
||||
try {
|
||||
RealmModel appRealm = session.realms().getRealmByName("test");
|
||||
|
||||
UserFederationMapperModel mapperModel = appRealm.getUserFederationMapperByName(ldapModel.getId(), "groupsMapper");
|
||||
FederationTestUtils.updateGroupMapperConfigOptions(mapperModel, GroupMapperConfig.MODE, LDAPGroupMapperMode.LDAP_ONLY.toString());
|
||||
appRealm.updateUserFederationMapper(mapperModel);
|
||||
|
||||
UserModel john = session.users().getUserByUsername("johnkeycloak", appRealm);
|
||||
UserModel mary = session.users().getUserByUsername("marykeycloak", appRealm);
|
||||
|
||||
// 1 - Grant some groups in LDAP
|
||||
|
||||
// This group should already exists as it was imported from LDAP
|
||||
GroupModel group1 = KeycloakModelUtils.findGroupByPath(appRealm, "/group1");
|
||||
john.joinGroup(group1);
|
||||
|
||||
// This group should already exists as it was imported from LDAP
|
||||
GroupModel group11 = KeycloakModelUtils.findGroupByPath(appRealm, "/group1/group11");
|
||||
mary.joinGroup(group11);
|
||||
|
||||
// This group should already exists as it was imported from LDAP
|
||||
GroupModel group12 = KeycloakModelUtils.findGroupByPath(appRealm, "/group1/group12");
|
||||
john.joinGroup(group12);
|
||||
mary.joinGroup(group12);
|
||||
|
||||
// 2 - Check that group mappings are not in local Keycloak DB (They are in LDAP).
|
||||
|
||||
UserModel johnDb = session.userStorage().getUserByUsername("johnkeycloak", appRealm);
|
||||
Set<GroupModel> johnDbGroups = johnDb.getGroups();
|
||||
Assert.assertEquals(0, johnDbGroups.size());
|
||||
|
||||
// 3 - Check that group mappings are in LDAP and hence available through federation
|
||||
|
||||
Set<GroupModel> johnGroups = john.getGroups();
|
||||
Assert.assertEquals(2, johnGroups.size());
|
||||
Assert.assertTrue(johnGroups.contains(group1));
|
||||
Assert.assertFalse(johnGroups.contains(group11));
|
||||
Assert.assertTrue(johnGroups.contains(group12));
|
||||
|
||||
// 4 - Check through userProvider
|
||||
List<UserModel> group1Members = session.users().getGroupMembers(appRealm, group1, 0, 10);
|
||||
List<UserModel> group11Members = session.users().getGroupMembers(appRealm, group11, 0, 10);
|
||||
List<UserModel> group12Members = session.users().getGroupMembers(appRealm, group12, 0, 10);
|
||||
|
||||
Assert.assertEquals(1, group1Members.size());
|
||||
Assert.assertEquals("johnkeycloak", group1Members.get(0).getUsername());
|
||||
Assert.assertEquals(1, group11Members.size());
|
||||
Assert.assertEquals("marykeycloak", group11Members.get(0).getUsername());
|
||||
Assert.assertEquals(2, group12Members.size());
|
||||
|
||||
// 4 - Delete some group mappings and check they are deleted
|
||||
|
||||
john.leaveGroup(group1);
|
||||
john.leaveGroup(group12);
|
||||
|
||||
mary.leaveGroup(group1);
|
||||
mary.leaveGroup(group12);
|
||||
|
||||
johnGroups = john.getGroups();
|
||||
Assert.assertEquals(0, johnGroups.size());
|
||||
|
||||
} finally {
|
||||
keycloakRule.stopSession(session, false);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test02_readOnlyGroupMappings() {
|
||||
KeycloakSession session = keycloakRule.startSession();
|
||||
try {
|
||||
System.out.println("starting test02_readOnlyGroupMappings");
|
||||
RealmModel appRealm = session.realms().getRealmByName("test");
|
||||
|
||||
UserFederationMapperModel mapperModel = appRealm.getUserFederationMapperByName(ldapModel.getId(), "groupsMapper");
|
||||
FederationTestUtils.updateGroupMapperConfigOptions(mapperModel, GroupMapperConfig.MODE, LDAPGroupMapperMode.READ_ONLY.toString());
|
||||
appRealm.updateUserFederationMapper(mapperModel);
|
||||
|
||||
UserModel mary = session.users().getUserByUsername("marykeycloak", appRealm);
|
||||
|
||||
GroupModel group1 = KeycloakModelUtils.findGroupByPath(appRealm, "/group1");
|
||||
GroupModel group11 = KeycloakModelUtils.findGroupByPath(appRealm, "/group1/group11");
|
||||
GroupModel group12 = KeycloakModelUtils.findGroupByPath(appRealm, "/group1/group12");
|
||||
|
||||
// Add some group mappings directly into LDAP
|
||||
LDAPFederationProvider ldapProvider = FederationTestUtils.getLdapProvider(session, ldapModel);
|
||||
GroupLDAPFederationMapper groupMapper = FederationTestUtils.getGroupMapper(mapperModel, ldapProvider, appRealm);
|
||||
|
||||
LDAPObject maryLdap = ldapProvider.loadLDAPUserByUsername(appRealm, "marykeycloak");
|
||||
groupMapper.addGroupMappingInLDAP("group1", maryLdap);
|
||||
groupMapper.addGroupMappingInLDAP("group11", maryLdap);
|
||||
|
||||
// Add some group mapping to model
|
||||
mary.joinGroup(group12);
|
||||
|
||||
// Assert that mary has both LDAP and DB mapped groups
|
||||
Set<GroupModel> maryGroups = mary.getGroups();
|
||||
Assert.assertEquals(3, maryGroups.size());
|
||||
Assert.assertTrue(maryGroups.contains(group1));
|
||||
Assert.assertTrue(maryGroups.contains(group11));
|
||||
Assert.assertTrue(maryGroups.contains(group12));
|
||||
|
||||
// Assert that access through DB will have just DB mapped groups
|
||||
System.out.println("******");
|
||||
UserModel maryDB = session.userStorage().getUserByUsername("marykeycloak", appRealm);
|
||||
Set<GroupModel> maryDBGroups = maryDB.getGroups();
|
||||
Assert.assertFalse(maryDBGroups.contains(group1));
|
||||
Assert.assertFalse(maryDBGroups.contains(group11));
|
||||
Assert.assertTrue(maryDBGroups.contains(group12));
|
||||
|
||||
// Check through userProvider
|
||||
List<UserModel> group1Members = session.users().getGroupMembers(appRealm, group1, 0, 10);
|
||||
List<UserModel> group11Members = session.users().getGroupMembers(appRealm, group11, 0, 10);
|
||||
List<UserModel> group12Members = session.users().getGroupMembers(appRealm, group12, 0, 10);
|
||||
Assert.assertEquals(1, group1Members.size());
|
||||
Assert.assertEquals("marykeycloak", group1Members.get(0).getUsername());
|
||||
Assert.assertEquals(1, group11Members.size());
|
||||
Assert.assertEquals("marykeycloak", group11Members.get(0).getUsername());
|
||||
Assert.assertEquals(1, group12Members.size());
|
||||
Assert.assertEquals("marykeycloak", group12Members.get(0).getUsername());
|
||||
|
||||
mary.leaveGroup(group12);
|
||||
try {
|
||||
mary.leaveGroup(group1);
|
||||
Assert.fail("It wasn't expected to successfully delete LDAP group mappings in READ_ONLY mode");
|
||||
} catch (ModelException expected) {
|
||||
}
|
||||
|
||||
// Delete role mappings directly in LDAP
|
||||
deleteGroupMappingsInLDAP(groupMapper, maryLdap, "group1");
|
||||
deleteGroupMappingsInLDAP(groupMapper, maryLdap, "group11");
|
||||
} finally {
|
||||
keycloakRule.stopSession(session, false);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test03_importGroupMappings() {
|
||||
KeycloakSession session = keycloakRule.startSession();
|
||||
try {
|
||||
RealmModel appRealm = session.realms().getRealmByName("test");
|
||||
|
||||
UserFederationMapperModel mapperModel = appRealm.getUserFederationMapperByName(ldapModel.getId(), "groupsMapper");
|
||||
FederationTestUtils.updateGroupMapperConfigOptions(mapperModel, GroupMapperConfig.MODE, LDAPGroupMapperMode.IMPORT.toString());
|
||||
appRealm.updateUserFederationMapper(mapperModel);
|
||||
|
||||
// Add some group mappings directly in LDAP
|
||||
LDAPFederationProvider ldapProvider = FederationTestUtils.getLdapProvider(session, ldapModel);
|
||||
GroupLDAPFederationMapper groupMapper = FederationTestUtils.getGroupMapper(mapperModel, ldapProvider, appRealm);
|
||||
|
||||
LDAPObject robLdap = ldapProvider.loadLDAPUserByUsername(appRealm, "robkeycloak");
|
||||
groupMapper.addGroupMappingInLDAP("group11", robLdap);
|
||||
groupMapper.addGroupMappingInLDAP("group12", robLdap);
|
||||
|
||||
// Get user and check that he has requested groupa from LDAP
|
||||
UserModel rob = session.users().getUserByUsername("robkeycloak", appRealm);
|
||||
Set<GroupModel> robGroups = rob.getGroups();
|
||||
|
||||
GroupModel group1 = KeycloakModelUtils.findGroupByPath(appRealm, "/group1");
|
||||
GroupModel group11 = KeycloakModelUtils.findGroupByPath(appRealm, "/group1/group11");
|
||||
GroupModel group12 = KeycloakModelUtils.findGroupByPath(appRealm, "/group1/group12");
|
||||
|
||||
Assert.assertFalse(robGroups.contains(group1));
|
||||
Assert.assertTrue(robGroups.contains(group11));
|
||||
Assert.assertTrue(robGroups.contains(group12));
|
||||
|
||||
// Delete some group mappings in LDAP and check that it doesn't have any effect and user still has groups
|
||||
deleteGroupMappingsInLDAP(groupMapper, robLdap, "group11");
|
||||
deleteGroupMappingsInLDAP(groupMapper, robLdap, "group12");
|
||||
robGroups = rob.getGroups();
|
||||
Assert.assertTrue(robGroups.contains(group11));
|
||||
Assert.assertTrue(robGroups.contains(group12));
|
||||
|
||||
// Delete group mappings through model and verifies that user doesn't have them anymore
|
||||
rob.leaveGroup(group11);
|
||||
rob.leaveGroup(group12);
|
||||
robGroups = rob.getGroups();
|
||||
Assert.assertEquals(0, robGroups.size());
|
||||
} finally {
|
||||
keycloakRule.stopSession(session, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// KEYCLOAK-2682
|
||||
@Test
|
||||
public void test04_groupReferencingNonExistentMember() {
|
||||
KeycloakSession session = keycloakRule.startSession();
|
||||
try {
|
||||
// Ignoring this test on ActiveDirectory as it's not allowed to have LDAP group referencing nonexistent member. KEYCLOAK-2682 was related to OpenLDAP TODO: Better solution than programmatic...
|
||||
LDAPConfig config = FederationTestUtils.getLdapProvider(session, ldapModel).getLdapIdentityStore().getConfig();
|
||||
if (config.isActiveDirectory()) {
|
||||
return;
|
||||
}
|
||||
|
||||
RealmModel appRealm = session.realms().getRealmByName("test");
|
||||
|
||||
UserFederationMapperModel mapperModel = appRealm.getUserFederationMapperByName(ldapModel.getId(), "groupsMapper");
|
||||
FederationTestUtils.updateGroupMapperConfigOptions(mapperModel, GroupMapperConfig.MODE, LDAPGroupMapperMode.LDAP_ONLY.toString());
|
||||
appRealm.updateUserFederationMapper(mapperModel);
|
||||
|
||||
// 1 - Add some group to LDAP for testing
|
||||
LDAPFederationProvider ldapProvider = FederationTestUtils.getLdapProvider(session, ldapModel);
|
||||
GroupLDAPFederationMapper groupMapper = FederationTestUtils.getGroupMapper(mapperModel, ldapProvider, appRealm);
|
||||
LDAPObject group2 = FederationTestUtils.createLDAPGroup(session, appRealm, ldapModel, "group2", descriptionAttrName, "group2 - description");
|
||||
|
||||
// 2 - Add one existing user rob to LDAP group
|
||||
LDAPObject jamesLdap = ldapProvider.loadLDAPUserByUsername(appRealm, "jameskeycloak");
|
||||
LDAPUtils.addMember(ldapProvider, MembershipType.DN, LDAPConstants.MEMBER, group2, jamesLdap, false);
|
||||
|
||||
// 3 - Add non-existing user to LDAP group
|
||||
LDAPDn nonExistentDn = LDAPDn.fromString(ldapProvider.getLdapIdentityStore().getConfig().getUsersDn());
|
||||
nonExistentDn.addFirst(jamesLdap.getRdnAttributeName(), "nonexistent");
|
||||
LDAPObject nonExistentLdapUser = new LDAPObject();
|
||||
nonExistentLdapUser.setDn(nonExistentDn);
|
||||
LDAPUtils.addMember(ldapProvider, MembershipType.DN, LDAPConstants.MEMBER, group2, nonExistentLdapUser, true);
|
||||
|
||||
// 4 - Check group members. Just existing user rob should be present
|
||||
groupMapper.syncDataFromFederationProviderToKeycloak();
|
||||
GroupModel kcGroup2 = KeycloakModelUtils.findGroupByPath(appRealm, "/group2");
|
||||
List<UserModel> groupUsers = session.users().getGroupMembers(appRealm, kcGroup2, 0, 5);
|
||||
Assert.assertEquals(1, groupUsers.size());
|
||||
UserModel rob = groupUsers.get(0);
|
||||
Assert.assertEquals("jameskeycloak", rob.getUsername());
|
||||
|
||||
} finally {
|
||||
keycloakRule.stopSession(session, false);
|
||||
}
|
||||
}
|
||||
|
||||
private void deleteGroupMappingsInLDAP(GroupLDAPFederationMapper groupMapper, LDAPObject ldapUser, String groupName) {
|
||||
LDAPObject ldapGroup = groupMapper.loadLDAPGroupByName(groupName);
|
||||
groupMapper.deleteGroupMappingInLDAP(ldapUser, ldapGroup);
|
||||
}
|
||||
}
|
|
@ -1,239 +0,0 @@
|
|||
/*
|
||||
* 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.ldap.base;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.ClassRule;
|
||||
import org.junit.FixMethodOrder;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.RuleChain;
|
||||
import org.junit.rules.TestRule;
|
||||
import org.junit.runners.MethodSorters;
|
||||
import org.keycloak.OAuth2Constants;
|
||||
import org.keycloak.federation.ldap.LDAPFederationProvider;
|
||||
import org.keycloak.federation.ldap.LDAPFederationProviderFactory;
|
||||
import org.keycloak.federation.ldap.idm.model.LDAPObject;
|
||||
import org.keycloak.models.ClientModel;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.LDAPConstants;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.models.UserFederationProvider;
|
||||
import org.keycloak.models.UserFederationProviderModel;
|
||||
import org.keycloak.models.UserModel;
|
||||
import org.keycloak.models.utils.KeycloakModelUtils;
|
||||
import org.keycloak.protocol.oidc.OIDCLoginProtocolService;
|
||||
import org.keycloak.protocol.oidc.mappers.UserAttributeMapper;
|
||||
import org.keycloak.services.managers.RealmManager;
|
||||
import org.keycloak.testsuite.OAuthClient;
|
||||
import org.keycloak.testsuite.federation.ldap.FederationTestUtils;
|
||||
import org.keycloak.testsuite.federation.ldap.LDAPExampleServlet;
|
||||
import org.keycloak.testsuite.pages.LoginPage;
|
||||
import org.keycloak.testsuite.rule.KeycloakRule;
|
||||
import org.keycloak.testsuite.rule.LDAPRule;
|
||||
import org.keycloak.testsuite.rule.WebResource;
|
||||
import org.keycloak.testsuite.rule.WebRule;
|
||||
import org.openqa.selenium.WebDriver;
|
||||
|
||||
import javax.ws.rs.core.UriBuilder;
|
||||
import java.net.URL;
|
||||
import java.util.Arrays;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||
*/
|
||||
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
|
||||
public class LDAPMultipleAttributesTest {
|
||||
|
||||
protected String APP_SERVER_BASE_URL = "http://localhost:8081";
|
||||
protected String LOGIN_URL = OIDCLoginProtocolService.authUrl(UriBuilder.fromUri(APP_SERVER_BASE_URL + "/auth")).build("test").toString();
|
||||
|
||||
private static LDAPRule ldapRule = new LDAPRule();
|
||||
|
||||
private static UserFederationProviderModel ldapModel = null;
|
||||
|
||||
private static KeycloakRule keycloakRule = new KeycloakRule(new KeycloakRule.KeycloakSetup() {
|
||||
|
||||
@Override
|
||||
public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
|
||||
Map<String,String> ldapConfig = ldapRule.getConfig();
|
||||
ldapConfig.put(LDAPConstants.EDIT_MODE, UserFederationProvider.EditMode.WRITABLE.toString());
|
||||
|
||||
ldapModel = appRealm.addUserFederationProvider(LDAPFederationProviderFactory.PROVIDER_NAME, ldapConfig, 0, "test-ldap", -1, -1, 0);
|
||||
FederationTestUtils.addZipCodeLDAPMapper(appRealm, ldapModel);
|
||||
FederationTestUtils.addUserAttributeMapper(appRealm, ldapModel, "streetMapper", "street", LDAPConstants.STREET);
|
||||
|
||||
// Remove current users and add default users
|
||||
LDAPFederationProvider ldapFedProvider = FederationTestUtils.getLdapProvider(session, ldapModel);
|
||||
FederationTestUtils.removeAllLDAPUsers(ldapFedProvider, appRealm);
|
||||
|
||||
LDAPObject james = FederationTestUtils.addLDAPUser(ldapFedProvider, appRealm, "jbrown", "James", "Brown", "jbrown@keycloak.org", null, "88441");
|
||||
FederationTestUtils.updateLDAPPassword(ldapFedProvider, james, "Password1");
|
||||
|
||||
// User for testing duplicating surname and postalCode
|
||||
LDAPObject bruce = FederationTestUtils.addLDAPUser(ldapFedProvider, appRealm, "bwilson", "Bruce", "Wilson", "bwilson@keycloak.org", "Elm 5", "88441", "77332");
|
||||
bruce.setAttribute("sn", new LinkedHashSet<>(Arrays.asList("Wilson", "Schneider")));
|
||||
ldapFedProvider.getLdapIdentityStore().update(bruce);
|
||||
FederationTestUtils.updateLDAPPassword(ldapFedProvider, bruce, "Password1");
|
||||
|
||||
// Create ldap-portal client
|
||||
ClientModel ldapClient = KeycloakModelUtils.createClient(appRealm, "ldap-portal");
|
||||
ldapClient.addRedirectUri("/ldap-portal");
|
||||
ldapClient.addRedirectUri("/ldap-portal/*");
|
||||
ldapClient.setManagementUrl("/ldap-portal");
|
||||
ldapClient.addProtocolMapper(UserAttributeMapper.createClaimMapper("postalCode", "postal_code", "postal_code", "String", true, "", true, true, true));
|
||||
ldapClient.addProtocolMapper(UserAttributeMapper.createClaimMapper("street", "street", "street", "String", true, "", true, true, false));
|
||||
ldapClient.addScopeMapping(appRealm.getRole("user"));
|
||||
ldapClient.setSecret("password");
|
||||
|
||||
// Deploy ldap-portal client
|
||||
URL url = getClass().getResource("/ldap/ldap-app-keycloak.json");
|
||||
keycloakRule.createApplicationDeployment()
|
||||
.name("ldap-portal").contextPath("/ldap-portal")
|
||||
.servletClass(LDAPExampleServlet.class).adapterConfigPath(url.getPath())
|
||||
.role("user").deployApplication();
|
||||
}
|
||||
});
|
||||
|
||||
@ClassRule
|
||||
public static TestRule chain = RuleChain
|
||||
.outerRule(ldapRule)
|
||||
.around(keycloakRule);
|
||||
|
||||
@Rule
|
||||
public WebRule webRule = new WebRule(this);
|
||||
|
||||
@WebResource
|
||||
protected WebDriver driver;
|
||||
|
||||
@WebResource
|
||||
protected OAuthClient oauth;
|
||||
|
||||
@WebResource
|
||||
protected LoginPage loginPage;
|
||||
|
||||
@Test
|
||||
public void testModel() {
|
||||
KeycloakSession session = keycloakRule.startSession();
|
||||
try {
|
||||
RealmModel appRealm = session.realms().getRealmByName("test");
|
||||
|
||||
FederationTestUtils.assertUserImported(session.users(), appRealm, "jbrown", "James", "Brown", "jbrown@keycloak.org", "88441");
|
||||
|
||||
UserModel user = session.users().getUserByUsername("bwilson", appRealm);
|
||||
Assert.assertEquals("bwilson@keycloak.org", user.getEmail());
|
||||
Assert.assertEquals("Bruce", user.getFirstName());
|
||||
|
||||
// There are 2 lastnames in ldif
|
||||
Assert.assertTrue("Wilson".equals(user.getLastName()) || "Schneider".equals(user.getLastName()));
|
||||
|
||||
// Actually there are 2 postalCodes
|
||||
List<String> postalCodes = user.getAttribute("postal_code");
|
||||
assertPostalCodes(postalCodes, "88441", "77332");
|
||||
List<String> tmp = new LinkedList<>();
|
||||
tmp.addAll(postalCodes);
|
||||
postalCodes = tmp;
|
||||
postalCodes.remove("77332");
|
||||
user.setAttribute("postal_code", postalCodes);
|
||||
|
||||
} finally {
|
||||
keycloakRule.stopSession(session, true);
|
||||
}
|
||||
|
||||
session = keycloakRule.startSession();
|
||||
try {
|
||||
RealmModel appRealm = session.realms().getRealmByName("test");
|
||||
UserModel user = session.users().getUserByUsername("bwilson", appRealm);
|
||||
List<String> postalCodes = user.getAttribute("postal_code");
|
||||
assertPostalCodes(postalCodes, "88441");
|
||||
List<String> tmp = new LinkedList<>();
|
||||
tmp.addAll(postalCodes);
|
||||
postalCodes = tmp;
|
||||
postalCodes.add("77332");
|
||||
user.setAttribute("postal_code", postalCodes);
|
||||
} finally {
|
||||
keycloakRule.stopSession(session, true);
|
||||
}
|
||||
|
||||
session = keycloakRule.startSession();
|
||||
try {
|
||||
RealmModel appRealm = session.realms().getRealmByName("test");
|
||||
UserModel user = session.users().getUserByUsername("bwilson", appRealm);
|
||||
assertPostalCodes(user.getAttribute("postal_code"), "88441", "77332");
|
||||
} finally {
|
||||
keycloakRule.stopSession(session, true);
|
||||
}
|
||||
}
|
||||
|
||||
private void assertPostalCodes(List<String> postalCodes, String... expectedPostalCodes) {
|
||||
if (expectedPostalCodes == null && postalCodes.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
Assert.assertEquals(expectedPostalCodes.length, postalCodes.size());
|
||||
for (String expected : expectedPostalCodes) {
|
||||
if (!postalCodes.contains(expected)) {
|
||||
Assert.fail("postalCode '" + expected + "' not in postalCodes: " + postalCodes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void ldapPortalEndToEndTest() {
|
||||
// Login as bwilson
|
||||
driver.navigate().to(APP_SERVER_BASE_URL + "/ldap-portal");
|
||||
Assert.assertTrue(driver.getCurrentUrl().startsWith(LOGIN_URL));
|
||||
loginPage.login("bwilson", "Password1");
|
||||
Assert.assertTrue(driver.getCurrentUrl().startsWith(APP_SERVER_BASE_URL + "/ldap-portal"));
|
||||
String pageSource = driver.getPageSource();
|
||||
System.out.println(pageSource);
|
||||
Assert.assertTrue(pageSource.contains("bwilson") && pageSource.contains("Bruce"));
|
||||
Assert.assertTrue(pageSource.contains("street") && pageSource.contains("Elm 5"));
|
||||
Assert.assertTrue(pageSource.contains("postal_code") && pageSource.contains("88441") && pageSource.contains("77332"));
|
||||
|
||||
// Logout
|
||||
String logoutUri = OIDCLoginProtocolService.logoutUrl(UriBuilder.fromUri(APP_SERVER_BASE_URL + "/auth"))
|
||||
.queryParam(OAuth2Constants.REDIRECT_URI, APP_SERVER_BASE_URL + "/ldap-portal").build("test").toString();
|
||||
driver.navigate().to(logoutUri);
|
||||
|
||||
// Login as jbrown
|
||||
driver.navigate().to(APP_SERVER_BASE_URL + "/ldap-portal");
|
||||
Assert.assertTrue(driver.getCurrentUrl().startsWith(LOGIN_URL));
|
||||
loginPage.login("jbrown", "Password1");
|
||||
Assert.assertTrue(driver.getCurrentUrl().startsWith(APP_SERVER_BASE_URL + "/ldap-portal"));
|
||||
pageSource = driver.getPageSource();
|
||||
System.out.println(pageSource);
|
||||
Assert.assertTrue(pageSource.contains("jbrown") && pageSource.contains("James Brown"));
|
||||
Assert.assertFalse(pageSource.contains("street"));
|
||||
Assert.assertTrue(pageSource.contains("postal_code") && pageSource.contains("88441"));
|
||||
Assert.assertFalse(pageSource.contains("77332"));
|
||||
|
||||
// Logout
|
||||
driver.navigate().to(logoutUri);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -1,355 +0,0 @@
|
|||
/*
|
||||
* 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.ldap.base;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.ClassRule;
|
||||
import org.junit.FixMethodOrder;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.RuleChain;
|
||||
import org.junit.rules.TestRule;
|
||||
import org.junit.runners.MethodSorters;
|
||||
import org.keycloak.federation.ldap.LDAPFederationProvider;
|
||||
import org.keycloak.federation.ldap.LDAPFederationProviderFactory;
|
||||
import org.keycloak.federation.ldap.idm.model.LDAPObject;
|
||||
import org.keycloak.federation.ldap.mappers.membership.LDAPGroupMapperMode;
|
||||
import org.keycloak.federation.ldap.mappers.membership.role.RoleLDAPFederationMapper;
|
||||
import org.keycloak.models.AccountRoles;
|
||||
import org.keycloak.models.ClientModel;
|
||||
import org.keycloak.models.Constants;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.LDAPConstants;
|
||||
import org.keycloak.models.ModelException;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.models.RoleModel;
|
||||
import org.keycloak.models.UserFederationMapperModel;
|
||||
import org.keycloak.models.UserFederationProvider;
|
||||
import org.keycloak.models.UserFederationProviderModel;
|
||||
import org.keycloak.models.UserModel;
|
||||
import org.keycloak.services.managers.RealmManager;
|
||||
import org.keycloak.testsuite.OAuthClient;
|
||||
import org.keycloak.testsuite.federation.ldap.FederationTestUtils;
|
||||
import org.keycloak.testsuite.pages.AppPage;
|
||||
import org.keycloak.testsuite.pages.LoginPage;
|
||||
import org.keycloak.testsuite.rule.KeycloakRule;
|
||||
import org.keycloak.testsuite.rule.LDAPRule;
|
||||
import org.keycloak.testsuite.rule.WebResource;
|
||||
import org.keycloak.testsuite.rule.WebRule;
|
||||
import org.openqa.selenium.WebDriver;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||
*/
|
||||
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
|
||||
public class LDAPRoleMappingsTest {
|
||||
|
||||
private static LDAPRule ldapRule = new LDAPRule();
|
||||
|
||||
private static UserFederationProviderModel ldapModel = null;
|
||||
|
||||
private static KeycloakRule keycloakRule = new KeycloakRule(new KeycloakRule.KeycloakSetup() {
|
||||
|
||||
@Override
|
||||
public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
|
||||
FederationTestUtils.addLocalUser(manager.getSession(), appRealm, "mary", "mary@test.com", "password-app");
|
||||
|
||||
Map<String,String> ldapConfig = ldapRule.getConfig();
|
||||
ldapConfig.put(LDAPConstants.SYNC_REGISTRATIONS, "true");
|
||||
ldapConfig.put(LDAPConstants.EDIT_MODE, UserFederationProvider.EditMode.WRITABLE.toString());
|
||||
|
||||
ldapModel = appRealm.addUserFederationProvider(LDAPFederationProviderFactory.PROVIDER_NAME, ldapConfig, 0, "test-ldap", -1, -1, 0);
|
||||
|
||||
// Delete all LDAP users
|
||||
LDAPFederationProvider ldapFedProvider = FederationTestUtils.getLdapProvider(session, ldapModel);
|
||||
FederationTestUtils.removeAllLDAPUsers(ldapFedProvider, appRealm);
|
||||
|
||||
// Add sample application
|
||||
ClientModel finance = appRealm.addClient("finance");
|
||||
|
||||
// Delete all LDAP roles
|
||||
FederationTestUtils.addOrUpdateRoleLDAPMappers(appRealm, ldapModel, LDAPGroupMapperMode.LDAP_ONLY);
|
||||
FederationTestUtils.removeAllLDAPRoles(manager.getSession(), appRealm, ldapModel, "realmRolesMapper");
|
||||
FederationTestUtils.removeAllLDAPRoles(manager.getSession(), appRealm, ldapModel, "financeRolesMapper");
|
||||
|
||||
// Add some users for testing
|
||||
LDAPObject john = FederationTestUtils.addLDAPUser(ldapFedProvider, appRealm, "johnkeycloak", "John", "Doe", "john@email.org", null, "1234");
|
||||
FederationTestUtils.updateLDAPPassword(ldapFedProvider, john, "Password1");
|
||||
|
||||
LDAPObject mary = FederationTestUtils.addLDAPUser(ldapFedProvider, appRealm, "marykeycloak", "Mary", "Kelly", "mary@email.org", null, "5678");
|
||||
FederationTestUtils.updateLDAPPassword(ldapFedProvider, mary, "Password1");
|
||||
|
||||
LDAPObject rob = FederationTestUtils.addLDAPUser(ldapFedProvider, appRealm, "robkeycloak", "Rob", "Brown", "rob@email.org", null, "8910");
|
||||
FederationTestUtils.updateLDAPPassword(ldapFedProvider, rob, "Password1");
|
||||
|
||||
// Add some roles for testing
|
||||
FederationTestUtils.createLDAPRole(manager.getSession(), appRealm, ldapModel, "realmRolesMapper", "realmRole1");
|
||||
FederationTestUtils.createLDAPRole(manager.getSession(), appRealm, ldapModel, "realmRolesMapper", "realmRole2");
|
||||
FederationTestUtils.createLDAPRole(manager.getSession(), appRealm, ldapModel, "financeRolesMapper", "financeRole1");
|
||||
|
||||
// Sync LDAP roles to Keycloak DB
|
||||
FederationTestUtils.syncRolesFromLDAP(appRealm, ldapFedProvider, ldapModel);
|
||||
}
|
||||
});
|
||||
|
||||
@ClassRule
|
||||
public static TestRule chain = RuleChain
|
||||
.outerRule(ldapRule)
|
||||
.around(keycloakRule);
|
||||
|
||||
@Rule
|
||||
public WebRule webRule = new WebRule(this);
|
||||
|
||||
@WebResource
|
||||
protected OAuthClient oauth;
|
||||
|
||||
@WebResource
|
||||
protected WebDriver driver;
|
||||
|
||||
@WebResource
|
||||
protected AppPage appPage;
|
||||
|
||||
@WebResource
|
||||
protected LoginPage loginPage;
|
||||
|
||||
@Test
|
||||
public void test01_ldapOnlyRoleMappings() {
|
||||
KeycloakSession session = keycloakRule.startSession();
|
||||
try {
|
||||
RealmModel appRealm = session.realms().getRealmByName("test");
|
||||
|
||||
FederationTestUtils.addOrUpdateRoleLDAPMappers(appRealm, ldapModel, LDAPGroupMapperMode.LDAP_ONLY);
|
||||
|
||||
UserModel john = session.users().getUserByUsername("johnkeycloak", appRealm);
|
||||
UserModel mary = session.users().getUserByUsername("marykeycloak", appRealm);
|
||||
|
||||
// 1 - Grant some roles in LDAP
|
||||
|
||||
// This role should already exists as it was imported from LDAP
|
||||
RoleModel realmRole1 = appRealm.getRole("realmRole1");
|
||||
john.grantRole(realmRole1);
|
||||
|
||||
// This role should already exists as it was imported from LDAP
|
||||
RoleModel realmRole2 = appRealm.getRole("realmRole2");
|
||||
mary.grantRole(realmRole2);
|
||||
|
||||
// This role may already exists from previous test (was imported from LDAP), but may not
|
||||
RoleModel realmRole3 = appRealm.getRole("realmRole3");
|
||||
if (realmRole3 == null) {
|
||||
realmRole3 = appRealm.addRole("realmRole3");
|
||||
}
|
||||
|
||||
john.grantRole(realmRole3);
|
||||
mary.grantRole(realmRole3);
|
||||
|
||||
ClientModel accountApp = appRealm.getClientByClientId(Constants.ACCOUNT_MANAGEMENT_CLIENT_ID);
|
||||
ClientModel financeApp = appRealm.getClientByClientId("finance");
|
||||
|
||||
RoleModel manageAccountRole = accountApp.getRole(AccountRoles.MANAGE_ACCOUNT);
|
||||
RoleModel financeRole1 = financeApp.getRole("financeRole1");
|
||||
john.grantRole(financeRole1);
|
||||
|
||||
// 2 - Check that role mappings are not in local Keycloak DB (They are in LDAP).
|
||||
|
||||
UserModel johnDb = session.userStorage().getUserByUsername("johnkeycloak", appRealm);
|
||||
Set<RoleModel> johnDbRoles = johnDb.getRoleMappings();
|
||||
Assert.assertFalse(johnDbRoles.contains(realmRole1));
|
||||
Assert.assertFalse(johnDbRoles.contains(realmRole2));
|
||||
Assert.assertFalse(johnDbRoles.contains(realmRole3));
|
||||
Assert.assertFalse(johnDbRoles.contains(financeRole1));
|
||||
Assert.assertTrue(johnDbRoles.contains(manageAccountRole));
|
||||
|
||||
// 3 - Check that role mappings are in LDAP and hence available through federation
|
||||
|
||||
Set<RoleModel> johnRoles = john.getRoleMappings();
|
||||
Assert.assertTrue(johnRoles.contains(realmRole1));
|
||||
Assert.assertFalse(johnRoles.contains(realmRole2));
|
||||
Assert.assertTrue(johnRoles.contains(realmRole3));
|
||||
Assert.assertTrue(johnRoles.contains(financeRole1));
|
||||
Assert.assertTrue(johnRoles.contains(manageAccountRole));
|
||||
|
||||
Set<RoleModel> johnRealmRoles = john.getRealmRoleMappings();
|
||||
Assert.assertEquals(2, johnRealmRoles.size());
|
||||
Assert.assertTrue(johnRealmRoles.contains(realmRole1));
|
||||
Assert.assertTrue(johnRealmRoles.contains(realmRole3));
|
||||
|
||||
// account roles are not mapped in LDAP. Those are in Keycloak DB
|
||||
Set<RoleModel> johnAccountRoles = john.getClientRoleMappings(accountApp);
|
||||
Assert.assertTrue(johnAccountRoles.contains(manageAccountRole));
|
||||
|
||||
Set<RoleModel> johnFinanceRoles = john.getClientRoleMappings(financeApp);
|
||||
Assert.assertEquals(1, johnFinanceRoles.size());
|
||||
Assert.assertTrue(johnFinanceRoles.contains(financeRole1));
|
||||
|
||||
// 4 - Delete some role mappings and check they are deleted
|
||||
|
||||
john.deleteRoleMapping(realmRole3);
|
||||
john.deleteRoleMapping(realmRole1);
|
||||
john.deleteRoleMapping(financeRole1);
|
||||
john.deleteRoleMapping(manageAccountRole);
|
||||
|
||||
johnRoles = john.getRoleMappings();
|
||||
Assert.assertFalse(johnRoles.contains(realmRole1));
|
||||
Assert.assertFalse(johnRoles.contains(realmRole2));
|
||||
Assert.assertFalse(johnRoles.contains(realmRole3));
|
||||
Assert.assertFalse(johnRoles.contains(financeRole1));
|
||||
Assert.assertFalse(johnRoles.contains(manageAccountRole));
|
||||
|
||||
// Cleanup
|
||||
mary.deleteRoleMapping(realmRole2);
|
||||
mary.deleteRoleMapping(realmRole3);
|
||||
john.grantRole(manageAccountRole);
|
||||
} finally {
|
||||
keycloakRule.stopSession(session, false);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test02_readOnlyRoleMappings() {
|
||||
KeycloakSession session = keycloakRule.startSession();
|
||||
try {
|
||||
RealmModel appRealm = session.realms().getRealmByName("test");
|
||||
|
||||
FederationTestUtils.addOrUpdateRoleLDAPMappers(appRealm, ldapModel, LDAPGroupMapperMode.READ_ONLY);
|
||||
|
||||
UserModel mary = session.users().getUserByUsername("marykeycloak", appRealm);
|
||||
|
||||
RoleModel realmRole1 = appRealm.getRole("realmRole1");
|
||||
RoleModel realmRole2 = appRealm.getRole("realmRole2");
|
||||
RoleModel realmRole3 = appRealm.getRole("realmRole3");
|
||||
if (realmRole3 == null) {
|
||||
realmRole3 = appRealm.addRole("realmRole3");
|
||||
}
|
||||
|
||||
// Add some role mappings directly into LDAP
|
||||
UserFederationMapperModel roleMapperModel = appRealm.getUserFederationMapperByName(ldapModel.getId(), "realmRolesMapper");
|
||||
LDAPFederationProvider ldapProvider = FederationTestUtils.getLdapProvider(session, ldapModel);
|
||||
RoleLDAPFederationMapper roleMapper = FederationTestUtils.getRoleMapper(roleMapperModel, ldapProvider, appRealm);
|
||||
|
||||
LDAPObject maryLdap = ldapProvider.loadLDAPUserByUsername(appRealm, "marykeycloak");
|
||||
roleMapper.addRoleMappingInLDAP("realmRole1", maryLdap);
|
||||
roleMapper.addRoleMappingInLDAP("realmRole2", maryLdap);
|
||||
|
||||
// Add some role to model
|
||||
mary.grantRole(realmRole3);
|
||||
|
||||
// Assert that mary has both LDAP and DB mapped roles
|
||||
Set<RoleModel> maryRoles = mary.getRealmRoleMappings();
|
||||
Assert.assertTrue(maryRoles.contains(realmRole1));
|
||||
Assert.assertTrue(maryRoles.contains(realmRole2));
|
||||
Assert.assertTrue(maryRoles.contains(realmRole3));
|
||||
|
||||
// Assert that access through DB will have just DB mapped role
|
||||
UserModel maryDB = session.userStorage().getUserByUsername("marykeycloak", appRealm);
|
||||
Set<RoleModel> maryDBRoles = maryDB.getRealmRoleMappings();
|
||||
Assert.assertFalse(maryDBRoles.contains(realmRole1));
|
||||
Assert.assertFalse(maryDBRoles.contains(realmRole2));
|
||||
Assert.assertTrue(maryDBRoles.contains(realmRole3));
|
||||
|
||||
mary.deleteRoleMapping(realmRole3);
|
||||
try {
|
||||
mary.deleteRoleMapping(realmRole1);
|
||||
Assert.fail("It wasn't expected to successfully delete LDAP role mappings in READ_ONLY mode");
|
||||
} catch (ModelException expected) {
|
||||
}
|
||||
|
||||
// Delete role mappings directly in LDAP
|
||||
deleteRoleMappingsInLDAP(roleMapper, maryLdap, "realmRole1");
|
||||
deleteRoleMappingsInLDAP(roleMapper, maryLdap, "realmRole2");
|
||||
} finally {
|
||||
keycloakRule.stopSession(session, false);
|
||||
}
|
||||
|
||||
session = keycloakRule.startSession();
|
||||
try {
|
||||
RealmModel appRealm = session.realms().getRealmByName("test");
|
||||
UserModel mary = session.users().getUserByUsername("marykeycloak", appRealm);
|
||||
|
||||
// Assert role mappings is not available
|
||||
Set<RoleModel> maryRoles = mary.getRealmRoleMappings();
|
||||
Assert.assertFalse(maryRoles.contains(appRealm.getRole("realmRole1")));
|
||||
Assert.assertFalse(maryRoles.contains(appRealm.getRole("realmRole2")));
|
||||
Assert.assertFalse(maryRoles.contains(appRealm.getRole("realmRole3")));
|
||||
} finally {
|
||||
keycloakRule.stopSession(session, false);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test03_importRoleMappings() {
|
||||
KeycloakSession session = keycloakRule.startSession();
|
||||
try {
|
||||
RealmModel appRealm = session.realms().getRealmByName("test");
|
||||
|
||||
FederationTestUtils.addOrUpdateRoleLDAPMappers(appRealm, ldapModel, LDAPGroupMapperMode.IMPORT);
|
||||
|
||||
// Add some role mappings directly in LDAP
|
||||
UserFederationMapperModel roleMapperModel = appRealm.getUserFederationMapperByName(ldapModel.getId(), "realmRolesMapper");
|
||||
LDAPFederationProvider ldapProvider = FederationTestUtils.getLdapProvider(session, ldapModel);
|
||||
RoleLDAPFederationMapper roleMapper = FederationTestUtils.getRoleMapper(roleMapperModel, ldapProvider, appRealm);
|
||||
|
||||
LDAPObject robLdap = ldapProvider.loadLDAPUserByUsername(appRealm, "robkeycloak");
|
||||
roleMapper.addRoleMappingInLDAP("realmRole1", robLdap);
|
||||
roleMapper.addRoleMappingInLDAP("realmRole2", robLdap);
|
||||
|
||||
// Get user and check that he has requested roles from LDAP
|
||||
UserModel rob = session.users().getUserByUsername("robkeycloak", appRealm);
|
||||
RoleModel realmRole1 = appRealm.getRole("realmRole1");
|
||||
RoleModel realmRole2 = appRealm.getRole("realmRole2");
|
||||
RoleModel realmRole3 = appRealm.getRole("realmRole3");
|
||||
if (realmRole3 == null) {
|
||||
realmRole3 = appRealm.addRole("realmRole3");
|
||||
}
|
||||
Set<RoleModel> robRoles = rob.getRealmRoleMappings();
|
||||
Assert.assertTrue(robRoles.contains(realmRole1));
|
||||
Assert.assertTrue(robRoles.contains(realmRole2));
|
||||
Assert.assertFalse(robRoles.contains(realmRole3));
|
||||
|
||||
// Add some role mappings in model and check that user has it
|
||||
rob.grantRole(realmRole3);
|
||||
robRoles = rob.getRealmRoleMappings();
|
||||
Assert.assertTrue(robRoles.contains(realmRole3));
|
||||
|
||||
// Delete some role mappings in LDAP and check that it doesn't have any effect and user still has role
|
||||
deleteRoleMappingsInLDAP(roleMapper, robLdap, "realmRole1");
|
||||
deleteRoleMappingsInLDAP(roleMapper, robLdap, "realmRole2");
|
||||
robRoles = rob.getRealmRoleMappings();
|
||||
Assert.assertTrue(robRoles.contains(realmRole1));
|
||||
Assert.assertTrue(robRoles.contains(realmRole2));
|
||||
|
||||
// Delete role mappings through model and verifies that user doesn't have them anymore
|
||||
rob.deleteRoleMapping(realmRole1);
|
||||
rob.deleteRoleMapping(realmRole2);
|
||||
rob.deleteRoleMapping(realmRole3);
|
||||
robRoles = rob.getRealmRoleMappings();
|
||||
Assert.assertFalse(robRoles.contains(realmRole1));
|
||||
Assert.assertFalse(robRoles.contains(realmRole2));
|
||||
Assert.assertFalse(robRoles.contains(realmRole3));
|
||||
} finally {
|
||||
keycloakRule.stopSession(session, false);
|
||||
}
|
||||
}
|
||||
|
||||
private void deleteRoleMappingsInLDAP(RoleLDAPFederationMapper roleMapper, LDAPObject ldapUser, String roleName) {
|
||||
LDAPObject ldapRole1 = roleMapper.loadLDAPRoleByName(roleName);
|
||||
roleMapper.deleteRoleMappingInLDAP(ldapUser, ldapRole1);
|
||||
}
|
||||
}
|
|
@ -1,368 +0,0 @@
|
|||
/*
|
||||
* 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.ldap.base;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.ClassRule;
|
||||
import org.junit.FixMethodOrder;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.RuleChain;
|
||||
import org.junit.rules.TestRule;
|
||||
import org.junit.runners.MethodSorters;
|
||||
import org.keycloak.common.util.Time;
|
||||
import org.keycloak.federation.ldap.LDAPFederationProvider;
|
||||
import org.keycloak.federation.ldap.LDAPFederationProviderFactory;
|
||||
import org.keycloak.federation.ldap.idm.model.LDAPObject;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.KeycloakSessionFactory;
|
||||
import org.keycloak.models.LDAPConstants;
|
||||
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.models.UserProvider;
|
||||
import org.keycloak.models.utils.KeycloakModelUtils;
|
||||
import org.keycloak.services.managers.RealmManager;
|
||||
import org.keycloak.services.managers.UsersSyncManager;
|
||||
import org.keycloak.testsuite.federation.ldap.FederationTestUtils;
|
||||
import org.keycloak.testsuite.rule.KeycloakRule;
|
||||
import org.keycloak.testsuite.rule.LDAPRule;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||
*/
|
||||
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
|
||||
public class LDAPSyncTest {
|
||||
|
||||
private static LDAPRule ldapRule = new LDAPRule();
|
||||
|
||||
private static UserFederationProviderModel ldapModel = null;
|
||||
|
||||
private static KeycloakRule keycloakRule = new KeycloakRule(new KeycloakRule.KeycloakSetup() {
|
||||
|
||||
@Override
|
||||
public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
|
||||
// Other tests may left Time offset uncleared, which could cause issues
|
||||
Time.setOffset(0);
|
||||
|
||||
Map<String,String> ldapConfig = ldapRule.getConfig();
|
||||
ldapConfig.put(LDAPConstants.SYNC_REGISTRATIONS, "false");
|
||||
ldapConfig.put(LDAPConstants.EDIT_MODE, UserFederationProvider.EditMode.WRITABLE.toString());
|
||||
ldapModel = appRealm.addUserFederationProvider(LDAPFederationProviderFactory.PROVIDER_NAME, ldapConfig, 0, "test-ldap",
|
||||
-1, -1, 0);
|
||||
|
||||
FederationTestUtils.addZipCodeLDAPMapper(appRealm, ldapModel);
|
||||
|
||||
// Delete all LDAP users and add 5 new users for testing
|
||||
LDAPFederationProvider ldapFedProvider = FederationTestUtils.getLdapProvider(session, ldapModel);
|
||||
FederationTestUtils.removeAllLDAPUsers(ldapFedProvider, appRealm);
|
||||
|
||||
for (int i=1 ; i<=5 ; i++) {
|
||||
LDAPObject ldapUser = FederationTestUtils.addLDAPUser(ldapFedProvider, appRealm, "user" + i, "User" + i + "FN", "User" + i + "LN", "user" + i + "@email.org", null, "12" + i);
|
||||
FederationTestUtils.updateLDAPPassword(ldapFedProvider, ldapUser, "Password1");
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@ClassRule
|
||||
public static TestRule chain = RuleChain
|
||||
.outerRule(ldapRule)
|
||||
.around(keycloakRule);
|
||||
|
||||
// @Test
|
||||
// public void test01runit() throws Exception {
|
||||
// Thread.sleep(10000000);
|
||||
// }
|
||||
|
||||
@Test
|
||||
public void test01LDAPSync() {
|
||||
UsersSyncManager usersSyncManager = new UsersSyncManager();
|
||||
|
||||
// wait a bit
|
||||
sleep(ldapRule.getSleepTime());
|
||||
|
||||
KeycloakSession session = keycloakRule.startSession();
|
||||
try {
|
||||
KeycloakSessionFactory sessionFactory = session.getKeycloakSessionFactory();
|
||||
UserFederationSyncResult syncResult = usersSyncManager.syncAllUsers(sessionFactory, "test", ldapModel);
|
||||
FederationTestUtils.assertSyncEquals(syncResult, 5, 0, 0, 0);
|
||||
} finally {
|
||||
keycloakRule.stopSession(session, false);
|
||||
}
|
||||
|
||||
session = keycloakRule.startSession();
|
||||
try {
|
||||
RealmModel testRealm = session.realms().getRealm("test");
|
||||
UserProvider userProvider = session.userStorage();
|
||||
// Assert users imported
|
||||
FederationTestUtils.assertUserImported(userProvider, testRealm, "user1", "User1FN", "User1LN", "user1@email.org", "121");
|
||||
FederationTestUtils.assertUserImported(userProvider, testRealm, "user2", "User2FN", "User2LN", "user2@email.org", "122");
|
||||
FederationTestUtils.assertUserImported(userProvider, testRealm, "user3", "User3FN", "User3LN", "user3@email.org", "123");
|
||||
FederationTestUtils.assertUserImported(userProvider, testRealm, "user4", "User4FN", "User4LN", "user4@email.org", "124");
|
||||
FederationTestUtils.assertUserImported(userProvider, testRealm, "user5", "User5FN", "User5LN", "user5@email.org", "125");
|
||||
|
||||
// Assert lastSync time updated
|
||||
Assert.assertTrue(ldapModel.getLastSync() > 0);
|
||||
for (UserFederationProviderModel persistentFedModel : testRealm.getUserFederationProviders()) {
|
||||
if (LDAPFederationProviderFactory.PROVIDER_NAME.equals(persistentFedModel.getProviderName())) {
|
||||
Assert.assertTrue(persistentFedModel.getLastSync() > 0);
|
||||
} else {
|
||||
// Dummy provider has still 0
|
||||
Assert.assertEquals(0, persistentFedModel.getLastSync());
|
||||
}
|
||||
}
|
||||
|
||||
// wait a bit
|
||||
sleep(ldapRule.getSleepTime());
|
||||
|
||||
// Add user to LDAP and update 'user5' in LDAP
|
||||
LDAPFederationProvider ldapFedProvider = FederationTestUtils.getLdapProvider(session, ldapModel);
|
||||
FederationTestUtils.addLDAPUser(ldapFedProvider, testRealm, "user6", "User6FN", "User6LN", "user6@email.org", null, "126");
|
||||
LDAPObject ldapUser5 = ldapFedProvider.loadLDAPUserByUsername(testRealm, "user5");
|
||||
// NOTE: Changing LDAP attributes directly here
|
||||
ldapUser5.setSingleAttribute(LDAPConstants.EMAIL, "user5Updated@email.org");
|
||||
ldapUser5.setSingleAttribute(LDAPConstants.POSTAL_CODE, "521");
|
||||
ldapFedProvider.getLdapIdentityStore().update(ldapUser5);
|
||||
|
||||
// Assert still old users in local provider
|
||||
FederationTestUtils.assertUserImported(userProvider, testRealm, "user5", "User5FN", "User5LN", "user5@email.org", "125");
|
||||
Assert.assertNull(userProvider.getUserByUsername("user6", testRealm));
|
||||
|
||||
// Trigger partial sync
|
||||
KeycloakSessionFactory sessionFactory = session.getKeycloakSessionFactory();
|
||||
UserFederationSyncResult syncResult = usersSyncManager.syncChangedUsers(sessionFactory, "test", ldapModel);
|
||||
FederationTestUtils.assertSyncEquals(syncResult, 1, 1, 0, 0);
|
||||
} finally {
|
||||
keycloakRule.stopSession(session, false);
|
||||
}
|
||||
|
||||
session = keycloakRule.startSession();
|
||||
try {
|
||||
RealmModel testRealm = session.realms().getRealm("test");
|
||||
UserProvider userProvider = session.userStorage();
|
||||
// Assert users updated in local provider
|
||||
FederationTestUtils.assertUserImported(userProvider, testRealm, "user5", "User5FN", "User5LN", "user5updated@email.org", "521");
|
||||
FederationTestUtils.assertUserImported(userProvider, testRealm, "user6", "User6FN", "User6LN", "user6@email.org", "126");
|
||||
} finally {
|
||||
keycloakRule.stopSession(session, false);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test02duplicateUsernameAndEmailSync() {
|
||||
LDAPObject duplicatedLdapUser;
|
||||
|
||||
KeycloakSession session = keycloakRule.startSession();
|
||||
try {
|
||||
RealmModel testRealm = session.realms().getRealm("test");
|
||||
|
||||
FederationTestUtils.addLocalUser(session, testRealm, "user7", "user7@email.org", "password");
|
||||
LDAPFederationProvider ldapFedProvider = FederationTestUtils.getLdapProvider(session, ldapModel);
|
||||
|
||||
// Add user to LDAP with duplicated username "user7"
|
||||
duplicatedLdapUser = FederationTestUtils.addLDAPUser(ldapFedProvider, testRealm, "user7", "User7FN", "User7LN", "user7-something@email.org", null, "126");
|
||||
|
||||
} finally {
|
||||
keycloakRule.stopSession(session, true);
|
||||
}
|
||||
|
||||
session = keycloakRule.startSession();
|
||||
try {
|
||||
RealmModel testRealm = session.realms().getRealm("test");
|
||||
|
||||
// Assert syncing from LDAP fails due to duplicated username
|
||||
UserFederationSyncResult result = new UsersSyncManager().syncAllUsers(session.getKeycloakSessionFactory(), "test", ldapModel);
|
||||
Assert.assertEquals(1, result.getFailed());
|
||||
|
||||
// Remove "user7" from LDAP
|
||||
LDAPFederationProvider ldapFedProvider = FederationTestUtils.getLdapProvider(session, ldapModel);
|
||||
ldapFedProvider.getLdapIdentityStore().remove(duplicatedLdapUser);
|
||||
|
||||
// Add user to LDAP with duplicated email "user7@email.org"
|
||||
duplicatedLdapUser = FederationTestUtils.addLDAPUser(ldapFedProvider, testRealm, "user7-something", "User7FNN", "User7LNL", "user7@email.org", null, "126");
|
||||
} finally {
|
||||
keycloakRule.stopSession(session, true);
|
||||
}
|
||||
|
||||
session = keycloakRule.startSession();
|
||||
try {
|
||||
RealmModel testRealm = session.realms().getRealm("test");
|
||||
|
||||
// Assert syncing from LDAP fails due to duplicated email
|
||||
UserFederationSyncResult result = new UsersSyncManager().syncAllUsers(session.getKeycloakSessionFactory(), "test", ldapModel);
|
||||
Assert.assertEquals(1, result.getFailed());
|
||||
Assert.assertNull(session.userStorage().getUserByUsername("user7-something", testRealm));
|
||||
|
||||
// Update LDAP user to avoid duplicated email
|
||||
duplicatedLdapUser.setSingleAttribute(LDAPConstants.EMAIL, "user7-changed@email.org");
|
||||
LDAPFederationProvider ldapFedProvider = FederationTestUtils.getLdapProvider(session, ldapModel);
|
||||
ldapFedProvider.getLdapIdentityStore().update(duplicatedLdapUser);
|
||||
|
||||
// Assert user successfully synced now
|
||||
result = new UsersSyncManager().syncAllUsers(session.getKeycloakSessionFactory(), "test", ldapModel);
|
||||
Assert.assertEquals(0, result.getFailed());
|
||||
} finally {
|
||||
keycloakRule.stopSession(session, true);
|
||||
}
|
||||
|
||||
// Assert user imported in another transaction
|
||||
session = keycloakRule.startSession();
|
||||
try {
|
||||
RealmModel testRealm = session.realms().getRealm("test");
|
||||
FederationTestUtils.assertUserImported(session.userStorage(), testRealm, "user7-something", "User7FNN", "User7LNL", "user7-changed@email.org", "126");
|
||||
} finally {
|
||||
keycloakRule.stopSession(session, false);
|
||||
}
|
||||
}
|
||||
|
||||
// KEYCLOAK-1571
|
||||
@Test
|
||||
public void test03SameUUIDAndUsernameSync() {
|
||||
KeycloakSession session = keycloakRule.startSession();
|
||||
String origUuidAttrName;
|
||||
|
||||
try {
|
||||
RealmModel testRealm = session.realms().getRealm("test");
|
||||
|
||||
// Remove all users from model
|
||||
for (UserModel user : session.userStorage().getUsers(testRealm, true)) {
|
||||
session.userStorage().removeUser(testRealm, user);
|
||||
}
|
||||
|
||||
UserFederationProviderModel providerModel = KeycloakModelUtils.findUserFederationProviderByDisplayName(ldapModel.getDisplayName(), testRealm);
|
||||
|
||||
// Change name of UUID attribute to same like usernameAttribute
|
||||
LDAPFederationProvider ldapFedProvider = FederationTestUtils.getLdapProvider(session, ldapModel);
|
||||
String uidAttrName = ldapFedProvider.getLdapIdentityStore().getConfig().getUsernameLdapAttribute();
|
||||
origUuidAttrName = providerModel.getConfig().get(LDAPConstants.UUID_LDAP_ATTRIBUTE);
|
||||
providerModel.getConfig().put(LDAPConstants.UUID_LDAP_ATTRIBUTE, uidAttrName);
|
||||
|
||||
// Need to change this due to ApacheDS pagination bug (For other LDAP servers, pagination works fine) TODO: Remove once ApacheDS upgraded and pagination is fixed
|
||||
providerModel.getConfig().put(LDAPConstants.BATCH_SIZE_FOR_SYNC, "10");
|
||||
testRealm.updateUserFederationProvider(providerModel);
|
||||
|
||||
} finally {
|
||||
keycloakRule.stopSession(session, true);
|
||||
}
|
||||
|
||||
session = keycloakRule.startSession();
|
||||
try {
|
||||
RealmModel testRealm = session.realms().getRealm("test");
|
||||
UserFederationProviderModel providerModel = KeycloakModelUtils.findUserFederationProviderByDisplayName(ldapModel.getDisplayName(), testRealm);
|
||||
|
||||
KeycloakSessionFactory sessionFactory = session.getKeycloakSessionFactory();
|
||||
UserFederationSyncResult syncResult = new UsersSyncManager().syncAllUsers(sessionFactory, "test", providerModel);
|
||||
Assert.assertEquals(0, syncResult.getFailed());
|
||||
|
||||
} finally {
|
||||
keycloakRule.stopSession(session, false);
|
||||
}
|
||||
|
||||
session = keycloakRule.startSession();
|
||||
try {
|
||||
RealmModel testRealm = session.realms().getRealm("test");
|
||||
|
||||
// Assert users imported with correct LDAP_ID
|
||||
FederationTestUtils.assertUserImported(session.users(), testRealm, "user1", "User1FN", "User1LN", "user1@email.org", "121");
|
||||
FederationTestUtils.assertUserImported(session.users(), testRealm, "user2", "User2FN", "User2LN", "user2@email.org", "122");
|
||||
UserModel user1 = session.users().getUserByUsername("user1", testRealm);
|
||||
Assert.assertEquals("user1", user1.getFirstAttribute(LDAPConstants.LDAP_ID));
|
||||
|
||||
// Revert config changes
|
||||
UserFederationProviderModel providerModel = KeycloakModelUtils.findUserFederationProviderByDisplayName(ldapModel.getDisplayName(), testRealm);
|
||||
providerModel.getConfig().put(LDAPConstants.UUID_LDAP_ATTRIBUTE, origUuidAttrName);
|
||||
testRealm.updateUserFederationProvider(providerModel);
|
||||
} finally {
|
||||
keycloakRule.stopSession(session, true);
|
||||
}
|
||||
}
|
||||
|
||||
// KEYCLOAK-1728
|
||||
@Test
|
||||
public void test04MissingLDAPUsernameSync() {
|
||||
KeycloakSession session = keycloakRule.startSession();
|
||||
String origUsernameAttrName;
|
||||
|
||||
try {
|
||||
RealmModel testRealm = session.realms().getRealm("test");
|
||||
|
||||
// Remove all users from model
|
||||
for (UserModel user : session.userStorage().getUsers(testRealm, true)) {
|
||||
session.userStorage().removeUser(testRealm, user);
|
||||
}
|
||||
|
||||
UserFederationProviderModel providerModel = KeycloakModelUtils.findUserFederationProviderByDisplayName(ldapModel.getDisplayName(), testRealm);
|
||||
|
||||
// Add street mapper and add some user including street
|
||||
UserFederationMapperModel streetMapper = FederationTestUtils.addUserAttributeMapper(testRealm, ldapModel, "streetMapper", "street", LDAPConstants.STREET);
|
||||
LDAPFederationProvider ldapFedProvider = FederationTestUtils.getLdapProvider(session, ldapModel);
|
||||
LDAPObject streetUser = FederationTestUtils.addLDAPUser(ldapFedProvider, testRealm, "user8", "User8FN", "User8LN", "user8@email.org", "user8street", "126");
|
||||
|
||||
// Change name of username attribute name to street
|
||||
origUsernameAttrName = providerModel.getConfig().get(LDAPConstants.USERNAME_LDAP_ATTRIBUTE);
|
||||
providerModel.getConfig().put(LDAPConstants.USERNAME_LDAP_ATTRIBUTE, "street");
|
||||
|
||||
// Need to change this due to ApacheDS pagination bug (For other LDAP servers, pagination works fine) TODO: Remove once ApacheDS upgraded and pagination is fixed
|
||||
providerModel.getConfig().put(LDAPConstants.BATCH_SIZE_FOR_SYNC, "10");
|
||||
testRealm.updateUserFederationProvider(providerModel);
|
||||
|
||||
} finally {
|
||||
keycloakRule.stopSession(session, true);
|
||||
}
|
||||
|
||||
// Just user8 synced. All others failed to sync
|
||||
session = keycloakRule.startSession();
|
||||
try {
|
||||
RealmModel testRealm = session.realms().getRealm("test");
|
||||
UserFederationProviderModel providerModel = KeycloakModelUtils.findUserFederationProviderByDisplayName(ldapModel.getDisplayName(), testRealm);
|
||||
|
||||
KeycloakSessionFactory sessionFactory = session.getKeycloakSessionFactory();
|
||||
UserFederationSyncResult syncResult = new UsersSyncManager().syncAllUsers(sessionFactory, "test", providerModel);
|
||||
Assert.assertEquals(1, syncResult.getAdded());
|
||||
Assert.assertTrue(syncResult.getFailed() > 0);
|
||||
} finally {
|
||||
keycloakRule.stopSession(session, false);
|
||||
}
|
||||
|
||||
session = keycloakRule.startSession();
|
||||
try {
|
||||
RealmModel testRealm = session.realms().getRealm("test");
|
||||
|
||||
// Revert config changes
|
||||
UserFederationProviderModel providerModel = KeycloakModelUtils.findUserFederationProviderByDisplayName(ldapModel.getDisplayName(), testRealm);
|
||||
providerModel.getConfig().put(LDAPConstants.USERNAME_LDAP_ATTRIBUTE, origUsernameAttrName);
|
||||
testRealm.updateUserFederationProvider(providerModel);
|
||||
UserFederationMapperModel streetMapper = testRealm.getUserFederationMapperByName(providerModel.getId(), "streetMapper");
|
||||
testRealm.removeUserFederationMapper(streetMapper);
|
||||
} finally {
|
||||
keycloakRule.stopSession(session, true);
|
||||
}
|
||||
}
|
||||
|
||||
private void sleep(int time) {
|
||||
try {
|
||||
Thread.sleep(time);
|
||||
} catch (InterruptedException ie) {
|
||||
throw new RuntimeException(ie);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -22,8 +22,7 @@ import org.junit.FixMethodOrder;
|
|||
import org.junit.Test;
|
||||
import org.junit.runners.MethodSorters;
|
||||
import org.keycloak.common.constants.KerberosConstants;
|
||||
import org.keycloak.federation.ldap.mappers.FullNameLDAPFederationMapper;
|
||||
import org.keycloak.federation.ldap.mappers.FullNameLDAPFederationMapperFactory;
|
||||
import org.keycloak.component.ComponentModel;
|
||||
import org.keycloak.models.AuthenticationFlowModel;
|
||||
import org.keycloak.models.ClientModel;
|
||||
import org.keycloak.models.ClientTemplateModel;
|
||||
|
@ -49,6 +48,9 @@ import org.keycloak.protocol.oidc.mappers.OIDCAttributeMapperHelper;
|
|||
import org.keycloak.protocol.oidc.mappers.UserSessionNoteMapper;
|
||||
import org.keycloak.representations.idm.RealmRepresentation;
|
||||
import org.keycloak.services.managers.RealmManager;
|
||||
import org.keycloak.storage.UserStorageProviderModel;
|
||||
import org.keycloak.storage.ldap.mappers.FullNameLDAPStorageMapper;
|
||||
import org.keycloak.storage.ldap.mappers.FullNameLDAPStorageMapperFactory;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
@ -278,31 +280,28 @@ public class ImportTest extends AbstractModelTest {
|
|||
|
||||
// Test federation providers
|
||||
List<UserFederationProviderModel> fedProviders = realm.getUserFederationProviders();
|
||||
Assert.assertTrue(fedProviders.size() == 2);
|
||||
UserFederationProviderModel ldap1 = fedProviders.get(0);
|
||||
Assert.assertEquals("MyLDAPProvider1", ldap1.getDisplayName());
|
||||
Assert.assertEquals("ldap", ldap1.getProviderName());
|
||||
Assert.assertTrue(fedProviders.size() == 0);
|
||||
List<UserStorageProviderModel> storageProviders = realm.getUserStorageProviders();
|
||||
Assert.assertTrue(storageProviders.size() == 2);
|
||||
UserStorageProviderModel ldap1 = storageProviders.get(0);
|
||||
Assert.assertEquals("MyLDAPProvider1", ldap1.getName());
|
||||
Assert.assertEquals("ldap", ldap1.getProviderId());
|
||||
Assert.assertEquals(1, ldap1.getPriority());
|
||||
Assert.assertEquals("ldap://foo", ldap1.getConfig().get(LDAPConstants.CONNECTION_URL));
|
||||
Assert.assertEquals("ldap://foo", ldap1.getConfig().getFirst(LDAPConstants.CONNECTION_URL));
|
||||
|
||||
UserFederationProviderModel ldap2 = fedProviders.get(1);
|
||||
Assert.assertEquals("MyLDAPProvider2", ldap2.getDisplayName());
|
||||
Assert.assertEquals("ldap://bar", ldap2.getConfig().get(LDAPConstants.CONNECTION_URL));
|
||||
UserStorageProviderModel ldap2 = storageProviders.get(1);
|
||||
Assert.assertEquals("MyLDAPProvider2", ldap2.getName());
|
||||
Assert.assertEquals("ldap://bar", ldap2.getConfig().getFirst(LDAPConstants.CONNECTION_URL));
|
||||
|
||||
// Test federation mappers
|
||||
Set<UserFederationMapperModel> fedMappers1 = realm.getUserFederationMappersByFederationProvider(ldap1.getId());
|
||||
Assert.assertTrue(fedMappers1.size() == 1);
|
||||
UserFederationMapperModel fullNameMapper = fedMappers1.iterator().next();
|
||||
Set<UserFederationMapperModel> userFedMappers1 = realm.getUserFederationMappers();
|
||||
Assert.assertTrue(userFedMappers1.size() == 0);
|
||||
List<ComponentModel> fedMappers1 = realm.getComponents(ldap1.getId());
|
||||
ComponentModel fullNameMapper = fedMappers1.iterator().next();
|
||||
Assert.assertEquals("FullNameMapper", fullNameMapper.getName());
|
||||
Assert.assertEquals(FullNameLDAPFederationMapperFactory.PROVIDER_ID, fullNameMapper.getFederationMapperType());
|
||||
Assert.assertEquals(ldap1.getId(), fullNameMapper.getFederationProviderId());
|
||||
Assert.assertEquals("cn", fullNameMapper.getConfig().get(FullNameLDAPFederationMapper.LDAP_FULL_NAME_ATTRIBUTE));
|
||||
|
||||
// All builtin LDAP mappers should be here
|
||||
Set<UserFederationMapperModel> fedMappers2 = realm.getUserFederationMappersByFederationProvider(ldap2.getId());
|
||||
Assert.assertTrue(fedMappers2.size() > 3);
|
||||
Set<UserFederationMapperModel> allMappers = realm.getUserFederationMappers();
|
||||
Assert.assertEquals(allMappers.size(), fedMappers1.size() + fedMappers2.size());
|
||||
Assert.assertEquals(FullNameLDAPStorageMapperFactory.PROVIDER_ID, fullNameMapper.getProviderId());
|
||||
Assert.assertEquals(ldap1.getId(), fullNameMapper.getParentId());
|
||||
Assert.assertEquals("cn", fullNameMapper.getConfig().getFirst(FullNameLDAPStorageMapper.LDAP_FULL_NAME_ATTRIBUTE));
|
||||
|
||||
// Assert that federation link wasn't created during import
|
||||
UserFederationProviderFactory factory = (UserFederationProviderFactory)session.getKeycloakSessionFactory().getProviderFactory(UserFederationProvider.class, "dummy");
|
||||
|
|
Loading…
Reference in a new issue