KEYCLOAK-4298 Migrate LDAP tests to the new testsuite
This commit is contained in:
parent
65030e2c73
commit
27719565ae
49 changed files with 3896 additions and 5428 deletions
|
@ -16,6 +16,10 @@ By default the testsuite uses an embedded H2 database to test with other databas
|
||||||
Test utils
|
Test utils
|
||||||
==========
|
==========
|
||||||
|
|
||||||
|
All the utils can be executed from the directory testsuite/utils:
|
||||||
|
|
||||||
|
cd testsuite/utils
|
||||||
|
|
||||||
Keycloak server
|
Keycloak server
|
||||||
---------------
|
---------------
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,7 @@ package org.keycloak.testsuite.rest;
|
||||||
import org.jboss.resteasy.annotations.cache.NoCache;
|
import org.jboss.resteasy.annotations.cache.NoCache;
|
||||||
import org.jboss.resteasy.spi.BadRequestException;
|
import org.jboss.resteasy.spi.BadRequestException;
|
||||||
import org.jboss.resteasy.spi.HttpRequest;
|
import org.jboss.resteasy.spi.HttpRequest;
|
||||||
|
import org.keycloak.common.util.MultivaluedHashMap;
|
||||||
import org.keycloak.common.util.Time;
|
import org.keycloak.common.util.Time;
|
||||||
import org.keycloak.component.ComponentModel;
|
import org.keycloak.component.ComponentModel;
|
||||||
import org.keycloak.events.Event;
|
import org.keycloak.events.Event;
|
||||||
|
@ -35,6 +36,7 @@ import org.keycloak.models.AuthenticationFlowModel;
|
||||||
import org.keycloak.models.ClientModel;
|
import org.keycloak.models.ClientModel;
|
||||||
import org.keycloak.models.FederatedIdentityModel;
|
import org.keycloak.models.FederatedIdentityModel;
|
||||||
import org.keycloak.models.KeycloakSession;
|
import org.keycloak.models.KeycloakSession;
|
||||||
|
import org.keycloak.models.LDAPConstants;
|
||||||
import org.keycloak.models.RealmModel;
|
import org.keycloak.models.RealmModel;
|
||||||
import org.keycloak.models.RealmProvider;
|
import org.keycloak.models.RealmProvider;
|
||||||
import org.keycloak.models.UserCredentialModel;
|
import org.keycloak.models.UserCredentialModel;
|
||||||
|
@ -54,6 +56,8 @@ import org.keycloak.services.managers.RealmManager;
|
||||||
import org.keycloak.services.resource.RealmResourceProvider;
|
import org.keycloak.services.resource.RealmResourceProvider;
|
||||||
import org.keycloak.services.scheduled.ClearExpiredUserSessions;
|
import org.keycloak.services.scheduled.ClearExpiredUserSessions;
|
||||||
import org.keycloak.storage.UserStorageProvider;
|
import org.keycloak.storage.UserStorageProvider;
|
||||||
|
import org.keycloak.storage.UserStorageProviderModel;
|
||||||
|
import org.keycloak.storage.ldap.LDAPStorageProviderFactory;
|
||||||
import org.keycloak.testsuite.components.TestProvider;
|
import org.keycloak.testsuite.components.TestProvider;
|
||||||
import org.keycloak.testsuite.components.TestProviderFactory;
|
import org.keycloak.testsuite.components.TestProviderFactory;
|
||||||
import org.keycloak.testsuite.events.EventsListenerProvider;
|
import org.keycloak.testsuite.events.EventsListenerProvider;
|
||||||
|
@ -63,6 +67,7 @@ import org.keycloak.testsuite.forms.PassThroughClientAuthenticator;
|
||||||
import org.keycloak.testsuite.rest.representation.AuthenticatorState;
|
import org.keycloak.testsuite.rest.representation.AuthenticatorState;
|
||||||
import org.keycloak.testsuite.rest.resource.TestCacheResource;
|
import org.keycloak.testsuite.rest.resource.TestCacheResource;
|
||||||
import org.keycloak.testsuite.rest.resource.TestJavascriptResource;
|
import org.keycloak.testsuite.rest.resource.TestJavascriptResource;
|
||||||
|
import org.keycloak.testsuite.rest.resource.TestLDAPResource;
|
||||||
import org.keycloak.testsuite.rest.resource.TestingExportImportResource;
|
import org.keycloak.testsuite.rest.resource.TestingExportImportResource;
|
||||||
import org.keycloak.testsuite.runonserver.ModuleUtil;
|
import org.keycloak.testsuite.runonserver.ModuleUtil;
|
||||||
import org.keycloak.testsuite.runonserver.FetchOnServer;
|
import org.keycloak.testsuite.runonserver.FetchOnServer;
|
||||||
|
@ -572,6 +577,13 @@ public class TestingResourceProvider implements RealmResourceProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Path("/ldap/{realm}")
|
||||||
|
public TestLDAPResource ldap(@PathParam("realm") final String realmName) {
|
||||||
|
RealmModel realm = session.realms().getRealmByName(realmName);
|
||||||
|
return new TestLDAPResource(session, realm);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void close() {
|
public void close() {
|
||||||
}
|
}
|
||||||
|
@ -682,6 +694,7 @@ public class TestingResourceProvider implements RealmResourceProvider {
|
||||||
return reps;
|
return reps;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@GET
|
@GET
|
||||||
@Path("/identity-config")
|
@Path("/identity-config")
|
||||||
@Produces(MediaType.APPLICATION_JSON)
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
|
|
|
@ -0,0 +1,164 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2017 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.rest.resource;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import javax.ws.rs.Consumes;
|
||||||
|
import javax.ws.rs.POST;
|
||||||
|
import javax.ws.rs.Path;
|
||||||
|
import javax.ws.rs.Produces;
|
||||||
|
import javax.ws.rs.QueryParam;
|
||||||
|
|
||||||
|
import org.keycloak.common.util.MultivaluedHashMap;
|
||||||
|
import org.keycloak.component.ComponentModel;
|
||||||
|
import org.keycloak.models.KeycloakSession;
|
||||||
|
import org.keycloak.models.LDAPConstants;
|
||||||
|
import org.keycloak.models.RealmModel;
|
||||||
|
import org.keycloak.models.utils.KeycloakModelUtils;
|
||||||
|
import org.keycloak.storage.UserStorageProvider;
|
||||||
|
import org.keycloak.storage.UserStorageProviderModel;
|
||||||
|
import org.keycloak.storage.ldap.LDAPStorageProvider;
|
||||||
|
import org.keycloak.storage.ldap.LDAPStorageProviderFactory;
|
||||||
|
import org.keycloak.storage.ldap.LDAPUtils;
|
||||||
|
import org.keycloak.storage.ldap.idm.model.LDAPObject;
|
||||||
|
import org.keycloak.storage.ldap.mappers.membership.LDAPGroupMapperMode;
|
||||||
|
import org.keycloak.storage.ldap.mappers.membership.MembershipType;
|
||||||
|
import org.keycloak.storage.ldap.mappers.membership.group.GroupLDAPStorageMapperFactory;
|
||||||
|
import org.keycloak.testsuite.util.LDAPTestUtils;
|
||||||
|
import org.keycloak.utils.MediaType;
|
||||||
|
|
||||||
|
import static org.keycloak.testsuite.util.LDAPTestUtils.getGroupDescriptionLDAPAttrName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||||
|
*/
|
||||||
|
public class TestLDAPResource {
|
||||||
|
|
||||||
|
private final KeycloakSession session;
|
||||||
|
private final RealmModel realm;
|
||||||
|
|
||||||
|
public TestLDAPResource(KeycloakSession session, RealmModel realm) {
|
||||||
|
this.session = session;
|
||||||
|
this.realm = realm;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param ldapCfg configuration of LDAP provider
|
||||||
|
* @param importEnabled specify if LDAP provider will have import enabled
|
||||||
|
* @return ID of newly created provider
|
||||||
|
*/
|
||||||
|
@POST
|
||||||
|
@Path("/create-ldap-provider")
|
||||||
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
|
public String createLDAPProvider(Map<String,String> ldapCfg, @QueryParam("import") boolean importEnabled) {
|
||||||
|
MultivaluedHashMap<String, String> ldapConfig = toComponentConfig(ldapCfg);
|
||||||
|
ldapConfig.putSingle(LDAPConstants.SYNC_REGISTRATIONS, "true");
|
||||||
|
ldapConfig.putSingle(LDAPConstants.EDIT_MODE, UserStorageProvider.EditMode.WRITABLE.toString());
|
||||||
|
|
||||||
|
UserStorageProviderModel model = new UserStorageProviderModel();
|
||||||
|
model.setLastSync(0);
|
||||||
|
model.setChangedSyncPeriod(-1);
|
||||||
|
model.setFullSyncPeriod(-1);
|
||||||
|
model.setName("test-ldap");
|
||||||
|
model.setPriority(0);
|
||||||
|
model.setProviderId(LDAPStorageProviderFactory.PROVIDER_NAME);
|
||||||
|
model.setConfig(ldapConfig);
|
||||||
|
|
||||||
|
model.setImportEnabled(importEnabled);
|
||||||
|
|
||||||
|
model.setCachePolicy(UserStorageProviderModel.CachePolicy.MAX_LIFESPAN);
|
||||||
|
model.setMaxLifespan(600000); // Lifetime is 10 minutes
|
||||||
|
|
||||||
|
ComponentModel ldapModel = realm.addComponentModel(model);
|
||||||
|
return ldapModel.getId();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static MultivaluedHashMap<String, String> toComponentConfig(Map<String, String> ldapConfig) {
|
||||||
|
MultivaluedHashMap<String, String> config = new MultivaluedHashMap<>();
|
||||||
|
for (Map.Entry<String, String> entry : ldapConfig.entrySet()) {
|
||||||
|
config.add(entry.getKey(), entry.getValue());
|
||||||
|
|
||||||
|
}
|
||||||
|
return config;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prepare groups LDAP tests. Creates some LDAP mappers as well as some built-in GRoups and users in LDAP
|
||||||
|
*/
|
||||||
|
@POST
|
||||||
|
@Path("/configure-groups")
|
||||||
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
|
public void prepareGroupsLDAPTest() {
|
||||||
|
LDAPTestUtils.addLocalUser(session, realm, "mary", "mary@test.com", "password-app");
|
||||||
|
LDAPTestUtils.addLocalUser(session, realm, "john", "john@test.com", "password-app");
|
||||||
|
|
||||||
|
ComponentModel ldapModel = LDAPTestUtils.getLdapProviderModel(session, realm);
|
||||||
|
LDAPStorageProvider ldapFedProvider = LDAPTestUtils.getLdapProvider(session, ldapModel);
|
||||||
|
String descriptionAttrName = getGroupDescriptionLDAPAttrName(ldapFedProvider);
|
||||||
|
|
||||||
|
// Add group mapper
|
||||||
|
LDAPTestUtils.addOrUpdateGroupMapper(realm, ldapModel, LDAPGroupMapperMode.LDAP_ONLY, descriptionAttrName);
|
||||||
|
|
||||||
|
// Remove all LDAP groups
|
||||||
|
LDAPTestUtils.removeAllLDAPGroups(session, realm, ldapModel, "groupsMapper");
|
||||||
|
|
||||||
|
// Add some groups for testing
|
||||||
|
LDAPObject group1 = LDAPTestUtils.createLDAPGroup(session, realm, ldapModel, "group1", descriptionAttrName, "group1 - description");
|
||||||
|
LDAPObject group11 = LDAPTestUtils.createLDAPGroup(session, realm, ldapModel, "group11");
|
||||||
|
LDAPObject group12 = LDAPTestUtils.createLDAPGroup(session, realm, ldapModel, "group12", descriptionAttrName, "group12 - description");
|
||||||
|
|
||||||
|
LDAPObject defaultGroup1 = LDAPTestUtils.createLDAPGroup(session, realm, ldapModel, "defaultGroup1", descriptionAttrName, "Default Group1 - description");
|
||||||
|
LDAPObject defaultGroup11 = LDAPTestUtils.createLDAPGroup(session, realm, ldapModel, "defaultGroup11");
|
||||||
|
LDAPObject defaultGroup12 = LDAPTestUtils.createLDAPGroup(session, realm, ldapModel, "defaultGroup12", descriptionAttrName, "Default Group12 - description");
|
||||||
|
|
||||||
|
LDAPUtils.addMember(ldapFedProvider, MembershipType.DN, LDAPConstants.MEMBER, "not-used", group1, group11, false);
|
||||||
|
LDAPUtils.addMember(ldapFedProvider, MembershipType.DN, LDAPConstants.MEMBER, "not-used", group1, group12, true);
|
||||||
|
|
||||||
|
LDAPUtils.addMember(ldapFedProvider, MembershipType.DN, LDAPConstants.MEMBER, "not-used", defaultGroup1, defaultGroup11, false);
|
||||||
|
LDAPUtils.addMember(ldapFedProvider, MembershipType.DN, LDAPConstants.MEMBER, "not-used", defaultGroup1, defaultGroup12, true);
|
||||||
|
|
||||||
|
// Sync LDAP groups to Keycloak DB
|
||||||
|
ComponentModel mapperModel = LDAPTestUtils.getSubcomponentByName(realm, ldapModel, "groupsMapper");
|
||||||
|
new GroupLDAPStorageMapperFactory().create(session, mapperModel).syncDataFromFederationProviderToKeycloak(realm);
|
||||||
|
|
||||||
|
realm.addDefaultGroup(KeycloakModelUtils.findGroupByPath(realm, "/defaultGroup1/defaultGroup11"));
|
||||||
|
realm.addDefaultGroup(KeycloakModelUtils.findGroupByPath(realm, "/defaultGroup1/defaultGroup12"));
|
||||||
|
|
||||||
|
// Delete all LDAP users
|
||||||
|
LDAPTestUtils.removeAllLDAPUsers(ldapFedProvider, realm);
|
||||||
|
|
||||||
|
// Add some LDAP users for testing
|
||||||
|
LDAPObject john = LDAPTestUtils.addLDAPUser(ldapFedProvider, realm, "johnkeycloak", "John", "Doe", "john@email.org", null, "1234");
|
||||||
|
LDAPTestUtils.updateLDAPPassword(ldapFedProvider, john, "Password1");
|
||||||
|
|
||||||
|
LDAPObject mary = LDAPTestUtils.addLDAPUser(ldapFedProvider, realm, "marykeycloak", "Mary", "Kelly", "mary@email.org", null, "5678");
|
||||||
|
LDAPTestUtils.updateLDAPPassword(ldapFedProvider, mary, "Password1");
|
||||||
|
|
||||||
|
LDAPObject rob = LDAPTestUtils.addLDAPUser(ldapFedProvider, realm, "robkeycloak", "Rob", "Brown", "rob@email.org", null, "8910");
|
||||||
|
LDAPTestUtils.updateLDAPPassword(ldapFedProvider, rob, "Password1");
|
||||||
|
|
||||||
|
LDAPObject james = LDAPTestUtils.addLDAPUser(ldapFedProvider, realm, "jameskeycloak", "James", "Brown", "james@email.org", null, "8910");
|
||||||
|
LDAPTestUtils.updateLDAPPassword(ldapFedProvider, james, "Password1");
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2016 Red Hat, Inc. and/or its affiliates
|
* Copyright 2017 Red Hat, Inc. and/or its affiliates
|
||||||
* and other contributors as indicated by the @author tags.
|
* and other contributors as indicated by the @author tags.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
@ -15,21 +15,17 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.keycloak.testsuite.federation.storage.ldap;
|
package org.keycloak.testsuite.util;
|
||||||
|
|
||||||
import org.junit.Assert;
|
|
||||||
import org.keycloak.common.util.MultivaluedHashMap;
|
|
||||||
import org.keycloak.component.ComponentModel;
|
import org.keycloak.component.ComponentModel;
|
||||||
import org.keycloak.models.KeycloakSession;
|
import org.keycloak.models.KeycloakSession;
|
||||||
import org.keycloak.models.LDAPConstants;
|
import org.keycloak.models.LDAPConstants;
|
||||||
import org.keycloak.models.RealmModel;
|
import org.keycloak.models.RealmModel;
|
||||||
import org.keycloak.models.UserCredentialModel;
|
import org.keycloak.models.UserCredentialModel;
|
||||||
import org.keycloak.models.UserModel;
|
import org.keycloak.models.UserModel;
|
||||||
import org.keycloak.models.UserProvider;
|
|
||||||
import org.keycloak.models.utils.KeycloakModelUtils;
|
import org.keycloak.models.utils.KeycloakModelUtils;
|
||||||
import org.keycloak.models.utils.UserModelDelegate;
|
import org.keycloak.models.utils.UserModelDelegate;
|
||||||
import org.keycloak.representations.idm.CredentialRepresentation;
|
import org.keycloak.representations.idm.CredentialRepresentation;
|
||||||
import org.keycloak.representations.idm.SynchronizationResultRepresentation;
|
|
||||||
import org.keycloak.storage.UserStorageProvider;
|
import org.keycloak.storage.UserStorageProvider;
|
||||||
import org.keycloak.storage.ldap.LDAPStorageProvider;
|
import org.keycloak.storage.ldap.LDAPStorageProvider;
|
||||||
import org.keycloak.storage.ldap.LDAPConfig;
|
import org.keycloak.storage.ldap.LDAPConfig;
|
||||||
|
@ -47,8 +43,6 @@ import org.keycloak.storage.ldap.mappers.membership.group.GroupMapperConfig;
|
||||||
import org.keycloak.storage.ldap.mappers.membership.role.RoleLDAPStorageMapper;
|
import org.keycloak.storage.ldap.mappers.membership.role.RoleLDAPStorageMapper;
|
||||||
import org.keycloak.storage.ldap.mappers.membership.role.RoleLDAPStorageMapperFactory;
|
import org.keycloak.storage.ldap.mappers.membership.role.RoleLDAPStorageMapperFactory;
|
||||||
import org.keycloak.storage.ldap.mappers.membership.role.RoleMapperConfig;
|
import org.keycloak.storage.ldap.mappers.membership.role.RoleMapperConfig;
|
||||||
import org.keycloak.storage.user.SynchronizationResult;
|
|
||||||
import org.keycloak.testsuite.rule.LDAPRule;
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
@ -61,21 +55,6 @@ import java.util.Set;
|
||||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||||
*/
|
*/
|
||||||
public class LDAPTestUtils {
|
public class LDAPTestUtils {
|
||||||
public static MultivaluedHashMap<String, String> getLdapRuleConfig(LDAPRule ldapRule) {
|
|
||||||
Map<String,String> ldapConfig = ldapRule.getConfig();
|
|
||||||
return toComponentConfig(ldapConfig);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public static MultivaluedHashMap<String, String> toComponentConfig(Map<String, String> ldapConfig) {
|
|
||||||
MultivaluedHashMap<String, String> config = new MultivaluedHashMap<>();
|
|
||||||
for (Map.Entry<String, String> entry : ldapConfig.entrySet()) {
|
|
||||||
config.add(entry.getKey(), entry.getValue());
|
|
||||||
|
|
||||||
}
|
|
||||||
return config;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public static UserModel addLocalUser(KeycloakSession session, RealmModel realm, String username, String email, String password) {
|
public static UserModel addLocalUser(KeycloakSession session, RealmModel realm, String username, String email, String password) {
|
||||||
UserModel user = session.userLocalStorage().addUser(realm, username);
|
UserModel user = session.userLocalStorage().addUser(realm, username);
|
||||||
|
@ -138,28 +117,20 @@ public class LDAPTestUtils {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static ComponentModel getLdapProviderModel(KeycloakSession session, RealmModel realm) {
|
||||||
|
List<ComponentModel> components = realm.getComponents(realm.getId(), UserStorageProvider.class.getName());
|
||||||
|
for (ComponentModel component : components) {
|
||||||
|
if ("test-ldap".equals(component.getName())) {
|
||||||
|
return component;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
public static LDAPStorageProvider getLdapProvider(KeycloakSession keycloakSession, ComponentModel ldapFedModel) {
|
public static LDAPStorageProvider getLdapProvider(KeycloakSession keycloakSession, ComponentModel ldapFedModel) {
|
||||||
return (LDAPStorageProvider)keycloakSession.getProvider(UserStorageProvider.class, ldapFedModel);
|
return (LDAPStorageProvider)keycloakSession.getProvider(UserStorageProvider.class, ldapFedModel);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static UserModel 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"));
|
|
||||||
return user;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void assertLoaded(UserModel user, String username, String expectedFirstName, String expectedLastName, String expectedEmail, String expectedPostalCode) {
|
|
||||||
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
|
// CRUD model mappers
|
||||||
|
|
||||||
|
@ -327,16 +298,7 @@ public class LDAPTestUtils {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static void assertSyncEquals(SynchronizationResult syncResult, int expectedAdded, int expectedUpdated, int expectedRemoved, int expectedFailed) {
|
public static String getGroupDescriptionLDAPAttrName(LDAPStorageProvider ldapProvider) {
|
||||||
Assert.assertEquals(expectedAdded, syncResult.getAdded());
|
return ldapProvider.getLdapIdentityStore().getConfig().isActiveDirectory() ? "displayName" : "description";
|
||||||
Assert.assertEquals(expectedUpdated, syncResult.getUpdated());
|
|
||||||
Assert.assertEquals(expectedRemoved, syncResult.getRemoved());
|
|
||||||
Assert.assertEquals(expectedFailed, syncResult.getFailed());
|
|
||||||
}
|
|
||||||
public static void assertSyncEquals(SynchronizationResultRepresentation 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());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -32,6 +32,7 @@
|
||||||
<module name="org.keycloak.keycloak-services"/>
|
<module name="org.keycloak.keycloak-services"/>
|
||||||
<module name="org.keycloak.keycloak-model-infinispan"/>
|
<module name="org.keycloak.keycloak-model-infinispan"/>
|
||||||
<module name="org.keycloak.keycloak-model-jpa"/>
|
<module name="org.keycloak.keycloak-model-jpa"/>
|
||||||
|
<module name="org.keycloak.keycloak-ldap-federation"/>
|
||||||
<module name="org.infinispan"/>
|
<module name="org.infinispan"/>
|
||||||
<module name="org.infinispan.client.hotrod"/>
|
<module name="org.infinispan.client.hotrod"/>
|
||||||
<module name="org.jboss.logging"/>
|
<module name="org.jboss.logging"/>
|
||||||
|
|
|
@ -97,7 +97,7 @@ public class KeycloakTestingClient {
|
||||||
public <T> T fetch(FetchOnServer function, Class<T> clazz) throws RunOnServerException {
|
public <T> T fetch(FetchOnServer function, Class<T> clazz) throws RunOnServerException {
|
||||||
try {
|
try {
|
||||||
String s = fetchString(function);
|
String s = fetchString(function);
|
||||||
return JsonSerialization.readValue(s, clazz);
|
return s==null ? null : JsonSerialization.readValue(s, clazz);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,56 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2017 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.client.resources;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import javax.ws.rs.Consumes;
|
||||||
|
import javax.ws.rs.POST;
|
||||||
|
import javax.ws.rs.Path;
|
||||||
|
import javax.ws.rs.Produces;
|
||||||
|
import javax.ws.rs.QueryParam;
|
||||||
|
|
||||||
|
import org.keycloak.utils.MediaType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||||
|
*/
|
||||||
|
public interface TestingLDAPResource {
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param ldapCfg configuration of LDAP provider
|
||||||
|
* @param importEnabled specify if LDAP provider will have import enabled
|
||||||
|
* @return ID of newly created provider
|
||||||
|
*/
|
||||||
|
@POST
|
||||||
|
@Path("/create-ldap-provider")
|
||||||
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
|
String createLDAPProvider(Map<String,String> ldapCfg, @QueryParam("import") boolean importEnabled);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prepare groups LDAP tests. Creates some LDAP mappers as well as some built-in GRoups and users in LDAP
|
||||||
|
*/
|
||||||
|
@POST
|
||||||
|
@Path("/configure-groups")
|
||||||
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
|
void prepareGroupsLDAPTest();
|
||||||
|
}
|
|
@ -204,6 +204,9 @@ public interface TestingResource {
|
||||||
@Path("/cache/{cache}")
|
@Path("/cache/{cache}")
|
||||||
TestingCacheResource cache(@PathParam("cache") String cacheName);
|
TestingCacheResource cache(@PathParam("cache") String cacheName);
|
||||||
|
|
||||||
|
@Path("/ldap/{realm}")
|
||||||
|
TestingLDAPResource ldap(@PathParam("realm") final String realmName);
|
||||||
|
|
||||||
@POST
|
@POST
|
||||||
@Path("/update-pass-through-auth-state")
|
@Path("/update-pass-through-auth-state")
|
||||||
@Produces(MediaType.APPLICATION_JSON)
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
|
@ -251,6 +254,7 @@ public interface TestingResource {
|
||||||
@Produces(MediaType.APPLICATION_JSON)
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
Map<String, TestProvider.DetailsRepresentation> getTestComponentDetails();
|
Map<String, TestProvider.DetailsRepresentation> getTestComponentDetails();
|
||||||
|
|
||||||
|
|
||||||
@GET
|
@GET
|
||||||
@Path("/identity-config")
|
@Path("/identity-config")
|
||||||
@Produces(MediaType.APPLICATION_JSON)
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
|
|
||||||
package org.keycloak.testsuite.util;
|
package org.keycloak.testsuite.util;
|
||||||
|
|
||||||
|
import org.junit.Assume;
|
||||||
import org.junit.rules.ExternalResource;
|
import org.junit.rules.ExternalResource;
|
||||||
import org.keycloak.models.LDAPConstants;
|
import org.keycloak.models.LDAPConstants;
|
||||||
import org.keycloak.util.ldap.LDAPEmbeddedServer;
|
import org.keycloak.util.ldap.LDAPEmbeddedServer;
|
||||||
|
@ -39,14 +40,23 @@ public class LDAPRule extends ExternalResource {
|
||||||
|
|
||||||
private static final String PROPERTY_CERTIFICATE_PASSWORD = "certificatePassword";
|
private static final String PROPERTY_CERTIFICATE_PASSWORD = "certificatePassword";
|
||||||
|
|
||||||
protected LDAPTestConfiguration ldapTestConfiguration;
|
LDAPTestConfiguration ldapTestConfiguration;
|
||||||
protected LDAPEmbeddedServer ldapEmbeddedServer;
|
private LDAPEmbeddedServer ldapEmbeddedServer;
|
||||||
|
private LDAPAssume assume;
|
||||||
|
|
||||||
|
public LDAPRule assumeTrue(LDAPAssume assume) {
|
||||||
|
this.assume = assume;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void before() throws Throwable {
|
protected void before() throws Throwable {
|
||||||
String connectionPropsLocation = getConnectionPropertiesLocation();
|
String connectionPropsLocation = getConnectionPropertiesLocation();
|
||||||
ldapTestConfiguration = LDAPTestConfiguration.readConfiguration(connectionPropsLocation);
|
ldapTestConfiguration = LDAPTestConfiguration.readConfiguration(connectionPropsLocation);
|
||||||
|
|
||||||
|
Assume.assumeTrue("Assumption in LDAPRule is false. Skiping the test", assume==null || assume.assumeTrue(ldapTestConfiguration));
|
||||||
|
|
||||||
if (ldapTestConfiguration.isStartEmbeddedLdapServer()) {
|
if (ldapTestConfiguration.isStartEmbeddedLdapServer()) {
|
||||||
ldapEmbeddedServer = createServer();
|
ldapEmbeddedServer = createServer();
|
||||||
ldapEmbeddedServer.init();
|
ldapEmbeddedServer.init();
|
||||||
|
@ -75,8 +85,6 @@ public class LDAPRule extends ExternalResource {
|
||||||
Properties defaultProperties = new Properties();
|
Properties defaultProperties = new Properties();
|
||||||
defaultProperties.setProperty(LDAPEmbeddedServer.PROPERTY_DSF, LDAPEmbeddedServer.DSF_INMEMORY);
|
defaultProperties.setProperty(LDAPEmbeddedServer.PROPERTY_DSF, LDAPEmbeddedServer.DSF_INMEMORY);
|
||||||
defaultProperties.setProperty(LDAPEmbeddedServer.PROPERTY_LDIF_FILE, "classpath:ldap/users.ldif");
|
defaultProperties.setProperty(LDAPEmbeddedServer.PROPERTY_LDIF_FILE, "classpath:ldap/users.ldif");
|
||||||
defaultProperties.setProperty(LDAPConstants.CONNECTION_URL, "ldaps://localhost:10636");
|
|
||||||
defaultProperties.setProperty(LDAPEmbeddedServer.PROPERTY_BIND_PORT, "10636");
|
|
||||||
defaultProperties.setProperty(PROPERTY_ENABLE_SSL, "true");
|
defaultProperties.setProperty(PROPERTY_ENABLE_SSL, "true");
|
||||||
defaultProperties.setProperty(PROPERTY_CERTIFICATE_PASSWORD, "secret");
|
defaultProperties.setProperty(PROPERTY_CERTIFICATE_PASSWORD, "secret");
|
||||||
defaultProperties.setProperty(PROPERTY_KEYSTORE_FILE, this.getClass().getClassLoader().getResource(LDAPRule.PRIVATE_KEY).getFile());
|
defaultProperties.setProperty(PROPERTY_KEYSTORE_FILE, this.getClass().getClassLoader().getResource(LDAPRule.PRIVATE_KEY).getFile());
|
||||||
|
@ -91,4 +99,12 @@ public class LDAPRule extends ExternalResource {
|
||||||
public int getSleepTime() {
|
public int getSleepTime() {
|
||||||
return ldapTestConfiguration.getSleepTime();
|
return ldapTestConfiguration.getSleepTime();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** Allows to run particular LDAP test just under specific conditions (eg. some test running just on Active Directory) **/
|
||||||
|
public interface LDAPAssume {
|
||||||
|
|
||||||
|
boolean assumeTrue(LDAPTestConfiguration ldapConfig);
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,110 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2017 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 java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.jboss.arquillian.graphene.page.Page;
|
||||||
|
import org.keycloak.models.RealmModel;
|
||||||
|
import org.keycloak.representations.idm.ComponentRepresentation;
|
||||||
|
import org.keycloak.representations.idm.RealmRepresentation;
|
||||||
|
import org.keycloak.storage.ldap.mappers.LDAPStorageMapper;
|
||||||
|
import org.keycloak.testsuite.AbstractTestRealmKeycloakTest;
|
||||||
|
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.OAuthGrantPage;
|
||||||
|
import org.keycloak.testsuite.pages.RegisterPage;
|
||||||
|
import org.keycloak.testsuite.util.LDAPRule;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||||
|
*/
|
||||||
|
public abstract class AbstractLDAPTest extends AbstractTestRealmKeycloakTest {
|
||||||
|
|
||||||
|
static final String TEST_REALM_NAME = "test";
|
||||||
|
|
||||||
|
protected static String ldapModelId;
|
||||||
|
|
||||||
|
@Page
|
||||||
|
protected AppPage appPage;
|
||||||
|
|
||||||
|
@Page
|
||||||
|
protected LoginPage loginPage;
|
||||||
|
|
||||||
|
@Page
|
||||||
|
protected RegisterPage registerPage;
|
||||||
|
|
||||||
|
@Page
|
||||||
|
protected AccountPasswordPage changePasswordPage;
|
||||||
|
|
||||||
|
@Page
|
||||||
|
protected AccountUpdateProfilePage profilePage;
|
||||||
|
|
||||||
|
@Page
|
||||||
|
protected OAuthGrantPage grantPage;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void configureTestRealm(RealmRepresentation testRealm) {
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void importTestRealms() {
|
||||||
|
super.importTestRealms();
|
||||||
|
log.infof("Test realms imported");
|
||||||
|
|
||||||
|
createLDAPProvider();
|
||||||
|
|
||||||
|
afterImportTestRealm();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected void createLDAPProvider() {
|
||||||
|
Map<String, String> cfg = getLDAPRule().getConfig();
|
||||||
|
ldapModelId = testingClient.testing().ldap(TEST_REALM_NAME).createLDAPProvider(cfg, isImportEnabled());
|
||||||
|
log.infof("LDAP Provider created");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected boolean isImportEnabled() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Executed once per class. It is executed after the test realm is imported
|
||||||
|
*/
|
||||||
|
protected abstract void afterImportTestRealm();
|
||||||
|
|
||||||
|
protected abstract LDAPRule getLDAPRule();
|
||||||
|
|
||||||
|
|
||||||
|
protected ComponentRepresentation findMapperRepByName(String name) {
|
||||||
|
List<ComponentRepresentation> mappers = testRealm().components().query(ldapModelId, LDAPStorageMapper.class.getName());
|
||||||
|
for (ComponentRepresentation mapper : mappers) {
|
||||||
|
if (mapper.getName().equals(name)) {
|
||||||
|
return mapper;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
File diff suppressed because one or more lines are too long
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2016 Red Hat, Inc. and/or its affiliates
|
* Copyright 2017 Red Hat, Inc. and/or its affiliates
|
||||||
* and other contributors as indicated by the @author tags.
|
* and other contributors as indicated by the @author tags.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
@ -15,21 +15,29 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.keycloak.testsuite.federation.storage.ldap;
|
package org.keycloak.testsuite.federation.ldap;
|
||||||
|
|
||||||
|
import org.jboss.arquillian.container.test.api.Deployment;
|
||||||
|
import org.jboss.arquillian.container.test.api.TargetsContainer;
|
||||||
|
import org.jboss.shrinkwrap.api.spec.WebArchive;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
|
import org.junit.Before;
|
||||||
import org.junit.ClassRule;
|
import org.junit.ClassRule;
|
||||||
import org.junit.FixMethodOrder;
|
import org.junit.FixMethodOrder;
|
||||||
import org.junit.Rule;
|
import org.junit.Rule;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runners.MethodSorters;
|
import org.junit.runners.MethodSorters;
|
||||||
|
import org.keycloak.admin.client.resource.UserResource;
|
||||||
import org.keycloak.common.util.MultivaluedHashMap;
|
import org.keycloak.common.util.MultivaluedHashMap;
|
||||||
import org.keycloak.component.ComponentModel;
|
import org.keycloak.component.ComponentModel;
|
||||||
import org.keycloak.storage.UserStorageProvider;
|
import org.keycloak.storage.UserStorageProvider;
|
||||||
import org.keycloak.storage.UserStorageProviderModel;
|
import org.keycloak.storage.UserStorageProviderModel;
|
||||||
import org.keycloak.storage.ldap.LDAPStorageProvider;
|
import org.keycloak.storage.ldap.LDAPStorageProvider;
|
||||||
import org.keycloak.storage.ldap.LDAPStorageProviderFactory;
|
import org.keycloak.storage.ldap.LDAPStorageProviderFactory;
|
||||||
|
import org.keycloak.storage.ldap.LDAPUtils;
|
||||||
|
import org.keycloak.storage.ldap.idm.model.LDAPObject;
|
||||||
import org.keycloak.storage.ldap.mappers.membership.LDAPGroupMapperMode;
|
import org.keycloak.storage.ldap.mappers.membership.LDAPGroupMapperMode;
|
||||||
|
import org.keycloak.storage.ldap.mappers.membership.MembershipType;
|
||||||
import org.keycloak.storage.ldap.mappers.membership.group.GroupLDAPStorageMapperFactory;
|
import org.keycloak.storage.ldap.mappers.membership.group.GroupLDAPStorageMapperFactory;
|
||||||
import org.keycloak.storage.ldap.mappers.membership.group.GroupMapperConfig;
|
import org.keycloak.storage.ldap.mappers.membership.group.GroupMapperConfig;
|
||||||
import org.keycloak.models.GroupModel;
|
import org.keycloak.models.GroupModel;
|
||||||
|
@ -37,50 +45,63 @@ import org.keycloak.models.KeycloakSession;
|
||||||
import org.keycloak.models.LDAPConstants;
|
import org.keycloak.models.LDAPConstants;
|
||||||
import org.keycloak.models.RealmModel;
|
import org.keycloak.models.RealmModel;
|
||||||
import org.keycloak.models.utils.KeycloakModelUtils;
|
import org.keycloak.models.utils.KeycloakModelUtils;
|
||||||
import org.keycloak.services.managers.RealmManager;
|
|
||||||
import org.keycloak.storage.user.SynchronizationResult;
|
import org.keycloak.storage.user.SynchronizationResult;
|
||||||
import org.keycloak.testsuite.rule.KeycloakRule;
|
import org.keycloak.testsuite.runonserver.RunOnServerDeployment;
|
||||||
import org.keycloak.testsuite.rule.LDAPRule;
|
import org.keycloak.testsuite.util.LDAPRule;
|
||||||
|
import org.keycloak.testsuite.util.LDAPTestUtils;
|
||||||
|
|
||||||
|
import static org.keycloak.testsuite.arquillian.DeploymentTargetModifier.AUTH_SERVER_CURRENT;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||||
*/
|
*/
|
||||||
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
|
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
|
||||||
public class LDAPGroupMapper2WaySyncTest {
|
public class LDAPGroupMapper2WaySyncTest extends AbstractLDAPTest {
|
||||||
|
|
||||||
|
|
||||||
@ClassRule
|
@ClassRule
|
||||||
public static LDAPRule ldapRule = new LDAPRule();
|
public static LDAPRule ldapRule = new LDAPRule();
|
||||||
|
|
||||||
private static ComponentModel ldapModel = null;
|
@Deployment
|
||||||
private static String descriptionAttrName = null;
|
@TargetsContainer(AUTH_SERVER_CURRENT)
|
||||||
|
public static WebArchive deploy() {
|
||||||
|
return RunOnServerDeployment.create(UserResource.class, AbstractLDAPTest.class)
|
||||||
|
.addPackages(true,
|
||||||
|
"org.keycloak.testsuite",
|
||||||
|
"org.keycloak.testsuite.federation.ldap");
|
||||||
|
}
|
||||||
|
|
||||||
@Rule
|
|
||||||
public KeycloakRule keycloakRule = new KeycloakRule(new KeycloakRule.KeycloakSetup() {
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
|
protected LDAPRule getLDAPRule() {
|
||||||
MultivaluedHashMap<String,String> ldapConfig = LDAPTestUtils.getLdapRuleConfig(ldapRule);
|
return ldapRule;
|
||||||
ldapConfig.putSingle(LDAPConstants.SYNC_REGISTRATIONS, "true");
|
}
|
||||||
ldapConfig.putSingle(LDAPConstants.EDIT_MODE, UserStorageProvider.EditMode.WRITABLE.toString());
|
|
||||||
ldapConfig.putSingle(LDAPConstants.BATCH_SIZE_FOR_SYNC, "4"); // Issues with pagination on ApacheDS
|
|
||||||
UserStorageProviderModel model = new UserStorageProviderModel();
|
|
||||||
model.setLastSync(0);
|
|
||||||
model.setChangedSyncPeriod(-1);
|
|
||||||
model.setFullSyncPeriod(-1);
|
|
||||||
model.setName("test-ldap");
|
|
||||||
model.setPriority(0);
|
|
||||||
model.setProviderId(LDAPStorageProviderFactory.PROVIDER_NAME);
|
|
||||||
model.setConfig(ldapConfig);
|
|
||||||
|
|
||||||
ldapModel = appRealm.addComponentModel(model);
|
@Override
|
||||||
LDAPStorageProvider ldapFedProvider = LDAPTestUtils.getLdapProvider(session, ldapModel);
|
protected void afterImportTestRealm() {
|
||||||
descriptionAttrName = ldapFedProvider.getLdapIdentityStore().getConfig().isActiveDirectory() ? "displayName" : "description";
|
testingClient.server().run(session -> {
|
||||||
|
LDAPTestContext ctx = LDAPTestContext.init(session);
|
||||||
|
RealmModel appRealm = ctx.getRealm();
|
||||||
|
|
||||||
|
ctx.getLdapModel().put(LDAPConstants.BATCH_SIZE_FOR_SYNC, "4"); // Issues with pagination on ApacheDS
|
||||||
|
appRealm.updateComponent(ctx.getLdapModel());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void before() {
|
||||||
|
testingClient.server().run(session -> {
|
||||||
|
LDAPTestContext ctx = LDAPTestContext.init(session);
|
||||||
|
RealmModel appRealm = ctx.getRealm();
|
||||||
|
|
||||||
|
String descriptionAttrName = LDAPTestUtils.getGroupDescriptionLDAPAttrName(ctx.getLdapProvider());
|
||||||
|
|
||||||
// Add group mapper
|
// Add group mapper
|
||||||
LDAPTestUtils.addOrUpdateGroupMapper(appRealm, ldapModel, LDAPGroupMapperMode.LDAP_ONLY, descriptionAttrName);
|
LDAPTestUtils.addOrUpdateGroupMapper(appRealm, ctx.getLdapModel(), LDAPGroupMapperMode.LDAP_ONLY, descriptionAttrName);
|
||||||
|
|
||||||
// Remove all LDAP groups
|
// Remove all LDAP groups
|
||||||
LDAPTestUtils.removeAllLDAPGroups(session, appRealm, ldapModel, "groupsMapper");
|
LDAPTestUtils.removeAllLDAPGroups(session, appRealm, ctx.getLdapModel(), "groupsMapper");
|
||||||
|
|
||||||
// Add some groups for testing into Keycloak
|
// Add some groups for testing into Keycloak
|
||||||
removeAllModelGroups(appRealm);
|
removeAllModelGroups(appRealm);
|
||||||
|
@ -98,17 +119,19 @@ public class LDAPGroupMapper2WaySyncTest {
|
||||||
|
|
||||||
GroupModel group2 = appRealm.createGroup("group2");
|
GroupModel group2 = appRealm.createGroup("group2");
|
||||||
appRealm.moveGroup(group2, null);
|
appRealm.moveGroup(group2, null);
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void test01_syncNoPreserveGroupInheritance() throws Exception {
|
public void test01_syncNoPreserveGroupInheritance() throws Exception {
|
||||||
KeycloakSession session = keycloakRule.startSession();
|
testingClient.server().run(session -> {
|
||||||
try {
|
LDAPTestContext ctx = LDAPTestContext.init(session);
|
||||||
RealmModel realm = session.realms().getRealmByName("test");
|
RealmModel realm = ctx.getRealm();
|
||||||
ComponentModel mapperModel = LDAPTestUtils.getSubcomponentByName(realm,ldapModel, "groupsMapper");
|
|
||||||
LDAPStorageProvider ldapProvider = LDAPTestUtils.getLdapProvider(session, ldapModel);
|
ComponentModel mapperModel = LDAPTestUtils.getSubcomponentByName(realm, ctx.getLdapModel(), "groupsMapper");
|
||||||
|
LDAPStorageProvider ldapProvider = LDAPTestUtils.getLdapProvider(session, ctx.getLdapModel());
|
||||||
|
|
||||||
// Update group mapper to skip preserve inheritance and check it will pass now
|
// Update group mapper to skip preserve inheritance and check it will pass now
|
||||||
LDAPTestUtils.updateGroupMapperConfigOptions(mapperModel, GroupMapperConfig.PRESERVE_GROUP_INHERITANCE, "false");
|
LDAPTestUtils.updateGroupMapperConfigOptions(mapperModel, GroupMapperConfig.PRESERVE_GROUP_INHERITANCE, "false");
|
||||||
|
@ -116,35 +139,34 @@ public class LDAPGroupMapper2WaySyncTest {
|
||||||
|
|
||||||
// Sync from Keycloak into LDAP
|
// Sync from Keycloak into LDAP
|
||||||
SynchronizationResult syncResult = new GroupLDAPStorageMapperFactory().create(session, mapperModel).syncDataFromKeycloakToFederationProvider(realm);
|
SynchronizationResult syncResult = new GroupLDAPStorageMapperFactory().create(session, mapperModel).syncDataFromKeycloakToFederationProvider(realm);
|
||||||
LDAPTestUtils.assertSyncEquals(syncResult, 4, 0, 0, 0);
|
LDAPTestAsserts.assertSyncEquals(syncResult, 4, 0, 0, 0);
|
||||||
} finally {
|
});
|
||||||
keycloakRule.stopSession(session, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
session = keycloakRule.startSession();
|
testingClient.server().run(session -> {
|
||||||
try {
|
LDAPTestContext ctx = LDAPTestContext.init(session);
|
||||||
RealmModel realm = session.realms().getRealmByName("test");
|
RealmModel realm = ctx.getRealm();
|
||||||
|
|
||||||
// Delete all KC groups now
|
// Delete all KC groups now
|
||||||
removeAllModelGroups(realm);
|
removeAllModelGroups(realm);
|
||||||
Assert.assertNull(KeycloakModelUtils.findGroupByPath(realm, "/group1"));
|
Assert.assertNull(KeycloakModelUtils.findGroupByPath(realm, "/group1"));
|
||||||
Assert.assertNull(KeycloakModelUtils.findGroupByPath(realm, "/group11"));
|
Assert.assertNull(KeycloakModelUtils.findGroupByPath(realm, "/group11"));
|
||||||
Assert.assertNull(KeycloakModelUtils.findGroupByPath(realm, "/group2"));
|
Assert.assertNull(KeycloakModelUtils.findGroupByPath(realm, "/group2"));
|
||||||
} finally {
|
});
|
||||||
keycloakRule.stopSession(session, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
session = keycloakRule.startSession();
|
testingClient.server().run(session -> {
|
||||||
try {
|
LDAPTestContext ctx = LDAPTestContext.init(session);
|
||||||
RealmModel realm = session.realms().getRealmByName("test");
|
RealmModel realm = ctx.getRealm();
|
||||||
ComponentModel mapperModel = LDAPTestUtils.getSubcomponentByName(realm,ldapModel, "groupsMapper");
|
|
||||||
LDAPStorageProvider ldapProvider = LDAPTestUtils.getLdapProvider(session, ldapModel);
|
String descriptionAttrName = LDAPTestUtils.getGroupDescriptionLDAPAttrName(ctx.getLdapProvider());
|
||||||
|
|
||||||
|
ComponentModel mapperModel = LDAPTestUtils.getSubcomponentByName(realm, ctx.getLdapModel(), "groupsMapper");
|
||||||
|
LDAPStorageProvider ldapProvider = LDAPTestUtils.getLdapProvider(session, ctx.getLdapModel());
|
||||||
|
|
||||||
// Sync from LDAP back into Keycloak
|
// Sync from LDAP back into Keycloak
|
||||||
SynchronizationResult syncResult = new GroupLDAPStorageMapperFactory().create(session, mapperModel).syncDataFromFederationProviderToKeycloak(realm);
|
SynchronizationResult syncResult = new GroupLDAPStorageMapperFactory().create(session, mapperModel).syncDataFromFederationProviderToKeycloak(realm);
|
||||||
LDAPTestUtils.assertSyncEquals(syncResult, 4, 0, 0, 0);
|
LDAPTestAsserts.assertSyncEquals(syncResult, 4, 0, 0, 0);
|
||||||
|
|
||||||
// Assert groups are imported to keycloak. All are at top level
|
// Assert groups are imported to keycloak. All are at top level
|
||||||
GroupModel kcGroup1 = KeycloakModelUtils.findGroupByPath(realm, "/group1");
|
GroupModel kcGroup1 = KeycloakModelUtils.findGroupByPath(realm, "/group1");
|
||||||
|
@ -160,55 +182,53 @@ public class LDAPGroupMapper2WaySyncTest {
|
||||||
Assert.assertNull(kcGroup2.getFirstAttribute(descriptionAttrName));
|
Assert.assertNull(kcGroup2.getFirstAttribute(descriptionAttrName));
|
||||||
|
|
||||||
// test drop non-existing works
|
// test drop non-existing works
|
||||||
testDropNonExisting(session, realm, mapperModel, ldapProvider);
|
testDropNonExisting(session, ctx, mapperModel);
|
||||||
} finally {
|
});
|
||||||
keycloakRule.stopSession(session, true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void test02_syncWithGroupInheritance() throws Exception {
|
public void test02_syncWithGroupInheritance() throws Exception {
|
||||||
KeycloakSession session = keycloakRule.startSession();
|
testingClient.server().run(session -> {
|
||||||
try {
|
LDAPTestContext ctx = LDAPTestContext.init(session);
|
||||||
RealmModel realm = session.realms().getRealmByName("test");
|
RealmModel realm = ctx.getRealm();
|
||||||
ComponentModel mapperModel = LDAPTestUtils.getSubcomponentByName(realm,ldapModel, "groupsMapper");
|
|
||||||
LDAPStorageProvider ldapProvider = LDAPTestUtils.getLdapProvider(session, ldapModel);
|
ComponentModel mapperModel = LDAPTestUtils.getSubcomponentByName(realm, ctx.getLdapModel(), "groupsMapper");
|
||||||
|
LDAPStorageProvider ldapProvider = LDAPTestUtils.getLdapProvider(session, ctx.getLdapModel());
|
||||||
|
|
||||||
// Update group mapper to skip preserve inheritance and check it will pass now
|
// Update group mapper to skip preserve inheritance and check it will pass now
|
||||||
LDAPTestUtils.updateGroupMapperConfigOptions(mapperModel, GroupMapperConfig.PRESERVE_GROUP_INHERITANCE, "true");
|
LDAPTestUtils.updateGroupMapperConfigOptions(mapperModel, GroupMapperConfig.PRESERVE_GROUP_INHERITANCE, "true");
|
||||||
|
LDAPTestUtils.updateGroupMapperConfigOptions(mapperModel, GroupMapperConfig.DROP_NON_EXISTING_GROUPS_DURING_SYNC, "false");
|
||||||
realm.updateComponent(mapperModel);
|
realm.updateComponent(mapperModel);
|
||||||
|
|
||||||
// Sync from Keycloak into LDAP
|
// Sync from Keycloak into LDAP
|
||||||
SynchronizationResult syncResult = new GroupLDAPStorageMapperFactory().create(session, mapperModel).syncDataFromKeycloakToFederationProvider(realm);
|
SynchronizationResult syncResult = new GroupLDAPStorageMapperFactory().create(session, mapperModel).syncDataFromKeycloakToFederationProvider(realm);
|
||||||
LDAPTestUtils.assertSyncEquals(syncResult, 4, 0, 0, 0);
|
LDAPTestAsserts.assertSyncEquals(syncResult, 4, 0, 0, 0);
|
||||||
} finally {
|
});
|
||||||
keycloakRule.stopSession(session, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
session = keycloakRule.startSession();
|
testingClient.server().run(session -> {
|
||||||
try {
|
LDAPTestContext ctx = LDAPTestContext.init(session);
|
||||||
RealmModel realm = session.realms().getRealmByName("test");
|
RealmModel realm = ctx.getRealm();
|
||||||
|
|
||||||
// Delete all KC groups now
|
// Delete all KC groups now
|
||||||
removeAllModelGroups(realm);
|
removeAllModelGroups(realm);
|
||||||
Assert.assertNull(KeycloakModelUtils.findGroupByPath(realm, "/group1"));
|
Assert.assertNull(KeycloakModelUtils.findGroupByPath(realm, "/group1"));
|
||||||
Assert.assertNull(KeycloakModelUtils.findGroupByPath(realm, "/group11"));
|
Assert.assertNull(KeycloakModelUtils.findGroupByPath(realm, "/group11"));
|
||||||
Assert.assertNull(KeycloakModelUtils.findGroupByPath(realm, "/group2"));
|
Assert.assertNull(KeycloakModelUtils.findGroupByPath(realm, "/group2"));
|
||||||
} finally {
|
});
|
||||||
keycloakRule.stopSession(session, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
testingClient.server().run(session -> {
|
||||||
|
LDAPTestContext ctx = LDAPTestContext.init(session);
|
||||||
|
RealmModel realm = ctx.getRealm();
|
||||||
|
|
||||||
session = keycloakRule.startSession();
|
ComponentModel mapperModel = LDAPTestUtils.getSubcomponentByName(realm, ctx.getLdapModel(), "groupsMapper");
|
||||||
try {
|
LDAPStorageProvider ldapProvider = LDAPTestUtils.getLdapProvider(session, ctx.getLdapModel());
|
||||||
RealmModel realm = session.realms().getRealmByName("test");
|
|
||||||
ComponentModel mapperModel = LDAPTestUtils.getSubcomponentByName(realm,ldapModel, "groupsMapper");
|
String descriptionAttrName = LDAPTestUtils.getGroupDescriptionLDAPAttrName(ctx.getLdapProvider());
|
||||||
LDAPStorageProvider ldapProvider = LDAPTestUtils.getLdapProvider(session, ldapModel);
|
|
||||||
|
|
||||||
// Sync from LDAP back into Keycloak
|
// Sync from LDAP back into Keycloak
|
||||||
SynchronizationResult syncResult = new GroupLDAPStorageMapperFactory().create(session, mapperModel).syncDataFromFederationProviderToKeycloak(realm);
|
SynchronizationResult syncResult = new GroupLDAPStorageMapperFactory().create(session, mapperModel).syncDataFromFederationProviderToKeycloak(realm);
|
||||||
LDAPTestUtils.assertSyncEquals(syncResult, 4, 0, 0, 0);
|
LDAPTestAsserts.assertSyncEquals(syncResult, 4, 0, 0, 0);
|
||||||
|
|
||||||
// Assert groups are imported to keycloak. All are at top level
|
// Assert groups are imported to keycloak. All are at top level
|
||||||
GroupModel kcGroup1 = KeycloakModelUtils.findGroupByPath(realm, "/group1");
|
GroupModel kcGroup1 = KeycloakModelUtils.findGroupByPath(realm, "/group1");
|
||||||
|
@ -224,10 +244,8 @@ public class LDAPGroupMapper2WaySyncTest {
|
||||||
Assert.assertNull(kcGroup2.getFirstAttribute(descriptionAttrName));
|
Assert.assertNull(kcGroup2.getFirstAttribute(descriptionAttrName));
|
||||||
|
|
||||||
// test drop non-existing works
|
// test drop non-existing works
|
||||||
testDropNonExisting(session, realm, mapperModel, ldapProvider);
|
testDropNonExisting(session, ctx, mapperModel);
|
||||||
} finally {
|
});
|
||||||
keycloakRule.stopSession(session, true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -237,14 +255,16 @@ public class LDAPGroupMapper2WaySyncTest {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void testDropNonExisting(KeycloakSession session, RealmModel realm, ComponentModel mapperModel, LDAPStorageProvider ldapProvider) {
|
private static void testDropNonExisting(KeycloakSession session, LDAPTestContext ctx, ComponentModel mapperModel) {
|
||||||
|
RealmModel realm = ctx.getRealm();
|
||||||
|
|
||||||
// Put some group directly to LDAP
|
// Put some group directly to LDAP
|
||||||
LDAPTestUtils.createLDAPGroup(session, realm, ldapModel, "group3");
|
LDAPTestUtils.createLDAPGroup(session, realm, ctx.getLdapModel(), "group3");
|
||||||
|
|
||||||
// Sync and assert our group is still in LDAP
|
// Sync and assert our group is still in LDAP
|
||||||
SynchronizationResult syncResult = new GroupLDAPStorageMapperFactory().create(session, mapperModel).syncDataFromKeycloakToFederationProvider(realm);
|
SynchronizationResult syncResult = new GroupLDAPStorageMapperFactory().create(session, mapperModel).syncDataFromKeycloakToFederationProvider(realm);
|
||||||
LDAPTestUtils.assertSyncEquals(syncResult, 0, 4, 0, 0);
|
LDAPTestAsserts.assertSyncEquals(syncResult, 0, 4, 0, 0);
|
||||||
Assert.assertNotNull(LDAPTestUtils.getGroupMapper(mapperModel, ldapProvider, realm).loadLDAPGroupByName("group3"));
|
Assert.assertNotNull(LDAPTestUtils.getGroupMapper(mapperModel, ctx.getLdapProvider(), realm).loadLDAPGroupByName("group3"));
|
||||||
|
|
||||||
// Change config to drop non-existing groups
|
// Change config to drop non-existing groups
|
||||||
LDAPTestUtils.updateGroupMapperConfigOptions(mapperModel, GroupMapperConfig.DROP_NON_EXISTING_GROUPS_DURING_SYNC, "true");
|
LDAPTestUtils.updateGroupMapperConfigOptions(mapperModel, GroupMapperConfig.DROP_NON_EXISTING_GROUPS_DURING_SYNC, "true");
|
||||||
|
@ -252,7 +272,7 @@ public class LDAPGroupMapper2WaySyncTest {
|
||||||
|
|
||||||
// Sync and assert group removed from LDAP
|
// Sync and assert group removed from LDAP
|
||||||
syncResult = new GroupLDAPStorageMapperFactory().create(session, mapperModel).syncDataFromKeycloakToFederationProvider(realm);
|
syncResult = new GroupLDAPStorageMapperFactory().create(session, mapperModel).syncDataFromKeycloakToFederationProvider(realm);
|
||||||
LDAPTestUtils.assertSyncEquals(syncResult, 0, 4, 1, 0);
|
LDAPTestAsserts.assertSyncEquals(syncResult, 0, 4, 1, 0);
|
||||||
Assert.assertNull(LDAPTestUtils.getGroupMapper(mapperModel, ldapProvider, realm).loadLDAPGroupByName("group3"));
|
Assert.assertNull(LDAPTestUtils.getGroupMapper(mapperModel, ctx.getLdapProvider(), realm).loadLDAPGroupByName("group3"));
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2016 Red Hat, Inc. and/or its affiliates
|
* Copyright 2017 Red Hat, Inc. and/or its affiliates
|
||||||
* and other contributors as indicated by the @author tags.
|
* and other contributors as indicated by the @author tags.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
@ -15,25 +15,22 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.keycloak.testsuite.federation.storage.ldap;
|
package org.keycloak.testsuite.federation.ldap;
|
||||||
|
|
||||||
|
import org.jboss.arquillian.container.test.api.Deployment;
|
||||||
|
import org.jboss.arquillian.container.test.api.TargetsContainer;
|
||||||
|
import org.jboss.shrinkwrap.api.spec.WebArchive;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.ClassRule;
|
import org.junit.ClassRule;
|
||||||
import org.junit.FixMethodOrder;
|
import org.junit.FixMethodOrder;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.rules.RuleChain;
|
|
||||||
import org.junit.rules.TestRule;
|
|
||||||
import org.junit.runners.MethodSorters;
|
import org.junit.runners.MethodSorters;
|
||||||
import org.keycloak.admin.client.Keycloak;
|
import org.keycloak.admin.client.resource.UserResource;
|
||||||
import org.keycloak.common.util.MultivaluedHashMap;
|
|
||||||
import org.keycloak.component.ComponentModel;
|
import org.keycloak.component.ComponentModel;
|
||||||
import org.keycloak.models.Constants;
|
import org.keycloak.representations.idm.ComponentRepresentation;
|
||||||
import org.keycloak.representations.idm.SynchronizationResultRepresentation;
|
import org.keycloak.representations.idm.SynchronizationResultRepresentation;
|
||||||
import org.keycloak.storage.UserStorageProvider;
|
|
||||||
import org.keycloak.storage.UserStorageProviderModel;
|
|
||||||
import org.keycloak.storage.ldap.LDAPStorageProvider;
|
import org.keycloak.storage.ldap.LDAPStorageProvider;
|
||||||
import org.keycloak.storage.ldap.LDAPStorageProviderFactory;
|
|
||||||
import org.keycloak.storage.ldap.LDAPUtils;
|
import org.keycloak.storage.ldap.LDAPUtils;
|
||||||
import org.keycloak.storage.ldap.idm.model.LDAPObject;
|
import org.keycloak.storage.ldap.idm.model.LDAPObject;
|
||||||
import org.keycloak.storage.ldap.mappers.membership.LDAPGroupMapperMode;
|
import org.keycloak.storage.ldap.mappers.membership.LDAPGroupMapperMode;
|
||||||
|
@ -42,103 +39,97 @@ import org.keycloak.storage.ldap.mappers.membership.group.GroupLDAPStorageMapper
|
||||||
import org.keycloak.storage.ldap.mappers.membership.group.GroupLDAPStorageMapperFactory;
|
import org.keycloak.storage.ldap.mappers.membership.group.GroupLDAPStorageMapperFactory;
|
||||||
import org.keycloak.storage.ldap.mappers.membership.group.GroupMapperConfig;
|
import org.keycloak.storage.ldap.mappers.membership.group.GroupMapperConfig;
|
||||||
import org.keycloak.models.GroupModel;
|
import org.keycloak.models.GroupModel;
|
||||||
import org.keycloak.models.KeycloakSession;
|
|
||||||
import org.keycloak.models.LDAPConstants;
|
import org.keycloak.models.LDAPConstants;
|
||||||
import org.keycloak.models.ModelException;
|
import org.keycloak.models.ModelException;
|
||||||
import org.keycloak.models.RealmModel;
|
import org.keycloak.models.RealmModel;
|
||||||
import org.keycloak.models.UserModel;
|
import org.keycloak.models.UserModel;
|
||||||
import org.keycloak.models.utils.KeycloakModelUtils;
|
import org.keycloak.models.utils.KeycloakModelUtils;
|
||||||
import org.keycloak.services.managers.RealmManager;
|
|
||||||
import org.keycloak.storage.user.SynchronizationResult;
|
import org.keycloak.storage.user.SynchronizationResult;
|
||||||
import org.keycloak.testsuite.rule.KeycloakRule;
|
import org.keycloak.testsuite.runonserver.RunOnServerDeployment;
|
||||||
import org.keycloak.testsuite.rule.LDAPRule;
|
import org.keycloak.testsuite.util.LDAPRule;
|
||||||
|
import org.keycloak.testsuite.util.LDAPTestUtils;
|
||||||
|
|
||||||
import javax.ws.rs.BadRequestException;
|
import javax.ws.rs.BadRequestException;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.MASTER;
|
import static org.keycloak.testsuite.arquillian.DeploymentTargetModifier.AUTH_SERVER_CURRENT;
|
||||||
import static org.keycloak.models.AdminRoles.ADMIN;
|
|
||||||
import static org.keycloak.testsuite.Constants.AUTH_SERVER_ROOT;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||||
*/
|
*/
|
||||||
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
|
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
|
||||||
public class LDAPGroupMapperSyncTest {
|
public class LDAPGroupMapperSyncTest extends AbstractLDAPTest {
|
||||||
|
|
||||||
private static LDAPRule ldapRule = new LDAPRule();
|
|
||||||
|
|
||||||
private static ComponentModel 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) {
|
|
||||||
MultivaluedHashMap<String,String> ldapConfig = LDAPTestUtils.getLdapRuleConfig(ldapRule);
|
|
||||||
ldapConfig.putSingle(LDAPConstants.SYNC_REGISTRATIONS, "true");
|
|
||||||
ldapConfig.putSingle(LDAPConstants.EDIT_MODE, UserStorageProvider.EditMode.WRITABLE.toString());
|
|
||||||
UserStorageProviderModel model = new UserStorageProviderModel();
|
|
||||||
model.setLastSync(0);
|
|
||||||
model.setChangedSyncPeriod(-1);
|
|
||||||
model.setFullSyncPeriod(-1);
|
|
||||||
model.setName("test-ldap");
|
|
||||||
model.setPriority(0);
|
|
||||||
model.setProviderId(LDAPStorageProviderFactory.PROVIDER_NAME);
|
|
||||||
model.setConfig(ldapConfig);
|
|
||||||
|
|
||||||
ldapModel = appRealm.addComponentModel(model);
|
|
||||||
|
|
||||||
LDAPStorageProvider ldapFedProvider = LDAPTestUtils.getLdapProvider(session, ldapModel);
|
|
||||||
descriptionAttrName = ldapFedProvider.getLdapIdentityStore().getConfig().isActiveDirectory() ? "displayName" : "description";
|
|
||||||
|
|
||||||
// Add group mapper
|
|
||||||
LDAPTestUtils.addOrUpdateGroupMapper(appRealm, ldapModel, LDAPGroupMapperMode.LDAP_ONLY, descriptionAttrName);
|
|
||||||
|
|
||||||
// Remove all LDAP groups
|
|
||||||
LDAPTestUtils.removeAllLDAPGroups(session, appRealm, ldapModel, "groupsMapper");
|
|
||||||
|
|
||||||
// Add some groups for testing
|
|
||||||
LDAPObject group1 = LDAPTestUtils.createLDAPGroup(manager.getSession(), appRealm, ldapModel, "group1", descriptionAttrName, "group1 - description");
|
|
||||||
LDAPObject group11 = LDAPTestUtils.createLDAPGroup(manager.getSession(), appRealm, ldapModel, "group11");
|
|
||||||
LDAPObject group12 = LDAPTestUtils.createLDAPGroup(manager.getSession(), appRealm, ldapModel, "group12", descriptionAttrName, "group12 - description");
|
|
||||||
|
|
||||||
LDAPUtils.addMember(ldapFedProvider, MembershipType.DN, LDAPConstants.MEMBER, "not-used", group1, group11, false);
|
|
||||||
LDAPUtils.addMember(ldapFedProvider, MembershipType.DN, LDAPConstants.MEMBER, "not-used", group1, group12, true);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
@ClassRule
|
@ClassRule
|
||||||
public static TestRule chain = RuleChain
|
public static LDAPRule ldapRule = new LDAPRule();
|
||||||
.outerRule(ldapRule)
|
|
||||||
.around(keycloakRule);
|
@Deployment
|
||||||
|
@TargetsContainer(AUTH_SERVER_CURRENT)
|
||||||
|
public static WebArchive deploy() {
|
||||||
|
return RunOnServerDeployment.create(UserResource.class, AbstractLDAPTest.class)
|
||||||
|
.addPackages(true,
|
||||||
|
"org.keycloak.testsuite",
|
||||||
|
"org.keycloak.testsuite.federation.ldap");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected LDAPRule getLDAPRule() {
|
||||||
|
return ldapRule;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void afterImportTestRealm() {
|
||||||
|
testingClient.server().run(session -> {
|
||||||
|
LDAPTestContext ctx = LDAPTestContext.init(session);
|
||||||
|
RealmModel appRealm = ctx.getRealm();
|
||||||
|
|
||||||
|
String descriptionAttrName = LDAPTestUtils.getGroupDescriptionLDAPAttrName(ctx.getLdapProvider());
|
||||||
|
|
||||||
|
// Add group mapper
|
||||||
|
LDAPTestUtils.addOrUpdateGroupMapper(appRealm, ctx.getLdapModel(), LDAPGroupMapperMode.LDAP_ONLY, descriptionAttrName);
|
||||||
|
|
||||||
|
// Remove all LDAP groups
|
||||||
|
LDAPTestUtils.removeAllLDAPGroups(session, appRealm, ctx.getLdapModel(), "groupsMapper");
|
||||||
|
|
||||||
|
// Add some groups for testing
|
||||||
|
LDAPObject group1 = LDAPTestUtils.createLDAPGroup(session, appRealm, ctx.getLdapModel(), "group1", descriptionAttrName, "group1 - description");
|
||||||
|
LDAPObject group11 = LDAPTestUtils.createLDAPGroup(session, appRealm, ctx.getLdapModel(), "group11");
|
||||||
|
LDAPObject group12 = LDAPTestUtils.createLDAPGroup(session, appRealm, ctx.getLdapModel(), "group12", descriptionAttrName, "group12 - description");
|
||||||
|
|
||||||
|
LDAPUtils.addMember(ctx.getLdapProvider(), MembershipType.DN, LDAPConstants.MEMBER, "not-used", group1, group11, false);
|
||||||
|
LDAPUtils.addMember(ctx.getLdapProvider(), MembershipType.DN, LDAPConstants.MEMBER, "not-used", group1, group12, true);
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
protected Keycloak adminClient;
|
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void before() {
|
public void before() {
|
||||||
adminClient = Keycloak.getInstance(AUTH_SERVER_ROOT, MASTER, ADMIN, ADMIN, Constants.ADMIN_CLI_CLIENT_ID);
|
testingClient.server().run(session -> {
|
||||||
|
LDAPTestContext ctx = LDAPTestContext.init(session);
|
||||||
|
RealmModel realm = ctx.getRealm();
|
||||||
|
|
||||||
KeycloakSession session = keycloakRule.startSession();
|
|
||||||
try {
|
|
||||||
RealmModel realm = session.realms().getRealmByName("test");
|
|
||||||
List<GroupModel> kcGroups = realm.getTopLevelGroups();
|
List<GroupModel> kcGroups = realm.getTopLevelGroups();
|
||||||
for (GroupModel kcGroup : kcGroups) {
|
for (GroupModel kcGroup : kcGroups) {
|
||||||
realm.removeGroup(kcGroup);
|
realm.removeGroup(kcGroup);
|
||||||
}
|
}
|
||||||
} finally {
|
});
|
||||||
keycloakRule.stopSession(session, true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void test01_syncNoPreserveGroupInheritance() throws Exception {
|
public void test01_syncNoPreserveGroupInheritance() throws Exception {
|
||||||
KeycloakSession session = keycloakRule.startSession();
|
testingClient.server().run(session -> {
|
||||||
try {
|
LDAPTestContext ctx = LDAPTestContext.init(session);
|
||||||
RealmModel realm = session.realms().getRealmByName("test");
|
RealmModel realm = ctx.getRealm();
|
||||||
ComponentModel mapperModel = LDAPTestUtils.getSubcomponentByName(realm,ldapModel, "groupsMapper");
|
|
||||||
LDAPStorageProvider ldapProvider = LDAPTestUtils.getLdapProvider(session, ldapModel);
|
String descriptionAttrName = LDAPTestUtils.getGroupDescriptionLDAPAttrName(ctx.getLdapProvider());
|
||||||
|
|
||||||
|
ComponentModel mapperModel = LDAPTestUtils.getSubcomponentByName(realm, ctx.getLdapModel(), "groupsMapper");
|
||||||
|
LDAPStorageProvider ldapProvider = LDAPTestUtils.getLdapProvider(session, ctx.getLdapModel());
|
||||||
GroupLDAPStorageMapper groupMapper = LDAPTestUtils.getGroupMapper(mapperModel, ldapProvider, realm);
|
GroupLDAPStorageMapper groupMapper = LDAPTestUtils.getGroupMapper(mapperModel, ldapProvider, realm);
|
||||||
|
|
||||||
// Add recursive group mapping to LDAP. Check that sync with preserve group inheritance will fail
|
// Add recursive group mapping to LDAP. Check that sync with preserve group inheritance will fail
|
||||||
|
@ -173,41 +164,29 @@ public class LDAPGroupMapperSyncTest {
|
||||||
// Cleanup - remove recursive mapping in LDAP
|
// Cleanup - remove recursive mapping in LDAP
|
||||||
LDAPUtils.deleteMember(ldapProvider, MembershipType.DN, LDAPConstants.MEMBER, "not-used", group12, group1);
|
LDAPUtils.deleteMember(ldapProvider, MembershipType.DN, LDAPConstants.MEMBER, "not-used", group12, group1);
|
||||||
|
|
||||||
} finally {
|
// Cleanup - revert group mapper config
|
||||||
keycloakRule.stopSession(session, false);
|
LDAPTestUtils.updateGroupMapperConfigOptions(mapperModel, GroupMapperConfig.PRESERVE_GROUP_INHERITANCE, "true");
|
||||||
}
|
realm.updateComponent(mapperModel);
|
||||||
|
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testSyncRestAPI() {
|
|
||||||
KeycloakSession session = keycloakRule.startSession();
|
|
||||||
try {
|
|
||||||
RealmModel realm = session.realms().getRealmByName("test");
|
|
||||||
ComponentModel mapperModel = LDAPTestUtils.getSubcomponentByName(realm,ldapModel, "groupsMapper");
|
|
||||||
try {
|
|
||||||
// testing KEYCLOAK-3980 which threw an NPE because I was looking up the factory wrong.
|
|
||||||
SynchronizationResultRepresentation syncResultRep = adminClient.realm("test").userStorage().syncMapperData(ldapModel.getId(), mapperModel.getId(), "error");
|
|
||||||
Assert.fail("Should throw 400");
|
|
||||||
} catch (BadRequestException e) {
|
|
||||||
}
|
|
||||||
} finally {
|
|
||||||
keycloakRule.stopSession(session, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void test02_syncWithGroupInheritance() throws Exception {
|
public void test02_syncWithGroupInheritance() throws Exception {
|
||||||
KeycloakSession session = keycloakRule.startSession();
|
testingClient.server().run(session -> {
|
||||||
try {
|
LDAPTestContext ctx = LDAPTestContext.init(session);
|
||||||
RealmModel realm = session.realms().getRealmByName("test");
|
RealmModel realm = ctx.getRealm();
|
||||||
ComponentModel mapperModel = LDAPTestUtils.getSubcomponentByName(realm,ldapModel, "groupsMapper");
|
|
||||||
LDAPStorageProvider ldapProvider = LDAPTestUtils.getLdapProvider(session, ldapModel);
|
String descriptionAttrName = LDAPTestUtils.getGroupDescriptionLDAPAttrName(ctx.getLdapProvider());
|
||||||
|
|
||||||
|
ComponentModel mapperModel = LDAPTestUtils.getSubcomponentByName(realm, ctx.getLdapModel(), "groupsMapper");
|
||||||
|
LDAPStorageProvider ldapProvider = LDAPTestUtils.getLdapProvider(session, ctx.getLdapModel());
|
||||||
GroupLDAPStorageMapper groupMapper = LDAPTestUtils.getGroupMapper(mapperModel, ldapProvider, realm);
|
GroupLDAPStorageMapper groupMapper = LDAPTestUtils.getGroupMapper(mapperModel, ldapProvider, realm);
|
||||||
|
|
||||||
// Sync groups with inheritance
|
// Sync groups with inheritance
|
||||||
SynchronizationResult syncResult = new GroupLDAPStorageMapperFactory().create(session, mapperModel).syncDataFromFederationProviderToKeycloak(realm);
|
SynchronizationResult syncResult = new GroupLDAPStorageMapperFactory().create(session, mapperModel).syncDataFromFederationProviderToKeycloak(realm);
|
||||||
LDAPTestUtils.assertSyncEquals(syncResult, 3, 0, 0, 0);
|
LDAPTestAsserts.assertSyncEquals(syncResult, 3, 0, 0, 0);
|
||||||
|
|
||||||
// Assert groups are imported to keycloak including their inheritance from LDAP
|
// Assert groups are imported to keycloak including their inheritance from LDAP
|
||||||
GroupModel kcGroup1 = KeycloakModelUtils.findGroupByPath(realm, "/group1");
|
GroupModel kcGroup1 = KeycloakModelUtils.findGroupByPath(realm, "/group1");
|
||||||
|
@ -233,29 +212,28 @@ public class LDAPGroupMapperSyncTest {
|
||||||
|
|
||||||
// Sync and assert groups updated
|
// Sync and assert groups updated
|
||||||
syncResult = new GroupLDAPStorageMapperFactory().create(session, mapperModel).syncDataFromFederationProviderToKeycloak(realm);
|
syncResult = new GroupLDAPStorageMapperFactory().create(session, mapperModel).syncDataFromFederationProviderToKeycloak(realm);
|
||||||
LDAPTestUtils.assertSyncEquals(syncResult, 0, 3, 0, 0);
|
LDAPTestAsserts.assertSyncEquals(syncResult, 0, 3, 0, 0);
|
||||||
|
|
||||||
// Assert attributes changed in keycloak
|
// Assert attributes changed in keycloak
|
||||||
kcGroup1 = KeycloakModelUtils.findGroupByPath(realm, "/group1");
|
kcGroup1 = KeycloakModelUtils.findGroupByPath(realm, "/group1");
|
||||||
kcGroup12 = KeycloakModelUtils.findGroupByPath(realm, "/group1/group12");
|
kcGroup12 = KeycloakModelUtils.findGroupByPath(realm, "/group1/group12");
|
||||||
Assert.assertEquals("group1 - changed description", kcGroup1.getFirstAttribute(descriptionAttrName));
|
Assert.assertEquals("group1 - changed description", kcGroup1.getFirstAttribute(descriptionAttrName));
|
||||||
Assert.assertNull(kcGroup12.getFirstAttribute(descriptionAttrName));
|
Assert.assertNull(kcGroup12.getFirstAttribute(descriptionAttrName));
|
||||||
} finally {
|
});
|
||||||
keycloakRule.stopSession(session, false);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void test03_syncWithDropNonExistingGroups() throws Exception {
|
public void test03_syncWithDropNonExistingGroups() throws Exception {
|
||||||
KeycloakSession session = keycloakRule.startSession();
|
testingClient.server().run(session -> {
|
||||||
try {
|
LDAPTestContext ctx = LDAPTestContext.init(session);
|
||||||
RealmModel realm = session.realms().getRealmByName("test");
|
RealmModel realm = ctx.getRealm();
|
||||||
ComponentModel mapperModel = LDAPTestUtils.getSubcomponentByName(realm,ldapModel, "groupsMapper");
|
|
||||||
LDAPStorageProvider ldapProvider = LDAPTestUtils.getLdapProvider(session, ldapModel);
|
ComponentModel mapperModel = LDAPTestUtils.getSubcomponentByName(realm, ctx.getLdapModel(), "groupsMapper");
|
||||||
|
LDAPStorageProvider ldapProvider = LDAPTestUtils.getLdapProvider(session, ctx.getLdapModel());
|
||||||
|
|
||||||
// Sync groups with inheritance
|
// Sync groups with inheritance
|
||||||
SynchronizationResult syncResult = new GroupLDAPStorageMapperFactory().create(session, mapperModel).syncDataFromFederationProviderToKeycloak(realm);
|
SynchronizationResult syncResult = new GroupLDAPStorageMapperFactory().create(session, mapperModel).syncDataFromFederationProviderToKeycloak(realm);
|
||||||
LDAPTestUtils.assertSyncEquals(syncResult, 3, 0, 0, 0);
|
LDAPTestAsserts.assertSyncEquals(syncResult, 3, 0, 0, 0);
|
||||||
|
|
||||||
// Assert groups are imported to keycloak including their inheritance from LDAP
|
// Assert groups are imported to keycloak including their inheritance from LDAP
|
||||||
GroupModel kcGroup1 = KeycloakModelUtils.findGroupByPath(realm, "/group1");
|
GroupModel kcGroup1 = KeycloakModelUtils.findGroupByPath(realm, "/group1");
|
||||||
|
@ -272,7 +250,7 @@ public class LDAPGroupMapperSyncTest {
|
||||||
|
|
||||||
// Sync groups again from LDAP. Nothing deleted
|
// Sync groups again from LDAP. Nothing deleted
|
||||||
syncResult = new GroupLDAPStorageMapperFactory().create(session, mapperModel).syncDataFromFederationProviderToKeycloak(realm);
|
syncResult = new GroupLDAPStorageMapperFactory().create(session, mapperModel).syncDataFromFederationProviderToKeycloak(realm);
|
||||||
LDAPTestUtils.assertSyncEquals(syncResult, 0, 3, 0, 0);
|
LDAPTestAsserts.assertSyncEquals(syncResult, 0, 3, 0, 0);
|
||||||
|
|
||||||
Assert.assertNotNull(KeycloakModelUtils.findGroupByPath(realm, "/group1/group11"));
|
Assert.assertNotNull(KeycloakModelUtils.findGroupByPath(realm, "/group1/group11"));
|
||||||
Assert.assertNotNull(KeycloakModelUtils.findGroupByPath(realm, "/group1/group12"));
|
Assert.assertNotNull(KeycloakModelUtils.findGroupByPath(realm, "/group1/group12"));
|
||||||
|
@ -293,20 +271,19 @@ public class LDAPGroupMapperSyncTest {
|
||||||
Assert.assertNotNull(KeycloakModelUtils.findGroupByPath(realm, "/group1/group12"));
|
Assert.assertNotNull(KeycloakModelUtils.findGroupByPath(realm, "/group1/group12"));
|
||||||
Assert.assertNull(KeycloakModelUtils.findGroupByPath(realm, "/model1"));
|
Assert.assertNull(KeycloakModelUtils.findGroupByPath(realm, "/model1"));
|
||||||
Assert.assertNull(KeycloakModelUtils.findGroupByPath(realm, "/group1/model2"));
|
Assert.assertNull(KeycloakModelUtils.findGroupByPath(realm, "/group1/model2"));
|
||||||
} finally {
|
});
|
||||||
keycloakRule.stopSession(session, false);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void test04_syncNoPreserveGroupInheritanceWithLazySync() throws Exception {
|
public void test04_syncNoPreserveGroupInheritanceWithLazySync() throws Exception {
|
||||||
KeycloakSession session = keycloakRule.startSession();
|
testingClient.server().run(session -> {
|
||||||
try {
|
LDAPTestContext ctx = LDAPTestContext.init(session);
|
||||||
RealmModel realm = session.realms().getRealmByName("test");
|
RealmModel realm = ctx.getRealm();
|
||||||
ComponentModel mapperModel = LDAPTestUtils.getSubcomponentByName(realm,ldapModel, "groupsMapper");
|
|
||||||
LDAPStorageProvider ldapProvider = LDAPTestUtils.getLdapProvider(session, ldapModel);
|
ComponentModel mapperModel = LDAPTestUtils.getSubcomponentByName(realm, ctx.getLdapModel(), "groupsMapper");
|
||||||
|
LDAPStorageProvider ldapProvider = LDAPTestUtils.getLdapProvider(session, ctx.getLdapModel());
|
||||||
GroupLDAPStorageMapper groupMapper = LDAPTestUtils.getGroupMapper(mapperModel, ldapProvider, realm);
|
GroupLDAPStorageMapper groupMapper = LDAPTestUtils.getGroupMapper(mapperModel, ldapProvider, realm);
|
||||||
|
|
||||||
// Update group mapper to skip preserve inheritance
|
// Update group mapper to skip preserve inheritance
|
||||||
|
@ -346,8 +323,19 @@ public class LDAPGroupMapperSyncTest {
|
||||||
// Delete group mapping
|
// Delete group mapping
|
||||||
john.leaveGroup(group11);
|
john.leaveGroup(group11);
|
||||||
|
|
||||||
} finally {
|
});
|
||||||
keycloakRule.stopSession(session, false);
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test05SyncRestAPI() {
|
||||||
|
ComponentRepresentation groupMapperRep = findMapperRepByName("groupsMapper");
|
||||||
|
|
||||||
|
try {
|
||||||
|
// testing KEYCLOAK-3980 which threw an NPE because I was looking up the factory wrong.
|
||||||
|
SynchronizationResultRepresentation syncResultRep = adminClient.realm("test").userStorage().syncMapperData( ldapModelId, groupMapperRep.getId(), "error");
|
||||||
|
Assert.fail("Should throw 400");
|
||||||
|
} catch (BadRequestException e) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2016 Red Hat, Inc. and/or its affiliates
|
* Copyright 2017 Red Hat, Inc. and/or its affiliates
|
||||||
* and other contributors as indicated by the @author tags.
|
* and other contributors as indicated by the @author tags.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
@ -15,160 +15,87 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.keycloak.testsuite.federation.storage.ldap;
|
package org.keycloak.testsuite.federation.ldap;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.jboss.arquillian.container.test.api.Deployment;
|
||||||
|
import org.jboss.arquillian.container.test.api.TargetsContainer;
|
||||||
|
import org.jboss.shrinkwrap.api.spec.WebArchive;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.ClassRule;
|
import org.junit.ClassRule;
|
||||||
import org.junit.FixMethodOrder;
|
import org.junit.FixMethodOrder;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.rules.RuleChain;
|
|
||||||
import org.junit.rules.TestRule;
|
|
||||||
import org.junit.runners.MethodSorters;
|
import org.junit.runners.MethodSorters;
|
||||||
import org.keycloak.common.util.MultivaluedHashMap;
|
import org.keycloak.admin.client.resource.UserResource;
|
||||||
import org.keycloak.component.ComponentModel;
|
import org.keycloak.component.ComponentModel;
|
||||||
import org.keycloak.storage.UserStorageProvider;
|
import org.keycloak.models.GroupModel;
|
||||||
import org.keycloak.storage.UserStorageProviderModel;
|
import org.keycloak.models.ModelException;
|
||||||
|
import org.keycloak.models.UserModel;
|
||||||
|
import org.keycloak.representations.idm.ComponentRepresentation;
|
||||||
import org.keycloak.storage.ldap.LDAPConfig;
|
import org.keycloak.storage.ldap.LDAPConfig;
|
||||||
import org.keycloak.storage.ldap.LDAPStorageProvider;
|
import org.keycloak.storage.ldap.LDAPStorageProvider;
|
||||||
import org.keycloak.storage.ldap.LDAPStorageProviderFactory;
|
|
||||||
import org.keycloak.storage.ldap.LDAPUtils;
|
import org.keycloak.storage.ldap.LDAPUtils;
|
||||||
import org.keycloak.storage.ldap.idm.model.LDAPDn;
|
import org.keycloak.storage.ldap.idm.model.LDAPDn;
|
||||||
import org.keycloak.storage.ldap.idm.model.LDAPObject;
|
import org.keycloak.storage.ldap.idm.model.LDAPObject;
|
||||||
import org.keycloak.storage.ldap.mappers.membership.LDAPGroupMapperMode;
|
import org.keycloak.storage.ldap.mappers.membership.LDAPGroupMapperMode;
|
||||||
import org.keycloak.storage.ldap.mappers.membership.MembershipType;
|
import org.keycloak.storage.ldap.mappers.membership.MembershipType;
|
||||||
import org.keycloak.storage.ldap.mappers.membership.group.GroupLDAPStorageMapper;
|
import org.keycloak.storage.ldap.mappers.membership.group.GroupLDAPStorageMapper;
|
||||||
import org.keycloak.storage.ldap.mappers.membership.group.GroupLDAPStorageMapperFactory;
|
|
||||||
import org.keycloak.storage.ldap.mappers.membership.group.GroupMapperConfig;
|
|
||||||
import org.keycloak.models.GroupModel;
|
|
||||||
import org.keycloak.models.KeycloakSession;
|
|
||||||
import org.keycloak.models.LDAPConstants;
|
import org.keycloak.models.LDAPConstants;
|
||||||
import org.keycloak.models.ModelException;
|
|
||||||
import org.keycloak.models.RealmModel;
|
import org.keycloak.models.RealmModel;
|
||||||
import org.keycloak.models.UserModel;
|
|
||||||
import org.keycloak.models.utils.KeycloakModelUtils;
|
import org.keycloak.models.utils.KeycloakModelUtils;
|
||||||
import org.keycloak.services.managers.RealmManager;
|
import org.keycloak.storage.ldap.mappers.membership.group.GroupMapperConfig;
|
||||||
import org.keycloak.testsuite.rule.KeycloakRule;
|
import org.keycloak.testsuite.runonserver.RunOnServerDeployment;
|
||||||
import org.keycloak.testsuite.rule.LDAPRule;
|
import org.keycloak.testsuite.util.LDAPRule;
|
||||||
|
import org.keycloak.testsuite.util.LDAPTestUtils;
|
||||||
|
|
||||||
import java.util.List;
|
import static org.keycloak.testsuite.arquillian.DeploymentTargetModifier.AUTH_SERVER_CURRENT;
|
||||||
import java.util.Set;
|
import static org.keycloak.testsuite.util.LDAPTestUtils.getGroupDescriptionLDAPAttrName;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||||
*/
|
*/
|
||||||
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
|
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
|
||||||
public class LDAPGroupMapperTest {
|
public class LDAPGroupMapperTest extends AbstractLDAPTest {
|
||||||
|
|
||||||
private static LDAPRule ldapRule = new LDAPRule();
|
@ClassRule
|
||||||
|
public static LDAPRule ldapRule = new LDAPRule();
|
||||||
|
|
||||||
private static ComponentModel ldapModel = null;
|
@Deployment
|
||||||
private static String descriptionAttrName = null;
|
@TargetsContainer(AUTH_SERVER_CURRENT)
|
||||||
|
public static WebArchive deploy() {
|
||||||
|
return RunOnServerDeployment.create(UserResource.class, AbstractLDAPTest.class)
|
||||||
static class GroupTestKeycloakSetup extends KeycloakRule.KeycloakSetup {
|
.addPackages(true,
|
||||||
|
"org.keycloak.testsuite",
|
||||||
private final LDAPRule ldapRule;
|
"org.keycloak.testsuite.federation.ldap");
|
||||||
|
|
||||||
ComponentModel ldapModel = null;
|
|
||||||
String descriptionAttrName = null;
|
|
||||||
|
|
||||||
|
|
||||||
public GroupTestKeycloakSetup(LDAPRule ldapRule) {
|
|
||||||
this.ldapRule = ldapRule;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
|
protected LDAPRule getLDAPRule() {
|
||||||
LDAPTestUtils.addLocalUser(manager.getSession(), appRealm, "mary", "mary@test.com", "password-app");
|
return ldapRule;
|
||||||
LDAPTestUtils.addLocalUser(manager.getSession(), appRealm, "john", "john@test.com", "password-app");
|
}
|
||||||
|
|
||||||
MultivaluedHashMap<String,String> ldapConfig = LDAPTestUtils.getLdapRuleConfig(ldapRule);
|
@Override
|
||||||
ldapConfig.putSingle(LDAPConstants.SYNC_REGISTRATIONS, "true");
|
protected void afterImportTestRealm() {
|
||||||
ldapConfig.putSingle(LDAPConstants.EDIT_MODE, UserStorageProvider.EditMode.WRITABLE.toString());
|
testingClient.testing().ldap(TEST_REALM_NAME).prepareGroupsLDAPTest();
|
||||||
UserStorageProviderModel model = new UserStorageProviderModel();
|
|
||||||
model.setLastSync(0);
|
|
||||||
model.setChangedSyncPeriod(-1);
|
|
||||||
model.setFullSyncPeriod(-1);
|
|
||||||
model.setName("test-ldap");
|
|
||||||
model.setPriority(0);
|
|
||||||
model.setProviderId(LDAPStorageProviderFactory.PROVIDER_NAME);
|
|
||||||
model.setConfig(ldapConfig);
|
|
||||||
|
|
||||||
ldapModel = appRealm.addComponentModel(model);
|
|
||||||
LDAPStorageProvider ldapFedProvider = LDAPTestUtils.getLdapProvider(session, ldapModel);
|
|
||||||
descriptionAttrName = ldapFedProvider.getLdapIdentityStore().getConfig().isActiveDirectory() ? "displayName" : "description";
|
|
||||||
|
|
||||||
// Add group mapper
|
|
||||||
LDAPTestUtils.addOrUpdateGroupMapper(appRealm, ldapModel, LDAPGroupMapperMode.LDAP_ONLY, descriptionAttrName);
|
|
||||||
|
|
||||||
// Remove all LDAP groups
|
|
||||||
LDAPTestUtils.removeAllLDAPGroups(session, appRealm, ldapModel, "groupsMapper");
|
|
||||||
|
|
||||||
// Add some groups for testing
|
|
||||||
LDAPObject group1 = LDAPTestUtils.createLDAPGroup(manager.getSession(), appRealm, ldapModel, "group1", descriptionAttrName, "group1 - description");
|
|
||||||
LDAPObject group11 = LDAPTestUtils.createLDAPGroup(manager.getSession(), appRealm, ldapModel, "group11");
|
|
||||||
LDAPObject group12 = LDAPTestUtils.createLDAPGroup(manager.getSession(), appRealm, ldapModel, "group12", descriptionAttrName, "group12 - description");
|
|
||||||
|
|
||||||
LDAPObject defaultGroup1 = LDAPTestUtils.createLDAPGroup(manager.getSession(), appRealm, ldapModel, "defaultGroup1", descriptionAttrName, "Default Group1 - description");
|
|
||||||
LDAPObject defaultGroup11 = LDAPTestUtils.createLDAPGroup(manager.getSession(), appRealm, ldapModel, "defaultGroup11");
|
|
||||||
LDAPObject defaultGroup12 = LDAPTestUtils.createLDAPGroup(manager.getSession(), appRealm, ldapModel, "defaultGroup12", descriptionAttrName, "Default Group12 - description");
|
|
||||||
|
|
||||||
LDAPUtils.addMember(ldapFedProvider, MembershipType.DN, LDAPConstants.MEMBER, "not-used", group1, group11, false);
|
|
||||||
LDAPUtils.addMember(ldapFedProvider, MembershipType.DN, LDAPConstants.MEMBER, "not-used", group1, group12, true);
|
|
||||||
|
|
||||||
LDAPUtils.addMember(ldapFedProvider, MembershipType.DN, LDAPConstants.MEMBER, "not-used", defaultGroup1, defaultGroup11, false);
|
|
||||||
LDAPUtils.addMember(ldapFedProvider, MembershipType.DN, LDAPConstants.MEMBER, "not-used", defaultGroup1, defaultGroup12, true);
|
|
||||||
|
|
||||||
// Sync LDAP groups to Keycloak DB
|
|
||||||
ComponentModel mapperModel = LDAPTestUtils.getSubcomponentByName(appRealm, ldapModel, "groupsMapper");
|
|
||||||
new GroupLDAPStorageMapperFactory().create(session, mapperModel).syncDataFromFederationProviderToKeycloak(appRealm);
|
|
||||||
|
|
||||||
appRealm.addDefaultGroup(KeycloakModelUtils.findGroupByPath(appRealm, "/defaultGroup1/defaultGroup11"));
|
|
||||||
appRealm.addDefaultGroup(KeycloakModelUtils.findGroupByPath(appRealm, "/defaultGroup1/defaultGroup12"));
|
|
||||||
|
|
||||||
// Delete all LDAP users
|
|
||||||
LDAPTestUtils.removeAllLDAPUsers(ldapFedProvider, appRealm);
|
|
||||||
|
|
||||||
// Add some LDAP users for testing
|
|
||||||
LDAPObject john = LDAPTestUtils.addLDAPUser(ldapFedProvider, appRealm, "johnkeycloak", "John", "Doe", "john@email.org", null, "1234");
|
|
||||||
LDAPTestUtils.updateLDAPPassword(ldapFedProvider, john, "Password1");
|
|
||||||
|
|
||||||
LDAPObject mary = LDAPTestUtils.addLDAPUser(ldapFedProvider, appRealm, "marykeycloak", "Mary", "Kelly", "mary@email.org", null, "5678");
|
|
||||||
LDAPTestUtils.updateLDAPPassword(ldapFedProvider, mary, "Password1");
|
|
||||||
|
|
||||||
LDAPObject rob = LDAPTestUtils.addLDAPUser(ldapFedProvider, appRealm, "robkeycloak", "Rob", "Brown", "rob@email.org", null, "8910");
|
|
||||||
LDAPTestUtils.updateLDAPPassword(ldapFedProvider, rob, "Password1");
|
|
||||||
|
|
||||||
LDAPObject james = LDAPTestUtils.addLDAPUser(ldapFedProvider, appRealm, "jameskeycloak", "James", "Brown", "james@email.org", null, "8910");
|
|
||||||
LDAPTestUtils.updateLDAPPassword(ldapFedProvider, james, "Password1");
|
|
||||||
|
|
||||||
postSetup(appRealm, ldapFedProvider);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void postSetup(RealmModel appRealm, LDAPStorageProvider ldapProvider) {
|
|
||||||
LDAPGroupMapperTest.ldapModel = this.ldapModel;
|
|
||||||
LDAPGroupMapperTest.descriptionAttrName = this.descriptionAttrName;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private static KeycloakRule keycloakRule = new KeycloakRule(new GroupTestKeycloakSetup(ldapRule));
|
|
||||||
|
|
||||||
@ClassRule
|
|
||||||
public static TestRule chain = RuleChain
|
|
||||||
.outerRule(ldapRule)
|
|
||||||
.around(keycloakRule);
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void test01_ldapOnlyGroupMappings() {
|
public void test01_ldapOnlyGroupMappings() {
|
||||||
KeycloakSession session = keycloakRule.startSession();
|
test01_ldapOnlyGroupMappings(true);
|
||||||
try {
|
}
|
||||||
RealmModel appRealm = session.realms().getRealmByName("test");
|
|
||||||
|
|
||||||
ComponentModel mapperModel = LDAPTestUtils.getSubcomponentByName(appRealm,ldapModel, "groupsMapper");
|
|
||||||
|
protected void test01_ldapOnlyGroupMappings(boolean importEnabled) {
|
||||||
|
testingClient.server().run(session -> {
|
||||||
|
LDAPTestContext ctx = LDAPTestContext.init(session);
|
||||||
|
RealmModel appRealm = ctx.getRealm();
|
||||||
|
|
||||||
|
ComponentModel mapperModel = LDAPTestUtils.getSubcomponentByName(appRealm, ctx.getLdapModel(), "groupsMapper");
|
||||||
LDAPTestUtils.updateGroupMapperConfigOptions(mapperModel, GroupMapperConfig.MODE, LDAPGroupMapperMode.LDAP_ONLY.toString());
|
LDAPTestUtils.updateGroupMapperConfigOptions(mapperModel, GroupMapperConfig.MODE, LDAPGroupMapperMode.LDAP_ONLY.toString());
|
||||||
appRealm.updateComponent(mapperModel);
|
appRealm.updateComponent(mapperModel);
|
||||||
|
|
||||||
|
@ -189,14 +116,32 @@ public class LDAPGroupMapperTest {
|
||||||
GroupModel group12 = KeycloakModelUtils.findGroupByPath(appRealm, "/group1/group12");
|
GroupModel group12 = KeycloakModelUtils.findGroupByPath(appRealm, "/group1/group12");
|
||||||
john.joinGroup(group12);
|
john.joinGroup(group12);
|
||||||
mary.joinGroup(group12);
|
mary.joinGroup(group12);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
// 2 - Check that group mappings are not in local Keycloak DB (They are in LDAP).
|
// 2 - Check that group mappings are not in local Keycloak DB (They are in LDAP).
|
||||||
|
if (importEnabled) {
|
||||||
|
testingClient.server().run(session -> {
|
||||||
|
LDAPTestContext ctx = LDAPTestContext.init(session);
|
||||||
|
RealmModel appRealm = ctx.getRealm();
|
||||||
|
|
||||||
UserModel johnDb = session.userLocalStorage().getUserByUsername("johnkeycloak", appRealm);
|
UserModel johnDb = session.userLocalStorage().getUserByUsername("johnkeycloak", appRealm);
|
||||||
Set<GroupModel> johnDbGroups = johnDb.getGroups();
|
Set<GroupModel> johnDbGroups = johnDb.getGroups();
|
||||||
Assert.assertEquals(2, johnDbGroups.size());
|
Assert.assertEquals(2, johnDbGroups.size());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// 3 - Check that group mappings are in LDAP and hence available through federation
|
// 3 - Check that group mappings are in LDAP and hence available through federation
|
||||||
|
testingClient.server().run(session -> {
|
||||||
|
LDAPTestContext ctx = LDAPTestContext.init(session);
|
||||||
|
RealmModel appRealm = ctx.getRealm();
|
||||||
|
|
||||||
|
GroupModel group1 = KeycloakModelUtils.findGroupByPath(appRealm, "/group1");
|
||||||
|
GroupModel group11 = KeycloakModelUtils.findGroupByPath(appRealm, "/group1/group11");
|
||||||
|
GroupModel group12 = KeycloakModelUtils.findGroupByPath(appRealm, "/group1/group12");
|
||||||
|
UserModel john = session.users().getUserByUsername("johnkeycloak", appRealm);
|
||||||
|
UserModel mary = session.users().getUserByUsername("marykeycloak", appRealm);
|
||||||
|
|
||||||
Set<GroupModel> johnGroups = john.getGroups();
|
Set<GroupModel> johnGroups = john.getGroups();
|
||||||
Assert.assertEquals(2, johnGroups.size());
|
Assert.assertEquals(2, johnGroups.size());
|
||||||
|
@ -225,20 +170,22 @@ public class LDAPGroupMapperTest {
|
||||||
|
|
||||||
johnGroups = john.getGroups();
|
johnGroups = john.getGroups();
|
||||||
Assert.assertEquals(0, johnGroups.size());
|
Assert.assertEquals(0, johnGroups.size());
|
||||||
|
});
|
||||||
} finally {
|
|
||||||
keycloakRule.stopSession(session, false);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void test02_readOnlyGroupMappings() {
|
public void test02_readOnlyGroupMappings() {
|
||||||
KeycloakSession session = keycloakRule.startSession();
|
test02_readOnlyGroupMappings(true);
|
||||||
try {
|
}
|
||||||
System.out.println("starting test02_readOnlyGroupMappings");
|
|
||||||
RealmModel appRealm = session.realms().getRealmByName("test");
|
|
||||||
|
|
||||||
ComponentModel mapperModel = LDAPTestUtils.getSubcomponentByName(appRealm,ldapModel, "groupsMapper");
|
|
||||||
|
|
||||||
|
protected void test02_readOnlyGroupMappings(boolean importEnabled) {
|
||||||
|
testingClient.server().run(session -> {
|
||||||
|
LDAPTestContext ctx = LDAPTestContext.init(session);
|
||||||
|
RealmModel appRealm = ctx.getRealm();
|
||||||
|
|
||||||
|
ComponentModel mapperModel = LDAPTestUtils.getSubcomponentByName(appRealm, ctx.getLdapModel(), "groupsMapper");
|
||||||
LDAPTestUtils.updateGroupMapperConfigOptions(mapperModel, GroupMapperConfig.MODE, LDAPGroupMapperMode.READ_ONLY.toString());
|
LDAPTestUtils.updateGroupMapperConfigOptions(mapperModel, GroupMapperConfig.MODE, LDAPGroupMapperMode.READ_ONLY.toString());
|
||||||
appRealm.updateComponent(mapperModel);
|
appRealm.updateComponent(mapperModel);
|
||||||
|
|
||||||
|
@ -249,10 +196,9 @@ public class LDAPGroupMapperTest {
|
||||||
GroupModel group12 = KeycloakModelUtils.findGroupByPath(appRealm, "/group1/group12");
|
GroupModel group12 = KeycloakModelUtils.findGroupByPath(appRealm, "/group1/group12");
|
||||||
|
|
||||||
// Add some group mappings directly into LDAP
|
// Add some group mappings directly into LDAP
|
||||||
LDAPStorageProvider ldapProvider = LDAPTestUtils.getLdapProvider(session, ldapModel);
|
GroupLDAPStorageMapper groupMapper = LDAPTestUtils.getGroupMapper(mapperModel, ctx.getLdapProvider(), appRealm);
|
||||||
GroupLDAPStorageMapper groupMapper = LDAPTestUtils.getGroupMapper(mapperModel, ldapProvider, appRealm);
|
|
||||||
|
|
||||||
LDAPObject maryLdap = ldapProvider.loadLDAPUserByUsername(appRealm, "marykeycloak");
|
LDAPObject maryLdap = ctx.getLdapProvider().loadLDAPUserByUsername(appRealm, "marykeycloak");
|
||||||
groupMapper.addGroupMappingInLDAP(appRealm, group1, maryLdap);
|
groupMapper.addGroupMappingInLDAP(appRealm, group1, maryLdap);
|
||||||
groupMapper.addGroupMappingInLDAP(appRealm, group11, maryLdap);
|
groupMapper.addGroupMappingInLDAP(appRealm, group11, maryLdap);
|
||||||
|
|
||||||
|
@ -265,16 +211,62 @@ public class LDAPGroupMapperTest {
|
||||||
Assert.assertTrue(maryGroups.contains(group1));
|
Assert.assertTrue(maryGroups.contains(group1));
|
||||||
Assert.assertTrue(maryGroups.contains(group11));
|
Assert.assertTrue(maryGroups.contains(group11));
|
||||||
Assert.assertTrue(maryGroups.contains(group12));
|
Assert.assertTrue(maryGroups.contains(group12));
|
||||||
|
});
|
||||||
|
|
||||||
// Assert that access through DB will have just DB mapped groups
|
// Assert that access through DB will have just DB mapped groups
|
||||||
System.out.println("******");
|
if (importEnabled) {
|
||||||
|
testingClient.server().run(session -> {
|
||||||
|
LDAPTestContext ctx = LDAPTestContext.init(session);
|
||||||
|
RealmModel appRealm = ctx.getRealm();
|
||||||
|
|
||||||
|
GroupModel group1 = KeycloakModelUtils.findGroupByPath(appRealm, "/group1");
|
||||||
|
GroupModel group11 = KeycloakModelUtils.findGroupByPath(appRealm, "/group1/group11");
|
||||||
|
GroupModel group12 = KeycloakModelUtils.findGroupByPath(appRealm, "/group1/group12");
|
||||||
|
|
||||||
UserModel maryDB = session.userLocalStorage().getUserByUsername("marykeycloak", appRealm);
|
UserModel maryDB = session.userLocalStorage().getUserByUsername("marykeycloak", appRealm);
|
||||||
|
|
||||||
Set<GroupModel> maryDBGroups = maryDB.getGroups();
|
Set<GroupModel> maryDBGroups = maryDB.getGroups();
|
||||||
Assert.assertFalse(maryDBGroups.contains(group1));
|
Assert.assertFalse(maryDBGroups.contains(group1));
|
||||||
Assert.assertFalse(maryDBGroups.contains(group11));
|
Assert.assertFalse(maryDBGroups.contains(group11));
|
||||||
Assert.assertTrue(maryDBGroups.contains(group12));
|
Assert.assertTrue(maryDBGroups.contains(group12));
|
||||||
|
|
||||||
|
// Test the group mapping available for group12
|
||||||
|
List<UserModel> group12Members = session.users().getGroupMembers(appRealm, group12, 0, 10);
|
||||||
|
Assert.assertEquals(1, group12Members.size());
|
||||||
|
Assert.assertEquals("marykeycloak", group12Members.get(0).getUsername());
|
||||||
|
|
||||||
|
UserModel mary = session.users().getUserByUsername("marykeycloak", appRealm);
|
||||||
|
mary.leaveGroup(group12);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
testingClient.server().run(session -> {
|
||||||
|
LDAPTestContext ctx = LDAPTestContext.init(session);
|
||||||
|
RealmModel appRealm = ctx.getRealm();
|
||||||
|
|
||||||
|
GroupModel group12 = KeycloakModelUtils.findGroupByPath(appRealm, "/group1/group12");
|
||||||
|
|
||||||
|
// Test the group mapping NOT available for group12
|
||||||
|
List<UserModel> group12Members = session.users().getGroupMembers(appRealm, group12, 0, 10);
|
||||||
|
Assert.assertEquals(0, group12Members.size());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Check through userProvider
|
// Check through userProvider
|
||||||
|
testingClient.server().run(session -> {
|
||||||
|
LDAPTestContext ctx = LDAPTestContext.init(session);
|
||||||
|
RealmModel appRealm = ctx.getRealm();
|
||||||
|
|
||||||
|
GroupModel group1 = KeycloakModelUtils.findGroupByPath(appRealm, "/group1");
|
||||||
|
GroupModel group11 = KeycloakModelUtils.findGroupByPath(appRealm, "/group1/group11");
|
||||||
|
GroupModel group12 = KeycloakModelUtils.findGroupByPath(appRealm, "/group1/group12");
|
||||||
|
UserModel john = session.users().getUserByUsername("johnkeycloak", appRealm);
|
||||||
|
UserModel mary = session.users().getUserByUsername("marykeycloak", appRealm);
|
||||||
|
|
||||||
|
ComponentModel mapperModel = LDAPTestUtils.getSubcomponentByName(appRealm, ctx.getLdapModel(), "groupsMapper");
|
||||||
|
GroupLDAPStorageMapper groupMapper = LDAPTestUtils.getGroupMapper(mapperModel, ctx.getLdapProvider(), appRealm);
|
||||||
|
LDAPObject maryLdap = ctx.getLdapProvider().loadLDAPUserByUsername(appRealm, "marykeycloak");
|
||||||
|
|
||||||
List<UserModel> group1Members = session.users().getGroupMembers(appRealm, group1, 0, 10);
|
List<UserModel> group1Members = session.users().getGroupMembers(appRealm, group1, 0, 10);
|
||||||
List<UserModel> group11Members = session.users().getGroupMembers(appRealm, group11, 0, 10);
|
List<UserModel> group11Members = session.users().getGroupMembers(appRealm, group11, 0, 10);
|
||||||
List<UserModel> group12Members = session.users().getGroupMembers(appRealm, group12, 0, 10);
|
List<UserModel> group12Members = session.users().getGroupMembers(appRealm, group12, 0, 10);
|
||||||
|
@ -282,36 +274,35 @@ public class LDAPGroupMapperTest {
|
||||||
Assert.assertEquals("marykeycloak", group1Members.get(0).getUsername());
|
Assert.assertEquals("marykeycloak", group1Members.get(0).getUsername());
|
||||||
Assert.assertEquals(1, group11Members.size());
|
Assert.assertEquals(1, group11Members.size());
|
||||||
Assert.assertEquals("marykeycloak", group11Members.get(0).getUsername());
|
Assert.assertEquals("marykeycloak", group11Members.get(0).getUsername());
|
||||||
Assert.assertEquals(1, group12Members.size());
|
|
||||||
Assert.assertEquals("marykeycloak", group12Members.get(0).getUsername());
|
|
||||||
|
|
||||||
mary.leaveGroup(group12);
|
|
||||||
try {
|
try {
|
||||||
mary.leaveGroup(group1);
|
mary.leaveGroup(group1);
|
||||||
Assert.fail("It wasn't expected to successfully delete LDAP group mappings in READ_ONLY mode");
|
Assert.fail("It wasn't expected to successfully delete LDAP group mappings in READ_ONLY mode");
|
||||||
} catch (ModelException expected) {
|
} catch (ModelException expected) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete role mappings directly in LDAP
|
// Delete group mappings directly in LDAP
|
||||||
deleteGroupMappingsInLDAP(groupMapper, maryLdap, "group1");
|
LDAPObject ldapGroup = groupMapper.loadLDAPGroupByName("group1");
|
||||||
deleteGroupMappingsInLDAP(groupMapper, maryLdap, "group11");
|
groupMapper.deleteGroupMappingInLDAP(maryLdap, ldapGroup);
|
||||||
} finally {
|
|
||||||
keycloakRule.stopSession(session, false);
|
ldapGroup = groupMapper.loadLDAPGroupByName("group11");
|
||||||
}
|
groupMapper.deleteGroupMappingInLDAP(maryLdap, ldapGroup);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void test03_importGroupMappings() {
|
public void test03_importGroupMappings() {
|
||||||
KeycloakSession session = keycloakRule.startSession();
|
testingClient.server().run(session -> {
|
||||||
try {
|
LDAPTestContext ctx = LDAPTestContext.init(session);
|
||||||
RealmModel appRealm = session.realms().getRealmByName("test");
|
RealmModel appRealm = ctx.getRealm();
|
||||||
|
|
||||||
ComponentModel mapperModel = LDAPTestUtils.getSubcomponentByName(appRealm,ldapModel, "groupsMapper");
|
ComponentModel mapperModel = LDAPTestUtils.getSubcomponentByName(appRealm, ctx.getLdapModel(), "groupsMapper");
|
||||||
LDAPTestUtils.updateGroupMapperConfigOptions(mapperModel, GroupMapperConfig.MODE, LDAPGroupMapperMode.IMPORT.toString());
|
LDAPTestUtils.updateGroupMapperConfigOptions(mapperModel, GroupMapperConfig.MODE, LDAPGroupMapperMode.IMPORT.toString());
|
||||||
appRealm.updateComponent(mapperModel);
|
appRealm.updateComponent(mapperModel);
|
||||||
|
|
||||||
// Add some group mappings directly in LDAP
|
// Add some group mappings directly in LDAP
|
||||||
LDAPStorageProvider ldapProvider = LDAPTestUtils.getLdapProvider(session, ldapModel);
|
LDAPStorageProvider ldapProvider = LDAPTestUtils.getLdapProvider(session, ctx.getLdapModel());
|
||||||
GroupLDAPStorageMapper groupMapper = LDAPTestUtils.getGroupMapper(mapperModel, ldapProvider, appRealm);
|
GroupLDAPStorageMapper groupMapper = LDAPTestUtils.getGroupMapper(mapperModel, ldapProvider, appRealm);
|
||||||
|
|
||||||
GroupModel group1 = KeycloakModelUtils.findGroupByPath(appRealm, "/group1");
|
GroupModel group1 = KeycloakModelUtils.findGroupByPath(appRealm, "/group1");
|
||||||
|
@ -322,7 +313,7 @@ public class LDAPGroupMapperTest {
|
||||||
groupMapper.addGroupMappingInLDAP(appRealm, group11, robLdap);
|
groupMapper.addGroupMappingInLDAP(appRealm, group11, robLdap);
|
||||||
groupMapper.addGroupMappingInLDAP(appRealm, group12, robLdap);
|
groupMapper.addGroupMappingInLDAP(appRealm, group12, robLdap);
|
||||||
|
|
||||||
// Get user and check that he has requested groupa from LDAP
|
// Get user and check that he has requested groups from LDAP
|
||||||
UserModel rob = session.users().getUserByUsername("robkeycloak", appRealm);
|
UserModel rob = session.users().getUserByUsername("robkeycloak", appRealm);
|
||||||
Set<GroupModel> robGroups = rob.getGroups();
|
Set<GroupModel> robGroups = rob.getGroups();
|
||||||
|
|
||||||
|
@ -331,8 +322,12 @@ public class LDAPGroupMapperTest {
|
||||||
Assert.assertTrue(robGroups.contains(group12));
|
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
|
// Delete some group mappings in LDAP and check that it doesn't have any effect and user still has groups
|
||||||
deleteGroupMappingsInLDAP(groupMapper, robLdap, "group11");
|
LDAPObject ldapGroup = groupMapper.loadLDAPGroupByName("group11");
|
||||||
deleteGroupMappingsInLDAP(groupMapper, robLdap, "group12");
|
groupMapper.deleteGroupMappingInLDAP(robLdap, ldapGroup);
|
||||||
|
|
||||||
|
ldapGroup = groupMapper.loadLDAPGroupByName("group12");
|
||||||
|
groupMapper.deleteGroupMappingInLDAP(robLdap, ldapGroup);
|
||||||
|
|
||||||
robGroups = rob.getGroups();
|
robGroups = rob.getGroups();
|
||||||
Assert.assertTrue(robGroups.contains(group11));
|
Assert.assertTrue(robGroups.contains(group11));
|
||||||
Assert.assertTrue(robGroups.contains(group12));
|
Assert.assertTrue(robGroups.contains(group12));
|
||||||
|
@ -342,33 +337,33 @@ public class LDAPGroupMapperTest {
|
||||||
rob.leaveGroup(group12);
|
rob.leaveGroup(group12);
|
||||||
robGroups = rob.getGroups();
|
robGroups = rob.getGroups();
|
||||||
Assert.assertEquals(2, robGroups.size());
|
Assert.assertEquals(2, robGroups.size());
|
||||||
} finally {
|
});
|
||||||
keycloakRule.stopSession(session, false);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// KEYCLOAK-2682
|
// KEYCLOAK-2682
|
||||||
@Test
|
@Test
|
||||||
public void test04_groupReferencingNonExistentMember() {
|
public void test04_groupReferencingNonExistentMember() {
|
||||||
KeycloakSession session = keycloakRule.startSession();
|
testingClient.server().run(session -> {
|
||||||
try {
|
LDAPTestContext ctx = LDAPTestContext.init(session);
|
||||||
|
RealmModel appRealm = ctx.getRealm();
|
||||||
|
|
||||||
// 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...
|
// 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 = LDAPTestUtils.getLdapProvider(session, ldapModel).getLdapIdentityStore().getConfig();
|
LDAPConfig config = ctx.getLdapProvider().getLdapIdentityStore().getConfig();
|
||||||
if (config.isActiveDirectory()) {
|
if (config.isActiveDirectory()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
RealmModel appRealm = session.realms().getRealmByName("test");
|
ComponentModel mapperModel = LDAPTestUtils.getSubcomponentByName(appRealm, ctx.getLdapModel(), "groupsMapper");
|
||||||
|
|
||||||
ComponentModel mapperModel = LDAPTestUtils.getSubcomponentByName(appRealm,ldapModel, "groupsMapper");
|
|
||||||
LDAPTestUtils.updateGroupMapperConfigOptions(mapperModel, GroupMapperConfig.MODE, LDAPGroupMapperMode.LDAP_ONLY.toString());
|
LDAPTestUtils.updateGroupMapperConfigOptions(mapperModel, GroupMapperConfig.MODE, LDAPGroupMapperMode.LDAP_ONLY.toString());
|
||||||
appRealm.updateComponent(mapperModel);
|
appRealm.updateComponent(mapperModel);
|
||||||
|
|
||||||
|
String descriptionAttrName = getGroupDescriptionLDAPAttrName(ctx.getLdapProvider());
|
||||||
|
|
||||||
// 1 - Add some group to LDAP for testing
|
// 1 - Add some group to LDAP for testing
|
||||||
LDAPStorageProvider ldapProvider = LDAPTestUtils.getLdapProvider(session, ldapModel);
|
LDAPStorageProvider ldapProvider = LDAPTestUtils.getLdapProvider(session, ctx.getLdapModel());
|
||||||
GroupLDAPStorageMapper groupMapper = LDAPTestUtils.getGroupMapper(mapperModel, ldapProvider, appRealm);
|
GroupLDAPStorageMapper groupMapper = LDAPTestUtils.getGroupMapper(mapperModel, ldapProvider, appRealm);
|
||||||
LDAPObject group2 = LDAPTestUtils.createLDAPGroup(session, appRealm, ldapModel, "group2", descriptionAttrName, "group2 - description");
|
LDAPObject group2 = LDAPTestUtils.createLDAPGroup(session, appRealm, ctx.getLdapModel(), "group2", descriptionAttrName, "group2 - description");
|
||||||
|
|
||||||
// 2 - Add one existing user rob to LDAP group
|
// 2 - Add one existing user rob to LDAP group
|
||||||
LDAPObject jamesLdap = ldapProvider.loadLDAPUserByUsername(appRealm, "jameskeycloak");
|
LDAPObject jamesLdap = ldapProvider.loadLDAPUserByUsername(appRealm, "jameskeycloak");
|
||||||
|
@ -389,9 +384,7 @@ public class LDAPGroupMapperTest {
|
||||||
UserModel rob = groupUsers.get(0);
|
UserModel rob = groupUsers.get(0);
|
||||||
Assert.assertEquals("jameskeycloak", rob.getUsername());
|
Assert.assertEquals("jameskeycloak", rob.getUsername());
|
||||||
|
|
||||||
} finally {
|
});
|
||||||
keycloakRule.stopSession(session, false);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -400,38 +393,37 @@ public class LDAPGroupMapperTest {
|
||||||
// just because it's available on all the LDAP servers
|
// just because it's available on all the LDAP servers
|
||||||
@Test
|
@Test
|
||||||
public void test05_getGroupsFromUserMemberOfStrategyTest() throws Exception {
|
public void test05_getGroupsFromUserMemberOfStrategyTest() throws Exception {
|
||||||
KeycloakSession session = keycloakRule.startSession();
|
ComponentRepresentation groupMapperRep = findMapperRepByName("groupsMapper");
|
||||||
MultivaluedHashMap<String, String> oldGroupMapperCfg;
|
|
||||||
try {
|
testingClient.server().run(session -> {
|
||||||
LDAPStorageProvider ldapProvider = LDAPTestUtils.getLdapProvider(session, ldapModel);
|
LDAPTestContext ctx = LDAPTestContext.init(session);
|
||||||
RealmModel appRealm = session.realms().getRealmByName("test");
|
RealmModel appRealm = ctx.getRealm();
|
||||||
|
|
||||||
// Create street attribute mapper
|
// Create street attribute mapper
|
||||||
LDAPTestUtils.addUserAttributeMapper(appRealm, ldapModel, "streetMapper", "street", LDAPConstants.STREET);
|
LDAPTestUtils.addUserAttributeMapper(appRealm, ctx.getLdapModel(), "streetMapper", "street", LDAPConstants.STREET);
|
||||||
|
|
||||||
// Find DN of "group1"
|
// Find DN of "group1"
|
||||||
ComponentModel mapperModel = LDAPTestUtils.getSubcomponentByName(appRealm,ldapModel, "groupsMapper");
|
ComponentModel mapperModel = LDAPTestUtils.getSubcomponentByName(appRealm, ctx.getLdapModel(), "groupsMapper");
|
||||||
oldGroupMapperCfg = new MultivaluedHashMap<>(mapperModel.getConfig());
|
GroupLDAPStorageMapper groupMapper = LDAPTestUtils.getGroupMapper(mapperModel, ctx.getLdapProvider(), appRealm);
|
||||||
GroupLDAPStorageMapper groupMapper = LDAPTestUtils.getGroupMapper(mapperModel, ldapProvider, appRealm);
|
|
||||||
LDAPObject ldapGroup = groupMapper.loadLDAPGroupByName("group1");
|
LDAPObject ldapGroup = groupMapper.loadLDAPGroupByName("group1");
|
||||||
String ldapGroupDN = ldapGroup.getDn().toString();
|
String ldapGroupDN = ldapGroup.getDn().toString();
|
||||||
|
|
||||||
// Create new user in LDAP. Add him some "street" referencing existing LDAP Group
|
// Create new user in LDAP. Add him some "street" referencing existing LDAP Group
|
||||||
LDAPObject carlos = LDAPTestUtils.addLDAPUser(ldapProvider, appRealm, "carloskeycloak", "Carlos", "Doel", "carlos.doel@email.org", ldapGroupDN, "1234");
|
LDAPObject carlos = LDAPTestUtils.addLDAPUser(ctx.getLdapProvider(), appRealm, "carloskeycloak", "Carlos", "Doel", "carlos.doel@email.org", ldapGroupDN, "1234");
|
||||||
LDAPTestUtils.updateLDAPPassword(ldapProvider, carlos, "Password1");
|
LDAPTestUtils.updateLDAPPassword(ctx.getLdapProvider(), carlos, "Password1");
|
||||||
|
|
||||||
// Update group mapper
|
// Update group mapper
|
||||||
LDAPTestUtils.updateGroupMapperConfigOptions(mapperModel,
|
LDAPTestUtils.updateGroupMapperConfigOptions(mapperModel,
|
||||||
GroupMapperConfig.USER_ROLES_RETRIEVE_STRATEGY, GroupMapperConfig.GET_GROUPS_FROM_USER_MEMBEROF_ATTRIBUTE,
|
GroupMapperConfig.USER_ROLES_RETRIEVE_STRATEGY, GroupMapperConfig.GET_GROUPS_FROM_USER_MEMBEROF_ATTRIBUTE,
|
||||||
GroupMapperConfig.MEMBEROF_LDAP_ATTRIBUTE, LDAPConstants.STREET);
|
GroupMapperConfig.MEMBEROF_LDAP_ATTRIBUTE, LDAPConstants.STREET);
|
||||||
appRealm.updateComponent(mapperModel);
|
appRealm.updateComponent(mapperModel);
|
||||||
} finally {
|
});
|
||||||
keycloakRule.stopSession(session, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
session = keycloakRule.startSession();
|
ComponentRepresentation streetMapperRep = findMapperRepByName("streetMapper");
|
||||||
try {
|
|
||||||
RealmModel appRealm = session.realms().getRealmByName("test");
|
testingClient.server().run(session -> {
|
||||||
|
LDAPTestContext ctx = LDAPTestContext.init(session);
|
||||||
|
RealmModel appRealm = ctx.getRealm();
|
||||||
|
|
||||||
// Get user in Keycloak. Ensure that he is member of requested group
|
// Get user in Keycloak. Ensure that he is member of requested group
|
||||||
UserModel carlos = session.users().getUserByUsername("carloskeycloak", appRealm);
|
UserModel carlos = session.users().getUserByUsername("carloskeycloak", appRealm);
|
||||||
|
@ -446,17 +438,12 @@ public class LDAPGroupMapperTest {
|
||||||
Assert.assertFalse(carlosGroups.contains(group12));
|
Assert.assertFalse(carlosGroups.contains(group12));
|
||||||
|
|
||||||
Assert.assertEquals(1, carlosGroups.size());
|
Assert.assertEquals(1, carlosGroups.size());
|
||||||
|
});
|
||||||
|
|
||||||
// Revert mappers
|
// Revert mappers
|
||||||
ComponentModel streetMapper = LDAPTestUtils.getSubcomponentByName(appRealm,ldapModel, "streetMapper");
|
testRealm().components().component(streetMapperRep.getId()).remove();
|
||||||
appRealm.removeComponent(streetMapper);
|
groupMapperRep.getConfig().putSingle(GroupMapperConfig.USER_ROLES_RETRIEVE_STRATEGY, GroupMapperConfig.LOAD_GROUPS_BY_MEMBER_ATTRIBUTE);
|
||||||
|
testRealm().components().component(groupMapperRep.getId()).update(groupMapperRep);
|
||||||
ComponentModel groupMapper = LDAPTestUtils.getSubcomponentByName(appRealm,ldapModel, "groupsMapper");
|
|
||||||
groupMapper.setConfig(oldGroupMapperCfg);
|
|
||||||
appRealm.updateComponent(groupMapper);
|
|
||||||
} finally {
|
|
||||||
keycloakRule.stopSession(session, true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -464,9 +451,9 @@ public class LDAPGroupMapperTest {
|
||||||
@Test
|
@Test
|
||||||
public void test06_addingUserToNewKeycloakGroup() throws Exception {
|
public void test06_addingUserToNewKeycloakGroup() throws Exception {
|
||||||
// Add some groups to Keycloak
|
// Add some groups to Keycloak
|
||||||
KeycloakSession session = keycloakRule.startSession();
|
testingClient.server().run(session -> {
|
||||||
try {
|
LDAPTestContext ctx = LDAPTestContext.init(session);
|
||||||
RealmModel appRealm = session.realms().getRealmByName("test");
|
RealmModel appRealm = ctx.getRealm();
|
||||||
|
|
||||||
GroupModel group3 = appRealm.createGroup("group3");
|
GroupModel group3 = appRealm.createGroup("group3");
|
||||||
session.realms().addTopLevelGroup(appRealm, group3);
|
session.realms().addTopLevelGroup(appRealm, group3);
|
||||||
|
@ -482,14 +469,12 @@ public class LDAPGroupMapperTest {
|
||||||
GroupModel group1 = KeycloakModelUtils.findGroupByPath(appRealm, "/group1");
|
GroupModel group1 = KeycloakModelUtils.findGroupByPath(appRealm, "/group1");
|
||||||
group1.addChild(group14);
|
group1.addChild(group14);
|
||||||
|
|
||||||
} finally {
|
});
|
||||||
keycloakRule.stopSession(session, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add user to some newly created KC groups
|
// Add user to some newly created KC groups
|
||||||
session = keycloakRule.startSession();
|
testingClient.server().run(session -> {
|
||||||
try {
|
LDAPTestContext ctx = LDAPTestContext.init(session);
|
||||||
RealmModel appRealm = session.realms().getRealmByName("test");
|
RealmModel appRealm = ctx.getRealm();
|
||||||
|
|
||||||
UserModel john = session.users().getUserByUsername("johnkeycloak", appRealm);
|
UserModel john = session.users().getUserByUsername("johnkeycloak", appRealm);
|
||||||
|
|
||||||
|
@ -504,14 +489,12 @@ public class LDAPGroupMapperTest {
|
||||||
|
|
||||||
GroupModel group14 = KeycloakModelUtils.findGroupByPath(appRealm, "/group1/group14");
|
GroupModel group14 = KeycloakModelUtils.findGroupByPath(appRealm, "/group1/group14");
|
||||||
john.joinGroup(group14);
|
john.joinGroup(group14);
|
||||||
} finally {
|
});
|
||||||
keycloakRule.stopSession(session, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check user group memberships
|
// Check user group memberships
|
||||||
session = keycloakRule.startSession();
|
testingClient.server().run(session -> {
|
||||||
try {
|
LDAPTestContext ctx = LDAPTestContext.init(session);
|
||||||
RealmModel appRealm = session.realms().getRealmByName("test");
|
RealmModel appRealm = ctx.getRealm();
|
||||||
|
|
||||||
UserModel john = session.users().getUserByUsername("johnkeycloak", appRealm);
|
UserModel john = session.users().getUserByUsername("johnkeycloak", appRealm);
|
||||||
|
|
||||||
|
@ -527,9 +510,7 @@ public class LDAPGroupMapperTest {
|
||||||
Assert.assertTrue(groups.contains(group31));
|
Assert.assertTrue(groups.contains(group31));
|
||||||
Assert.assertTrue(groups.contains(group32));
|
Assert.assertTrue(groups.contains(group32));
|
||||||
Assert.assertTrue(groups.contains(group4));
|
Assert.assertTrue(groups.contains(group4));
|
||||||
} finally {
|
});
|
||||||
keycloakRule.stopSession(session, true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -537,11 +518,11 @@ public class LDAPGroupMapperTest {
|
||||||
public void test07_newUserDefaultGroupsImportModeTest() throws Exception {
|
public void test07_newUserDefaultGroupsImportModeTest() throws Exception {
|
||||||
|
|
||||||
// Check user group memberships
|
// Check user group memberships
|
||||||
KeycloakSession session = keycloakRule.startSession();
|
testingClient.server().run(session -> {
|
||||||
try {
|
LDAPTestContext ctx = LDAPTestContext.init(session);
|
||||||
RealmModel appRealm = session.realms().getRealmByName("test");
|
RealmModel appRealm = ctx.getRealm();
|
||||||
|
|
||||||
ComponentModel mapperModel = LDAPTestUtils.getSubcomponentByName(appRealm,ldapModel, "groupsMapper");
|
ComponentModel mapperModel = LDAPTestUtils.getSubcomponentByName(appRealm, ctx.getLdapModel(), "groupsMapper");
|
||||||
LDAPTestUtils.updateGroupMapperConfigOptions(mapperModel, GroupMapperConfig.MODE, LDAPGroupMapperMode.IMPORT.toString());
|
LDAPTestUtils.updateGroupMapperConfigOptions(mapperModel, GroupMapperConfig.MODE, LDAPGroupMapperMode.IMPORT.toString());
|
||||||
appRealm.updateComponent(mapperModel);
|
appRealm.updateComponent(mapperModel);
|
||||||
|
|
||||||
|
@ -567,13 +548,7 @@ public class LDAPGroupMapperTest {
|
||||||
Assert.assertFalse(groups.contains(group32));
|
Assert.assertFalse(groups.contains(group32));
|
||||||
Assert.assertFalse(groups.contains(group4));
|
Assert.assertFalse(groups.contains(group4));
|
||||||
|
|
||||||
} finally {
|
});
|
||||||
keycloakRule.stopSession(session, true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void deleteGroupMappingsInLDAP(GroupLDAPStorageMapper groupMapper, LDAPObject ldapUser, String groupName) {
|
|
||||||
LDAPObject ldapGroup = groupMapper.loadLDAPGroupByName(groupName);
|
|
||||||
groupMapper.deleteGroupMappingInLDAP(ldapUser, ldapGroup);
|
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -0,0 +1,147 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2017 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.jboss.arquillian.container.test.api.Deployment;
|
||||||
|
import org.jboss.arquillian.container.test.api.TargetsContainer;
|
||||||
|
import org.jboss.shrinkwrap.api.spec.WebArchive;
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.ClassRule;
|
||||||
|
import org.junit.FixMethodOrder;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runners.MethodSorters;
|
||||||
|
import org.keycloak.OAuth2Constants;
|
||||||
|
import org.keycloak.admin.client.resource.UserResource;
|
||||||
|
import org.keycloak.component.ComponentModel;
|
||||||
|
import org.keycloak.models.RealmModel;
|
||||||
|
import org.keycloak.representations.idm.RealmRepresentation;
|
||||||
|
import org.keycloak.storage.UserStorageProvider;
|
||||||
|
import org.keycloak.storage.ldap.LDAPStorageProvider;
|
||||||
|
import org.keycloak.storage.ldap.idm.model.LDAPObject;
|
||||||
|
import org.keycloak.testsuite.pages.AppPage;
|
||||||
|
import org.keycloak.testsuite.runonserver.RunOnServerDeployment;
|
||||||
|
import org.keycloak.testsuite.util.LDAPRule;
|
||||||
|
import org.keycloak.testsuite.util.LDAPTestConfiguration;
|
||||||
|
import org.keycloak.testsuite.util.LDAPTestUtils;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static org.keycloak.testsuite.admin.AbstractAdminTest.loadJson;
|
||||||
|
import static org.keycloak.testsuite.arquillian.DeploymentTargetModifier.AUTH_SERVER_CURRENT;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests that legacy UserFederationProvider json export is converted to ComponentModel
|
||||||
|
*
|
||||||
|
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||||
|
*/
|
||||||
|
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
|
||||||
|
public class LDAPLegacyImportTest extends AbstractLDAPTest {
|
||||||
|
|
||||||
|
@ClassRule
|
||||||
|
public static LDAPRule ldapRule = new LDAPRule()
|
||||||
|
.assumeTrue((LDAPTestConfiguration ldapConfig) -> {
|
||||||
|
|
||||||
|
return ldapConfig.isStartEmbeddedLdapServer();
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
@Deployment
|
||||||
|
@TargetsContainer(AUTH_SERVER_CURRENT)
|
||||||
|
public static WebArchive deploy() {
|
||||||
|
return RunOnServerDeployment.create(UserResource.class, AbstractLDAPTest.class)
|
||||||
|
.addPackages(true,
|
||||||
|
"org.keycloak.testsuite",
|
||||||
|
"org.keycloak.testsuite.federation.ldap");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected LDAPRule getLDAPRule() {
|
||||||
|
return ldapRule;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addTestRealms(List<RealmRepresentation> testRealms) {
|
||||||
|
RealmRepresentation testRealm = loadJson(getClass().getResourceAsStream("/ldap/fed-provider-export.json"), RealmRepresentation.class);
|
||||||
|
testRealms.add(testRealm);
|
||||||
|
configureTestRealm(testRealm);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Overriden as we won't create LDAP provider here. It is present in the JSON file fed-provider-export.json already
|
||||||
|
@Override
|
||||||
|
protected void createLDAPProvider() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void afterImportTestRealm() {
|
||||||
|
testingClient.server().run(session -> {
|
||||||
|
LDAPTestContext ctx = LDAPTestContext.init(session);
|
||||||
|
RealmModel appRealm = ctx.getRealm();
|
||||||
|
ComponentModel ldapModel = appRealm.getComponents(appRealm.getId(), UserStorageProvider.class.getName()).get(0);
|
||||||
|
|
||||||
|
LDAPTestUtils.addLocalUser(session, appRealm, "marykeycloak", "mary@test.com", "password-app");
|
||||||
|
|
||||||
|
// Delete all LDAP users and add some new for testing
|
||||||
|
LDAPStorageProvider ldapFedProvider = LDAPTestUtils.getLdapProvider(session, ldapModel);
|
||||||
|
LDAPTestUtils.removeAllLDAPUsers(ldapFedProvider, appRealm);
|
||||||
|
|
||||||
|
LDAPObject john = LDAPTestUtils.addLDAPUser(ldapFedProvider, appRealm, "johnkeycloak", "John", "Doe", "john@email.org", null, "1234");
|
||||||
|
LDAPTestUtils.updateLDAPPassword(ldapFedProvider, john, "Password1");
|
||||||
|
|
||||||
|
LDAPObject existing = LDAPTestUtils.addLDAPUser(ldapFedProvider, appRealm, "existing", "Existing", "Foo", "existing@email.org", null, "5678");
|
||||||
|
|
||||||
|
appRealm.getClientByClientId("test-app").setDirectAccessGrantsEnabled(true);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//@Test
|
||||||
|
public void runit() throws Exception {
|
||||||
|
Thread.sleep(10000000);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@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());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2016 Red Hat, Inc. and/or its affiliates
|
* Copyright 2017 Red Hat, Inc. and/or its affiliates
|
||||||
* and other contributors as indicated by the @author tags.
|
* and other contributors as indicated by the @author tags.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
@ -15,44 +15,35 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.keycloak.testsuite.federation.storage.ldap;
|
package org.keycloak.testsuite.federation.ldap;
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
|
import org.jboss.arquillian.container.test.api.Deployment;
|
||||||
|
import org.jboss.arquillian.container.test.api.TargetsContainer;
|
||||||
|
import org.jboss.shrinkwrap.api.spec.WebArchive;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.ClassRule;
|
import org.junit.ClassRule;
|
||||||
import org.junit.FixMethodOrder;
|
import org.junit.FixMethodOrder;
|
||||||
import org.junit.Rule;
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.rules.RuleChain;
|
|
||||||
import org.junit.rules.TestRule;
|
|
||||||
import org.junit.runners.MethodSorters;
|
import org.junit.runners.MethodSorters;
|
||||||
import org.keycloak.common.util.MultivaluedHashMap;
|
import org.keycloak.admin.client.resource.UserResource;
|
||||||
import org.keycloak.component.ComponentModel;
|
import org.keycloak.component.ComponentModel;
|
||||||
import org.keycloak.models.KeycloakSession;
|
import org.keycloak.models.KeycloakSession;
|
||||||
import org.keycloak.models.LDAPConstants;
|
import org.keycloak.models.LDAPConstants;
|
||||||
import org.keycloak.models.RealmModel;
|
import org.keycloak.models.RealmModel;
|
||||||
import org.keycloak.models.UserModel;
|
import org.keycloak.models.UserModel;
|
||||||
import org.keycloak.models.utils.KeycloakModelUtils;
|
import org.keycloak.models.utils.KeycloakModelUtils;
|
||||||
import org.keycloak.services.managers.RealmManager;
|
|
||||||
import org.keycloak.storage.UserStorageProvider;
|
|
||||||
import org.keycloak.storage.UserStorageProviderModel;
|
import org.keycloak.storage.UserStorageProviderModel;
|
||||||
import org.keycloak.storage.ldap.LDAPStorageProvider;
|
import org.keycloak.storage.ldap.LDAPStorageProvider;
|
||||||
import org.keycloak.storage.ldap.LDAPStorageProviderFactory;
|
|
||||||
import org.keycloak.storage.ldap.mappers.FullNameLDAPStorageMapper;
|
import org.keycloak.storage.ldap.mappers.FullNameLDAPStorageMapper;
|
||||||
import org.keycloak.storage.ldap.mappers.FullNameLDAPStorageMapperFactory;
|
import org.keycloak.storage.ldap.mappers.FullNameLDAPStorageMapperFactory;
|
||||||
import org.keycloak.storage.ldap.mappers.LDAPStorageMapper;
|
import org.keycloak.storage.ldap.mappers.LDAPStorageMapper;
|
||||||
import org.keycloak.testsuite.OAuthClient;
|
|
||||||
import org.keycloak.testsuite.pages.AccountPasswordPage;
|
|
||||||
import org.keycloak.testsuite.pages.AccountUpdateProfilePage;
|
|
||||||
import org.keycloak.testsuite.pages.AppPage;
|
import org.keycloak.testsuite.pages.AppPage;
|
||||||
import org.keycloak.testsuite.pages.LoginPage;
|
import org.keycloak.testsuite.runonserver.RunOnServerDeployment;
|
||||||
import org.keycloak.testsuite.pages.RegisterPage;
|
import org.keycloak.testsuite.util.LDAPRule;
|
||||||
import org.keycloak.testsuite.rule.KeycloakRule;
|
import org.keycloak.testsuite.util.LDAPTestConfiguration;
|
||||||
import org.keycloak.testsuite.rule.LDAPRule;
|
import org.keycloak.testsuite.util.LDAPTestUtils;
|
||||||
import org.keycloak.testsuite.rule.WebResource;
|
|
||||||
import org.keycloak.testsuite.rule.WebRule;
|
import static org.keycloak.testsuite.arquillian.DeploymentTargetModifier.AUTH_SERVER_CURRENT;
|
||||||
import org.openqa.selenium.WebDriver;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test for the MSAD setup with usernameAttribute=sAMAccountName, rdnAttribute=cn and fullNameMapper mapped to cn
|
* Test for the MSAD setup with usernameAttribute=sAMAccountName, rdnAttribute=cn and fullNameMapper mapped to cn
|
||||||
|
@ -60,42 +51,49 @@ import org.openqa.selenium.WebDriver;
|
||||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||||
*/
|
*/
|
||||||
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
|
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
|
||||||
public class LDAPMSADFullNameTest {
|
public class LDAPMSADFullNameTest extends AbstractLDAPTest {
|
||||||
|
|
||||||
// Run this test just on MSAD and just when sAMAccountName is mapped to username
|
// Run this test just on MSAD and just when sAMAccountName is mapped to username
|
||||||
private static LDAPRule ldapRule = new LDAPRule((Map<String, String> ldapConfig) -> {
|
@ClassRule
|
||||||
|
public static LDAPRule ldapRule = new LDAPRule()
|
||||||
|
.assumeTrue((LDAPTestConfiguration ldapConfig) -> {
|
||||||
|
|
||||||
String vendor = ldapConfig.get(LDAPConstants.VENDOR);
|
String vendor = ldapConfig.getLDAPConfig().get(LDAPConstants.VENDOR);
|
||||||
if (!vendor.equals(LDAPConstants.VENDOR_ACTIVE_DIRECTORY)) {
|
if (!vendor.equals(LDAPConstants.VENDOR_ACTIVE_DIRECTORY)) {
|
||||||
return true;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
String usernameAttr = ldapConfig.get(LDAPConstants.USERNAME_LDAP_ATTRIBUTE);
|
String usernameAttr = ldapConfig.getLDAPConfig().get(LDAPConstants.USERNAME_LDAP_ATTRIBUTE);
|
||||||
return !usernameAttr.equalsIgnoreCase(LDAPConstants.SAM_ACCOUNT_NAME);
|
return usernameAttr.equalsIgnoreCase(LDAPConstants.SAM_ACCOUNT_NAME);
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
private static ComponentModel ldapModel = null;
|
|
||||||
|
|
||||||
private static KeycloakRule keycloakRule = new KeycloakRule(new KeycloakRule.KeycloakSetup() {
|
|
||||||
|
@Deployment
|
||||||
|
@TargetsContainer(AUTH_SERVER_CURRENT)
|
||||||
|
public static WebArchive deploy() {
|
||||||
|
return RunOnServerDeployment.create(UserResource.class, AbstractLDAPTest.class)
|
||||||
|
.addPackages(true,
|
||||||
|
"org.keycloak.testsuite",
|
||||||
|
"org.keycloak.testsuite.federation.ldap");
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
|
protected LDAPRule getLDAPRule() {
|
||||||
LDAPTestUtils.addLocalUser(manager.getSession(), appRealm, "marykeycloak", "mary@test.com", "password-app");
|
return ldapRule;
|
||||||
|
}
|
||||||
|
|
||||||
MultivaluedHashMap<String,String> ldapConfig = LDAPTestUtils.getLdapRuleConfig(ldapRule);
|
|
||||||
ldapConfig.putSingle(LDAPConstants.SYNC_REGISTRATIONS, "true");
|
|
||||||
ldapConfig.putSingle(LDAPConstants.EDIT_MODE, UserStorageProvider.EditMode.WRITABLE.toString());
|
|
||||||
UserStorageProviderModel model = new UserStorageProviderModel();
|
|
||||||
model.setLastSync(0);
|
|
||||||
model.setChangedSyncPeriod(-1);
|
|
||||||
model.setFullSyncPeriod(-1);
|
|
||||||
model.setName("test-ldap");
|
|
||||||
model.setPriority(1);
|
|
||||||
model.setProviderId(LDAPStorageProviderFactory.PROVIDER_NAME);
|
|
||||||
model.getConfig().addAll(ldapConfig);
|
|
||||||
|
|
||||||
ldapModel = appRealm.addComponentModel(model);
|
@Override
|
||||||
|
protected void afterImportTestRealm() {
|
||||||
|
testingClient.server().run(session -> {
|
||||||
|
LDAPTestContext ctx = LDAPTestContext.init(session);
|
||||||
|
RealmModel appRealm = ctx.getRealm();
|
||||||
|
UserStorageProviderModel ldapModel = ctx.getLdapModel();
|
||||||
|
|
||||||
|
LDAPTestUtils.addLocalUser(session, appRealm, "marykeycloak", "mary@test.com", "password-app");
|
||||||
|
|
||||||
LDAPTestUtils.addZipCodeLDAPMapper(appRealm, ldapModel);
|
LDAPTestUtils.addZipCodeLDAPMapper(appRealm, ldapModel);
|
||||||
|
|
||||||
// Delete all LDAP users and add some new for testing
|
// Delete all LDAP users and add some new for testing
|
||||||
|
@ -114,38 +112,8 @@ public class LDAPMSADFullNameTest {
|
||||||
appRealm.addComponentModel(mapperModel);
|
appRealm.addComponentModel(mapperModel);
|
||||||
|
|
||||||
appRealm.getClientByClientId("test-app").setDirectAccessGrantsEnabled(true);
|
appRealm.getClientByClientId("test-app").setDirectAccessGrantsEnabled(true);
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@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;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -156,31 +124,24 @@ public class LDAPMSADFullNameTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void test01_addUserWithoutFullName() {
|
public void test01_addUserWithoutFullName() {
|
||||||
KeycloakSession session = keycloakRule.startSession();
|
testingClient.server().run(session -> {
|
||||||
try {
|
LDAPTestContext ctx = LDAPTestContext.init(session);
|
||||||
RealmManager manager = new RealmManager(session);
|
RealmModel appRealm = ctx.getRealm();
|
||||||
RealmModel appRealm = manager.getRealm("test");
|
|
||||||
|
|
||||||
UserModel john = session.users().addUser(appRealm, "johnkeycloak");
|
UserModel john = session.users().addUser(appRealm, "johnkeycloak");
|
||||||
john.setEmail("johnkeycloak@email.cz");
|
john.setEmail("johnkeycloak@email.cz");
|
||||||
} finally {
|
});
|
||||||
keycloakRule.stopSession(session, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
session = keycloakRule.startSession();
|
testingClient.server().run(session -> {
|
||||||
try {
|
LDAPTestContext ctx = LDAPTestContext.init(session);
|
||||||
RealmManager manager = new RealmManager(session);
|
RealmModel appRealm = ctx.getRealm();
|
||||||
RealmModel appRealm = manager.getRealm("test");
|
|
||||||
|
|
||||||
UserModel john = session.users().getUserByUsername("johnkeycloak", appRealm);
|
UserModel john = session.users().getUserByUsername("johnkeycloak", appRealm);
|
||||||
Assert.assertNotNull(john.getFederationLink());
|
Assert.assertNotNull(john.getFederationLink());
|
||||||
assertDnStartsWith(session, john, "cn=johnkeycloak");
|
assertDnStartsWith(session, ctx, john, "cn=johnkeycloak");
|
||||||
|
|
||||||
session.users().removeUser(appRealm, john);
|
session.users().removeUser(appRealm, john);
|
||||||
} finally {
|
});
|
||||||
keycloakRule.stopSession(session, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -194,76 +155,63 @@ public class LDAPMSADFullNameTest {
|
||||||
registerPage.register("Johny", "Anthony", "johnyanth@check.cz", "johnkeycloak", "Password1", "Password1");
|
registerPage.register("Johny", "Anthony", "johnyanth@check.cz", "johnkeycloak", "Password1", "Password1");
|
||||||
Assert.assertEquals(AppPage.RequestType.AUTH_RESPONSE, appPage.getRequestType());
|
Assert.assertEquals(AppPage.RequestType.AUTH_RESPONSE, appPage.getRequestType());
|
||||||
|
|
||||||
KeycloakSession session = keycloakRule.startSession();
|
testingClient.server().run(session -> {
|
||||||
try {
|
LDAPTestContext ctx = LDAPTestContext.init(session);
|
||||||
RealmModel appRealm = session.realms().getRealmByName("test");
|
RealmModel appRealm = ctx.getRealm();
|
||||||
|
|
||||||
UserModel john = session.users().getUserByUsername("johnkeycloak", appRealm);
|
UserModel john = session.users().getUserByUsername("johnkeycloak", appRealm);
|
||||||
assertUser(session, john, "johnkeycloak", "Johny", "Anthony", true, "cn=Johny Anthony");
|
assertUser(session, ctx, john, "johnkeycloak", "Johny", "Anthony", true, "cn=Johny Anthony");
|
||||||
|
|
||||||
session.users().removeUser(appRealm, john);
|
session.users().removeUser(appRealm, john);
|
||||||
} finally {
|
});
|
||||||
keycloakRule.stopSession(session, true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void test03_addUserWithFirstNameOnly() {
|
public void test03_addUserWithFirstNameOnly() {
|
||||||
KeycloakSession session = keycloakRule.startSession();
|
testingClient.server().run(session -> {
|
||||||
try {
|
LDAPTestContext ctx = LDAPTestContext.init(session);
|
||||||
RealmManager manager = new RealmManager(session);
|
RealmModel appRealm = ctx.getRealm();
|
||||||
RealmModel appRealm = manager.getRealm("test");
|
|
||||||
|
|
||||||
UserModel john = session.users().addUser(appRealm, "johnkeycloak");
|
UserModel john = session.users().addUser(appRealm, "johnkeycloak");
|
||||||
john.setEmail("johnkeycloak@email.cz");
|
john.setEmail("johnkeycloak@email.cz");
|
||||||
john.setFirstName("Johnyyy");
|
john.setFirstName("Johnyyy");
|
||||||
john.setEnabled(true);
|
john.setEnabled(true);
|
||||||
} finally {
|
});
|
||||||
keycloakRule.stopSession(session, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
session = keycloakRule.startSession();
|
testingClient.server().run(session -> {
|
||||||
try {
|
LDAPTestContext ctx = LDAPTestContext.init(session);
|
||||||
RealmManager manager = new RealmManager(session);
|
RealmModel appRealm = ctx.getRealm();
|
||||||
RealmModel appRealm = manager.getRealm("test");
|
|
||||||
|
|
||||||
UserModel john = session.users().getUserByUsername("johnkeycloak", appRealm);
|
UserModel john = session.users().getUserByUsername("johnkeycloak", appRealm);
|
||||||
assertUser(session, john, "johnkeycloak", "Johnyyy", "", true, "cn=Johnyyy");
|
assertUser(session, ctx, john, "johnkeycloak", "Johnyyy", "", true, "cn=Johnyyy");
|
||||||
|
|
||||||
session.users().removeUser(appRealm, john);
|
session.users().removeUser(appRealm, john);
|
||||||
} finally {
|
});
|
||||||
keycloakRule.stopSession(session, true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void test04_addUserWithLastNameOnly() {
|
public void test04_addUserWithLastNameOnly() {
|
||||||
KeycloakSession session = keycloakRule.startSession();
|
testingClient.server().run(session -> {
|
||||||
try {
|
LDAPTestContext ctx = LDAPTestContext.init(session);
|
||||||
RealmManager manager = new RealmManager(session);
|
RealmModel appRealm = ctx.getRealm();
|
||||||
RealmModel appRealm = manager.getRealm("test");
|
|
||||||
|
|
||||||
UserModel john = session.users().addUser(appRealm, "johnkeycloak");
|
UserModel john = session.users().addUser(appRealm, "johnkeycloak");
|
||||||
john.setEmail("johnkeycloak@email.cz");
|
john.setEmail("johnkeycloak@email.cz");
|
||||||
john.setLastName("Anthonyy");
|
john.setLastName("Anthonyy");
|
||||||
john.setEnabled(true);
|
john.setEnabled(true);
|
||||||
} finally {
|
});
|
||||||
keycloakRule.stopSession(session, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
session = keycloakRule.startSession();
|
testingClient.server().run(session -> {
|
||||||
try {
|
LDAPTestContext ctx = LDAPTestContext.init(session);
|
||||||
RealmManager manager = new RealmManager(session);
|
RealmModel appRealm = ctx.getRealm();
|
||||||
RealmModel appRealm = manager.getRealm("test");
|
|
||||||
|
|
||||||
UserModel john = session.users().getUserByUsername("johnkeycloak", appRealm);
|
UserModel john = session.users().getUserByUsername("johnkeycloak", appRealm);
|
||||||
assertUser(session, john, "johnkeycloak", "", "Anthonyy", true, "cn=Anthonyy");
|
assertUser(session, ctx, john, "johnkeycloak", "", "Anthonyy", true, "cn=Anthonyy");
|
||||||
|
|
||||||
session.users().removeUser(appRealm, john);
|
session.users().removeUser(appRealm, john);
|
||||||
} finally {
|
});
|
||||||
keycloakRule.stopSession(session, true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -277,25 +225,23 @@ public class LDAPMSADFullNameTest {
|
||||||
registerPage.register("Jož,o", "Baříč", "johnyanth@check.cz", "johnkeycloak", "Password1", "Password1");
|
registerPage.register("Jož,o", "Baříč", "johnyanth@check.cz", "johnkeycloak", "Password1", "Password1");
|
||||||
Assert.assertEquals(AppPage.RequestType.AUTH_RESPONSE, appPage.getRequestType());
|
Assert.assertEquals(AppPage.RequestType.AUTH_RESPONSE, appPage.getRequestType());
|
||||||
|
|
||||||
KeycloakSession session = keycloakRule.startSession();
|
testingClient.server().run(session -> {
|
||||||
try {
|
LDAPTestContext ctx = LDAPTestContext.init(session);
|
||||||
RealmModel appRealm = session.realms().getRealmByName("test");
|
RealmModel appRealm = ctx.getRealm();
|
||||||
|
|
||||||
UserModel john = session.users().getUserByUsername("johnkeycloak", appRealm);
|
UserModel john = session.users().getUserByUsername("johnkeycloak", appRealm);
|
||||||
assertUser(session, john, "johnkeycloak", "Jož,o", "Baříč", true, "cn=Jož\\,o Baříč");
|
assertUser(session, ctx, john, "johnkeycloak", "Jož,o", "Baříč", true, "cn=Jož\\,o Baříč");
|
||||||
|
|
||||||
session.users().removeUser(appRealm, john);
|
session.users().removeUser(appRealm, john);
|
||||||
} finally {
|
});
|
||||||
keycloakRule.stopSession(session, true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void test06_conflicts() {
|
public void test06_conflicts() {
|
||||||
KeycloakSession session = keycloakRule.startSession();
|
testingClient.server().run(session -> {
|
||||||
try {
|
LDAPTestContext ctx = LDAPTestContext.init(session);
|
||||||
RealmManager manager = new RealmManager(session);
|
RealmModel appRealm = ctx.getRealm();
|
||||||
RealmModel appRealm = manager.getRealm("test");
|
|
||||||
|
|
||||||
UserModel john = session.users().addUser(appRealm, "existingkc");
|
UserModel john = session.users().addUser(appRealm, "existingkc");
|
||||||
john.setFirstName("John");
|
john.setFirstName("John");
|
||||||
|
@ -304,9 +250,7 @@ public class LDAPMSADFullNameTest {
|
||||||
|
|
||||||
UserModel john2 = session.users().addUser(appRealm, "existingkc1");
|
UserModel john2 = session.users().addUser(appRealm, "existingkc1");
|
||||||
john2.setEnabled(true);
|
john2.setEnabled(true);
|
||||||
} finally {
|
});
|
||||||
keycloakRule.stopSession(session, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
loginPage.open();
|
loginPage.open();
|
||||||
loginPage.clickRegister();
|
loginPage.clickRegister();
|
||||||
|
@ -323,47 +267,44 @@ public class LDAPMSADFullNameTest {
|
||||||
registerPage.assertCurrent();
|
registerPage.assertCurrent();
|
||||||
registerPage.register("John", "Existing", "johnyanth2@check.cz", "existingkc3", "Password1", "Password1");
|
registerPage.register("John", "Existing", "johnyanth2@check.cz", "existingkc3", "Password1", "Password1");
|
||||||
|
|
||||||
session = keycloakRule.startSession();
|
testingClient.server().run(session -> {
|
||||||
try {
|
LDAPTestContext ctx = LDAPTestContext.init(session);
|
||||||
RealmManager manager = new RealmManager(session);
|
RealmModel appRealm = ctx.getRealm();
|
||||||
RealmModel appRealm = manager.getRealm("test");
|
|
||||||
|
|
||||||
UserModel existingKc = session.users().getUserByUsername("existingkc", appRealm);
|
UserModel existingKc = session.users().getUserByUsername("existingkc", appRealm);
|
||||||
assertUser(session, existingKc, "existingkc", "John", "Existing", true, "cn=John Existing");
|
assertUser(session, ctx, existingKc, "existingkc", "John", "Existing", true, "cn=John Existing");
|
||||||
|
|
||||||
UserModel existingKc1 = session.users().getUserByUsername("existingkc1", appRealm);
|
UserModel existingKc1 = session.users().getUserByUsername("existingkc1", appRealm);
|
||||||
assertUser(session, existingKc1, "existingkc1", "", "", true, "cn=existingkc1");
|
assertUser(session, ctx, existingKc1, "existingkc1", "", "", true, "cn=existingkc1");
|
||||||
|
|
||||||
UserModel existingKc2 = session.users().getUserByUsername("existingkc2", appRealm);
|
UserModel existingKc2 = session.users().getUserByUsername("existingkc2", appRealm);
|
||||||
assertUser(session, existingKc2, "existingkc2", "John", "Existing", true, "cn=John Existing0");
|
assertUser(session, ctx, existingKc2, "existingkc2", "John", "Existing", true, "cn=John Existing0");
|
||||||
|
|
||||||
UserModel existingKc3 = session.users().getUserByUsername("existingkc3", appRealm);
|
UserModel existingKc3 = session.users().getUserByUsername("existingkc3", appRealm);
|
||||||
assertUser(session, existingKc3, "existingkc3", "John", "Existing", true, "cn=John Existing1");
|
assertUser(session, ctx, existingKc3, "existingkc3", "John", "Existing", true, "cn=John Existing1");
|
||||||
|
|
||||||
session.users().removeUser(appRealm, existingKc);
|
session.users().removeUser(appRealm, existingKc);
|
||||||
session.users().removeUser(appRealm, existingKc1);
|
session.users().removeUser(appRealm, existingKc1);
|
||||||
session.users().removeUser(appRealm, existingKc2);
|
session.users().removeUser(appRealm, existingKc2);
|
||||||
session.users().removeUser(appRealm, existingKc3);
|
session.users().removeUser(appRealm, existingKc3);
|
||||||
} finally {
|
});
|
||||||
keycloakRule.stopSession(session, true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void assertUser(KeycloakSession session, UserModel user, String expectedUsername, String expectedFirstName, String expectedLastName, boolean expectedEnabled, String expectedDn) {
|
private static void assertUser(KeycloakSession session, LDAPTestContext ctx, UserModel user, String expectedUsername, String expectedFirstName, String expectedLastName, boolean expectedEnabled, String expectedDn) {
|
||||||
Assert.assertNotNull(user);
|
Assert.assertNotNull(user);
|
||||||
Assert.assertNotNull(user.getFederationLink());
|
Assert.assertNotNull(user.getFederationLink());
|
||||||
Assert.assertEquals(user.getFederationLink(), ldapModel.getId());
|
Assert.assertEquals(user.getFederationLink(), ctx.getLdapModel().getId());
|
||||||
Assert.assertEquals(expectedUsername, user.getUsername());
|
Assert.assertEquals(expectedUsername, user.getUsername());
|
||||||
Assert.assertEquals(expectedFirstName, user.getFirstName());
|
Assert.assertEquals(expectedFirstName, user.getFirstName());
|
||||||
Assert.assertEquals(expectedLastName, user.getLastName());
|
Assert.assertEquals(expectedLastName, user.getLastName());
|
||||||
Assert.assertEquals(expectedEnabled, user.isEnabled());
|
Assert.assertEquals(expectedEnabled, user.isEnabled());
|
||||||
assertDnStartsWith(session, user, expectedDn);
|
assertDnStartsWith(session, ctx, user, expectedDn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void assertDnStartsWith(KeycloakSession session, UserModel user, String expectedRDn) {
|
private static void assertDnStartsWith(KeycloakSession session, LDAPTestContext ctx, UserModel user, String expectedRDn) {
|
||||||
String usersDn = LDAPTestUtils.getLdapProvider(session, ldapModel).getLdapIdentityStore().getConfig().getUsersDn();
|
String usersDn = ctx.getLdapProvider().getLdapIdentityStore().getConfig().getUsersDn();
|
||||||
String userDN = user.getFirstAttribute(LDAPConstants.LDAP_ENTRY_DN);
|
String userDN = user.getFirstAttribute(LDAPConstants.LDAP_ENTRY_DN);
|
||||||
Assert.assertTrue(userDN.equalsIgnoreCase(expectedRDn + "," + usersDn));
|
Assert.assertTrue(userDN.equalsIgnoreCase(expectedRDn + "," + usersDn));
|
||||||
}
|
}
|
|
@ -0,0 +1,163 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2017 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.jboss.arquillian.container.test.api.Deployment;
|
||||||
|
import org.jboss.arquillian.container.test.api.TargetsContainer;
|
||||||
|
import org.jboss.arquillian.graphene.page.Page;
|
||||||
|
import org.jboss.shrinkwrap.api.spec.WebArchive;
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.ClassRule;
|
||||||
|
import org.junit.FixMethodOrder;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runners.MethodSorters;
|
||||||
|
import org.keycloak.admin.client.resource.UserResource;
|
||||||
|
import org.keycloak.models.RealmModel;
|
||||||
|
import org.keycloak.models.UserModel;
|
||||||
|
import org.keycloak.storage.ldap.LDAPStorageProvider;
|
||||||
|
import org.keycloak.storage.ldap.idm.model.LDAPObject;
|
||||||
|
import org.keycloak.testsuite.pages.AppPage;
|
||||||
|
import org.keycloak.testsuite.pages.LoginPasswordUpdatePage;
|
||||||
|
import org.keycloak.testsuite.runonserver.RunOnServerDeployment;
|
||||||
|
import org.keycloak.testsuite.util.LDAPRule;
|
||||||
|
import org.keycloak.testsuite.util.LDAPTestConfiguration;
|
||||||
|
import org.keycloak.testsuite.util.LDAPTestUtils;
|
||||||
|
|
||||||
|
import static org.keycloak.testsuite.arquillian.DeploymentTargetModifier.AUTH_SERVER_CURRENT;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||||
|
*/
|
||||||
|
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
|
||||||
|
public class LDAPMSADMapperTest extends AbstractLDAPTest {
|
||||||
|
|
||||||
|
// Run this test just on MSAD
|
||||||
|
@ClassRule
|
||||||
|
public static LDAPRule ldapRule = new LDAPRule()
|
||||||
|
.assumeTrue((LDAPTestConfiguration ldapConfig) -> {
|
||||||
|
|
||||||
|
// TODO: This is skipped as it requires that MSAD server is set to not allow weak passwords (There needs to be pwdProperties=1 set on MSAD side).
|
||||||
|
// TODO: Currently we can't rely on it. See KEYCLOAK-4276
|
||||||
|
return false;
|
||||||
|
// return LDAPConstants.VENDOR_ACTIVE_DIRECTORY.equals(vendor);
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@Deployment
|
||||||
|
@TargetsContainer(AUTH_SERVER_CURRENT)
|
||||||
|
public static WebArchive deploy() {
|
||||||
|
return RunOnServerDeployment.create(UserResource.class, AbstractLDAPTest.class)
|
||||||
|
.addPackages(true,
|
||||||
|
"org.keycloak.testsuite",
|
||||||
|
"org.keycloak.testsuite.federation.ldap");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected LDAPRule getLDAPRule() {
|
||||||
|
return ldapRule;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void afterImportTestRealm() {
|
||||||
|
testingClient.server().run(session -> {
|
||||||
|
LDAPTestContext ctx = LDAPTestContext.init(session);
|
||||||
|
RealmModel appRealm = ctx.getRealm();
|
||||||
|
|
||||||
|
LDAPTestUtils.addLocalUser(session, appRealm, "marykeycloak", "mary@test.com", "password-app");
|
||||||
|
|
||||||
|
LDAPTestUtils.addZipCodeLDAPMapper(appRealm, ctx.getLdapModel());
|
||||||
|
|
||||||
|
// Delete all LDAP users and add some new for testing
|
||||||
|
LDAPStorageProvider ldapFedProvider = LDAPTestUtils.getLdapProvider(session, ctx.getLdapModel());
|
||||||
|
LDAPTestUtils.removeAllLDAPUsers(ldapFedProvider, appRealm);
|
||||||
|
|
||||||
|
LDAPObject john = LDAPTestUtils.addLDAPUser(ldapFedProvider, appRealm, "johnkeycloak", "John", "Doe", "john@email.org", null, "1234");
|
||||||
|
LDAPTestUtils.updateLDAPPassword(ldapFedProvider, john, "Password1");
|
||||||
|
|
||||||
|
appRealm.getClientByClientId("test-app").setDirectAccessGrantsEnabled(true);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// @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;
|
||||||
|
//
|
||||||
|
|
||||||
|
@Page
|
||||||
|
protected LoginPasswordUpdatePage passwordUpdatePage;
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test01RegisterUserWithWeakPasswordFirst() {
|
||||||
|
loginPage.open();
|
||||||
|
loginPage.clickRegister();
|
||||||
|
registerPage.assertCurrent();
|
||||||
|
|
||||||
|
// Weak password. This will fail to update password to MSAD due to password policy.
|
||||||
|
registerPage.register("firstName", "lastName", "email2@check.cz", "registerUserSuccess2", "password", "password");
|
||||||
|
|
||||||
|
// Another weak password
|
||||||
|
passwordUpdatePage.assertCurrent();
|
||||||
|
passwordUpdatePage.changePassword("pass", "pass");
|
||||||
|
Assert.assertEquals("Invalid password: new password doesn't match password policies.", passwordUpdatePage.getError());
|
||||||
|
|
||||||
|
// Strong password. Successfully update password and being redirected to the app
|
||||||
|
passwordUpdatePage.changePassword("Password1", "Password1");
|
||||||
|
Assert.assertEquals(AppPage.RequestType.AUTH_RESPONSE, appPage.getRequestType());
|
||||||
|
|
||||||
|
testingClient.server().run(session -> {
|
||||||
|
LDAPTestContext ctx = LDAPTestContext.init(session);
|
||||||
|
RealmModel appRealm = ctx.getRealm();
|
||||||
|
|
||||||
|
UserModel user = session.users().getUserByUsername("registerUserSuccess2", appRealm);
|
||||||
|
Assert.assertNotNull(user);
|
||||||
|
Assert.assertNotNull(user.getFederationLink());
|
||||||
|
Assert.assertEquals(user.getFederationLink(), ctx.getLdapModel().getId());
|
||||||
|
Assert.assertEquals("registerusersuccess2", user.getUsername());
|
||||||
|
Assert.assertEquals("firstName", user.getFirstName());
|
||||||
|
Assert.assertEquals("lastName", user.getLastName());
|
||||||
|
Assert.assertTrue(user.isEnabled());
|
||||||
|
Assert.assertEquals(0, user.getRequiredActions().size());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,247 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2017 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.jboss.arquillian.container.test.api.Deployment;
|
||||||
|
import org.jboss.arquillian.container.test.api.TargetsContainer;
|
||||||
|
import org.jboss.shrinkwrap.api.spec.WebArchive;
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.ClassRule;
|
||||||
|
import org.junit.FixMethodOrder;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runners.MethodSorters;
|
||||||
|
import org.keycloak.admin.client.resource.UserResource;
|
||||||
|
import org.keycloak.models.ClientModel;
|
||||||
|
import org.keycloak.models.LDAPConstants;
|
||||||
|
import org.keycloak.models.RealmModel;
|
||||||
|
import org.keycloak.models.UserModel;
|
||||||
|
import org.keycloak.models.utils.KeycloakModelUtils;
|
||||||
|
import org.keycloak.protocol.oidc.OIDCLoginProtocol;
|
||||||
|
import org.keycloak.protocol.oidc.mappers.UserAttributeMapper;
|
||||||
|
import org.keycloak.representations.IDToken;
|
||||||
|
import org.keycloak.storage.ldap.LDAPStorageProvider;
|
||||||
|
import org.keycloak.storage.ldap.idm.model.LDAPObject;
|
||||||
|
import org.keycloak.testsuite.runonserver.RunOnServerDeployment;
|
||||||
|
import org.keycloak.testsuite.util.LDAPRule;
|
||||||
|
import org.keycloak.testsuite.util.LDAPTestConfiguration;
|
||||||
|
import org.keycloak.testsuite.util.LDAPTestUtils;
|
||||||
|
import org.keycloak.testsuite.util.OAuthClient;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.LinkedHashSet;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static org.keycloak.testsuite.arquillian.DeploymentTargetModifier.AUTH_SERVER_CURRENT;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||||
|
*/
|
||||||
|
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
|
||||||
|
public class LDAPMultipleAttributesTest extends AbstractLDAPTest {
|
||||||
|
|
||||||
|
|
||||||
|
// Skip this test on MSAD due to lack of supported user multivalued attributes
|
||||||
|
@ClassRule
|
||||||
|
public static LDAPRule ldapRule = new LDAPRule()
|
||||||
|
.assumeTrue((LDAPTestConfiguration ldapConfig) -> {
|
||||||
|
|
||||||
|
String vendor = ldapConfig.getLDAPConfig().get(LDAPConstants.VENDOR);
|
||||||
|
return !LDAPConstants.VENDOR_ACTIVE_DIRECTORY.equals(vendor);
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
@Deployment
|
||||||
|
@TargetsContainer(AUTH_SERVER_CURRENT)
|
||||||
|
public static WebArchive deploy() {
|
||||||
|
return RunOnServerDeployment.create(UserResource.class, AbstractLDAPTest.class)
|
||||||
|
.addPackages(true,
|
||||||
|
"org.keycloak.testsuite",
|
||||||
|
"org.keycloak.testsuite.federation.ldap");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected LDAPRule getLDAPRule() {
|
||||||
|
return ldapRule;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void afterImportTestRealm() {
|
||||||
|
testingClient.server().run(session -> {
|
||||||
|
LDAPTestContext ctx = LDAPTestContext.init(session);
|
||||||
|
RealmModel appRealm = ctx.getRealm();
|
||||||
|
|
||||||
|
LDAPTestUtils.addZipCodeLDAPMapper(appRealm, ctx.getLdapModel());
|
||||||
|
LDAPTestUtils.addUserAttributeMapper(appRealm, ctx.getLdapModel(), "streetMapper", "street", LDAPConstants.STREET);
|
||||||
|
|
||||||
|
// Remove current users and add default users
|
||||||
|
LDAPStorageProvider ldapFedProvider = LDAPTestUtils.getLdapProvider(session, ctx.getLdapModel());
|
||||||
|
LDAPTestUtils.removeAllLDAPUsers(ldapFedProvider, appRealm);
|
||||||
|
|
||||||
|
LDAPObject james = LDAPTestUtils.addLDAPUser(ldapFedProvider, appRealm, "jbrown", "James", "Brown", "jbrown@keycloak.org", null, "88441");
|
||||||
|
LDAPTestUtils.updateLDAPPassword(ldapFedProvider, james, "Password1");
|
||||||
|
|
||||||
|
// User for testing duplicating surname and postalCode
|
||||||
|
LDAPObject bruce = LDAPTestUtils.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);
|
||||||
|
LDAPTestUtils.updateLDAPPassword(ldapFedProvider, bruce, "Password1");
|
||||||
|
|
||||||
|
// Create ldap-portal client
|
||||||
|
ClientModel ldapClient = KeycloakModelUtils.createClient(appRealm, "ldap-portal");
|
||||||
|
ldapClient.setProtocol(OIDCLoginProtocol.LOGIN_PROTOCOL);
|
||||||
|
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));
|
||||||
|
ldapClient.addProtocolMapper(UserAttributeMapper.createClaimMapper("street", "street", "street", "String", true, true, false));
|
||||||
|
ldapClient.addScopeMapping(appRealm.getRole("user"));
|
||||||
|
ldapClient.setSecret("password");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testUserImport() {
|
||||||
|
testingClient.server().run(session -> {
|
||||||
|
LDAPTestContext ctx = LDAPTestContext.init(session);
|
||||||
|
session.userCache().clear();
|
||||||
|
RealmModel appRealm = ctx.getRealm();
|
||||||
|
|
||||||
|
// Test user imported in local storage now
|
||||||
|
UserModel user = session.users().getUserByUsername("jbrown", appRealm);
|
||||||
|
Assert.assertNotNull(session.userLocalStorage().getUserById(user.getId(), appRealm));
|
||||||
|
LDAPTestAsserts.assertUserImported(session.userLocalStorage(), appRealm, "jbrown", "James", "Brown", "jbrown@keycloak.org", "88441");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testModel() {
|
||||||
|
testingClient.server().run(session -> {
|
||||||
|
LDAPTestContext ctx = LDAPTestContext.init(session);
|
||||||
|
session.userCache().clear();
|
||||||
|
RealmModel appRealm = ctx.getRealm();
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
testingClient.server().run(session -> {
|
||||||
|
LDAPTestContext ctx = LDAPTestContext.init(session);
|
||||||
|
RealmModel appRealm = ctx.getRealm();
|
||||||
|
|
||||||
|
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);
|
||||||
|
});
|
||||||
|
|
||||||
|
testingClient.server().run(session -> {
|
||||||
|
LDAPTestContext ctx = LDAPTestContext.init(session);
|
||||||
|
RealmModel appRealm = ctx.getRealm();
|
||||||
|
|
||||||
|
UserModel user = session.users().getUserByUsername("bwilson", appRealm);
|
||||||
|
assertPostalCodes(user.getAttribute("postal_code"), "88441", "77332");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private static 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
|
||||||
|
oauth.clientId("ldap-portal");
|
||||||
|
oauth.redirectUri("/ldap-portal");
|
||||||
|
|
||||||
|
loginPage.open();
|
||||||
|
loginPage.login("bwilson", "Password1");
|
||||||
|
|
||||||
|
String code = new OAuthClient.AuthorizationEndpointResponse(oauth).getCode();
|
||||||
|
OAuthClient.AccessTokenResponse response = oauth.doAccessTokenRequest(code, "password");
|
||||||
|
|
||||||
|
Assert.assertEquals(200, response.getStatusCode());
|
||||||
|
IDToken idToken = oauth.verifyIDToken(response.getIdToken());
|
||||||
|
|
||||||
|
Assert.assertEquals("Bruce Wilson", idToken.getName());
|
||||||
|
Assert.assertEquals("Elm 5", idToken.getOtherClaims().get("street"));
|
||||||
|
Collection postalCodes = (Collection) idToken.getOtherClaims().get("postal_code");
|
||||||
|
Assert.assertEquals(2, postalCodes.size());
|
||||||
|
Assert.assertTrue(postalCodes.contains("88441"));
|
||||||
|
Assert.assertTrue(postalCodes.contains("77332"));
|
||||||
|
|
||||||
|
oauth.doLogout(response.getRefreshToken(), "password");
|
||||||
|
|
||||||
|
// Login as jbrown
|
||||||
|
loginPage.open();
|
||||||
|
loginPage.login("jbrown", "Password1");
|
||||||
|
|
||||||
|
code = new OAuthClient.AuthorizationEndpointResponse(oauth).getCode();
|
||||||
|
response = oauth.doAccessTokenRequest(code, "password");
|
||||||
|
|
||||||
|
org.keycloak.testsuite.Assert.assertEquals(200, response.getStatusCode());
|
||||||
|
idToken = oauth.verifyIDToken(response.getIdToken());
|
||||||
|
|
||||||
|
Assert.assertEquals("James Brown", idToken.getName());
|
||||||
|
Assert.assertNull(idToken.getOtherClaims().get("street"));
|
||||||
|
postalCodes = (Collection) idToken.getOtherClaims().get("postal_code");
|
||||||
|
Assert.assertEquals(1, postalCodes.size());
|
||||||
|
Assert.assertTrue(postalCodes.contains("88441"));
|
||||||
|
Assert.assertFalse(postalCodes.contains("77332"));
|
||||||
|
|
||||||
|
oauth.doLogout(response.getRefreshToken(), "password");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2016 Red Hat, Inc. and/or its affiliates
|
* Copyright 2017 Red Hat, Inc. and/or its affiliates
|
||||||
* and other contributors as indicated by the @author tags.
|
* and other contributors as indicated by the @author tags.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
@ -15,34 +15,33 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.keycloak.testsuite.federation.storage.ldap;
|
package org.keycloak.testsuite.federation.ldap;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import org.jboss.logging.Logger;
|
import org.jboss.arquillian.container.test.api.Deployment;
|
||||||
|
import org.jboss.arquillian.container.test.api.TargetsContainer;
|
||||||
|
import org.jboss.shrinkwrap.api.spec.WebArchive;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.ClassRule;
|
import org.junit.ClassRule;
|
||||||
import org.junit.FixMethodOrder;
|
import org.junit.FixMethodOrder;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.rules.RuleChain;
|
|
||||||
import org.junit.rules.TestRule;
|
|
||||||
import org.junit.runners.MethodSorters;
|
import org.junit.runners.MethodSorters;
|
||||||
import org.keycloak.common.util.MultivaluedHashMap;
|
import org.keycloak.admin.client.resource.UserResource;
|
||||||
import org.keycloak.component.ComponentModel;
|
import org.keycloak.component.ComponentModel;
|
||||||
import org.keycloak.models.KeycloakSession;
|
|
||||||
import org.keycloak.models.LDAPConstants;
|
import org.keycloak.models.LDAPConstants;
|
||||||
import org.keycloak.models.RealmModel;
|
import org.keycloak.models.RealmModel;
|
||||||
import org.keycloak.models.UserModel;
|
import org.keycloak.models.UserModel;
|
||||||
import org.keycloak.services.managers.RealmManager;
|
import org.keycloak.representations.idm.ComponentRepresentation;
|
||||||
import org.keycloak.storage.UserStorageProvider;
|
|
||||||
import org.keycloak.storage.UserStorageProviderModel;
|
|
||||||
import org.keycloak.storage.ldap.LDAPStorageProvider;
|
import org.keycloak.storage.ldap.LDAPStorageProvider;
|
||||||
import org.keycloak.storage.ldap.LDAPStorageProviderFactory;
|
|
||||||
import org.keycloak.storage.ldap.idm.model.LDAPObject;
|
import org.keycloak.storage.ldap.idm.model.LDAPObject;
|
||||||
import org.keycloak.storage.ldap.mappers.LDAPStorageMapper;
|
import org.keycloak.storage.ldap.mappers.LDAPStorageMapper;
|
||||||
import org.keycloak.testsuite.rule.KeycloakRule;
|
import org.keycloak.testsuite.runonserver.RunOnServerDeployment;
|
||||||
import org.keycloak.testsuite.rule.LDAPRule;
|
import org.keycloak.testsuite.util.LDAPRule;
|
||||||
|
import org.keycloak.testsuite.util.LDAPTestConfiguration;
|
||||||
|
import org.keycloak.testsuite.util.LDAPTestUtils;
|
||||||
|
|
||||||
|
import static org.keycloak.testsuite.arquillian.DeploymentTargetModifier.AUTH_SERVER_CURRENT;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test for special scenarios, which don't work on MSAD (eg. renaming user RDN to "sn=john2" )
|
* Test for special scenarios, which don't work on MSAD (eg. renaming user RDN to "sn=john2" )
|
||||||
|
@ -50,45 +49,46 @@ import org.keycloak.testsuite.rule.LDAPRule;
|
||||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||||
*/
|
*/
|
||||||
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
|
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
|
||||||
public class LDAPNoMSADTest {
|
public class LDAPNoMSADTest extends AbstractLDAPTest {
|
||||||
|
|
||||||
private static final Logger log = Logger.getLogger(LDAPProvidersIntegrationTest.class);
|
|
||||||
|
|
||||||
|
|
||||||
// Skip this test on MSAD
|
// Skip this test on MSAD
|
||||||
private static LDAPRule ldapRule = new LDAPRule((Map<String, String> ldapConfig) -> {
|
@ClassRule
|
||||||
|
public static LDAPRule ldapRule = new LDAPRule()
|
||||||
|
.assumeTrue((LDAPTestConfiguration ldapConfig) -> {
|
||||||
|
|
||||||
String vendor = ldapConfig.get(LDAPConstants.VENDOR);
|
String vendor = ldapConfig.getLDAPConfig().get(LDAPConstants.VENDOR);
|
||||||
return (vendor.equals(LDAPConstants.VENDOR_ACTIVE_DIRECTORY));
|
return !LDAPConstants.VENDOR_ACTIVE_DIRECTORY.equals(vendor);
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
private static ComponentModel ldapModel = null;
|
|
||||||
|
|
||||||
|
@Deployment
|
||||||
private static KeycloakRule keycloakRule = new KeycloakRule(new KeycloakRule.KeycloakSetup() {
|
@TargetsContainer(AUTH_SERVER_CURRENT)
|
||||||
|
public static WebArchive deploy() {
|
||||||
|
return RunOnServerDeployment.create(UserResource.class, AbstractLDAPTest.class)
|
||||||
|
.addPackages(true,
|
||||||
|
"org.keycloak.testsuite",
|
||||||
|
"org.keycloak.testsuite.federation.ldap");
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
|
protected LDAPRule getLDAPRule() {
|
||||||
LDAPTestUtils.addLocalUser(manager.getSession(), appRealm, "marykeycloak", "mary@test.com", "password-app");
|
return ldapRule;
|
||||||
|
}
|
||||||
|
|
||||||
MultivaluedHashMap<String,String> ldapConfig = LDAPTestUtils.getLdapRuleConfig(ldapRule);
|
|
||||||
ldapConfig.putSingle(LDAPConstants.SYNC_REGISTRATIONS, "true");
|
|
||||||
ldapConfig.putSingle(LDAPConstants.EDIT_MODE, UserStorageProvider.EditMode.WRITABLE.toString());
|
|
||||||
UserStorageProviderModel model = new UserStorageProviderModel();
|
|
||||||
model.setLastSync(0);
|
|
||||||
model.setChangedSyncPeriod(-1);
|
|
||||||
model.setFullSyncPeriod(-1);
|
|
||||||
model.setName("test-ldap");
|
|
||||||
model.setPriority(0);
|
|
||||||
model.setProviderId(LDAPStorageProviderFactory.PROVIDER_NAME);
|
|
||||||
model.setConfig(ldapConfig);
|
|
||||||
|
|
||||||
ldapModel = appRealm.addComponentModel(model);
|
@Override
|
||||||
LDAPTestUtils.addZipCodeLDAPMapper(appRealm, ldapModel);
|
protected void afterImportTestRealm() {
|
||||||
|
testingClient.server().run(session -> {
|
||||||
|
LDAPTestContext ctx = LDAPTestContext.init(session);
|
||||||
|
RealmModel appRealm = ctx.getRealm();
|
||||||
|
|
||||||
|
LDAPTestUtils.addLocalUser(session, appRealm, "marykeycloak", "mary@test.com", "password-app");
|
||||||
|
|
||||||
|
LDAPTestUtils.addZipCodeLDAPMapper(appRealm, ctx.getLdapModel());
|
||||||
|
|
||||||
// Delete all LDAP users and add some new for testing
|
// Delete all LDAP users and add some new for testing
|
||||||
LDAPStorageProvider ldapFedProvider = LDAPTestUtils.getLdapProvider(session, ldapModel);
|
LDAPStorageProvider ldapFedProvider = LDAPTestUtils.getLdapProvider(session, ctx.getLdapModel());
|
||||||
LDAPTestUtils.removeAllLDAPUsers(ldapFedProvider, appRealm);
|
LDAPTestUtils.removeAllLDAPUsers(ldapFedProvider, appRealm);
|
||||||
|
|
||||||
LDAPObject john = LDAPTestUtils.addLDAPUser(ldapFedProvider, appRealm, "johnkeycloak", "John", "Doe", "john@email.org", null, "1234");
|
LDAPObject john = LDAPTestUtils.addLDAPUser(ldapFedProvider, appRealm, "johnkeycloak", "John", "Doe", "john@email.org", null, "1234");
|
||||||
|
@ -97,31 +97,29 @@ public class LDAPNoMSADTest {
|
||||||
LDAPObject existing = LDAPTestUtils.addLDAPUser(ldapFedProvider, appRealm, "existing", "Existing", "Foo", "existing@email.org", null, "5678");
|
LDAPObject existing = LDAPTestUtils.addLDAPUser(ldapFedProvider, appRealm, "existing", "Existing", "Foo", "existing@email.org", null, "5678");
|
||||||
|
|
||||||
appRealm.getClientByClientId("test-app").setDirectAccessGrantsEnabled(true);
|
appRealm.getClientByClientId("test-app").setDirectAccessGrantsEnabled(true);
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
}
|
||||||
@ClassRule
|
|
||||||
public static TestRule chain = RuleChain
|
|
||||||
.outerRule(ldapRule)
|
|
||||||
.around(keycloakRule);
|
|
||||||
|
|
||||||
|
|
||||||
// KEYCLOAK-4364
|
// KEYCLOAK-4364
|
||||||
@Test
|
@Test
|
||||||
public void testUpdateWithUnmappedRdnAttribute() {
|
public void testUpdateWithUnmappedRdnAttribute() {
|
||||||
KeycloakSession session = keycloakRule.startSession();
|
ComponentRepresentation snMapperRep = findMapperRepByName("last name");
|
||||||
|
|
||||||
|
testingClient.server().run(session -> {
|
||||||
|
LDAPTestContext ctx = LDAPTestContext.init(session);
|
||||||
|
RealmModel appRealm = ctx.getRealm();
|
||||||
ComponentModel snMapper = null;
|
ComponentModel snMapper = null;
|
||||||
try {
|
|
||||||
// Create LDAP user with "sn" attribute in RDN like "sn=johnkeycloak2,ou=People,dc=domain,dc=com"
|
// Create LDAP user with "sn" attribute in RDN like "sn=johnkeycloak2,ou=People,dc=domain,dc=com"
|
||||||
RealmModel appRealm = session.realms().getRealmByName("test");
|
LDAPStorageProvider ldapProvider = LDAPTestUtils.getLdapProvider(session, ctx.getLdapModel());
|
||||||
LDAPStorageProvider ldapProvider = LDAPTestUtils.getLdapProvider(session, ldapModel);
|
|
||||||
LDAPObject john2 = LDAPTestUtils.addLDAPUser(ldapProvider, appRealm, "johnkeycloak2", "john2", "Doe2", "john2@email.org", null, "4321");
|
LDAPObject john2 = LDAPTestUtils.addLDAPUser(ldapProvider, appRealm, "johnkeycloak2", "john2", "Doe2", "john2@email.org", null, "4321");
|
||||||
|
|
||||||
john2.setRdnAttributeName("sn");
|
john2.setRdnAttributeName("sn");
|
||||||
ldapProvider.getLdapIdentityStore().update(john2);
|
ldapProvider.getLdapIdentityStore().update(john2);
|
||||||
|
|
||||||
// Remove "sn" mapper
|
// Remove "sn" mapper
|
||||||
List<ComponentModel> components = appRealm.getComponents(ldapModel.getId(), LDAPStorageMapper.class.getName());
|
List<ComponentModel> components = appRealm.getComponents(ctx.getLdapModel().getId(), LDAPStorageMapper.class.getName());
|
||||||
for (ComponentModel mapper : components) {
|
for (ComponentModel mapper : components) {
|
||||||
if (mapper.getName().equals("last name")) {
|
if (mapper.getName().equals("last name")) {
|
||||||
snMapper = mapper;
|
snMapper = mapper;
|
||||||
|
@ -131,33 +129,24 @@ public class LDAPNoMSADTest {
|
||||||
|
|
||||||
Assert.assertNotNull(snMapper);
|
Assert.assertNotNull(snMapper);
|
||||||
appRealm.removeComponent(snMapper);
|
appRealm.removeComponent(snMapper);
|
||||||
} finally {
|
});
|
||||||
keycloakRule.stopSession(session, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Try to update johnkeycloak2 user. It shouldn't try to update DN
|
// Try to update johnkeycloak2 user. It shouldn't try to update DN
|
||||||
session = keycloakRule.startSession();
|
testingClient.server().run(session -> {
|
||||||
try {
|
LDAPTestContext ctx = LDAPTestContext.init(session);
|
||||||
RealmModel appRealm = session.realms().getRealmByName("test");
|
RealmModel appRealm = ctx.getRealm();
|
||||||
|
|
||||||
UserModel johnkeycloak2 = session.users().getUserByUsername("johnkeycloak2", appRealm);
|
UserModel johnkeycloak2 = session.users().getUserByUsername("johnkeycloak2", appRealm);
|
||||||
Assert.assertNotNull(johnkeycloak2);
|
Assert.assertNotNull(johnkeycloak2);
|
||||||
|
|
||||||
johnkeycloak2.setFirstName("foo2");
|
johnkeycloak2.setFirstName("foo2");
|
||||||
johnkeycloak2.setLastName("foo");
|
johnkeycloak2.setLastName("foo");
|
||||||
} finally {
|
});
|
||||||
keycloakRule.stopSession(session, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Re-create "sn" mapper back
|
// Re-create "sn" mapper back
|
||||||
session = keycloakRule.startSession();
|
snMapperRep.setId(null);
|
||||||
try {
|
testRealm().components().add(snMapperRep);
|
||||||
RealmModel appRealm = session.realms().getRealmByName("test");
|
|
||||||
snMapper.setId(null);
|
|
||||||
appRealm.addComponentModel(snMapper);
|
|
||||||
} finally {
|
|
||||||
keycloakRule.stopSession(session, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
File diff suppressed because it is too large
Load diff
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2016 Red Hat, Inc. and/or its affiliates
|
* Copyright 2017 Red Hat, Inc. and/or its affiliates
|
||||||
* and other contributors as indicated by the @author tags.
|
* and other contributors as indicated by the @author tags.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
@ -15,85 +15,89 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.keycloak.testsuite.federation.storage.ldap;
|
package org.keycloak.testsuite.federation.ldap;
|
||||||
|
|
||||||
|
import org.jboss.arquillian.container.test.api.Deployment;
|
||||||
|
import org.jboss.arquillian.container.test.api.TargetsContainer;
|
||||||
|
import org.jboss.shrinkwrap.api.spec.WebArchive;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.ClassRule;
|
import org.junit.ClassRule;
|
||||||
import org.junit.FixMethodOrder;
|
import org.junit.FixMethodOrder;
|
||||||
import org.junit.Rule;
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.rules.RuleChain;
|
|
||||||
import org.junit.rules.TestRule;
|
|
||||||
import org.junit.runners.MethodSorters;
|
import org.junit.runners.MethodSorters;
|
||||||
import org.keycloak.common.util.MultivaluedHashMap;
|
import org.keycloak.admin.client.resource.UserResource;
|
||||||
import org.keycloak.component.ComponentModel;
|
import org.keycloak.component.ComponentModel;
|
||||||
import org.keycloak.models.GroupModel;
|
import org.keycloak.models.ModelException;
|
||||||
import org.keycloak.models.utils.KeycloakModelUtils;
|
import org.keycloak.representations.idm.ComponentRepresentation;
|
||||||
import org.keycloak.services.managers.UserStorageSyncManager;
|
import org.keycloak.services.managers.UserStorageSyncManager;
|
||||||
import org.keycloak.storage.UserStorageProvider;
|
|
||||||
import org.keycloak.storage.UserStorageProviderModel;
|
import org.keycloak.storage.UserStorageProviderModel;
|
||||||
import org.keycloak.storage.ldap.LDAPStorageProvider;
|
import org.keycloak.storage.ldap.LDAPStorageProvider;
|
||||||
import org.keycloak.storage.ldap.LDAPStorageProviderFactory;
|
|
||||||
import org.keycloak.storage.ldap.idm.model.LDAPObject;
|
import org.keycloak.storage.ldap.idm.model.LDAPObject;
|
||||||
import org.keycloak.storage.ldap.mappers.membership.LDAPGroupMapperMode;
|
import org.keycloak.storage.ldap.mappers.membership.LDAPGroupMapperMode;
|
||||||
import org.keycloak.models.AccountRoles;
|
import org.keycloak.models.AccountRoles;
|
||||||
import org.keycloak.models.ClientModel;
|
import org.keycloak.models.ClientModel;
|
||||||
import org.keycloak.models.Constants;
|
import org.keycloak.models.Constants;
|
||||||
import org.keycloak.models.KeycloakSession;
|
|
||||||
import org.keycloak.models.LDAPConstants;
|
import org.keycloak.models.LDAPConstants;
|
||||||
import org.keycloak.models.ModelException;
|
|
||||||
import org.keycloak.models.RealmModel;
|
import org.keycloak.models.RealmModel;
|
||||||
import org.keycloak.models.RoleModel;
|
import org.keycloak.models.RoleModel;
|
||||||
import org.keycloak.models.UserModel;
|
import org.keycloak.models.UserModel;
|
||||||
import org.keycloak.services.managers.RealmManager;
|
|
||||||
import org.keycloak.storage.ldap.mappers.membership.group.GroupLDAPStorageMapper;
|
|
||||||
import org.keycloak.storage.ldap.mappers.membership.group.GroupMapperConfig;
|
|
||||||
import org.keycloak.storage.ldap.mappers.membership.role.RoleLDAPStorageMapper;
|
import org.keycloak.storage.ldap.mappers.membership.role.RoleLDAPStorageMapper;
|
||||||
import org.keycloak.storage.ldap.mappers.membership.role.RoleMapperConfig;
|
import org.keycloak.storage.ldap.mappers.membership.role.RoleMapperConfig;
|
||||||
import org.keycloak.storage.user.SynchronizationResult;
|
import org.keycloak.storage.user.SynchronizationResult;
|
||||||
import org.keycloak.testsuite.OAuthClient;
|
import org.keycloak.testsuite.runonserver.RunOnServerDeployment;
|
||||||
import org.keycloak.testsuite.pages.AppPage;
|
import org.keycloak.testsuite.util.LDAPRule;
|
||||||
import org.keycloak.testsuite.pages.LoginPage;
|
import org.keycloak.testsuite.util.LDAPTestUtils;
|
||||||
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.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
|
import static org.keycloak.testsuite.arquillian.DeploymentTargetModifier.AUTH_SERVER_CURRENT;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||||
*/
|
*/
|
||||||
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
|
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
|
||||||
public class LDAPRoleMappingsTest {
|
public class LDAPRoleMappingsTest extends AbstractLDAPTest {
|
||||||
|
|
||||||
private static LDAPRule ldapRule = new LDAPRule();
|
|
||||||
|
|
||||||
private static ComponentModel ldapModel = null;
|
@ClassRule
|
||||||
|
public static LDAPRule ldapRule = new LDAPRule();
|
||||||
|
|
||||||
|
|
||||||
|
@Deployment
|
||||||
|
@TargetsContainer(AUTH_SERVER_CURRENT)
|
||||||
|
public static WebArchive deploy() {
|
||||||
|
return RunOnServerDeployment.create(UserResource.class, AbstractLDAPTest.class)
|
||||||
|
.addPackages(true,
|
||||||
|
"org.keycloak.testsuite",
|
||||||
|
"org.keycloak.testsuite.federation.ldap");
|
||||||
|
}
|
||||||
|
|
||||||
private static KeycloakRule keycloakRule = new KeycloakRule(new KeycloakRule.KeycloakSetup() {
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
|
protected LDAPRule getLDAPRule() {
|
||||||
LDAPTestUtils.addLocalUser(manager.getSession(), appRealm, "mary", "mary@test.com", "password-app");
|
return ldapRule;
|
||||||
|
}
|
||||||
MultivaluedHashMap<String,String> ldapConfig = LDAPTestUtils.getLdapRuleConfig(ldapRule);
|
|
||||||
ldapConfig.remove(LDAPConstants.PAGINATION);
|
|
||||||
ldapConfig.putSingle(LDAPConstants.SYNC_REGISTRATIONS, "true");
|
|
||||||
ldapConfig.putSingle(LDAPConstants.EDIT_MODE, UserStorageProvider.EditMode.WRITABLE.toString());
|
|
||||||
UserStorageProviderModel model = new UserStorageProviderModel();
|
|
||||||
model.setLastSync(0);
|
|
||||||
model.setChangedSyncPeriod(-1);
|
|
||||||
model.setFullSyncPeriod(-1);
|
|
||||||
model.setName("test-ldap");
|
|
||||||
model.setPriority(0);
|
|
||||||
model.setProviderId(LDAPStorageProviderFactory.PROVIDER_NAME);
|
|
||||||
model.setConfig(ldapConfig);
|
|
||||||
model.setImportEnabled(true);
|
|
||||||
|
|
||||||
|
|
||||||
ldapModel = appRealm.addComponentModel(model);
|
@Override
|
||||||
|
protected void afterImportTestRealm() {
|
||||||
|
// Disable pagination
|
||||||
|
testingClient.server().run(session -> {
|
||||||
|
LDAPTestContext ctx = LDAPTestContext.init(session);
|
||||||
|
RealmModel appRealm = ctx.getRealm();
|
||||||
|
|
||||||
|
ctx.getLdapModel().put(LDAPConstants.PAGINATION, "false");
|
||||||
|
appRealm.updateComponent(ctx.getLdapModel());
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
testingClient.server().run(session -> {
|
||||||
|
LDAPTestContext ctx = LDAPTestContext.init(session);
|
||||||
|
RealmModel appRealm = ctx.getRealm();
|
||||||
|
UserStorageProviderModel ldapModel = ctx.getLdapModel();
|
||||||
|
|
||||||
|
LDAPTestUtils.addLocalUser(session, appRealm, "mary", "mary@test.com", "password-app");
|
||||||
|
|
||||||
// Delete all LDAP users
|
// Delete all LDAP users
|
||||||
LDAPStorageProvider ldapFedProvider = LDAPTestUtils.getLdapProvider(session, ldapModel);
|
LDAPStorageProvider ldapFedProvider = LDAPTestUtils.getLdapProvider(session, ldapModel);
|
||||||
|
@ -104,8 +108,8 @@ public class LDAPRoleMappingsTest {
|
||||||
|
|
||||||
// Delete all LDAP roles
|
// Delete all LDAP roles
|
||||||
LDAPTestUtils.addOrUpdateRoleLDAPMappers(appRealm, ldapModel, LDAPGroupMapperMode.LDAP_ONLY);
|
LDAPTestUtils.addOrUpdateRoleLDAPMappers(appRealm, ldapModel, LDAPGroupMapperMode.LDAP_ONLY);
|
||||||
LDAPTestUtils.removeAllLDAPRoles(manager.getSession(), appRealm, ldapModel, "realmRolesMapper");
|
LDAPTestUtils.removeAllLDAPRoles(session, appRealm, ldapModel, "realmRolesMapper");
|
||||||
LDAPTestUtils.removeAllLDAPRoles(manager.getSession(), appRealm, ldapModel, "financeRolesMapper");
|
LDAPTestUtils.removeAllLDAPRoles(session, appRealm, ldapModel, "financeRolesMapper");
|
||||||
|
|
||||||
// Add some users for testing
|
// Add some users for testing
|
||||||
LDAPObject john = LDAPTestUtils.addLDAPUser(ldapFedProvider, appRealm, "johnkeycloak", "John", "Doe", "john@email.org", null, "1234");
|
LDAPObject john = LDAPTestUtils.addLDAPUser(ldapFedProvider, appRealm, "johnkeycloak", "John", "Doe", "john@email.org", null, "1234");
|
||||||
|
@ -118,42 +122,26 @@ public class LDAPRoleMappingsTest {
|
||||||
LDAPTestUtils.updateLDAPPassword(ldapFedProvider, rob, "Password1");
|
LDAPTestUtils.updateLDAPPassword(ldapFedProvider, rob, "Password1");
|
||||||
|
|
||||||
// Add some roles for testing
|
// Add some roles for testing
|
||||||
LDAPTestUtils.createLDAPRole(manager.getSession(), appRealm, ldapModel, "realmRolesMapper", "realmRole1");
|
LDAPTestUtils.createLDAPRole(session, appRealm, ldapModel, "realmRolesMapper", "realmRole1");
|
||||||
LDAPTestUtils.createLDAPRole(manager.getSession(), appRealm, ldapModel, "realmRolesMapper", "realmRole2");
|
LDAPTestUtils.createLDAPRole(session, appRealm, ldapModel, "realmRolesMapper", "realmRole2");
|
||||||
LDAPTestUtils.createLDAPRole(manager.getSession(), appRealm, ldapModel, "financeRolesMapper", "financeRole1");
|
LDAPTestUtils.createLDAPRole(session, appRealm, ldapModel, "financeRolesMapper", "financeRole1");
|
||||||
|
|
||||||
// Sync LDAP roles to Keycloak DB
|
// Sync LDAP roles to Keycloak DB
|
||||||
LDAPTestUtils.syncRolesFromLDAP(appRealm, ldapFedProvider, ldapModel);
|
LDAPTestUtils.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
|
@Test
|
||||||
public void test01_ldapOnlyRoleMappings() {
|
public void test01_ldapOnlyRoleMappings() {
|
||||||
KeycloakSession session = keycloakRule.startSession();
|
testingClient.server().run(session -> {
|
||||||
try {
|
LDAPTestContext ctx = LDAPTestContext.init(session);
|
||||||
RealmModel appRealm = session.realms().getRealmByName("test");
|
RealmModel appRealm = ctx.getRealm();
|
||||||
|
|
||||||
LDAPTestUtils.addOrUpdateRoleLDAPMappers(appRealm, ldapModel, LDAPGroupMapperMode.LDAP_ONLY);
|
LDAPTestUtils.addOrUpdateRoleLDAPMappers(appRealm, ctx.getLdapModel(), LDAPGroupMapperMode.LDAP_ONLY);
|
||||||
|
|
||||||
UserModel john = session.users().getUserByUsername("johnkeycloak", appRealm);
|
UserModel john = session.users().getUserByUsername("johnkeycloak", appRealm);
|
||||||
UserModel mary = session.users().getUserByUsername("marykeycloak", appRealm);
|
UserModel mary = session.users().getUserByUsername("marykeycloak", appRealm);
|
||||||
|
@ -234,18 +222,17 @@ public class LDAPRoleMappingsTest {
|
||||||
mary.deleteRoleMapping(realmRole2);
|
mary.deleteRoleMapping(realmRole2);
|
||||||
mary.deleteRoleMapping(realmRole3);
|
mary.deleteRoleMapping(realmRole3);
|
||||||
john.grantRole(manageAccountRole);
|
john.grantRole(manageAccountRole);
|
||||||
} finally {
|
});
|
||||||
keycloakRule.stopSession(session, false);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void test02_readOnlyRoleMappings() {
|
public void test02_readOnlyRoleMappings() {
|
||||||
KeycloakSession session = keycloakRule.startSession();
|
testingClient.server().run(session -> {
|
||||||
try {
|
LDAPTestContext ctx = LDAPTestContext.init(session);
|
||||||
RealmModel appRealm = session.realms().getRealmByName("test");
|
RealmModel appRealm = ctx.getRealm();
|
||||||
|
|
||||||
LDAPTestUtils.addOrUpdateRoleLDAPMappers(appRealm, ldapModel, LDAPGroupMapperMode.READ_ONLY);
|
LDAPTestUtils.addOrUpdateRoleLDAPMappers(appRealm, ctx.getLdapModel(), LDAPGroupMapperMode.READ_ONLY);
|
||||||
|
|
||||||
UserModel mary = session.users().getUserByUsername("marykeycloak", appRealm);
|
UserModel mary = session.users().getUserByUsername("marykeycloak", appRealm);
|
||||||
|
|
||||||
|
@ -257,8 +244,8 @@ public class LDAPRoleMappingsTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add some role mappings directly into LDAP
|
// Add some role mappings directly into LDAP
|
||||||
ComponentModel roleMapperModel = LDAPTestUtils.getSubcomponentByName(appRealm, ldapModel, "realmRolesMapper");
|
ComponentModel roleMapperModel = LDAPTestUtils.getSubcomponentByName(appRealm, ctx.getLdapModel(), "realmRolesMapper");
|
||||||
LDAPStorageProvider ldapProvider = LDAPTestUtils.getLdapProvider(session, ldapModel);
|
LDAPStorageProvider ldapProvider = LDAPTestUtils.getLdapProvider(session, ctx.getLdapModel());
|
||||||
RoleLDAPStorageMapper roleMapper = LDAPTestUtils.getRoleMapper(roleMapperModel, ldapProvider, appRealm);
|
RoleLDAPStorageMapper roleMapper = LDAPTestUtils.getRoleMapper(roleMapperModel, ldapProvider, appRealm);
|
||||||
|
|
||||||
LDAPObject maryLdap = ldapProvider.loadLDAPUserByUsername(appRealm, "marykeycloak");
|
LDAPObject maryLdap = ldapProvider.loadLDAPUserByUsername(appRealm, "marykeycloak");
|
||||||
|
@ -291,13 +278,12 @@ public class LDAPRoleMappingsTest {
|
||||||
// Delete role mappings directly in LDAP
|
// Delete role mappings directly in LDAP
|
||||||
deleteRoleMappingsInLDAP(roleMapper, maryLdap, "realmRole1");
|
deleteRoleMappingsInLDAP(roleMapper, maryLdap, "realmRole1");
|
||||||
deleteRoleMappingsInLDAP(roleMapper, maryLdap, "realmRole2");
|
deleteRoleMappingsInLDAP(roleMapper, maryLdap, "realmRole2");
|
||||||
} finally {
|
});
|
||||||
keycloakRule.stopSession(session, false);
|
|
||||||
}
|
testingClient.server().run(session -> {
|
||||||
|
LDAPTestContext ctx = LDAPTestContext.init(session);
|
||||||
|
RealmModel appRealm = ctx.getRealm();
|
||||||
|
|
||||||
session = keycloakRule.startSession();
|
|
||||||
try {
|
|
||||||
RealmModel appRealm = session.realms().getRealmByName("test");
|
|
||||||
UserModel mary = session.users().getUserByUsername("marykeycloak", appRealm);
|
UserModel mary = session.users().getUserByUsername("marykeycloak", appRealm);
|
||||||
|
|
||||||
// Assert role mappings is not available
|
// Assert role mappings is not available
|
||||||
|
@ -305,22 +291,21 @@ public class LDAPRoleMappingsTest {
|
||||||
Assert.assertFalse(maryRoles.contains(appRealm.getRole("realmRole1")));
|
Assert.assertFalse(maryRoles.contains(appRealm.getRole("realmRole1")));
|
||||||
Assert.assertFalse(maryRoles.contains(appRealm.getRole("realmRole2")));
|
Assert.assertFalse(maryRoles.contains(appRealm.getRole("realmRole2")));
|
||||||
Assert.assertFalse(maryRoles.contains(appRealm.getRole("realmRole3")));
|
Assert.assertFalse(maryRoles.contains(appRealm.getRole("realmRole3")));
|
||||||
} finally {
|
});
|
||||||
keycloakRule.stopSession(session, false);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void test03_importRoleMappings() {
|
public void test03_importRoleMappings() {
|
||||||
KeycloakSession session = keycloakRule.startSession();
|
testingClient.server().run(session -> {
|
||||||
try {
|
LDAPTestContext ctx = LDAPTestContext.init(session);
|
||||||
RealmModel appRealm = session.realms().getRealmByName("test");
|
RealmModel appRealm = ctx.getRealm();
|
||||||
|
|
||||||
LDAPTestUtils.addOrUpdateRoleLDAPMappers(appRealm, ldapModel, LDAPGroupMapperMode.IMPORT);
|
LDAPTestUtils.addOrUpdateRoleLDAPMappers(appRealm, ctx.getLdapModel(), LDAPGroupMapperMode.IMPORT);
|
||||||
|
|
||||||
// Add some role mappings directly in LDAP
|
// Add some role mappings directly in LDAP
|
||||||
ComponentModel roleMapperModel = LDAPTestUtils.getSubcomponentByName(appRealm, ldapModel, "realmRolesMapper");
|
ComponentModel roleMapperModel = LDAPTestUtils.getSubcomponentByName(appRealm, ctx.getLdapModel(), "realmRolesMapper");
|
||||||
LDAPStorageProvider ldapProvider = LDAPTestUtils.getLdapProvider(session, ldapModel);
|
LDAPStorageProvider ldapProvider = LDAPTestUtils.getLdapProvider(session, ctx.getLdapModel());
|
||||||
RoleLDAPStorageMapper roleMapper = LDAPTestUtils.getRoleMapper(roleMapperModel, ldapProvider, appRealm);
|
RoleLDAPStorageMapper roleMapper = LDAPTestUtils.getRoleMapper(roleMapperModel, ldapProvider, appRealm);
|
||||||
|
|
||||||
LDAPObject robLdap = ldapProvider.loadLDAPUserByUsername(appRealm, "robkeycloak");
|
LDAPObject robLdap = ldapProvider.loadLDAPUserByUsername(appRealm, "robkeycloak");
|
||||||
|
@ -360,54 +345,53 @@ public class LDAPRoleMappingsTest {
|
||||||
Assert.assertFalse(robRoles.contains(realmRole1));
|
Assert.assertFalse(robRoles.contains(realmRole1));
|
||||||
Assert.assertFalse(robRoles.contains(realmRole2));
|
Assert.assertFalse(robRoles.contains(realmRole2));
|
||||||
Assert.assertFalse(robRoles.contains(realmRole3));
|
Assert.assertFalse(robRoles.contains(realmRole3));
|
||||||
} finally {
|
});
|
||||||
keycloakRule.stopSession(session, false);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void deleteRoleMappingsInLDAP(RoleLDAPStorageMapper roleMapper, LDAPObject ldapUser, String roleName) {
|
|
||||||
|
private static void deleteRoleMappingsInLDAP(RoleLDAPStorageMapper roleMapper, LDAPObject ldapUser, String roleName) {
|
||||||
LDAPObject ldapRole1 = roleMapper.loadLDAPRoleByName(roleName);
|
LDAPObject ldapRole1 = roleMapper.loadLDAPRoleByName(roleName);
|
||||||
roleMapper.deleteRoleMappingInLDAP(ldapUser, ldapRole1);
|
roleMapper.deleteRoleMappingInLDAP(ldapUser, ldapRole1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* KEYCLOAK-5698
|
* KEYCLOAK-5698
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void test04_syncRoleMappings() {
|
public void test04_syncRoleMappings() {
|
||||||
KeycloakSession session = keycloakRule.startSession();
|
testingClient.server().run(session -> {
|
||||||
try {
|
LDAPTestContext ctx = LDAPTestContext.init(session);
|
||||||
RealmModel appRealm = session.realms().getRealmByName("test");
|
RealmModel appRealm = ctx.getRealm();
|
||||||
|
|
||||||
LDAPStorageProvider ldapProvider = LDAPTestUtils.getLdapProvider(session, ldapModel);
|
LDAPStorageProvider ldapProvider = LDAPTestUtils.getLdapProvider(session, ctx.getLdapModel());
|
||||||
LDAPObject john = LDAPTestUtils.addLDAPUser(ldapProvider, appRealm, "johnrolemapper", "John", "RoleMapper", "johnrolemapper@email.org", null, "1234");
|
LDAPObject john = LDAPTestUtils.addLDAPUser(ldapProvider, appRealm, "johnrolemapper", "John", "RoleMapper", "johnrolemapper@email.org", null, "1234");
|
||||||
LDAPTestUtils.updateLDAPPassword(ldapProvider, john, "Password1");
|
LDAPTestUtils.updateLDAPPassword(ldapProvider, john, "Password1");
|
||||||
LDAPTestUtils.addOrUpdateRoleLDAPMappers(appRealm, ldapModel, LDAPGroupMapperMode.LDAP_ONLY);
|
LDAPTestUtils.addOrUpdateRoleLDAPMappers(appRealm, ctx.getLdapModel(), LDAPGroupMapperMode.LDAP_ONLY);
|
||||||
UserStorageSyncManager usersSyncManager = new UserStorageSyncManager();
|
UserStorageSyncManager usersSyncManager = new UserStorageSyncManager();
|
||||||
SynchronizationResult syncResult = usersSyncManager.syncChangedUsers(session.getKeycloakSessionFactory(), appRealm.getId(), new UserStorageProviderModel(ldapModel));
|
SynchronizationResult syncResult = usersSyncManager.syncChangedUsers(session.getKeycloakSessionFactory(),
|
||||||
|
appRealm.getId(), new UserStorageProviderModel(ctx.getLdapModel()));
|
||||||
syncResult.getAdded();
|
syncResult.getAdded();
|
||||||
} finally {
|
});
|
||||||
keycloakRule.stopSession(session, true);
|
|
||||||
}
|
testingClient.server().run(session -> {
|
||||||
|
LDAPTestContext ctx = LDAPTestContext.init(session);
|
||||||
|
RealmModel appRealm = ctx.getRealm();
|
||||||
|
|
||||||
session = keycloakRule.startSession();
|
|
||||||
try {
|
|
||||||
// make sure user is cached.
|
// make sure user is cached.
|
||||||
RealmModel appRealm = session.realms().getRealmByName("test");
|
|
||||||
UserModel johnRoleMapper = session.users().getUserByUsername("johnrolemapper", appRealm);
|
UserModel johnRoleMapper = session.users().getUserByUsername("johnrolemapper", appRealm);
|
||||||
Assert.assertNotNull(johnRoleMapper);
|
Assert.assertNotNull(johnRoleMapper);
|
||||||
Assert.assertEquals(0, johnRoleMapper.getRealmRoleMappings().size());
|
Assert.assertEquals(0, johnRoleMapper.getRealmRoleMappings().size());
|
||||||
|
|
||||||
} finally {
|
});
|
||||||
keycloakRule.stopSession(session, true);
|
|
||||||
}
|
testingClient.server().run(session -> {
|
||||||
|
LDAPTestContext ctx = LDAPTestContext.init(session);
|
||||||
|
RealmModel appRealm = ctx.getRealm();
|
||||||
|
|
||||||
session = keycloakRule.startSession();
|
|
||||||
try {
|
|
||||||
RealmModel appRealm = session.realms().getRealmByName("test");
|
|
||||||
// Add some role mappings directly in LDAP
|
// Add some role mappings directly in LDAP
|
||||||
LDAPStorageProvider ldapProvider = LDAPTestUtils.getLdapProvider(session, ldapModel);
|
LDAPStorageProvider ldapProvider = LDAPTestUtils.getLdapProvider(session, ctx.getLdapModel());
|
||||||
ComponentModel roleMapperModel = LDAPTestUtils.getSubcomponentByName(appRealm, ldapModel, "realmRolesMapper");
|
ComponentModel roleMapperModel = LDAPTestUtils.getSubcomponentByName(appRealm, ctx.getLdapModel(), "realmRolesMapper");
|
||||||
RoleLDAPStorageMapper roleMapper = LDAPTestUtils.getRoleMapper(roleMapperModel, ldapProvider, appRealm);
|
RoleLDAPStorageMapper roleMapper = LDAPTestUtils.getRoleMapper(roleMapperModel, ldapProvider, appRealm);
|
||||||
|
|
||||||
LDAPObject johnLdap = ldapProvider.loadLDAPUserByUsername(appRealm, "johnrolemapper");
|
LDAPObject johnLdap = ldapProvider.loadLDAPUserByUsername(appRealm, "johnrolemapper");
|
||||||
|
@ -422,19 +406,15 @@ public class LDAPRoleMappingsTest {
|
||||||
Set<RoleModel> johnRoles = johnRoleMapper.getRealmRoleMappings();
|
Set<RoleModel> johnRoles = johnRoleMapper.getRealmRoleMappings();
|
||||||
Assert.assertFalse(johnRoles.contains(realmRole1));
|
Assert.assertFalse(johnRoles.contains(realmRole1));
|
||||||
Assert.assertFalse(johnRoles.contains(realmRole2));
|
Assert.assertFalse(johnRoles.contains(realmRole2));
|
||||||
|
});
|
||||||
|
|
||||||
|
testingClient.server().run(session -> {
|
||||||
|
LDAPTestContext ctx = LDAPTestContext.init(session);
|
||||||
|
RealmModel appRealm = ctx.getRealm();
|
||||||
|
|
||||||
|
|
||||||
} finally {
|
|
||||||
keycloakRule.stopSession(session, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
session = keycloakRule.startSession();
|
|
||||||
try {
|
|
||||||
RealmModel appRealm = session.realms().getRealmByName("test");
|
|
||||||
// Add some role mappings directly in LDAP
|
// Add some role mappings directly in LDAP
|
||||||
LDAPStorageProvider ldapProvider = LDAPTestUtils.getLdapProvider(session, ldapModel);
|
LDAPStorageProvider ldapProvider = LDAPTestUtils.getLdapProvider(session, ctx.getLdapModel());
|
||||||
ComponentModel roleMapperModel = LDAPTestUtils.getSubcomponentByName(appRealm, ldapModel, "realmRolesMapper");
|
ComponentModel roleMapperModel = LDAPTestUtils.getSubcomponentByName(appRealm, ctx.getLdapModel(), "realmRolesMapper");
|
||||||
RoleLDAPStorageMapper roleMapper = LDAPTestUtils.getRoleMapper(roleMapperModel, ldapProvider, appRealm);
|
RoleLDAPStorageMapper roleMapper = LDAPTestUtils.getRoleMapper(roleMapperModel, ldapProvider, appRealm);
|
||||||
|
|
||||||
LDAPObject johnLdap = ldapProvider.loadLDAPUserByUsername(appRealm, "johnrolemapper");
|
LDAPObject johnLdap = ldapProvider.loadLDAPUserByUsername(appRealm, "johnrolemapper");
|
||||||
|
@ -442,14 +422,14 @@ public class LDAPRoleMappingsTest {
|
||||||
roleMapper.addRoleMappingInLDAP("realmRole2", johnLdap);
|
roleMapper.addRoleMappingInLDAP("realmRole2", johnLdap);
|
||||||
|
|
||||||
UserStorageSyncManager usersSyncManager = new UserStorageSyncManager();
|
UserStorageSyncManager usersSyncManager = new UserStorageSyncManager();
|
||||||
SynchronizationResult syncResult = usersSyncManager.syncChangedUsers(session.getKeycloakSessionFactory(), appRealm.getId(), new UserStorageProviderModel(ldapModel));
|
SynchronizationResult syncResult = usersSyncManager.syncChangedUsers(session.getKeycloakSessionFactory(),
|
||||||
} finally {
|
appRealm.getId(), new UserStorageProviderModel(ctx.getLdapModel()));
|
||||||
keycloakRule.stopSession(session, true);
|
});
|
||||||
}
|
|
||||||
|
testingClient.server().run(session -> {
|
||||||
|
LDAPTestContext ctx = LDAPTestContext.init(session);
|
||||||
|
RealmModel appRealm = ctx.getRealm();
|
||||||
|
|
||||||
session = keycloakRule.startSession();
|
|
||||||
try {
|
|
||||||
RealmModel appRealm = session.realms().getRealmByName("test");
|
|
||||||
// Get user and check that he has requested roles from LDAP
|
// Get user and check that he has requested roles from LDAP
|
||||||
UserModel johnRoleMapper = session.users().getUserByUsername("johnrolemapper", appRealm);
|
UserModel johnRoleMapper = session.users().getUserByUsername("johnrolemapper", appRealm);
|
||||||
RoleModel realmRole1 = appRealm.getRole("realmRole1");
|
RoleModel realmRole1 = appRealm.getRole("realmRole1");
|
||||||
|
@ -458,12 +438,7 @@ public class LDAPRoleMappingsTest {
|
||||||
Set<RoleModel> johnRoles = johnRoleMapper.getRealmRoleMappings();
|
Set<RoleModel> johnRoles = johnRoleMapper.getRealmRoleMappings();
|
||||||
Assert.assertTrue(johnRoles.contains(realmRole1));
|
Assert.assertTrue(johnRoles.contains(realmRole1));
|
||||||
Assert.assertTrue(johnRoles.contains(realmRole2));
|
Assert.assertTrue(johnRoles.contains(realmRole2));
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
} finally {
|
|
||||||
keycloakRule.stopSession(session, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -473,38 +448,37 @@ public class LDAPRoleMappingsTest {
|
||||||
// just because it's available on all the LDAP servers
|
// just because it's available on all the LDAP servers
|
||||||
@Test
|
@Test
|
||||||
public void test05_getRolesFromUserMemberOfStrategyTest() throws Exception {
|
public void test05_getRolesFromUserMemberOfStrategyTest() throws Exception {
|
||||||
KeycloakSession session = keycloakRule.startSession();
|
ComponentRepresentation realmRoleMapper = findMapperRepByName("realmRolesMapper");
|
||||||
MultivaluedHashMap<String, String> oldRoleMapperCfg;
|
|
||||||
try {
|
testingClient.server().run(session -> {
|
||||||
LDAPStorageProvider ldapProvider = LDAPTestUtils.getLdapProvider(session, ldapModel);
|
LDAPTestContext ctx = LDAPTestContext.init(session);
|
||||||
RealmModel appRealm = session.realms().getRealmByName("test");
|
RealmModel appRealm = ctx.getRealm();
|
||||||
|
|
||||||
// Create street attribute mapper
|
// Create street attribute mapper
|
||||||
LDAPTestUtils.addUserAttributeMapper(appRealm, ldapModel, "streetMapper", "street", LDAPConstants.STREET);
|
LDAPTestUtils.addUserAttributeMapper(appRealm, ctx.getLdapModel(), "streetMapper", "street", LDAPConstants.STREET);
|
||||||
|
|
||||||
// Find DN of "group1"
|
// Find DN of "group1"
|
||||||
ComponentModel mapperModel = LDAPTestUtils.getSubcomponentByName(appRealm,ldapModel, "realmRolesMapper");
|
ComponentModel mapperModel = LDAPTestUtils.getSubcomponentByName(appRealm, ctx.getLdapModel(), "realmRolesMapper");
|
||||||
oldRoleMapperCfg = new MultivaluedHashMap<>(mapperModel.getConfig());
|
RoleLDAPStorageMapper roleMapper = LDAPTestUtils.getRoleMapper(mapperModel, ctx.getLdapProvider(), appRealm);
|
||||||
RoleLDAPStorageMapper roleMapper = LDAPTestUtils.getRoleMapper(mapperModel, ldapProvider, appRealm);
|
|
||||||
LDAPObject ldapRole = roleMapper.loadLDAPRoleByName("realmRole1");
|
LDAPObject ldapRole = roleMapper.loadLDAPRoleByName("realmRole1");
|
||||||
String ldapRoleDN = ldapRole.getDn().toString();
|
String ldapRoleDN = ldapRole.getDn().toString();
|
||||||
|
|
||||||
// Create new user in LDAP. Add him some "street" referencing existing LDAP Group
|
// Create new user in LDAP. Add him some "street" referencing existing LDAP Group
|
||||||
LDAPObject carlos = LDAPTestUtils.addLDAPUser(ldapProvider, appRealm, "carloskeycloak", "Carlos", "Doel", "carlos.doel@email.org", ldapRoleDN, "1234");
|
LDAPObject carlos = LDAPTestUtils.addLDAPUser(ctx.getLdapProvider(), appRealm, "carloskeycloak", "Carlos", "Doel", "carlos.doel@email.org", ldapRoleDN, "1234");
|
||||||
LDAPTestUtils.updateLDAPPassword(ldapProvider, carlos, "Password1");
|
LDAPTestUtils.updateLDAPPassword(ctx.getLdapProvider(), carlos, "Password1");
|
||||||
|
|
||||||
// Update group mapper
|
// Update group mapper
|
||||||
LDAPTestUtils.updateGroupMapperConfigOptions(mapperModel,
|
LDAPTestUtils.updateGroupMapperConfigOptions(mapperModel,
|
||||||
RoleMapperConfig.USER_ROLES_RETRIEVE_STRATEGY, RoleMapperConfig.GET_ROLES_FROM_USER_MEMBEROF_ATTRIBUTE,
|
RoleMapperConfig.USER_ROLES_RETRIEVE_STRATEGY, RoleMapperConfig.GET_ROLES_FROM_USER_MEMBEROF_ATTRIBUTE,
|
||||||
RoleMapperConfig.MEMBEROF_LDAP_ATTRIBUTE, LDAPConstants.STREET);
|
RoleMapperConfig.MEMBEROF_LDAP_ATTRIBUTE, LDAPConstants.STREET);
|
||||||
appRealm.updateComponent(mapperModel);
|
appRealm.updateComponent(mapperModel);
|
||||||
} finally {
|
});
|
||||||
keycloakRule.stopSession(session, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
session = keycloakRule.startSession();
|
ComponentRepresentation streetMapper = findMapperRepByName("streetMapper");
|
||||||
try {
|
|
||||||
RealmModel appRealm = session.realms().getRealmByName("test");
|
testingClient.server().run(session -> {
|
||||||
|
LDAPTestContext ctx = LDAPTestContext.init(session);
|
||||||
|
RealmModel appRealm = ctx.getRealm();
|
||||||
|
|
||||||
// Get user in Keycloak. Ensure that he is member of requested group
|
// Get user in Keycloak. Ensure that he is member of requested group
|
||||||
UserModel carlos = session.users().getUserByUsername("carloskeycloak", appRealm);
|
UserModel carlos = session.users().getUserByUsername("carloskeycloak", appRealm);
|
||||||
|
@ -515,26 +489,20 @@ public class LDAPRoleMappingsTest {
|
||||||
|
|
||||||
Assert.assertTrue(carlosRoles.contains(realmRole1));
|
Assert.assertTrue(carlosRoles.contains(realmRole1));
|
||||||
Assert.assertFalse(carlosRoles.contains(realmRole2));
|
Assert.assertFalse(carlosRoles.contains(realmRole2));
|
||||||
|
});
|
||||||
|
|
||||||
// Revert mappers
|
// Revert mappers
|
||||||
ComponentModel streetMapper = LDAPTestUtils.getSubcomponentByName(appRealm,ldapModel, "streetMapper");
|
testRealm().components().component(streetMapper.getId()).remove();
|
||||||
appRealm.removeComponent(streetMapper);
|
testRealm().components().component(realmRoleMapper.getId()).remove();
|
||||||
|
realmRoleMapper.setId(null);
|
||||||
ComponentModel roleMapper = LDAPTestUtils.getSubcomponentByName(appRealm,ldapModel, "realmRolesMapper");
|
testRealm().components().add(realmRoleMapper);
|
||||||
roleMapper.setConfig(oldRoleMapperCfg);
|
|
||||||
appRealm.updateComponent(roleMapper);
|
|
||||||
} finally {
|
|
||||||
keycloakRule.stopSession(session, true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void test06_newUserDefaultRolesImportModeTest() throws Exception {
|
public void test06_newUserDefaultRolesImportModeTest() throws Exception {
|
||||||
|
testingClient.server().run(session -> {
|
||||||
// Check user group memberships
|
LDAPTestContext ctx = LDAPTestContext.init(session);
|
||||||
KeycloakSession session = keycloakRule.startSession();
|
RealmModel appRealm = ctx.getRealm();
|
||||||
try {
|
|
||||||
RealmModel appRealm = session.realms().getRealmByName("test");
|
|
||||||
|
|
||||||
// Set a default role on the realm
|
// Set a default role on the realm
|
||||||
appRealm.addDefaultRole("realmRole1");
|
appRealm.addDefaultRole("realmRole1");
|
||||||
|
@ -552,8 +520,6 @@ public class LDAPRoleMappingsTest {
|
||||||
Assert.assertTrue(davidRoles.contains(defaultRole));
|
Assert.assertTrue(davidRoles.contains(defaultRole));
|
||||||
Assert.assertFalse(davidRoles.contains(realmRole2));
|
Assert.assertFalse(davidRoles.contains(realmRole2));
|
||||||
|
|
||||||
} finally {
|
});
|
||||||
keycloakRule.stopSession(session, true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2016 Red Hat, Inc. and/or its affiliates
|
* Copyright 2017 Red Hat, Inc. and/or its affiliates
|
||||||
* and other contributors as indicated by the @author tags.
|
* and other contributors as indicated by the @author tags.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
@ -15,128 +15,96 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.keycloak.testsuite.federation.storage.ldap;
|
package org.keycloak.testsuite.federation.ldap;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import org.junit.After;
|
import org.jboss.arquillian.container.test.api.Deployment;
|
||||||
|
import org.jboss.arquillian.container.test.api.TargetsContainer;
|
||||||
|
import org.jboss.shrinkwrap.api.spec.WebArchive;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.Before;
|
|
||||||
import org.junit.ClassRule;
|
import org.junit.ClassRule;
|
||||||
import org.junit.FixMethodOrder;
|
import org.junit.FixMethodOrder;
|
||||||
import org.junit.Rule;
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.rules.RuleChain;
|
|
||||||
import org.junit.rules.TestRule;
|
|
||||||
import org.junit.runners.MethodSorters;
|
import org.junit.runners.MethodSorters;
|
||||||
import org.keycloak.OAuth2Constants;
|
import org.keycloak.OAuth2Constants;
|
||||||
import org.keycloak.admin.client.Keycloak;
|
import org.keycloak.admin.client.resource.UserResource;
|
||||||
import org.keycloak.component.ComponentModel;
|
import org.keycloak.component.ComponentModel;
|
||||||
import org.keycloak.models.Constants;
|
|
||||||
import org.keycloak.models.GroupModel;
|
import org.keycloak.models.GroupModel;
|
||||||
import org.keycloak.models.KeycloakSession;
|
|
||||||
import org.keycloak.models.LDAPConstants;
|
import org.keycloak.models.LDAPConstants;
|
||||||
import org.keycloak.models.RealmModel;
|
import org.keycloak.models.RealmModel;
|
||||||
import org.keycloak.models.UserModel;
|
import org.keycloak.models.UserModel;
|
||||||
import org.keycloak.models.utils.KeycloakModelUtils;
|
import org.keycloak.models.utils.KeycloakModelUtils;
|
||||||
import org.keycloak.representations.idm.UserRepresentation;
|
import org.keycloak.representations.idm.UserRepresentation;
|
||||||
import org.keycloak.storage.ldap.LDAPStorageProvider;
|
|
||||||
import org.keycloak.storage.ldap.idm.model.LDAPObject;
|
import org.keycloak.storage.ldap.idm.model.LDAPObject;
|
||||||
import org.keycloak.storage.ldap.mappers.membership.LDAPGroupMapperMode;
|
import org.keycloak.storage.ldap.mappers.membership.LDAPGroupMapperMode;
|
||||||
import org.keycloak.storage.ldap.mappers.membership.group.GroupLDAPStorageMapperFactory;
|
import org.keycloak.storage.ldap.mappers.membership.group.GroupLDAPStorageMapperFactory;
|
||||||
import org.keycloak.storage.ldap.mappers.membership.group.GroupMapperConfig;
|
import org.keycloak.storage.ldap.mappers.membership.group.GroupMapperConfig;
|
||||||
import org.keycloak.testsuite.OAuthClient;
|
|
||||||
import org.keycloak.testsuite.pages.AppPage;
|
import org.keycloak.testsuite.pages.AppPage;
|
||||||
import org.keycloak.testsuite.pages.LoginPage;
|
import org.keycloak.testsuite.runonserver.RunOnServerDeployment;
|
||||||
import org.keycloak.testsuite.pages.RegisterPage;
|
import org.keycloak.testsuite.util.LDAPRule;
|
||||||
import org.keycloak.testsuite.rule.KeycloakRule;
|
import org.keycloak.testsuite.util.LDAPTestConfiguration;
|
||||||
import org.keycloak.testsuite.rule.LDAPRule;
|
import org.keycloak.testsuite.util.LDAPTestUtils;
|
||||||
import org.keycloak.testsuite.rule.WebResource;
|
|
||||||
import org.keycloak.testsuite.rule.WebRule;
|
|
||||||
import org.openqa.selenium.WebDriver;
|
|
||||||
|
|
||||||
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.MASTER;
|
import static org.keycloak.testsuite.arquillian.DeploymentTargetModifier.AUTH_SERVER_CURRENT;
|
||||||
import static org.keycloak.models.AdminRoles.ADMIN;
|
import static org.keycloak.testsuite.util.LDAPTestUtils.getGroupDescriptionLDAPAttrName;
|
||||||
import static org.keycloak.testsuite.Constants.AUTH_SERVER_ROOT;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||||
*/
|
*/
|
||||||
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
|
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
|
||||||
public class LDAPSpecialCharsTest {
|
public class LDAPSpecialCharsTest extends AbstractLDAPTest {
|
||||||
|
|
||||||
|
|
||||||
// Skip this test for MSAD with sAMAccountName as it is not allowed to use specialCharacters in sAMAccountName attribute
|
// Skip this test for MSAD with sAMAccountName as it is not allowed to use specialCharacters in sAMAccountName attribute
|
||||||
private static LDAPRule ldapRule = new LDAPRule((Map<String, String> ldapConfig) -> {
|
@ClassRule
|
||||||
|
public static LDAPRule ldapRule = new LDAPRule()
|
||||||
|
.assumeTrue((LDAPTestConfiguration ldapConfig) -> {
|
||||||
|
|
||||||
String vendor = ldapConfig.get(LDAPConstants.VENDOR);
|
String vendor = ldapConfig.getLDAPConfig().get(LDAPConstants.VENDOR);
|
||||||
String usernameAttr = ldapConfig.get(LDAPConstants.USERNAME_LDAP_ATTRIBUTE);
|
String usernameAttr = ldapConfig.getLDAPConfig().get(LDAPConstants.USERNAME_LDAP_ATTRIBUTE);
|
||||||
|
|
||||||
return (vendor.equals(LDAPConstants.VENDOR_ACTIVE_DIRECTORY) && usernameAttr.equalsIgnoreCase(LDAPConstants.SAM_ACCOUNT_NAME));
|
boolean skip = (vendor.equals(LDAPConstants.VENDOR_ACTIVE_DIRECTORY) && usernameAttr.equalsIgnoreCase(LDAPConstants.SAM_ACCOUNT_NAME));
|
||||||
|
return !skip;
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
static ComponentModel ldapModel = null;
|
|
||||||
static String descriptionAttrName = null;
|
|
||||||
|
|
||||||
|
@Deployment
|
||||||
private static KeycloakRule keycloakRule = new KeycloakRule(new LDAPGroupMapperTest.GroupTestKeycloakSetup(ldapRule) {
|
@TargetsContainer(AUTH_SERVER_CURRENT)
|
||||||
|
public static WebArchive deploy() {
|
||||||
|
return RunOnServerDeployment.create(UserResource.class, AbstractLDAPTest.class)
|
||||||
|
.addPackages(true,
|
||||||
|
"org.keycloak.testsuite",
|
||||||
|
"org.keycloak.testsuite.federation.ldap");
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void postSetup(RealmModel appRealm, LDAPStorageProvider ldapProvider) {
|
protected LDAPRule getLDAPRule() {
|
||||||
LDAPSpecialCharsTest.ldapModel = this.ldapModel;
|
return ldapRule;
|
||||||
LDAPSpecialCharsTest.descriptionAttrName = this.descriptionAttrName;
|
}
|
||||||
|
|
||||||
LDAPObject groupSpecialCharacters = LDAPTestUtils.createLDAPGroup(session, appRealm, ldapModel, "group-spec,ia*l_characžter)s", descriptionAttrName, "group-special-characters");
|
|
||||||
|
@Override
|
||||||
|
protected void afterImportTestRealm() {
|
||||||
|
testingClient.testing().ldap(TEST_REALM_NAME).prepareGroupsLDAPTest();
|
||||||
|
|
||||||
|
testingClient.server().run(session -> {
|
||||||
|
LDAPTestContext ctx = LDAPTestContext.init(session);
|
||||||
|
RealmModel appRealm = ctx.getRealm();
|
||||||
|
|
||||||
|
String descriptionAttrName = getGroupDescriptionLDAPAttrName(ctx.getLdapProvider());
|
||||||
|
|
||||||
|
LDAPObject groupSpecialCharacters = LDAPTestUtils.createLDAPGroup(session, appRealm, ctx.getLdapModel(), "group-spec,ia*l_characžter)s", descriptionAttrName, "group-special-characters");
|
||||||
|
|
||||||
// Resync LDAP groups to Keycloak DB
|
// Resync LDAP groups to Keycloak DB
|
||||||
ComponentModel mapperModel = LDAPTestUtils.getSubcomponentByName(appRealm, ldapModel, "groupsMapper");
|
ComponentModel mapperModel = LDAPTestUtils.getSubcomponentByName(appRealm, ctx.getLdapModel(), "groupsMapper");
|
||||||
new GroupLDAPStorageMapperFactory().create(session, mapperModel).syncDataFromFederationProviderToKeycloak(appRealm);
|
new GroupLDAPStorageMapperFactory().create(session, mapperModel).syncDataFromFederationProviderToKeycloak(appRealm);
|
||||||
|
|
||||||
LDAPObject james2 = LDAPTestUtils.addLDAPUser(ldapProvider, appRealm, "jamees,key*cložak)ppp", "James2", "Brown2", "james2@email.org", null, "89102");
|
LDAPObject james2 = LDAPTestUtils.addLDAPUser(ctx.getLdapProvider(), appRealm, "jamees,key*cložak)ppp", "James2", "Brown2", "james2@email.org", null, "89102");
|
||||||
LDAPTestUtils.updateLDAPPassword(ldapProvider, james2, "Password1");
|
LDAPTestUtils.updateLDAPPassword(ctx.getLdapProvider(), james2, "Password1");
|
||||||
}
|
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
@ClassRule
|
|
||||||
public static TestRule chain = RuleChain
|
|
||||||
.outerRule(ldapRule)
|
|
||||||
.around(keycloakRule);
|
|
||||||
|
|
||||||
|
|
||||||
protected Keycloak adminClient;
|
|
||||||
|
|
||||||
@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;
|
|
||||||
|
|
||||||
|
|
||||||
@Before
|
|
||||||
public void before() {
|
|
||||||
adminClient = Keycloak.getInstance(AUTH_SERVER_ROOT, MASTER, ADMIN, ADMIN, Constants.ADMIN_CLI_CLIENT_ID);
|
|
||||||
}
|
|
||||||
|
|
||||||
@After
|
|
||||||
public void after() {
|
|
||||||
adminClient.close();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -149,6 +117,7 @@ public class LDAPSpecialCharsTest {
|
||||||
assertContainsUsername(users, "johnkeycloak");
|
assertContainsUsername(users, "johnkeycloak");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void assertContainsUsername(List<UserRepresentation> users, String username) {
|
private void assertContainsUsername(List<UserRepresentation> users, String username) {
|
||||||
boolean found = users.stream().filter((UserRepresentation user) -> {
|
boolean found = users.stream().filter((UserRepresentation user) -> {
|
||||||
|
|
||||||
|
@ -182,11 +151,11 @@ public class LDAPSpecialCharsTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void test03_specialCharUserJoiningSpecialCharGroup() {
|
public void test03_specialCharUserJoiningSpecialCharGroup() {
|
||||||
KeycloakSession session = keycloakRule.startSession();
|
testingClient.server().run(session -> {
|
||||||
try {
|
LDAPTestContext ctx = LDAPTestContext.init(session);
|
||||||
RealmModel appRealm = session.realms().getRealmByName("test");
|
RealmModel appRealm = ctx.getRealm();
|
||||||
|
|
||||||
ComponentModel mapperModel = LDAPTestUtils.getSubcomponentByName(appRealm,ldapModel, "groupsMapper");
|
ComponentModel mapperModel = LDAPTestUtils.getSubcomponentByName(appRealm, ctx.getLdapModel(), "groupsMapper");
|
||||||
LDAPTestUtils.updateGroupMapperConfigOptions(mapperModel, GroupMapperConfig.MODE, LDAPGroupMapperMode.LDAP_ONLY.toString());
|
LDAPTestUtils.updateGroupMapperConfigOptions(mapperModel, GroupMapperConfig.MODE, LDAPGroupMapperMode.LDAP_ONLY.toString());
|
||||||
appRealm.updateComponent(mapperModel);
|
appRealm.updateComponent(mapperModel);
|
||||||
|
|
||||||
|
@ -201,13 +170,13 @@ public class LDAPSpecialCharsTest {
|
||||||
|
|
||||||
specialUser.joinGroup(specialGroup);
|
specialUser.joinGroup(specialGroup);
|
||||||
|
|
||||||
// 3 - Check that group mappings are in LDAP and hence available through federation
|
// 2 - Check that group mappings are in LDAP and hence available through federation
|
||||||
|
|
||||||
Set<GroupModel> userGroups = specialUser.getGroups();
|
Set<GroupModel> userGroups = specialUser.getGroups();
|
||||||
Assert.assertEquals(1, userGroups.size());
|
Assert.assertEquals(1, userGroups.size());
|
||||||
Assert.assertTrue(userGroups.contains(specialGroup));
|
Assert.assertTrue(userGroups.contains(specialGroup));
|
||||||
|
|
||||||
// 4 - Check through userProvider
|
// 3 - Check through userProvider
|
||||||
List<UserModel> groupMembers = session.users().getGroupMembers(appRealm, specialGroup, 0, 10);
|
List<UserModel> groupMembers = session.users().getGroupMembers(appRealm, specialGroup, 0, 10);
|
||||||
|
|
||||||
Assert.assertEquals(1, groupMembers.size());
|
Assert.assertEquals(1, groupMembers.size());
|
||||||
|
@ -220,9 +189,7 @@ public class LDAPSpecialCharsTest {
|
||||||
userGroups = specialUser.getGroups();
|
userGroups = specialUser.getGroups();
|
||||||
Assert.assertEquals(0, userGroups.size());
|
Assert.assertEquals(0, userGroups.size());
|
||||||
|
|
||||||
} finally {
|
});
|
||||||
keycloakRule.stopSession(session, false);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -0,0 +1,358 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2017 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.jboss.arquillian.container.test.api.Deployment;
|
||||||
|
import org.jboss.arquillian.container.test.api.TargetsContainer;
|
||||||
|
import org.jboss.shrinkwrap.api.spec.WebArchive;
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.ClassRule;
|
||||||
|
import org.junit.FixMethodOrder;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runners.MethodSorters;
|
||||||
|
import org.keycloak.admin.client.resource.UserResource;
|
||||||
|
import org.keycloak.component.ComponentModel;
|
||||||
|
import org.keycloak.representations.idm.ComponentRepresentation;
|
||||||
|
import org.keycloak.services.managers.UserStorageSyncManager;
|
||||||
|
import org.keycloak.storage.ldap.idm.model.LDAPObject;
|
||||||
|
import org.keycloak.models.KeycloakSessionFactory;
|
||||||
|
import org.keycloak.models.LDAPConstants;
|
||||||
|
import org.keycloak.models.RealmModel;
|
||||||
|
import org.keycloak.models.UserModel;
|
||||||
|
import org.keycloak.models.UserProvider;
|
||||||
|
import org.keycloak.models.cache.UserCache;
|
||||||
|
import org.keycloak.storage.UserStorageProviderModel;
|
||||||
|
import org.keycloak.storage.ldap.LDAPStorageProvider;
|
||||||
|
import org.keycloak.storage.ldap.LDAPStorageProviderFactory;
|
||||||
|
import org.keycloak.storage.user.SynchronizationResult;
|
||||||
|
import org.keycloak.testsuite.runonserver.RunOnServerDeployment;
|
||||||
|
import org.keycloak.testsuite.util.LDAPRule;
|
||||||
|
import org.keycloak.testsuite.util.LDAPTestUtils;
|
||||||
|
import org.keycloak.testsuite.util.WaitUtils;
|
||||||
|
|
||||||
|
import static org.keycloak.testsuite.arquillian.DeploymentTargetModifier.AUTH_SERVER_CURRENT;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||||
|
*/
|
||||||
|
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
|
||||||
|
public class LDAPSyncTest extends AbstractLDAPTest {
|
||||||
|
|
||||||
|
@ClassRule
|
||||||
|
public static LDAPRule ldapRule = new LDAPRule();
|
||||||
|
|
||||||
|
@Deployment
|
||||||
|
@TargetsContainer(AUTH_SERVER_CURRENT)
|
||||||
|
public static WebArchive deploy() {
|
||||||
|
return RunOnServerDeployment.create(UserResource.class, AbstractLDAPTest.class)
|
||||||
|
.addPackages(true,
|
||||||
|
"org.keycloak.testsuite",
|
||||||
|
"org.keycloak.testsuite.federation.ldap");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected LDAPRule getLDAPRule() {
|
||||||
|
return ldapRule;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void afterImportTestRealm() {
|
||||||
|
// Don't sync registrations in this test
|
||||||
|
testingClient.server().run(session -> {
|
||||||
|
LDAPTestContext ctx = LDAPTestContext.init(session);
|
||||||
|
RealmModel appRealm = ctx.getRealm();
|
||||||
|
|
||||||
|
ComponentModel ldapModel = LDAPTestUtils.getLdapProviderModel(session, appRealm);
|
||||||
|
ldapModel.put(LDAPConstants.SYNC_REGISTRATIONS, "false");
|
||||||
|
appRealm.updateComponent(ldapModel);
|
||||||
|
});
|
||||||
|
|
||||||
|
testingClient.server().run(session -> {
|
||||||
|
LDAPTestContext ctx = LDAPTestContext.init(session);
|
||||||
|
RealmModel appRealm = ctx.getRealm();
|
||||||
|
|
||||||
|
LDAPTestUtils.addLocalUser(session, appRealm, "marykeycloak", "mary@test.com", "password-app");
|
||||||
|
|
||||||
|
ComponentModel ldapModel = LDAPTestUtils.getLdapProviderModel(session, appRealm);
|
||||||
|
|
||||||
|
LDAPTestUtils.addZipCodeLDAPMapper(appRealm, ldapModel);
|
||||||
|
|
||||||
|
// Delete all LDAP users and add 5 new users for testing
|
||||||
|
LDAPStorageProvider ldapFedProvider = LDAPTestUtils.getLdapProvider(session, ldapModel);
|
||||||
|
LDAPTestUtils.removeAllLDAPUsers(ldapFedProvider, appRealm);
|
||||||
|
|
||||||
|
for (int i=1 ; i<=5 ; i++) {
|
||||||
|
LDAPObject ldapUser = LDAPTestUtils.addLDAPUser(ldapFedProvider, appRealm, "user" + i, "User" + i + "FN", "User" + i + "LN", "user" + i + "@email.org", null, "12" + i);
|
||||||
|
LDAPTestUtils.updateLDAPPassword(ldapFedProvider, ldapUser, "Password1");
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// @Test
|
||||||
|
// public void test01runit() throws Exception {
|
||||||
|
// Thread.sleep(10000000);
|
||||||
|
// }
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test01LDAPSync() {
|
||||||
|
// wait a bit
|
||||||
|
WaitUtils.pause(ldapRule.getSleepTime());
|
||||||
|
|
||||||
|
// Sync 5 users from LDAP
|
||||||
|
testingClient.server().run(session -> {
|
||||||
|
LDAPTestContext ctx = LDAPTestContext.init(session);
|
||||||
|
|
||||||
|
UserStorageSyncManager usersSyncManager = new UserStorageSyncManager();
|
||||||
|
KeycloakSessionFactory sessionFactory = session.getKeycloakSessionFactory();
|
||||||
|
SynchronizationResult syncResult = usersSyncManager.syncAllUsers(sessionFactory, "test", ctx.getLdapModel());
|
||||||
|
LDAPTestAsserts.assertSyncEquals(syncResult, 5, 0, 0, 0);
|
||||||
|
});
|
||||||
|
|
||||||
|
testingClient.server().run(session -> {
|
||||||
|
LDAPTestContext ctx = LDAPTestContext.init(session);
|
||||||
|
RealmModel testRealm = ctx.getRealm();
|
||||||
|
UserProvider userProvider = session.userLocalStorage();
|
||||||
|
|
||||||
|
// Assert users imported
|
||||||
|
LDAPTestAsserts.assertUserImported(userProvider, testRealm, "user1", "User1FN", "User1LN", "user1@email.org", "121");
|
||||||
|
LDAPTestAsserts.assertUserImported(userProvider, testRealm, "user2", "User2FN", "User2LN", "user2@email.org", "122");
|
||||||
|
LDAPTestAsserts.assertUserImported(userProvider, testRealm, "user3", "User3FN", "User3LN", "user3@email.org", "123");
|
||||||
|
LDAPTestAsserts.assertUserImported(userProvider, testRealm, "user4", "User4FN", "User4LN", "user4@email.org", "124");
|
||||||
|
LDAPTestAsserts.assertUserImported(userProvider, testRealm, "user5", "User5FN", "User5LN", "user5@email.org", "125");
|
||||||
|
|
||||||
|
// Assert lastSync time updated
|
||||||
|
Assert.assertTrue(ctx.getLdapModel().getLastSync() > 0);
|
||||||
|
for (UserStorageProviderModel persistentFedModel : testRealm.getUserStorageProviders()) {
|
||||||
|
if (LDAPStorageProviderFactory.PROVIDER_NAME.equals(persistentFedModel.getProviderId())) {
|
||||||
|
Assert.assertTrue(persistentFedModel.getLastSync() > 0);
|
||||||
|
} else {
|
||||||
|
// Dummy provider has still 0
|
||||||
|
Assert.assertEquals(0, persistentFedModel.getLastSync());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// wait a bit
|
||||||
|
WaitUtils.pause(ldapRule.getSleepTime());
|
||||||
|
|
||||||
|
testingClient.server().run(session -> {
|
||||||
|
LDAPTestContext ctx = LDAPTestContext.init(session);
|
||||||
|
RealmModel testRealm = ctx.getRealm();
|
||||||
|
UserProvider userProvider = session.userLocalStorage();
|
||||||
|
UserStorageSyncManager usersSyncManager = new UserStorageSyncManager();
|
||||||
|
|
||||||
|
// Add user to LDAP and update 'user5' in LDAP
|
||||||
|
LDAPTestUtils.addLDAPUser(ctx.getLdapProvider(), testRealm, "user6", "User6FN", "User6LN", "user6@email.org", null, "126");
|
||||||
|
LDAPObject ldapUser5 = ctx.getLdapProvider().loadLDAPUserByUsername(testRealm, "user5");
|
||||||
|
// NOTE: Changing LDAP attributes directly here
|
||||||
|
ldapUser5.setSingleAttribute(LDAPConstants.EMAIL, "user5Updated@email.org");
|
||||||
|
ldapUser5.setSingleAttribute(LDAPConstants.POSTAL_CODE, "521");
|
||||||
|
ctx.getLdapProvider().getLdapIdentityStore().update(ldapUser5);
|
||||||
|
|
||||||
|
// Assert still old users in local provider
|
||||||
|
LDAPTestAsserts.assertUserImported(userProvider, testRealm, "user5", "User5FN", "User5LN", "user5@email.org", "125");
|
||||||
|
Assert.assertNull(userProvider.getUserByUsername("user6", testRealm));
|
||||||
|
|
||||||
|
// Trigger partial sync
|
||||||
|
KeycloakSessionFactory sessionFactory = session.getKeycloakSessionFactory();
|
||||||
|
SynchronizationResult syncResult = usersSyncManager.syncChangedUsers(sessionFactory, "test", ctx.getLdapModel());
|
||||||
|
LDAPTestAsserts.assertSyncEquals(syncResult, 1, 1, 0, 0);
|
||||||
|
});
|
||||||
|
|
||||||
|
testingClient.server().run(session -> {
|
||||||
|
RealmModel testRealm = session.realms().getRealm("test");
|
||||||
|
UserProvider userProvider = session.userLocalStorage();
|
||||||
|
// Assert users updated in local provider
|
||||||
|
LDAPTestAsserts.assertUserImported(userProvider, testRealm, "user5", "User5FN", "User5LN", "user5updated@email.org", "521");
|
||||||
|
LDAPTestAsserts.assertUserImported(userProvider, testRealm, "user6", "User6FN", "User6LN", "user6@email.org", "126");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test02duplicateUsernameAndEmailSync() {
|
||||||
|
|
||||||
|
testingClient.server().run(session -> {
|
||||||
|
LDAPTestContext ctx = LDAPTestContext.init(session);
|
||||||
|
|
||||||
|
LDAPTestUtils.addLocalUser(session, ctx.getRealm(), "user7", "user7@email.org", "password");
|
||||||
|
|
||||||
|
// Add user to LDAP with duplicated username "user7"
|
||||||
|
LDAPObject duplicatedLdapUser = LDAPTestUtils.addLDAPUser(ctx.getLdapProvider(), ctx.getRealm(), "user7", "User7FN", "User7LN", "user7-something@email.org", null, "126");
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
testingClient.server().run(session -> {
|
||||||
|
LDAPTestContext ctx = LDAPTestContext.init(session);
|
||||||
|
|
||||||
|
// Assert syncing from LDAP fails due to duplicated username
|
||||||
|
SynchronizationResult result = new UserStorageSyncManager().syncAllUsers(session.getKeycloakSessionFactory(), "test", ctx.getLdapModel());
|
||||||
|
Assert.assertEquals(1, result.getFailed());
|
||||||
|
|
||||||
|
// Remove "user7" from LDAP
|
||||||
|
LDAPObject duplicatedLdapUser = ctx.getLdapProvider().loadLDAPUserByUsername(ctx.getRealm(), "user7");
|
||||||
|
ctx.getLdapProvider().getLdapIdentityStore().remove(duplicatedLdapUser);
|
||||||
|
|
||||||
|
// Add user to LDAP with duplicated email "user7@email.org"
|
||||||
|
duplicatedLdapUser = LDAPTestUtils.addLDAPUser(ctx.getLdapProvider(), ctx.getRealm(), "user7-something", "User7FNN", "User7LNL", "user7@email.org", null, "126");
|
||||||
|
});
|
||||||
|
|
||||||
|
testingClient.server().run(session -> {
|
||||||
|
LDAPTestContext ctx = LDAPTestContext.init(session);
|
||||||
|
|
||||||
|
// Assert syncing from LDAP fails due to duplicated email
|
||||||
|
SynchronizationResult result = new UserStorageSyncManager().syncAllUsers(session.getKeycloakSessionFactory(), "test", ctx.getLdapModel());
|
||||||
|
Assert.assertEquals(1, result.getFailed());
|
||||||
|
Assert.assertNull(session.userLocalStorage().getUserByUsername("user7-something", ctx.getRealm()));
|
||||||
|
|
||||||
|
// Update LDAP user to avoid duplicated email
|
||||||
|
LDAPObject duplicatedLdapUser = ctx.getLdapProvider().loadLDAPUserByUsername(ctx.getRealm(), "user7-something");
|
||||||
|
duplicatedLdapUser.setSingleAttribute(LDAPConstants.EMAIL, "user7-changed@email.org");
|
||||||
|
ctx.getLdapProvider().getLdapIdentityStore().update(duplicatedLdapUser);
|
||||||
|
|
||||||
|
// Assert user successfully synced now
|
||||||
|
result = new UserStorageSyncManager().syncAllUsers(session.getKeycloakSessionFactory(), "test", ctx.getLdapModel());
|
||||||
|
Assert.assertEquals(0, result.getFailed());
|
||||||
|
});
|
||||||
|
|
||||||
|
// Assert user was imported. Use another transaction for that
|
||||||
|
testingClient.server().run(session -> {
|
||||||
|
RealmModel testRealm = session.realms().getRealm("test");
|
||||||
|
LDAPTestAsserts.assertUserImported(session.userLocalStorage(), testRealm, "user7-something", "User7FNN", "User7LNL", "user7-changed@email.org", "126");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// KEYCLOAK-1571
|
||||||
|
@Test
|
||||||
|
public void test03SameUUIDAndUsernameSync() {
|
||||||
|
String origUuidAttrName = testingClient.server().fetch(session -> {
|
||||||
|
LDAPTestContext ctx = LDAPTestContext.init(session);
|
||||||
|
|
||||||
|
// Remove all users from model
|
||||||
|
for (UserModel user : session.userLocalStorage().getUsers(ctx.getRealm(), true)) {
|
||||||
|
session.userLocalStorage().removeUser(ctx.getRealm(), user);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Change name of UUID attribute to same like usernameAttribute
|
||||||
|
String uidAttrName = ctx.getLdapProvider().getLdapIdentityStore().getConfig().getUsernameLdapAttribute();
|
||||||
|
String origUuidAttrNamee = ctx.getLdapModel().get(LDAPConstants.UUID_LDAP_ATTRIBUTE);
|
||||||
|
ctx.getLdapModel().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
|
||||||
|
ctx.getLdapModel().put(LDAPConstants.BATCH_SIZE_FOR_SYNC, "10");
|
||||||
|
ctx.getRealm().updateComponent(ctx.getLdapModel());
|
||||||
|
|
||||||
|
return origUuidAttrNamee;
|
||||||
|
|
||||||
|
}, String.class);
|
||||||
|
|
||||||
|
testingClient.server().run(session -> {
|
||||||
|
LDAPTestContext ctx = LDAPTestContext.init(session);
|
||||||
|
|
||||||
|
KeycloakSessionFactory sessionFactory = session.getKeycloakSessionFactory();
|
||||||
|
SynchronizationResult syncResult = new UserStorageSyncManager().syncAllUsers(sessionFactory, "test", ctx.getLdapModel());
|
||||||
|
Assert.assertEquals(0, syncResult.getFailed());
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
testingClient.server().run(session -> {
|
||||||
|
LDAPTestContext ctx = LDAPTestContext.init(session);
|
||||||
|
|
||||||
|
// Assert users imported with correct LDAP_ID
|
||||||
|
LDAPTestAsserts.assertUserImported(session.users(), ctx.getRealm(), "user1", "User1FN", "User1LN", "user1@email.org", "121");
|
||||||
|
LDAPTestAsserts.assertUserImported(session.users(), ctx.getRealm(), "user2", "User2FN", "User2LN", "user2@email.org", "122");
|
||||||
|
UserModel user1 = session.users().getUserByUsername("user1", ctx.getRealm());
|
||||||
|
Assert.assertEquals("user1", user1.getFirstAttribute(LDAPConstants.LDAP_ID));
|
||||||
|
});
|
||||||
|
|
||||||
|
// Revert config changes
|
||||||
|
ComponentRepresentation ldapRep = testRealm().components().component(ldapModelId).toRepresentation();
|
||||||
|
if (origUuidAttrName == null) {
|
||||||
|
ldapRep.getConfig().remove(LDAPConstants.UUID_LDAP_ATTRIBUTE);
|
||||||
|
} else {
|
||||||
|
ldapRep.getConfig().putSingle(LDAPConstants.UUID_LDAP_ATTRIBUTE, origUuidAttrName);
|
||||||
|
}
|
||||||
|
testRealm().components().component(ldapModelId).update(ldapRep);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// KEYCLOAK-1728
|
||||||
|
@Test
|
||||||
|
public void test04MissingLDAPUsernameSync() {
|
||||||
|
String origUsernameAttrName = testingClient.server().fetch(session -> {
|
||||||
|
LDAPTestContext ctx = LDAPTestContext.init(session);
|
||||||
|
|
||||||
|
// Remove all users from model
|
||||||
|
for (UserModel user : session.userLocalStorage().getUsers(ctx.getRealm(), true)) {
|
||||||
|
System.out.println("trying to delete user: " + user.getUsername());
|
||||||
|
UserCache userCache = session.userCache();
|
||||||
|
if (userCache != null) {
|
||||||
|
userCache.evict(ctx.getRealm(), user);
|
||||||
|
}
|
||||||
|
session.userLocalStorage().removeUser(ctx.getRealm(), user);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add street mapper and add some user including street
|
||||||
|
ComponentModel streetMapper = LDAPTestUtils.addUserAttributeMapper(ctx.getRealm(), ctx.getLdapModel(), "streetMapper", "street", LDAPConstants.STREET);
|
||||||
|
LDAPObject streetUser = LDAPTestUtils.addLDAPUser(ctx.getLdapProvider(), ctx.getRealm(), "user8", "User8FN", "User8LN", "user8@email.org", "user8street", "126");
|
||||||
|
|
||||||
|
// Change name of username attribute name to street
|
||||||
|
String origUsernameAttrNamee = ctx.getLdapModel().get(LDAPConstants.USERNAME_LDAP_ATTRIBUTE);
|
||||||
|
ctx.getLdapModel().getConfig().putSingle(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
|
||||||
|
ctx.getLdapModel().put(LDAPConstants.BATCH_SIZE_FOR_SYNC, "10");
|
||||||
|
ctx.getRealm().updateComponent(ctx.getLdapModel());
|
||||||
|
|
||||||
|
return origUsernameAttrNamee;
|
||||||
|
|
||||||
|
}, String.class);
|
||||||
|
|
||||||
|
// Just user8 synced. All others failed to sync
|
||||||
|
testingClient.server().run(session -> {
|
||||||
|
LDAPTestContext ctx = LDAPTestContext.init(session);
|
||||||
|
|
||||||
|
KeycloakSessionFactory sessionFactory = session.getKeycloakSessionFactory();
|
||||||
|
SynchronizationResult syncResult = new UserStorageSyncManager().syncAllUsers(sessionFactory, "test", ctx.getLdapModel());
|
||||||
|
Assert.assertEquals(1, syncResult.getAdded());
|
||||||
|
Assert.assertTrue(syncResult.getFailed() > 0);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Revert config changes
|
||||||
|
ComponentRepresentation ldapRep = testRealm().components().component(ldapModelId).toRepresentation();
|
||||||
|
if (origUsernameAttrName == null) {
|
||||||
|
ldapRep.getConfig().remove(LDAPConstants.USERNAME_LDAP_ATTRIBUTE);
|
||||||
|
} else {
|
||||||
|
ldapRep.getConfig().putSingle(LDAPConstants.USERNAME_LDAP_ATTRIBUTE, origUsernameAttrName);
|
||||||
|
}
|
||||||
|
testRealm().components().component(ldapModelId).update(ldapRep);
|
||||||
|
|
||||||
|
testingClient.server().run(session -> {
|
||||||
|
LDAPTestContext ctx = LDAPTestContext.init(session);
|
||||||
|
|
||||||
|
// Revert config changes
|
||||||
|
ComponentModel streetMapper = LDAPTestUtils.getSubcomponentByName(ctx.getRealm(), ctx.getLdapModel(), "streetMapper");
|
||||||
|
ctx.getRealm().removeComponent(streetMapper);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,64 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2017 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.models.RealmModel;
|
||||||
|
import org.keycloak.models.UserModel;
|
||||||
|
import org.keycloak.models.UserProvider;
|
||||||
|
import org.keycloak.representations.idm.SynchronizationResultRepresentation;
|
||||||
|
import org.keycloak.storage.user.SynchronizationResult;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Common LDAP asserts
|
||||||
|
*
|
||||||
|
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||||
|
*/
|
||||||
|
public class LDAPTestAsserts {
|
||||||
|
|
||||||
|
public static UserModel assertUserImported(UserProvider userProvider, RealmModel realm, String username, String expectedFirstName, String expectedLastName, String expectedEmail, String expectedPostalCode) {
|
||||||
|
UserModel user = userProvider.getUserByUsername(username, realm);
|
||||||
|
assertLoaded(user, username, expectedFirstName, expectedLastName, expectedEmail, expectedPostalCode);
|
||||||
|
return user;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static void assertLoaded(UserModel user, String username, String expectedFirstName, String expectedLastName, String expectedEmail, String expectedPostalCode) {
|
||||||
|
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"));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static void assertSyncEquals(SynchronizationResult 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());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static void assertSyncEquals(SynchronizationResultRepresentation 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());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,62 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2017 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.component.ComponentModel;
|
||||||
|
import org.keycloak.models.KeycloakSession;
|
||||||
|
import org.keycloak.models.RealmModel;
|
||||||
|
import org.keycloak.storage.UserStorageProviderModel;
|
||||||
|
import org.keycloak.storage.ldap.LDAPStorageProvider;
|
||||||
|
import org.keycloak.testsuite.util.LDAPTestUtils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||||
|
*/
|
||||||
|
public class LDAPTestContext {
|
||||||
|
|
||||||
|
private final RealmModel realm;
|
||||||
|
private final UserStorageProviderModel ldapModel;
|
||||||
|
private final LDAPStorageProvider ldapProvider;
|
||||||
|
|
||||||
|
public static LDAPTestContext init(KeycloakSession session) {
|
||||||
|
RealmModel testRealm = session.realms().getRealm(AbstractLDAPTest.TEST_REALM_NAME);
|
||||||
|
ComponentModel ldapCompModel = LDAPTestUtils.getLdapProviderModel(session, testRealm);
|
||||||
|
UserStorageProviderModel ldapModel = new UserStorageProviderModel(ldapCompModel);
|
||||||
|
LDAPStorageProvider ldapProvider = LDAPTestUtils.getLdapProvider(session, ldapModel);
|
||||||
|
return new LDAPTestContext(testRealm, ldapModel, ldapProvider);
|
||||||
|
}
|
||||||
|
|
||||||
|
private LDAPTestContext(RealmModel realm, UserStorageProviderModel ldapModel, LDAPStorageProvider ldapProvider) {
|
||||||
|
this.realm = realm;
|
||||||
|
this.ldapModel = ldapModel;
|
||||||
|
this.ldapProvider = ldapProvider;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public RealmModel getRealm() {
|
||||||
|
return realm;
|
||||||
|
}
|
||||||
|
|
||||||
|
public UserStorageProviderModel getLdapModel() {
|
||||||
|
return ldapModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LDAPStorageProvider getLdapProvider() {
|
||||||
|
return ldapProvider;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,57 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2017 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.noimport;
|
||||||
|
|
||||||
|
import org.junit.FixMethodOrder;
|
||||||
|
import org.junit.Ignore;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runners.MethodSorters;
|
||||||
|
import org.keycloak.testsuite.federation.ldap.LDAPGroupMapperTest;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||||
|
*/
|
||||||
|
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
|
||||||
|
public class LDAPGroupMapperNoImportTest extends LDAPGroupMapperTest {
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean isImportEnabled() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Override
|
||||||
|
public void test01_ldapOnlyGroupMappings() {
|
||||||
|
test01_ldapOnlyGroupMappings(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Override
|
||||||
|
public void test02_readOnlyGroupMappings() {
|
||||||
|
test02_readOnlyGroupMappings(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Override
|
||||||
|
@Ignore
|
||||||
|
public void test03_importGroupMappings() {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,61 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2017 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.noimport;
|
||||||
|
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.FixMethodOrder;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runners.MethodSorters;
|
||||||
|
import org.keycloak.models.RealmModel;
|
||||||
|
import org.keycloak.models.UserModel;
|
||||||
|
import org.keycloak.testsuite.federation.ldap.LDAPMultipleAttributesTest;
|
||||||
|
import org.keycloak.testsuite.federation.ldap.LDAPTestAsserts;
|
||||||
|
import org.keycloak.testsuite.federation.ldap.LDAPTestContext;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||||
|
*/
|
||||||
|
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
|
||||||
|
public class LDAPMultipleAttributesNoImportTest extends LDAPMultipleAttributesTest {
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean isImportEnabled() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testUserImport() {
|
||||||
|
testingClient.server().run(session -> {
|
||||||
|
LDAPTestContext ctx = LDAPTestContext.init(session);
|
||||||
|
session.userCache().clear();
|
||||||
|
RealmModel appRealm = ctx.getRealm();
|
||||||
|
|
||||||
|
// Test user NOT imported in local storage now. He is available just through "session.users()"
|
||||||
|
UserModel user = session.users().getUserByUsername("jbrown", appRealm);
|
||||||
|
Assert.assertNotNull(user);
|
||||||
|
Assert.assertNull(session.userLocalStorage().getUserById(user.getId(), appRealm));
|
||||||
|
LDAPTestAsserts.assertUserImported(session.users(), appRealm, "jbrown", "James", "Brown", "jbrown@keycloak.org", "88441");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,246 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2017 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.noimport;
|
||||||
|
|
||||||
|
import javax.ws.rs.core.Response;
|
||||||
|
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.FixMethodOrder;
|
||||||
|
import org.junit.Ignore;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runners.MethodSorters;
|
||||||
|
import org.keycloak.component.ComponentModel;
|
||||||
|
import org.keycloak.models.LDAPConstants;
|
||||||
|
import org.keycloak.models.RealmModel;
|
||||||
|
import org.keycloak.models.UserModel;
|
||||||
|
import org.keycloak.models.utils.KeycloakModelUtils;
|
||||||
|
import org.keycloak.models.utils.ModelToRepresentation;
|
||||||
|
import org.keycloak.representations.idm.ComponentRepresentation;
|
||||||
|
import org.keycloak.representations.idm.UserRepresentation;
|
||||||
|
import org.keycloak.storage.StorageId;
|
||||||
|
import org.keycloak.storage.ldap.LDAPStorageProvider;
|
||||||
|
import org.keycloak.storage.ldap.mappers.FullNameLDAPStorageMapper;
|
||||||
|
import org.keycloak.storage.ldap.mappers.FullNameLDAPStorageMapperFactory;
|
||||||
|
import org.keycloak.storage.ldap.mappers.LDAPStorageMapper;
|
||||||
|
import org.keycloak.storage.ldap.mappers.UserAttributeLDAPStorageMapper;
|
||||||
|
import org.keycloak.testsuite.federation.ldap.LDAPProvidersIntegrationTest;
|
||||||
|
import org.keycloak.testsuite.federation.ldap.LDAPTestAsserts;
|
||||||
|
import org.keycloak.testsuite.federation.ldap.LDAPTestContext;
|
||||||
|
import org.keycloak.testsuite.util.LDAPTestUtils;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||||
|
*/
|
||||||
|
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
|
||||||
|
public class LDAPProvidersIntegrationNoImportTest extends LDAPProvidersIntegrationTest {
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean isImportEnabled() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void assertFederatedUserLink(UserRepresentation user) {
|
||||||
|
StorageId storageId = new StorageId(user.getId());
|
||||||
|
Assert.assertFalse(storageId.isLocal());
|
||||||
|
Assert.assertEquals(ldapModelId, storageId.getProviderId());
|
||||||
|
|
||||||
|
// TODO: It should be possibly LDAP_ID (LDAP UUID) used as an externalId inside storageId...
|
||||||
|
Assert.assertEquals(storageId.getExternalId(), user.getUsername());
|
||||||
|
Assert.assertNull(user.getFederationLink());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// No sense to test this in no-import mode
|
||||||
|
@Test
|
||||||
|
@Ignore
|
||||||
|
@Override
|
||||||
|
public void testRemoveImportedUsers() {
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Override
|
||||||
|
public void testSearch() {
|
||||||
|
testingClient.server().run(session -> {
|
||||||
|
LDAPTestContext ctx = LDAPTestContext.init(session);
|
||||||
|
RealmModel appRealm = ctx.getRealm();
|
||||||
|
|
||||||
|
LDAPTestUtils.addLDAPUser(ctx.getLdapProvider(), appRealm, "username1", "John1", "Doel1", "user1@email.org", null, "121");
|
||||||
|
LDAPTestUtils.addLDAPUser(ctx.getLdapProvider(), appRealm, "username2", "John2", "Doel2", "user2@email.org", null, "122");
|
||||||
|
LDAPTestUtils.addLDAPUser(ctx.getLdapProvider(), appRealm, "username3", "John3", "Doel3", "user3@email.org", null, "123");
|
||||||
|
LDAPTestUtils.addLDAPUser(ctx.getLdapProvider(), appRealm, "username4", "John4", "Doel4", "user4@email.org", null, "124");
|
||||||
|
|
||||||
|
// search by username
|
||||||
|
UserModel user = session.users().searchForUser("username1", appRealm).get(0);
|
||||||
|
LDAPTestAsserts.assertLoaded(user, "username1", "John1", "Doel1", "user1@email.org", "121");
|
||||||
|
|
||||||
|
// search by email
|
||||||
|
user = session.users().searchForUser("user2@email.org", appRealm).get(0);
|
||||||
|
LDAPTestAsserts.assertLoaded(user, "username2", "John2", "Doel2", "user2@email.org", "122");
|
||||||
|
|
||||||
|
// search by lastName
|
||||||
|
user = session.users().searchForUser("Doel3", appRealm).get(0);
|
||||||
|
LDAPTestAsserts.assertLoaded(user, "username3", "John3", "Doel3", "user3@email.org", "123");
|
||||||
|
|
||||||
|
// search by firstName + lastName
|
||||||
|
user = session.users().searchForUser("John4 Doel4", appRealm).get(0);
|
||||||
|
LDAPTestAsserts.assertLoaded(user, "username4", "John4", "Doel4", "user4@email.org", "124");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// No need to test this in no-import mode. There won't be any users in localStorage after LDAP search
|
||||||
|
@Test
|
||||||
|
@Ignore
|
||||||
|
@Override
|
||||||
|
public void testSearchByAttributes() {
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Override
|
||||||
|
public void testSearchWithCustomLDAPFilter() {
|
||||||
|
// Add custom filter for searching users
|
||||||
|
testingClient.server().run(session -> {
|
||||||
|
LDAPTestContext ctx = LDAPTestContext.init(session);
|
||||||
|
RealmModel appRealm = ctx.getRealm();
|
||||||
|
|
||||||
|
ctx.getLdapModel().getConfig().putSingle(LDAPConstants.CUSTOM_USER_SEARCH_FILTER, "(|(mail=user5@email.org)(mail=user6@email.org))");
|
||||||
|
appRealm.updateComponent(ctx.getLdapModel());
|
||||||
|
});
|
||||||
|
|
||||||
|
testingClient.server().run(session -> {
|
||||||
|
LDAPTestContext ctx = LDAPTestContext.init(session);
|
||||||
|
RealmModel appRealm = ctx.getRealm();
|
||||||
|
|
||||||
|
LDAPTestUtils.addLDAPUser(ctx.getLdapProvider(), appRealm, "username5", "John5", "Doel5", "user5@email.org", null, "125");
|
||||||
|
LDAPTestUtils.addLDAPUser(ctx.getLdapProvider(), appRealm, "username6", "John6", "Doel6", "user6@email.org", null, "126");
|
||||||
|
LDAPTestUtils.addLDAPUser(ctx.getLdapProvider(), appRealm, "username7", "John7", "Doel7", "user7@email.org", null, "127");
|
||||||
|
|
||||||
|
// search by email
|
||||||
|
UserModel user = session.users().searchForUser("user5@email.org", appRealm).get(0);
|
||||||
|
LDAPTestAsserts.assertLoaded(user, "username5", "John5", "Doel5", "user5@email.org", "125");
|
||||||
|
|
||||||
|
user = session.users().searchForUser("John6 Doel6", appRealm).get(0);
|
||||||
|
LDAPTestAsserts.assertLoaded(user, "username6", "John6", "Doel6", "user6@email.org", "126");
|
||||||
|
|
||||||
|
Assert.assertTrue(session.users().searchForUser("user7@email.org", appRealm).isEmpty());
|
||||||
|
Assert.assertTrue(session.users().searchForUser("John7 Doel7", appRealm).isEmpty());
|
||||||
|
|
||||||
|
// Remove custom filter
|
||||||
|
ctx.getLdapModel().getConfig().remove(LDAPConstants.CUSTOM_USER_SEARCH_FILTER);
|
||||||
|
appRealm.updateComponent(ctx.getLdapModel());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Override
|
||||||
|
@Ignore // Unsynced mode doesn't have much sense in no-import
|
||||||
|
public void testUnsynced() throws Exception {
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Override
|
||||||
|
@Ignore // Unlinking users doesn't have much sense in no-import
|
||||||
|
public void zzTestUnlinkUsers() {
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testFullNameMapperWriteOnly() {
|
||||||
|
ComponentRepresentation firstNameMapperRep = testingClient.server().fetch(session -> {
|
||||||
|
LDAPTestContext ctx = LDAPTestContext.init(session);
|
||||||
|
RealmModel appRealm = ctx.getRealm();
|
||||||
|
|
||||||
|
// 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)
|
||||||
|
ComponentModel ldapModel = LDAPTestUtils.getLdapProviderModel(session, appRealm);
|
||||||
|
LDAPStorageProvider ldapFedProvider = LDAPTestUtils.getLdapProvider(session, ldapModel);
|
||||||
|
LDAPTestUtils.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)
|
||||||
|
ComponentModel firstNameMapper = LDAPTestUtils.getSubcomponentByName(appRealm, ldapModel, "first name");
|
||||||
|
String ldapFirstNameAttributeName = firstNameMapper.getConfig().getFirst(UserAttributeLDAPStorageMapper.LDAP_ATTRIBUTE);
|
||||||
|
appRealm.removeComponent(firstNameMapper);
|
||||||
|
|
||||||
|
ComponentRepresentation firstNameMapperRepp = ModelToRepresentation.toRepresentation(session, firstNameMapper, true);
|
||||||
|
|
||||||
|
ComponentModel fullNameMapperModel = KeycloakModelUtils.createComponentModel("full name", ldapModel.getId(), FullNameLDAPStorageMapperFactory.PROVIDER_ID, LDAPStorageMapper.class.getName(),
|
||||||
|
FullNameLDAPStorageMapper.LDAP_FULL_NAME_ATTRIBUTE, ldapFirstNameAttributeName,
|
||||||
|
FullNameLDAPStorageMapper.READ_ONLY, "false");
|
||||||
|
appRealm.addComponentModel(fullNameMapperModel);
|
||||||
|
|
||||||
|
return firstNameMapperRepp;
|
||||||
|
}, ComponentRepresentation.class);
|
||||||
|
|
||||||
|
testingClient.server().run(session -> {
|
||||||
|
LDAPTestContext ctx = LDAPTestContext.init(session);
|
||||||
|
RealmModel appRealm = ctx.getRealm();
|
||||||
|
|
||||||
|
// Assert user is successfully imported in Keycloak DB now with correct firstName and lastName
|
||||||
|
LDAPTestAsserts.assertUserImported(session.users(), appRealm, "fullname", "James", "Dee", "fullname@email.org", "4578");
|
||||||
|
|
||||||
|
// change mapper to writeOnly
|
||||||
|
ComponentModel fullNameMapperModel = LDAPTestUtils.getSubcomponentByName(appRealm, ctx.getLdapModel(), "full name");
|
||||||
|
fullNameMapperModel.getConfig().putSingle(FullNameLDAPStorageMapper.WRITE_ONLY, "true");
|
||||||
|
appRealm.updateComponent(fullNameMapperModel);
|
||||||
|
});
|
||||||
|
|
||||||
|
// User will be changed in LDAP too
|
||||||
|
testingClient.server().run(session -> {
|
||||||
|
LDAPTestContext ctx = LDAPTestContext.init(session);
|
||||||
|
RealmModel appRealm = ctx.getRealm();
|
||||||
|
|
||||||
|
UserModel fullnameUser = session.users().getUserByUsername("fullname", appRealm);
|
||||||
|
fullnameUser.setFirstName("James2");
|
||||||
|
fullnameUser.setLastName("Dee2");
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
// Assert changed user available in Keycloak, but his firstName is null (due the fullnameMapper is write-only and firstName mapper is removed)
|
||||||
|
testingClient.server().run(session -> {
|
||||||
|
LDAPTestContext ctx = LDAPTestContext.init(session);
|
||||||
|
RealmModel appRealm = ctx.getRealm();
|
||||||
|
|
||||||
|
// Assert user is successfully imported in Keycloak DB now with correct firstName and lastName
|
||||||
|
LDAPTestAsserts.assertUserImported(session.users(), appRealm, "fullname", null, "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
|
||||||
|
ComponentModel fullNameMapperModel = LDAPTestUtils.getSubcomponentByName(appRealm, ctx.getLdapModel(), "full name");
|
||||||
|
appRealm.removeComponent(fullNameMapperModel);
|
||||||
|
});
|
||||||
|
|
||||||
|
firstNameMapperRep.setId(null);
|
||||||
|
Response response = testRealm().components().add(firstNameMapperRep);
|
||||||
|
Assert.assertEquals(201, response.getStatus());
|
||||||
|
response.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2016 Red Hat, Inc. and/or its affiliates
|
* Copyright 2017 Red Hat, Inc. and/or its affiliates
|
||||||
* and other contributors as indicated by the @author tags.
|
* and other contributors as indicated by the @author tags.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
@ -15,77 +15,93 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.keycloak.testsuite.federation.storage.ldap.noimport;
|
package org.keycloak.testsuite.federation.ldap.noimport;
|
||||||
|
|
||||||
|
import org.jboss.arquillian.container.test.api.Deployment;
|
||||||
|
import org.jboss.arquillian.container.test.api.TargetsContainer;
|
||||||
|
import org.jboss.shrinkwrap.api.spec.WebArchive;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.ClassRule;
|
import org.junit.ClassRule;
|
||||||
import org.junit.FixMethodOrder;
|
import org.junit.FixMethodOrder;
|
||||||
import org.junit.Rule;
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.rules.RuleChain;
|
|
||||||
import org.junit.rules.TestRule;
|
|
||||||
import org.junit.runners.MethodSorters;
|
import org.junit.runners.MethodSorters;
|
||||||
import org.keycloak.common.util.MultivaluedHashMap;
|
import org.keycloak.admin.client.resource.UserResource;
|
||||||
import org.keycloak.component.ComponentModel;
|
import org.keycloak.component.ComponentModel;
|
||||||
import org.keycloak.models.AccountRoles;
|
import org.keycloak.models.AccountRoles;
|
||||||
import org.keycloak.models.ClientModel;
|
import org.keycloak.models.ClientModel;
|
||||||
import org.keycloak.models.Constants;
|
import org.keycloak.models.Constants;
|
||||||
import org.keycloak.models.KeycloakSession;
|
|
||||||
import org.keycloak.models.LDAPConstants;
|
import org.keycloak.models.LDAPConstants;
|
||||||
import org.keycloak.models.ModelException;
|
|
||||||
import org.keycloak.models.RealmModel;
|
import org.keycloak.models.RealmModel;
|
||||||
import org.keycloak.models.RoleModel;
|
import org.keycloak.models.RoleModel;
|
||||||
import org.keycloak.models.UserModel;
|
import org.keycloak.models.UserModel;
|
||||||
import org.keycloak.services.managers.RealmManager;
|
|
||||||
import org.keycloak.storage.UserStorageProvider;
|
|
||||||
import org.keycloak.storage.UserStorageProviderModel;
|
import org.keycloak.storage.UserStorageProviderModel;
|
||||||
import org.keycloak.storage.ldap.LDAPStorageProvider;
|
import org.keycloak.storage.ldap.LDAPStorageProvider;
|
||||||
import org.keycloak.storage.ldap.LDAPStorageProviderFactory;
|
|
||||||
import org.keycloak.storage.ldap.idm.model.LDAPObject;
|
import org.keycloak.storage.ldap.idm.model.LDAPObject;
|
||||||
import org.keycloak.storage.ldap.mappers.membership.LDAPGroupMapperMode;
|
import org.keycloak.storage.ldap.mappers.membership.LDAPGroupMapperMode;
|
||||||
import org.keycloak.storage.ldap.mappers.membership.role.RoleLDAPStorageMapper;
|
import org.keycloak.storage.ldap.mappers.membership.role.RoleLDAPStorageMapper;
|
||||||
import org.keycloak.testsuite.OAuthClient;
|
import org.keycloak.testsuite.federation.ldap.AbstractLDAPTest;
|
||||||
import org.keycloak.testsuite.federation.storage.ldap.LDAPTestUtils;
|
import org.keycloak.testsuite.federation.ldap.LDAPTestContext;
|
||||||
import org.keycloak.testsuite.pages.AppPage;
|
import org.keycloak.testsuite.runonserver.RunOnServerDeployment;
|
||||||
import org.keycloak.testsuite.pages.LoginPage;
|
import org.keycloak.testsuite.util.LDAPRule;
|
||||||
import org.keycloak.testsuite.rule.KeycloakRule;
|
import org.keycloak.testsuite.util.LDAPTestUtils;
|
||||||
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.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
|
import static org.keycloak.testsuite.arquillian.DeploymentTargetModifier.AUTH_SERVER_CURRENT;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||||
*/
|
*/
|
||||||
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
|
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
|
||||||
public class LDAPRoleMappingsNoImportTest {
|
public class LDAPRoleMappingsNoImportTest extends AbstractLDAPTest {
|
||||||
|
|
||||||
private static LDAPRule ldapRule = new LDAPRule();
|
|
||||||
|
|
||||||
private static ComponentModel ldapModel = null;
|
@ClassRule
|
||||||
|
public static LDAPRule ldapRule = new LDAPRule();
|
||||||
|
|
||||||
|
|
||||||
|
@Deployment
|
||||||
|
@TargetsContainer(AUTH_SERVER_CURRENT)
|
||||||
|
public static WebArchive deploy() {
|
||||||
|
return RunOnServerDeployment.create(UserResource.class, AbstractLDAPTest.class)
|
||||||
|
.addPackages(true,
|
||||||
|
"org.keycloak.testsuite",
|
||||||
|
"org.keycloak.testsuite.federation.ldap",
|
||||||
|
"org.keycloak.testsuite.federation.ldap.noimport");
|
||||||
|
}
|
||||||
|
|
||||||
private static KeycloakRule keycloakRule = new KeycloakRule(new KeycloakRule.KeycloakSetup() {
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
|
protected LDAPRule getLDAPRule() {
|
||||||
LDAPTestUtils.addLocalUser(manager.getSession(), appRealm, "mary", "mary@test.com", "password-app");
|
return ldapRule;
|
||||||
|
}
|
||||||
|
|
||||||
MultivaluedHashMap<String,String> ldapConfig = LDAPTestUtils.getLdapRuleConfig(ldapRule);
|
|
||||||
ldapConfig.putSingle(LDAPConstants.SYNC_REGISTRATIONS, "true");
|
|
||||||
ldapConfig.putSingle(LDAPConstants.EDIT_MODE, UserStorageProvider.EditMode.WRITABLE.toString());
|
|
||||||
UserStorageProviderModel model = new UserStorageProviderModel();
|
|
||||||
model.setLastSync(0);
|
|
||||||
model.setChangedSyncPeriod(-1);
|
|
||||||
model.setFullSyncPeriod(-1);
|
|
||||||
model.setName("test-ldap");
|
|
||||||
model.setPriority(0);
|
|
||||||
model.setProviderId(LDAPStorageProviderFactory.PROVIDER_NAME);
|
|
||||||
model.setConfig(ldapConfig);
|
|
||||||
model.setImportEnabled(false);
|
|
||||||
|
|
||||||
ldapModel = appRealm.addComponentModel(model);
|
@Override
|
||||||
|
protected boolean isImportEnabled() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void afterImportTestRealm() {
|
||||||
|
// Disable pagination
|
||||||
|
testingClient.server().run(session -> {
|
||||||
|
LDAPTestContext ctx = LDAPTestContext.init(session);
|
||||||
|
RealmModel appRealm = ctx.getRealm();
|
||||||
|
|
||||||
|
ctx.getLdapModel().put(LDAPConstants.PAGINATION, "false");
|
||||||
|
appRealm.updateComponent(ctx.getLdapModel());
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
testingClient.server().run(session -> {
|
||||||
|
LDAPTestContext ctx = LDAPTestContext.init(session);
|
||||||
|
RealmModel appRealm = ctx.getRealm();
|
||||||
|
UserStorageProviderModel ldapModel = ctx.getLdapModel();
|
||||||
|
|
||||||
|
LDAPTestUtils.addLocalUser(session, appRealm, "mary", "mary@test.com", "password-app");
|
||||||
|
|
||||||
|
|
||||||
// Delete all LDAP users
|
// Delete all LDAP users
|
||||||
LDAPStorageProvider ldapFedProvider = LDAPTestUtils.getLdapProvider(session, ldapModel);
|
LDAPStorageProvider ldapFedProvider = LDAPTestUtils.getLdapProvider(session, ldapModel);
|
||||||
|
@ -96,8 +112,8 @@ public class LDAPRoleMappingsNoImportTest {
|
||||||
|
|
||||||
// Delete all LDAP roles
|
// Delete all LDAP roles
|
||||||
LDAPTestUtils.addOrUpdateRoleLDAPMappers(appRealm, ldapModel, LDAPGroupMapperMode.LDAP_ONLY);
|
LDAPTestUtils.addOrUpdateRoleLDAPMappers(appRealm, ldapModel, LDAPGroupMapperMode.LDAP_ONLY);
|
||||||
LDAPTestUtils.removeAllLDAPRoles(manager.getSession(), appRealm, ldapModel, "realmRolesMapper");
|
LDAPTestUtils.removeAllLDAPRoles(session, appRealm, ldapModel, "realmRolesMapper");
|
||||||
LDAPTestUtils.removeAllLDAPRoles(manager.getSession(), appRealm, ldapModel, "financeRolesMapper");
|
LDAPTestUtils.removeAllLDAPRoles(session, appRealm, ldapModel, "financeRolesMapper");
|
||||||
|
|
||||||
// Add some users for testing
|
// Add some users for testing
|
||||||
LDAPObject john = LDAPTestUtils.addLDAPUser(ldapFedProvider, appRealm, "johnkeycloak", "John", "Doe", "john@email.org", null, "1234");
|
LDAPObject john = LDAPTestUtils.addLDAPUser(ldapFedProvider, appRealm, "johnkeycloak", "John", "Doe", "john@email.org", null, "1234");
|
||||||
|
@ -110,57 +126,40 @@ public class LDAPRoleMappingsNoImportTest {
|
||||||
LDAPTestUtils.updateLDAPPassword(ldapFedProvider, rob, "Password1");
|
LDAPTestUtils.updateLDAPPassword(ldapFedProvider, rob, "Password1");
|
||||||
|
|
||||||
// Add some roles for testing
|
// Add some roles for testing
|
||||||
LDAPTestUtils.createLDAPRole(manager.getSession(), appRealm, ldapModel, "realmRolesMapper", "realmRole1");
|
LDAPTestUtils.createLDAPRole(session, appRealm, ldapModel, "realmRolesMapper", "realmRole1");
|
||||||
LDAPTestUtils.createLDAPRole(manager.getSession(), appRealm, ldapModel, "realmRolesMapper", "realmRole2");
|
LDAPTestUtils.createLDAPRole(session, appRealm, ldapModel, "realmRolesMapper", "realmRole2");
|
||||||
LDAPTestUtils.createLDAPRole(manager.getSession(), appRealm, ldapModel, "financeRolesMapper", "financeRole1");
|
LDAPTestUtils.createLDAPRole(session, appRealm, ldapModel, "financeRolesMapper", "financeRole1");
|
||||||
|
|
||||||
// Sync LDAP roles to Keycloak DB
|
// Sync LDAP roles to Keycloak DB
|
||||||
LDAPTestUtils.syncRolesFromLDAP(appRealm, ldapFedProvider, ldapModel);
|
LDAPTestUtils.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
|
@Test
|
||||||
public void test01ReadMappings() {
|
public void test01ReadMappings() {
|
||||||
KeycloakSession session = keycloakRule.startSession();
|
testingClient.server().run(session -> {
|
||||||
try {
|
LDAPTestContext ctx = LDAPTestContext.init(session);
|
||||||
RealmModel appRealm = session.realms().getRealmByName("test");
|
RealmModel appRealm = ctx.getRealm();
|
||||||
LDAPTestUtils.addOrUpdateRoleLDAPMappers(appRealm, ldapModel, LDAPGroupMapperMode.LDAP_ONLY);
|
|
||||||
|
|
||||||
ComponentModel roleMapperModel = LDAPTestUtils.getSubcomponentByName(appRealm, ldapModel, "realmRolesMapper");
|
LDAPTestUtils.addOrUpdateRoleLDAPMappers(appRealm, ctx.getLdapModel(), LDAPGroupMapperMode.LDAP_ONLY);
|
||||||
LDAPStorageProvider ldapProvider = LDAPTestUtils.getLdapProvider(session, ldapModel);
|
|
||||||
|
ComponentModel roleMapperModel = LDAPTestUtils.getSubcomponentByName(appRealm, ctx.getLdapModel(), "realmRolesMapper");
|
||||||
|
LDAPStorageProvider ldapProvider = LDAPTestUtils.getLdapProvider(session, ctx.getLdapModel());
|
||||||
RoleLDAPStorageMapper roleMapper = LDAPTestUtils.getRoleMapper(roleMapperModel, ldapProvider, appRealm);
|
RoleLDAPStorageMapper roleMapper = LDAPTestUtils.getRoleMapper(roleMapperModel, ldapProvider, appRealm);
|
||||||
|
|
||||||
|
|
||||||
LDAPObject maryLdap = ldapProvider.loadLDAPUserByUsername(appRealm, "marykeycloak");
|
LDAPObject maryLdap = ldapProvider.loadLDAPUserByUsername(appRealm, "marykeycloak");
|
||||||
roleMapper.addRoleMappingInLDAP("realmRole1", maryLdap);
|
roleMapper.addRoleMappingInLDAP("realmRole1", maryLdap);
|
||||||
roleMapper.addRoleMappingInLDAP("realmRole2", maryLdap);
|
roleMapper.addRoleMappingInLDAP("realmRole2", maryLdap);
|
||||||
} finally {
|
} );
|
||||||
keycloakRule.stopSession(session, true);
|
|
||||||
}
|
testingClient.server().run(session -> {
|
||||||
session = keycloakRule.startSession();
|
|
||||||
try {
|
|
||||||
session.userCache().clear();
|
session.userCache().clear();
|
||||||
RealmModel appRealm = session.realms().getRealmByName("test");
|
LDAPTestContext ctx = LDAPTestContext.init(session);
|
||||||
|
RealmModel appRealm = ctx.getRealm();
|
||||||
|
|
||||||
UserModel mary = session.users().getUserByUsername("marykeycloak", appRealm);
|
UserModel mary = session.users().getUserByUsername("marykeycloak", appRealm);
|
||||||
// make sure we are in no-import mode!
|
// make sure we are in no-import mode!
|
||||||
|
@ -177,20 +176,19 @@ public class LDAPRoleMappingsNoImportTest {
|
||||||
Assert.assertTrue(maryRoles.contains(realmRole2));
|
Assert.assertTrue(maryRoles.contains(realmRole2));
|
||||||
|
|
||||||
// Add some role mappings directly into LDAP
|
// Add some role mappings directly into LDAP
|
||||||
ComponentModel roleMapperModel = LDAPTestUtils.getSubcomponentByName(appRealm, ldapModel, "realmRolesMapper");
|
ComponentModel roleMapperModel = LDAPTestUtils.getSubcomponentByName(appRealm, ctx.getLdapModel(), "realmRolesMapper");
|
||||||
LDAPStorageProvider ldapProvider = LDAPTestUtils.getLdapProvider(session, ldapModel);
|
LDAPStorageProvider ldapProvider = LDAPTestUtils.getLdapProvider(session, ctx.getLdapModel());
|
||||||
RoleLDAPStorageMapper roleMapper = LDAPTestUtils.getRoleMapper(roleMapperModel, ldapProvider, appRealm);
|
RoleLDAPStorageMapper roleMapper = LDAPTestUtils.getRoleMapper(roleMapperModel, ldapProvider, appRealm);
|
||||||
|
|
||||||
LDAPObject maryLdap = ldapProvider.loadLDAPUserByUsername(appRealm, "marykeycloak");
|
LDAPObject maryLdap = ldapProvider.loadLDAPUserByUsername(appRealm, "marykeycloak");
|
||||||
deleteRoleMappingsInLDAP(roleMapper, maryLdap, "realmRole1");
|
deleteRoleMappingsInLDAP(roleMapper, maryLdap, "realmRole1");
|
||||||
deleteRoleMappingsInLDAP(roleMapper, maryLdap, "realmRole2");
|
deleteRoleMappingsInLDAP(roleMapper, maryLdap, "realmRole2");
|
||||||
} finally {
|
});
|
||||||
keycloakRule.stopSession(session, true);
|
|
||||||
}
|
testingClient.server().run(session -> {
|
||||||
session = keycloakRule.startSession();
|
|
||||||
try {
|
|
||||||
session.userCache().clear();
|
session.userCache().clear();
|
||||||
RealmModel appRealm = session.realms().getRealmByName("test");
|
LDAPTestContext ctx = LDAPTestContext.init(session);
|
||||||
|
RealmModel appRealm = ctx.getRealm();
|
||||||
|
|
||||||
UserModel mary = session.users().getUserByUsername("marykeycloak", appRealm);
|
UserModel mary = session.users().getUserByUsername("marykeycloak", appRealm);
|
||||||
// This role should already exists as it was imported from LDAP
|
// This role should already exists as it was imported from LDAP
|
||||||
|
@ -202,19 +200,18 @@ public class LDAPRoleMappingsNoImportTest {
|
||||||
Set<RoleModel> maryRoles = mary.getRealmRoleMappings();
|
Set<RoleModel> maryRoles = mary.getRealmRoleMappings();
|
||||||
Assert.assertFalse(maryRoles.contains(realmRole1));
|
Assert.assertFalse(maryRoles.contains(realmRole1));
|
||||||
Assert.assertFalse(maryRoles.contains(realmRole2));
|
Assert.assertFalse(maryRoles.contains(realmRole2));
|
||||||
} finally {
|
});
|
||||||
keycloakRule.stopSession(session, true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void test02WriteMappings() {
|
public void test02WriteMappings() {
|
||||||
KeycloakSession session = keycloakRule.startSession();
|
testingClient.server().run(session -> {
|
||||||
try {
|
|
||||||
session.userCache().clear();
|
session.userCache().clear();
|
||||||
RealmModel appRealm = session.realms().getRealmByName("test");
|
LDAPTestContext ctx = LDAPTestContext.init(session);
|
||||||
|
RealmModel appRealm = ctx.getRealm();
|
||||||
|
|
||||||
LDAPTestUtils.addOrUpdateRoleLDAPMappers(appRealm, ldapModel, LDAPGroupMapperMode.LDAP_ONLY);
|
LDAPTestUtils.addOrUpdateRoleLDAPMappers(appRealm, ctx.getLdapModel(), LDAPGroupMapperMode.LDAP_ONLY);
|
||||||
|
|
||||||
UserModel john = session.users().getUserByUsername("johnkeycloak", appRealm);
|
UserModel john = session.users().getUserByUsername("johnkeycloak", appRealm);
|
||||||
UserModel mary = session.users().getUserByUsername("marykeycloak", appRealm);
|
UserModel mary = session.users().getUserByUsername("marykeycloak", appRealm);
|
||||||
|
@ -249,14 +246,13 @@ public class LDAPRoleMappingsNoImportTest {
|
||||||
RoleModel financeRole1 = financeApp.getRole("financeRole1");
|
RoleModel financeRole1 = financeApp.getRole("financeRole1");
|
||||||
john.grantRole(financeRole1);
|
john.grantRole(financeRole1);
|
||||||
session.userCache().clear();
|
session.userCache().clear();
|
||||||
} finally {
|
});
|
||||||
keycloakRule.stopSession(session, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
session = keycloakRule.startSession();
|
testingClient.server().run(session -> {
|
||||||
try {
|
|
||||||
session.userCache().clear();
|
session.userCache().clear();
|
||||||
RealmModel appRealm = session.realms().getRealmByName("test");
|
LDAPTestContext ctx = LDAPTestContext.init(session);
|
||||||
|
RealmModel appRealm = ctx.getRealm();
|
||||||
|
|
||||||
UserModel john = session.users().getUserByUsername("johnkeycloak", appRealm);
|
UserModel john = session.users().getUserByUsername("johnkeycloak", appRealm);
|
||||||
UserModel mary = session.users().getUserByUsername("marykeycloak", appRealm);
|
UserModel mary = session.users().getUserByUsername("marykeycloak", appRealm);
|
||||||
|
|
||||||
|
@ -310,21 +306,20 @@ public class LDAPRoleMappingsNoImportTest {
|
||||||
mary.deleteRoleMapping(realmRole2);
|
mary.deleteRoleMapping(realmRole2);
|
||||||
mary.deleteRoleMapping(realmRole3);
|
mary.deleteRoleMapping(realmRole3);
|
||||||
session.userCache().clear();
|
session.userCache().clear();
|
||||||
} finally {
|
});
|
||||||
keycloakRule.stopSession(session, false);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void test03_newUserDefaultRolesNoImportModeTest() throws Exception {
|
public void test03_newUserDefaultRolesNoImportModeTest() throws Exception {
|
||||||
|
|
||||||
// Check user group memberships
|
// Check user group memberships
|
||||||
KeycloakSession session = keycloakRule.startSession();
|
testingClient.server().run(session -> {
|
||||||
try {
|
|
||||||
session.userCache().clear();
|
session.userCache().clear();
|
||||||
RealmModel appRealm = session.realms().getRealmByName("test");
|
LDAPTestContext ctx = LDAPTestContext.init(session);
|
||||||
|
RealmModel appRealm = ctx.getRealm();
|
||||||
|
|
||||||
LDAPTestUtils.addOrUpdateRoleLDAPMappers(appRealm, ldapModel, LDAPGroupMapperMode.LDAP_ONLY);
|
LDAPTestUtils.addOrUpdateRoleLDAPMappers(appRealm, ctx.getLdapModel(), LDAPGroupMapperMode.LDAP_ONLY);
|
||||||
|
|
||||||
// Set a default role on the realm
|
// Set a default role on the realm
|
||||||
appRealm.addDefaultRole("realmRole1");
|
appRealm.addDefaultRole("realmRole1");
|
||||||
|
@ -350,12 +345,10 @@ public class LDAPRoleMappingsNoImportTest {
|
||||||
Set<RoleModel> johnRoles = john.getRealmRoleMappings();
|
Set<RoleModel> johnRoles = john.getRealmRoleMappings();
|
||||||
|
|
||||||
Assert.assertFalse(johnRoles.contains(defaultRole));
|
Assert.assertFalse(johnRoles.contains(defaultRole));
|
||||||
} finally {
|
});
|
||||||
keycloakRule.stopSession(session, true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void deleteRoleMappingsInLDAP(RoleLDAPStorageMapper roleMapper, LDAPObject ldapUser, String roleName) {
|
private static void deleteRoleMappingsInLDAP(RoleLDAPStorageMapper roleMapper, LDAPObject ldapUser, String roleName) {
|
||||||
LDAPObject ldapRole1 = roleMapper.loadLDAPRoleByName(roleName);
|
LDAPObject ldapRole1 = roleMapper.loadLDAPRoleByName(roleName);
|
||||||
roleMapper.deleteRoleMappingInLDAP(ldapUser, ldapRole1);
|
roleMapper.deleteRoleMappingInLDAP(ldapUser, ldapRole1);
|
||||||
}
|
}
|
|
@ -63,6 +63,18 @@
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
"clients": [
|
||||||
|
{
|
||||||
|
"clientId": "test-app",
|
||||||
|
"enabled": true,
|
||||||
|
"baseUrl": "http://localhost:8180/auth/realms/master/app/auth",
|
||||||
|
"redirectUris": [
|
||||||
|
"http://localhost:8180/auth/realms/master/app/auth/*"
|
||||||
|
],
|
||||||
|
"adminUrl": "http://localhost:8180/auth/realms/master/app/admin",
|
||||||
|
"secret": "password"
|
||||||
|
}
|
||||||
|
],
|
||||||
"defaultRoles": [
|
"defaultRoles": [
|
||||||
"user",
|
"user",
|
||||||
"offline_access",
|
"offline_access",
|
|
@ -18,3 +18,8 @@ dn: ou=FinanceRoles,dc=keycloak,dc=org
|
||||||
objectclass: top
|
objectclass: top
|
||||||
objectclass: organizationalUnit
|
objectclass: organizationalUnit
|
||||||
ou: FinanceRoles
|
ou: FinanceRoles
|
||||||
|
|
||||||
|
dn: ou=Groups,dc=keycloak,dc=org
|
||||||
|
objectclass: top
|
||||||
|
objectclass: organizationalUnit
|
||||||
|
ou: Groups
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
<module name="org.keycloak.keycloak-services"/>
|
<module name="org.keycloak.keycloak-services"/>
|
||||||
<module name="org.keycloak.keycloak-model-infinispan"/>
|
<module name="org.keycloak.keycloak-model-infinispan"/>
|
||||||
<module name="org.keycloak.keycloak-model-jpa"/>
|
<module name="org.keycloak.keycloak-model-jpa"/>
|
||||||
|
<module name="org.keycloak.keycloak-ldap-federation"/>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</deployment>
|
</deployment>
|
||||||
</jboss-deployment-structure>
|
</jboss-deployment-structure>
|
|
@ -249,12 +249,6 @@
|
||||||
<artifactId>selenium-chrome-driver</artifactId>
|
<artifactId>selenium-chrome-driver</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- Apache DS -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.keycloak</groupId>
|
|
||||||
<artifactId>keycloak-util-embedded-ldap</artifactId>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.picketlink</groupId>
|
<groupId>org.picketlink</groupId>
|
||||||
<artifactId>picketlink-wildfly-common</artifactId>
|
<artifactId>picketlink-wildfly-common</artifactId>
|
||||||
|
@ -351,36 +345,6 @@
|
||||||
</plugins>
|
</plugins>
|
||||||
</build>
|
</build>
|
||||||
</profile>
|
</profile>
|
||||||
<profile>
|
|
||||||
<id>ldap</id>
|
|
||||||
<build>
|
|
||||||
<plugins>
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.codehaus.mojo</groupId>
|
|
||||||
<artifactId>exec-maven-plugin</artifactId>
|
|
||||||
<configuration>
|
|
||||||
<mainClass>org.keycloak.util.ldap.LDAPEmbeddedServer</mainClass>
|
|
||||||
<classpathScope>test</classpathScope>
|
|
||||||
</configuration>
|
|
||||||
</plugin>
|
|
||||||
</plugins>
|
|
||||||
</build>
|
|
||||||
</profile>
|
|
||||||
<profile>
|
|
||||||
<id>kerberos</id>
|
|
||||||
<build>
|
|
||||||
<plugins>
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.codehaus.mojo</groupId>
|
|
||||||
<artifactId>exec-maven-plugin</artifactId>
|
|
||||||
<configuration>
|
|
||||||
<mainClass>org.keycloak.util.ldap.KerberosEmbeddedServer</mainClass>
|
|
||||||
<classpathScope>test</classpathScope>
|
|
||||||
</configuration>
|
|
||||||
</plugin>
|
|
||||||
</plugins>
|
|
||||||
</build>
|
|
||||||
</profile>
|
|
||||||
|
|
||||||
<profile>
|
<profile>
|
||||||
<id>jpa</id>
|
<id>jpa</id>
|
||||||
|
|
|
@ -1,151 +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.jboss.logging.Logger;
|
|
||||||
import org.keycloak.common.constants.KerberosConstants;
|
|
||||||
import org.keycloak.models.LDAPConstants;
|
|
||||||
import org.keycloak.storage.UserStorageProvider;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.net.URL;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Properties;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
|
||||||
*/
|
|
||||||
public class LDAPTestConfiguration {
|
|
||||||
|
|
||||||
private static final Logger log = Logger.getLogger(LDAPTestConfiguration.class);
|
|
||||||
|
|
||||||
private String connectionPropertiesLocation;
|
|
||||||
private int sleepTime;
|
|
||||||
private boolean startEmbeddedLdapServer = true;
|
|
||||||
private Map<String, String> config;
|
|
||||||
|
|
||||||
protected static final Map<String, String> PROP_MAPPINGS = new HashMap<String, String>();
|
|
||||||
|
|
||||||
protected static final Map<String, String> DEFAULT_VALUES = new HashMap<String, String>();
|
|
||||||
|
|
||||||
static {
|
|
||||||
PROP_MAPPINGS.put(LDAPConstants.CONNECTION_URL, "idm.test.ldap.connection.url");
|
|
||||||
PROP_MAPPINGS.put(LDAPConstants.BASE_DN, "idm.test.ldap.base.dn");
|
|
||||||
PROP_MAPPINGS.put(LDAPConstants.USERS_DN, "idm.test.ldap.user.dn.suffix");
|
|
||||||
PROP_MAPPINGS.put(LDAPConstants.BIND_DN, "idm.test.ldap.bind.dn");
|
|
||||||
PROP_MAPPINGS.put(LDAPConstants.BIND_CREDENTIAL, "idm.test.ldap.bind.credential");
|
|
||||||
PROP_MAPPINGS.put(LDAPConstants.VENDOR, "idm.test.ldap.vendor");
|
|
||||||
PROP_MAPPINGS.put(LDAPConstants.CONNECTION_POOLING, "idm.test.ldap.connection.pooling");
|
|
||||||
PROP_MAPPINGS.put(LDAPConstants.PAGINATION, "idm.test.ldap.pagination");
|
|
||||||
PROP_MAPPINGS.put(LDAPConstants.BATCH_SIZE_FOR_SYNC, "idm.test.ldap.batch.size.for.sync");
|
|
||||||
PROP_MAPPINGS.put(LDAPConstants.USERNAME_LDAP_ATTRIBUTE, "idm.test.ldap.username.ldap.attribute");
|
|
||||||
PROP_MAPPINGS.put(LDAPConstants.RDN_LDAP_ATTRIBUTE, "idm.test.ldap.rdn.ldap.attribute");
|
|
||||||
PROP_MAPPINGS.put(LDAPConstants.USER_OBJECT_CLASSES, "idm.test.ldap.user.object.classes");
|
|
||||||
PROP_MAPPINGS.put(LDAPConstants.EDIT_MODE, "idm.test.ldap.edit.mode");
|
|
||||||
|
|
||||||
PROP_MAPPINGS.put(KerberosConstants.ALLOW_KERBEROS_AUTHENTICATION, "idm.test.kerberos.allow.kerberos.authentication");
|
|
||||||
PROP_MAPPINGS.put(KerberosConstants.KERBEROS_REALM, "idm.test.kerberos.realm");
|
|
||||||
PROP_MAPPINGS.put(KerberosConstants.SERVER_PRINCIPAL, "idm.test.kerberos.server.principal");
|
|
||||||
PROP_MAPPINGS.put(KerberosConstants.KEYTAB, "idm.test.kerberos.keytab");
|
|
||||||
PROP_MAPPINGS.put(KerberosConstants.DEBUG, "idm.test.kerberos.debug");
|
|
||||||
PROP_MAPPINGS.put(KerberosConstants.ALLOW_PASSWORD_AUTHENTICATION, "idm.test.kerberos.allow.password.authentication");
|
|
||||||
PROP_MAPPINGS.put(KerberosConstants.UPDATE_PROFILE_FIRST_LOGIN, "idm.test.kerberos.update.profile.first.login");
|
|
||||||
PROP_MAPPINGS.put(KerberosConstants.USE_KERBEROS_FOR_PASSWORD_AUTHENTICATION, "idm.test.kerberos.use.kerberos.for.password.authentication");
|
|
||||||
|
|
||||||
DEFAULT_VALUES.put(LDAPConstants.CONNECTION_URL, "ldap://localhost:10389");
|
|
||||||
DEFAULT_VALUES.put(LDAPConstants.BASE_DN, "dc=keycloak,dc=org");
|
|
||||||
DEFAULT_VALUES.put(LDAPConstants.USERS_DN, "ou=People,dc=keycloak,dc=org");
|
|
||||||
DEFAULT_VALUES.put(LDAPConstants.BIND_DN, "uid=admin,ou=system");
|
|
||||||
DEFAULT_VALUES.put(LDAPConstants.BIND_CREDENTIAL, "secret");
|
|
||||||
DEFAULT_VALUES.put(LDAPConstants.VENDOR, LDAPConstants.VENDOR_OTHER);
|
|
||||||
DEFAULT_VALUES.put(LDAPConstants.CONNECTION_POOLING, "true");
|
|
||||||
DEFAULT_VALUES.put(LDAPConstants.PAGINATION, "true");
|
|
||||||
DEFAULT_VALUES.put(LDAPConstants.BATCH_SIZE_FOR_SYNC, String.valueOf(LDAPConstants.DEFAULT_BATCH_SIZE_FOR_SYNC));
|
|
||||||
DEFAULT_VALUES.put(LDAPConstants.USERNAME_LDAP_ATTRIBUTE, null);
|
|
||||||
DEFAULT_VALUES.put(LDAPConstants.USER_OBJECT_CLASSES, null);
|
|
||||||
DEFAULT_VALUES.put(LDAPConstants.EDIT_MODE, UserStorageProvider.EditMode.READ_ONLY.toString());
|
|
||||||
|
|
||||||
DEFAULT_VALUES.put(KerberosConstants.ALLOW_KERBEROS_AUTHENTICATION, "false");
|
|
||||||
DEFAULT_VALUES.put(KerberosConstants.KERBEROS_REALM, "KEYCLOAK.ORG");
|
|
||||||
DEFAULT_VALUES.put(KerberosConstants.SERVER_PRINCIPAL, "HTTP/localhost@KEYCLOAK.ORG");
|
|
||||||
// URL keytabUrl = LDAPTestConfiguration.class.getResource("/kerberos/http.keytab");
|
|
||||||
// String keyTabPath = new File(keytabUrl.getFile()).getAbsolutePath();
|
|
||||||
// DEFAULT_VALUES.put(KerberosConstants.KEYTAB, keyTabPath);
|
|
||||||
DEFAULT_VALUES.put(KerberosConstants.DEBUG, "true");
|
|
||||||
DEFAULT_VALUES.put(KerberosConstants.ALLOW_PASSWORD_AUTHENTICATION, "true");
|
|
||||||
DEFAULT_VALUES.put(KerberosConstants.UPDATE_PROFILE_FIRST_LOGIN, "true");
|
|
||||||
DEFAULT_VALUES.put(KerberosConstants.USE_KERBEROS_FOR_PASSWORD_AUTHENTICATION, "false");
|
|
||||||
}
|
|
||||||
|
|
||||||
public static LDAPTestConfiguration readConfiguration(String connectionPropertiesLocation) {
|
|
||||||
LDAPTestConfiguration ldapTestConfiguration = new LDAPTestConfiguration();
|
|
||||||
ldapTestConfiguration.setConnectionPropertiesLocation(connectionPropertiesLocation);
|
|
||||||
ldapTestConfiguration.loadConnectionProperties();
|
|
||||||
return ldapTestConfiguration;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void loadConnectionProperties() {
|
|
||||||
Properties p = new Properties();
|
|
||||||
try {
|
|
||||||
log.info("Reading LDAP configuration from: " + connectionPropertiesLocation);
|
|
||||||
InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream(connectionPropertiesLocation);
|
|
||||||
p.load(is);
|
|
||||||
}
|
|
||||||
catch (Exception e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
config = new HashMap<String, String>();
|
|
||||||
for (Map.Entry<String, String> property : PROP_MAPPINGS.entrySet()) {
|
|
||||||
String propertyName = property.getKey();
|
|
||||||
String configName = property.getValue();
|
|
||||||
|
|
||||||
String value = (String) p.get(configName);
|
|
||||||
if (value == null) {
|
|
||||||
value = DEFAULT_VALUES.get(propertyName);
|
|
||||||
}
|
|
||||||
|
|
||||||
config.put(propertyName, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
startEmbeddedLdapServer = Boolean.parseBoolean(p.getProperty("idm.test.ldap.start.embedded.ldap.server", "true"));
|
|
||||||
sleepTime = Integer.parseInt(p.getProperty("idm.test.ldap.sleepTime", "1000"));
|
|
||||||
config.put("startEmbeddedLdapServer", Boolean.toString(startEmbeddedLdapServer));
|
|
||||||
log.info("Start embedded server: " + startEmbeddedLdapServer);
|
|
||||||
log.info("Read config: " + config);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Map<String,String> getLDAPConfig() {
|
|
||||||
return config;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setConnectionPropertiesLocation(String connectionPropertiesLocation) {
|
|
||||||
this.connectionPropertiesLocation = connectionPropertiesLocation;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isStartEmbeddedLdapServer() {
|
|
||||||
return startEmbeddedLdapServer;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getSleepTime() {
|
|
||||||
return sleepTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -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.storage.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,166 +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.storage.ldap;
|
|
||||||
|
|
||||||
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.component.ComponentModel;
|
|
||||||
import org.keycloak.models.LDAPConstants;
|
|
||||||
import org.keycloak.models.RealmModel;
|
|
||||||
import org.keycloak.models.utils.RepresentationToModel;
|
|
||||||
import org.keycloak.representations.idm.RealmRepresentation;
|
|
||||||
import org.keycloak.services.managers.RealmManager;
|
|
||||||
import org.keycloak.storage.UserStorageProvider;
|
|
||||||
import org.keycloak.storage.ldap.LDAPStorageProvider;
|
|
||||||
import org.keycloak.storage.ldap.idm.model.LDAPObject;
|
|
||||||
import org.keycloak.testsuite.OAuthClient;
|
|
||||||
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.IOException;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Tests that legacy UserFederationProvider json export is converted to ComponentModel
|
|
||||||
*
|
|
||||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
|
||||||
*/
|
|
||||||
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
|
|
||||||
public class LDAPLegacyImportTest {
|
|
||||||
|
|
||||||
// This test is executed just for the embedded LDAP server
|
|
||||||
private static LDAPRule ldapRule = new LDAPRule((Map<String, String> ldapConfig) -> {
|
|
||||||
return !Boolean.parseBoolean(ldapConfig.get("startEmbeddedLdapServer"));
|
|
||||||
});
|
|
||||||
|
|
||||||
private static ComponentModel ldapModel = null;
|
|
||||||
|
|
||||||
|
|
||||||
private static KeycloakRule keycloakRule = new KeycloakRule(new KeycloakRule.KeycloakSetup() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
|
|
||||||
LDAPTestUtils.addLocalUser(manager.getSession(), appRealm, "marykeycloak", "mary@test.com", "password-app");
|
|
||||||
|
|
||||||
RealmRepresentation imported = null;
|
|
||||||
try {
|
|
||||||
imported = JsonSerialization.readValue(getClass().getResourceAsStream("/ldap/fed-provider-export.json"), RealmRepresentation.class);
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
RepresentationToModel.importUserFederationProvidersAndMappers(session, imported, appRealm);
|
|
||||||
ldapModel = appRealm.getComponents(appRealm.getId(), UserStorageProvider.class.getName()).get(0);
|
|
||||||
// Delete all LDAP users and add some new for testing
|
|
||||||
LDAPStorageProvider ldapFedProvider = LDAPTestUtils.getLdapProvider(session, ldapModel);
|
|
||||||
LDAPTestUtils.removeAllLDAPUsers(ldapFedProvider, appRealm);
|
|
||||||
|
|
||||||
LDAPObject john = LDAPTestUtils.addLDAPUser(ldapFedProvider, appRealm, "johnkeycloak", "John", "Doe", "john@email.org", null, "1234");
|
|
||||||
LDAPTestUtils.updateLDAPPassword(ldapFedProvider, john, "Password1");
|
|
||||||
|
|
||||||
LDAPObject existing = LDAPTestUtils.addLDAPUser(ldapFedProvider, appRealm, "existing", "Existing", "Foo", "existing@email.org", null, "5678");
|
|
||||||
|
|
||||||
appRealm.getClientByClientId("test-app").setDirectAccessGrantsEnabled(true);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
@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
|
|
||||||
public void runit() throws Exception {
|
|
||||||
Thread.sleep(10000000);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
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 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());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,176 +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.storage.ldap;
|
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
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.common.util.MultivaluedHashMap;
|
|
||||||
import org.keycloak.component.ComponentModel;
|
|
||||||
import org.keycloak.models.KeycloakSession;
|
|
||||||
import org.keycloak.models.LDAPConstants;
|
|
||||||
import org.keycloak.models.RealmModel;
|
|
||||||
import org.keycloak.models.UserModel;
|
|
||||||
import org.keycloak.services.managers.RealmManager;
|
|
||||||
import org.keycloak.storage.UserStorageProvider;
|
|
||||||
import org.keycloak.storage.UserStorageProviderModel;
|
|
||||||
import org.keycloak.storage.ldap.LDAPStorageProvider;
|
|
||||||
import org.keycloak.storage.ldap.LDAPStorageProviderFactory;
|
|
||||||
import org.keycloak.storage.ldap.idm.model.LDAPObject;
|
|
||||||
import org.keycloak.testsuite.OAuthClient;
|
|
||||||
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.LoginPasswordUpdatePage;
|
|
||||||
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.openqa.selenium.WebDriver;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
|
||||||
*/
|
|
||||||
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
|
|
||||||
public class LDAPMSADMapperTest {
|
|
||||||
|
|
||||||
// Run this test just on MSAD
|
|
||||||
private static LDAPRule ldapRule = new LDAPRule((Map<String, String> ldapConfig) -> {
|
|
||||||
|
|
||||||
String vendor = ldapConfig.get(LDAPConstants.VENDOR);
|
|
||||||
|
|
||||||
// TODO: This is skipped as it requires that MSAD server is set to not allow weak passwords (There needs to be pwdProperties=1 set on MSAD side).
|
|
||||||
// TODO: Currently we can't rely on it. See KEYCLOAK-4276
|
|
||||||
return true;
|
|
||||||
// return !(vendor.equals(LDAPConstants.VENDOR_ACTIVE_DIRECTORY));
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
private static ComponentModel ldapModel = null;
|
|
||||||
|
|
||||||
|
|
||||||
private static KeycloakRule keycloakRule = new KeycloakRule(new KeycloakRule.KeycloakSetup() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
|
|
||||||
LDAPTestUtils.addLocalUser(manager.getSession(), appRealm, "marykeycloak", "mary@test.com", "password-app");
|
|
||||||
|
|
||||||
MultivaluedHashMap<String,String> ldapConfig = LDAPTestUtils.getLdapRuleConfig(ldapRule);
|
|
||||||
ldapConfig.putSingle(LDAPConstants.SYNC_REGISTRATIONS, "true");
|
|
||||||
ldapConfig.putSingle(LDAPConstants.EDIT_MODE, UserStorageProvider.EditMode.WRITABLE.toString());
|
|
||||||
UserStorageProviderModel model = new UserStorageProviderModel();
|
|
||||||
model.setLastSync(0);
|
|
||||||
model.setChangedSyncPeriod(-1);
|
|
||||||
model.setFullSyncPeriod(-1);
|
|
||||||
model.setName("test-ldap");
|
|
||||||
model.setPriority(0);
|
|
||||||
model.setProviderId(LDAPStorageProviderFactory.PROVIDER_NAME);
|
|
||||||
model.setConfig(ldapConfig);
|
|
||||||
|
|
||||||
ldapModel = appRealm.addComponentModel(model);
|
|
||||||
LDAPTestUtils.addZipCodeLDAPMapper(appRealm, ldapModel);
|
|
||||||
|
|
||||||
// Delete all LDAP users and add some new for testing
|
|
||||||
LDAPStorageProvider ldapFedProvider = LDAPTestUtils.getLdapProvider(session, ldapModel);
|
|
||||||
LDAPTestUtils.removeAllLDAPUsers(ldapFedProvider, appRealm);
|
|
||||||
|
|
||||||
LDAPObject john = LDAPTestUtils.addLDAPUser(ldapFedProvider, appRealm, "johnkeycloak", "John", "Doe", "john@email.org", null, "1234");
|
|
||||||
LDAPTestUtils.updateLDAPPassword(ldapFedProvider, john, "Password1");
|
|
||||||
|
|
||||||
appRealm.getClientByClientId("test-app").setDirectAccessGrantsEnabled(true);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
@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;
|
|
||||||
|
|
||||||
@WebResource
|
|
||||||
protected LoginPasswordUpdatePage passwordUpdatePage;
|
|
||||||
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void test01RegisterUserWithWeakPasswordFirst() {
|
|
||||||
loginPage.open();
|
|
||||||
loginPage.clickRegister();
|
|
||||||
registerPage.assertCurrent();
|
|
||||||
|
|
||||||
// Weak password. This will fail to update password to MSAD due to password policy.
|
|
||||||
registerPage.register("firstName", "lastName", "email2@check.cz", "registerUserSuccess2", "password", "password");
|
|
||||||
|
|
||||||
// Another weak password
|
|
||||||
passwordUpdatePage.assertCurrent();
|
|
||||||
passwordUpdatePage.changePassword("pass", "pass");
|
|
||||||
Assert.assertEquals("Invalid password: new password doesn't match password policies.", passwordUpdatePage.getError());
|
|
||||||
|
|
||||||
// Strong password. Successfully update password and being redirected to the app
|
|
||||||
passwordUpdatePage.changePassword("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());
|
|
||||||
Assert.assertEquals("registerusersuccess2", user.getUsername());
|
|
||||||
Assert.assertEquals("firstName", user.getFirstName());
|
|
||||||
Assert.assertEquals("lastName", user.getLastName());
|
|
||||||
Assert.assertTrue(user.isEnabled());
|
|
||||||
Assert.assertEquals(0, user.getRequiredActions().size());
|
|
||||||
} finally {
|
|
||||||
keycloakRule.stopSession(session, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,270 +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.storage.ldap;
|
|
||||||
|
|
||||||
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.common.util.MultivaluedHashMap;
|
|
||||||
import org.keycloak.component.ComponentModel;
|
|
||||||
import org.keycloak.models.ClientModel;
|
|
||||||
import org.keycloak.models.KeycloakSession;
|
|
||||||
import org.keycloak.models.LDAPConstants;
|
|
||||||
import org.keycloak.models.RealmModel;
|
|
||||||
import org.keycloak.models.UserModel;
|
|
||||||
import org.keycloak.models.utils.KeycloakModelUtils;
|
|
||||||
import org.keycloak.protocol.oidc.OIDCLoginProtocol;
|
|
||||||
import org.keycloak.protocol.oidc.OIDCLoginProtocolService;
|
|
||||||
import org.keycloak.protocol.oidc.mappers.UserAttributeMapper;
|
|
||||||
import org.keycloak.services.managers.RealmManager;
|
|
||||||
import org.keycloak.storage.UserStorageProvider;
|
|
||||||
import org.keycloak.storage.UserStorageProviderModel;
|
|
||||||
import org.keycloak.storage.ldap.LDAPStorageProvider;
|
|
||||||
import org.keycloak.storage.ldap.LDAPStorageProviderFactory;
|
|
||||||
import org.keycloak.storage.ldap.idm.model.LDAPObject;
|
|
||||||
import org.keycloak.testsuite.OAuthClient;
|
|
||||||
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();
|
|
||||||
|
|
||||||
|
|
||||||
// Skip this test on MSAD due to lack of supported user multivalued attributes
|
|
||||||
private static LDAPRule ldapRule = new LDAPRule((Map<String, String> ldapConfig) -> {
|
|
||||||
|
|
||||||
String vendor = ldapConfig.get(LDAPConstants.VENDOR);
|
|
||||||
return (vendor.equals(LDAPConstants.VENDOR_ACTIVE_DIRECTORY));
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
public static UserStorageProviderModel ldapModel = null;
|
|
||||||
|
|
||||||
public static KeycloakRule keycloakRule = new KeycloakRule(new KeycloakRule.KeycloakSetup() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
|
|
||||||
MultivaluedHashMap<String,String> ldapConfig = LDAPTestUtils.getLdapRuleConfig(ldapRule);
|
|
||||||
ldapConfig.putSingle(LDAPConstants.EDIT_MODE, UserStorageProvider.EditMode.WRITABLE.toString());
|
|
||||||
|
|
||||||
UserStorageProviderModel model = new UserStorageProviderModel();
|
|
||||||
model.setLastSync(0);
|
|
||||||
model.setChangedSyncPeriod(-1);
|
|
||||||
model.setFullSyncPeriod(-1);
|
|
||||||
model.setName("test-ldap");
|
|
||||||
model.setPriority(0);
|
|
||||||
model.setProviderId(LDAPStorageProviderFactory.PROVIDER_NAME);
|
|
||||||
model.setConfig(ldapConfig);
|
|
||||||
ldapModel = new UserStorageProviderModel(appRealm.addComponentModel(model));
|
|
||||||
|
|
||||||
LDAPTestUtils.addZipCodeLDAPMapper(appRealm, ldapModel);
|
|
||||||
LDAPTestUtils.addUserAttributeMapper(appRealm, ldapModel, "streetMapper", "street", LDAPConstants.STREET);
|
|
||||||
|
|
||||||
// Remove current users and add default users
|
|
||||||
LDAPStorageProvider ldapFedProvider = LDAPTestUtils.getLdapProvider(session, ldapModel);
|
|
||||||
LDAPTestUtils.removeAllLDAPUsers(ldapFedProvider, appRealm);
|
|
||||||
|
|
||||||
LDAPObject james = LDAPTestUtils.addLDAPUser(ldapFedProvider, appRealm, "jbrown", "James", "Brown", "jbrown@keycloak.org", null, "88441");
|
|
||||||
LDAPTestUtils.updateLDAPPassword(ldapFedProvider, james, "Password1");
|
|
||||||
|
|
||||||
// User for testing duplicating surname and postalCode
|
|
||||||
LDAPObject bruce = LDAPTestUtils.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);
|
|
||||||
LDAPTestUtils.updateLDAPPassword(ldapFedProvider, bruce, "Password1");
|
|
||||||
|
|
||||||
// Create ldap-portal client
|
|
||||||
ClientModel ldapClient = KeycloakModelUtils.createClient(appRealm, "ldap-portal");
|
|
||||||
ldapClient.setProtocol(OIDCLoginProtocol.LOGIN_PROTOCOL);
|
|
||||||
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));
|
|
||||||
ldapClient.addProtocolMapper(UserAttributeMapper.createClaimMapper("street", "street", "street", "String", 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;
|
|
||||||
|
|
||||||
protected void checkUserAndImportMode(KeycloakSession session, RealmModel realm, String username, String expectedFirstName, String expectedLastName, String expectedEmail, String expectedPostalCode) {
|
|
||||||
LDAPTestUtils.assertUserImported(session.userLocalStorage(), realm, "jbrown", "James", "Brown", "jbrown@keycloak.org", "88441");
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void checkImportMode(KeycloakSession session, RealmModel realm, UserModel user) {
|
|
||||||
Assert.assertNotNull(session.userLocalStorage().getUserById(user.getId(), realm));
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testModel() {
|
|
||||||
KeycloakSession session = keycloakRule.startSession();
|
|
||||||
try {
|
|
||||||
session.userCache().clear();
|
|
||||||
RealmModel appRealm = session.realms().getRealmByName("test");
|
|
||||||
|
|
||||||
checkUserAndImportMode(session, appRealm, "jbrown", "James", "Brown", "jbrown@keycloak.org", "88441");
|
|
||||||
|
|
||||||
UserModel user = session.users().getUserByUsername("bwilson", appRealm);
|
|
||||||
checkImportMode(session, appRealm, user);
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,381 +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.storage.ldap;
|
|
||||||
|
|
||||||
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.MultivaluedHashMap;
|
|
||||||
import org.keycloak.common.util.Time;
|
|
||||||
import org.keycloak.component.ComponentModel;
|
|
||||||
import org.keycloak.services.managers.UserStorageSyncManager;
|
|
||||||
import org.keycloak.storage.UserStorageProvider;
|
|
||||||
import org.keycloak.storage.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.UserModel;
|
|
||||||
import org.keycloak.models.UserProvider;
|
|
||||||
import org.keycloak.models.cache.UserCache;
|
|
||||||
import org.keycloak.models.utils.KeycloakModelUtils;
|
|
||||||
import org.keycloak.services.managers.RealmManager;
|
|
||||||
import org.keycloak.storage.UserStorageProviderModel;
|
|
||||||
import org.keycloak.storage.ldap.LDAPStorageProvider;
|
|
||||||
import org.keycloak.storage.ldap.LDAPStorageProviderFactory;
|
|
||||||
import org.keycloak.storage.user.SynchronizationResult;
|
|
||||||
import org.keycloak.testsuite.rule.KeycloakRule;
|
|
||||||
import org.keycloak.testsuite.rule.LDAPRule;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @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 UserStorageProviderModel 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);
|
|
||||||
|
|
||||||
MultivaluedHashMap<String,String> ldapConfig = LDAPTestUtils.getLdapRuleConfig(ldapRule);
|
|
||||||
ldapConfig.putSingle(LDAPConstants.SYNC_REGISTRATIONS, "false");
|
|
||||||
ldapConfig.putSingle(LDAPConstants.EDIT_MODE, UserStorageProvider.EditMode.WRITABLE.toString());
|
|
||||||
UserStorageProviderModel model = new UserStorageProviderModel();
|
|
||||||
model.setLastSync(0);
|
|
||||||
model.setChangedSyncPeriod(-1);
|
|
||||||
model.setFullSyncPeriod(-1);
|
|
||||||
model.setName("test-ldap");
|
|
||||||
model.setPriority(0);
|
|
||||||
model.setProviderId(LDAPStorageProviderFactory.PROVIDER_NAME);
|
|
||||||
model.setConfig(ldapConfig);
|
|
||||||
|
|
||||||
ldapModel = new UserStorageProviderModel(appRealm.addComponentModel(model));
|
|
||||||
|
|
||||||
|
|
||||||
LDAPTestUtils.addZipCodeLDAPMapper(appRealm, ldapModel);
|
|
||||||
|
|
||||||
// Delete all LDAP users and add 5 new users for testing
|
|
||||||
LDAPStorageProvider ldapFedProvider = LDAPTestUtils.getLdapProvider(session, ldapModel);
|
|
||||||
LDAPTestUtils.removeAllLDAPUsers(ldapFedProvider, appRealm);
|
|
||||||
|
|
||||||
for (int i=1 ; i<=5 ; i++) {
|
|
||||||
LDAPObject ldapUser = LDAPTestUtils.addLDAPUser(ldapFedProvider, appRealm, "user" + i, "User" + i + "FN", "User" + i + "LN", "user" + i + "@email.org", null, "12" + i);
|
|
||||||
LDAPTestUtils.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() {
|
|
||||||
UserStorageSyncManager usersSyncManager = new UserStorageSyncManager();
|
|
||||||
|
|
||||||
// wait a bit
|
|
||||||
sleep(ldapRule.getSleepTime());
|
|
||||||
|
|
||||||
KeycloakSession session = keycloakRule.startSession();
|
|
||||||
try {
|
|
||||||
KeycloakSessionFactory sessionFactory = session.getKeycloakSessionFactory();
|
|
||||||
SynchronizationResult syncResult = usersSyncManager.syncAllUsers(sessionFactory, "test", ldapModel);
|
|
||||||
LDAPTestUtils.assertSyncEquals(syncResult, 5, 0, 0, 0);
|
|
||||||
} finally {
|
|
||||||
keycloakRule.stopSession(session, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
session = keycloakRule.startSession();
|
|
||||||
try {
|
|
||||||
RealmModel testRealm = session.realms().getRealm("test");
|
|
||||||
UserProvider userProvider = session.userLocalStorage();
|
|
||||||
// Assert users imported
|
|
||||||
LDAPTestUtils.assertUserImported(userProvider, testRealm, "user1", "User1FN", "User1LN", "user1@email.org", "121");
|
|
||||||
LDAPTestUtils.assertUserImported(userProvider, testRealm, "user2", "User2FN", "User2LN", "user2@email.org", "122");
|
|
||||||
LDAPTestUtils.assertUserImported(userProvider, testRealm, "user3", "User3FN", "User3LN", "user3@email.org", "123");
|
|
||||||
LDAPTestUtils.assertUserImported(userProvider, testRealm, "user4", "User4FN", "User4LN", "user4@email.org", "124");
|
|
||||||
LDAPTestUtils.assertUserImported(userProvider, testRealm, "user5", "User5FN", "User5LN", "user5@email.org", "125");
|
|
||||||
|
|
||||||
// Assert lastSync time updated
|
|
||||||
Assert.assertTrue(ldapModel.getLastSync() > 0);
|
|
||||||
for (UserStorageProviderModel persistentFedModel : testRealm.getUserStorageProviders()) {
|
|
||||||
if (LDAPStorageProviderFactory.PROVIDER_NAME.equals(persistentFedModel.getProviderId())) {
|
|
||||||
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
|
|
||||||
LDAPStorageProvider ldapFedProvider = LDAPTestUtils.getLdapProvider(session, ldapModel);
|
|
||||||
LDAPTestUtils.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
|
|
||||||
LDAPTestUtils.assertUserImported(userProvider, testRealm, "user5", "User5FN", "User5LN", "user5@email.org", "125");
|
|
||||||
Assert.assertNull(userProvider.getUserByUsername("user6", testRealm));
|
|
||||||
|
|
||||||
// Trigger partial sync
|
|
||||||
KeycloakSessionFactory sessionFactory = session.getKeycloakSessionFactory();
|
|
||||||
SynchronizationResult syncResult = usersSyncManager.syncChangedUsers(sessionFactory, "test", ldapModel);
|
|
||||||
LDAPTestUtils.assertSyncEquals(syncResult, 1, 1, 0, 0);
|
|
||||||
} finally {
|
|
||||||
keycloakRule.stopSession(session, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
session = keycloakRule.startSession();
|
|
||||||
try {
|
|
||||||
RealmModel testRealm = session.realms().getRealm("test");
|
|
||||||
UserProvider userProvider = session.userLocalStorage();
|
|
||||||
// Assert users updated in local provider
|
|
||||||
LDAPTestUtils.assertUserImported(userProvider, testRealm, "user5", "User5FN", "User5LN", "user5updated@email.org", "521");
|
|
||||||
LDAPTestUtils.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");
|
|
||||||
|
|
||||||
LDAPTestUtils.addLocalUser(session, testRealm, "user7", "user7@email.org", "password");
|
|
||||||
LDAPStorageProvider ldapFedProvider = LDAPTestUtils.getLdapProvider(session, ldapModel);
|
|
||||||
|
|
||||||
// Add user to LDAP with duplicated username "user7"
|
|
||||||
duplicatedLdapUser = LDAPTestUtils.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
|
|
||||||
SynchronizationResult result = new UserStorageSyncManager().syncAllUsers(session.getKeycloakSessionFactory(), "test", ldapModel);
|
|
||||||
Assert.assertEquals(1, result.getFailed());
|
|
||||||
|
|
||||||
// Remove "user7" from LDAP
|
|
||||||
LDAPStorageProvider ldapFedProvider = LDAPTestUtils.getLdapProvider(session, ldapModel);
|
|
||||||
ldapFedProvider.getLdapIdentityStore().remove(duplicatedLdapUser);
|
|
||||||
|
|
||||||
// Add user to LDAP with duplicated email "user7@email.org"
|
|
||||||
duplicatedLdapUser = LDAPTestUtils.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
|
|
||||||
SynchronizationResult result = new UserStorageSyncManager().syncAllUsers(session.getKeycloakSessionFactory(), "test", ldapModel);
|
|
||||||
Assert.assertEquals(1, result.getFailed());
|
|
||||||
Assert.assertNull(session.userLocalStorage().getUserByUsername("user7-something", testRealm));
|
|
||||||
|
|
||||||
// Update LDAP user to avoid duplicated email
|
|
||||||
duplicatedLdapUser.setSingleAttribute(LDAPConstants.EMAIL, "user7-changed@email.org");
|
|
||||||
LDAPStorageProvider ldapFedProvider = LDAPTestUtils.getLdapProvider(session, ldapModel);
|
|
||||||
ldapFedProvider.getLdapIdentityStore().update(duplicatedLdapUser);
|
|
||||||
|
|
||||||
// Assert user successfully synced now
|
|
||||||
result = new UserStorageSyncManager().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");
|
|
||||||
LDAPTestUtils.assertUserImported(session.userLocalStorage(), 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.userLocalStorage().getUsers(testRealm, true)) {
|
|
||||||
session.userLocalStorage().removeUser(testRealm, user);
|
|
||||||
}
|
|
||||||
|
|
||||||
UserStorageProviderModel providerModel = KeycloakModelUtils.findUserStorageProviderByName(ldapModel.getName(), testRealm);
|
|
||||||
|
|
||||||
// Change name of UUID attribute to same like usernameAttribute
|
|
||||||
LDAPStorageProvider ldapFedProvider = LDAPTestUtils.getLdapProvider(session, ldapModel);
|
|
||||||
String uidAttrName = ldapFedProvider.getLdapIdentityStore().getConfig().getUsernameLdapAttribute();
|
|
||||||
origUuidAttrName = providerModel.getConfig().getFirst(LDAPConstants.UUID_LDAP_ATTRIBUTE);
|
|
||||||
providerModel.getConfig().putSingle(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().putSingle(LDAPConstants.BATCH_SIZE_FOR_SYNC, "10");
|
|
||||||
testRealm.updateComponent(providerModel);
|
|
||||||
|
|
||||||
} finally {
|
|
||||||
keycloakRule.stopSession(session, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
session = keycloakRule.startSession();
|
|
||||||
try {
|
|
||||||
RealmModel testRealm = session.realms().getRealm("test");
|
|
||||||
UserStorageProviderModel providerModel = KeycloakModelUtils.findUserStorageProviderByName(ldapModel.getName(), testRealm);
|
|
||||||
|
|
||||||
KeycloakSessionFactory sessionFactory = session.getKeycloakSessionFactory();
|
|
||||||
SynchronizationResult syncResult = new UserStorageSyncManager().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
|
|
||||||
LDAPTestUtils.assertUserImported(session.users(), testRealm, "user1", "User1FN", "User1LN", "user1@email.org", "121");
|
|
||||||
LDAPTestUtils.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
|
|
||||||
UserStorageProviderModel providerModel = KeycloakModelUtils.findUserStorageProviderByName(ldapModel.getName(), testRealm);
|
|
||||||
providerModel.getConfig().putSingle(LDAPConstants.UUID_LDAP_ATTRIBUTE, origUuidAttrName);
|
|
||||||
testRealm.updateComponent(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.userLocalStorage().getUsers(testRealm, true)) {
|
|
||||||
System.out.println("trying to delete user: " + user.getUsername());
|
|
||||||
UserCache userCache = session.userCache();
|
|
||||||
if (userCache != null) {
|
|
||||||
userCache.evict(testRealm, user);
|
|
||||||
}
|
|
||||||
session.userLocalStorage().removeUser(testRealm, user);
|
|
||||||
}
|
|
||||||
|
|
||||||
UserStorageProviderModel providerModel = KeycloakModelUtils.findUserStorageProviderByName(ldapModel.getName(), testRealm);
|
|
||||||
|
|
||||||
// Add street mapper and add some user including street
|
|
||||||
ComponentModel streetMapper = LDAPTestUtils.addUserAttributeMapper(testRealm, ldapModel, "streetMapper", "street", LDAPConstants.STREET);
|
|
||||||
LDAPStorageProvider ldapFedProvider = LDAPTestUtils.getLdapProvider(session, ldapModel);
|
|
||||||
LDAPObject streetUser = LDAPTestUtils.addLDAPUser(ldapFedProvider, testRealm, "user8", "User8FN", "User8LN", "user8@email.org", "user8street", "126");
|
|
||||||
|
|
||||||
// Change name of username attribute name to street
|
|
||||||
origUsernameAttrName = providerModel.getConfig().getFirst(LDAPConstants.USERNAME_LDAP_ATTRIBUTE);
|
|
||||||
providerModel.getConfig().putSingle(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().putSingle(LDAPConstants.BATCH_SIZE_FOR_SYNC, "10");
|
|
||||||
testRealm.updateComponent(providerModel);
|
|
||||||
|
|
||||||
} finally {
|
|
||||||
keycloakRule.stopSession(session, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Just user8 synced. All others failed to sync
|
|
||||||
session = keycloakRule.startSession();
|
|
||||||
try {
|
|
||||||
RealmModel testRealm = session.realms().getRealm("test");
|
|
||||||
UserStorageProviderModel providerModel = KeycloakModelUtils.findUserStorageProviderByName(ldapModel.getName(), testRealm);
|
|
||||||
|
|
||||||
KeycloakSessionFactory sessionFactory = session.getKeycloakSessionFactory();
|
|
||||||
SynchronizationResult syncResult = new UserStorageSyncManager().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
|
|
||||||
UserStorageProviderModel providerModel = KeycloakModelUtils.findUserStorageProviderByName(ldapModel.getName(), testRealm);
|
|
||||||
providerModel.getConfig().putSingle(LDAPConstants.USERNAME_LDAP_ATTRIBUTE, origUsernameAttrName);
|
|
||||||
testRealm.updateComponent(providerModel);
|
|
||||||
ComponentModel streetMapper = LDAPTestUtils.getSubcomponentByName(testRealm, providerModel, "streetMapper");
|
|
||||||
testRealm.removeComponent(streetMapper);
|
|
||||||
} finally {
|
|
||||||
keycloakRule.stopSession(session, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void sleep(int time) {
|
|
||||||
try {
|
|
||||||
Thread.sleep(time);
|
|
||||||
} catch (InterruptedException ie) {
|
|
||||||
throw new RuntimeException(ie);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,378 +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.storage.ldap.noimport;
|
|
||||||
|
|
||||||
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.MultivaluedHashMap;
|
|
||||||
import org.keycloak.component.ComponentModel;
|
|
||||||
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.UserModel;
|
|
||||||
import org.keycloak.models.utils.KeycloakModelUtils;
|
|
||||||
import org.keycloak.services.managers.RealmManager;
|
|
||||||
import org.keycloak.storage.UserStorageProvider;
|
|
||||||
import org.keycloak.storage.UserStorageProviderModel;
|
|
||||||
import org.keycloak.storage.ldap.LDAPConfig;
|
|
||||||
import org.keycloak.storage.ldap.LDAPStorageProvider;
|
|
||||||
import org.keycloak.storage.ldap.LDAPStorageProviderFactory;
|
|
||||||
import org.keycloak.storage.ldap.LDAPUtils;
|
|
||||||
import org.keycloak.storage.ldap.idm.model.LDAPDn;
|
|
||||||
import org.keycloak.storage.ldap.idm.model.LDAPObject;
|
|
||||||
import org.keycloak.storage.ldap.mappers.membership.LDAPGroupMapperMode;
|
|
||||||
import org.keycloak.storage.ldap.mappers.membership.MembershipType;
|
|
||||||
import org.keycloak.storage.ldap.mappers.membership.group.GroupLDAPStorageMapper;
|
|
||||||
import org.keycloak.storage.ldap.mappers.membership.group.GroupLDAPStorageMapperFactory;
|
|
||||||
import org.keycloak.storage.ldap.mappers.membership.group.GroupMapperConfig;
|
|
||||||
import org.keycloak.testsuite.federation.storage.ldap.LDAPTestUtils;
|
|
||||||
import org.keycloak.testsuite.rule.KeycloakRule;
|
|
||||||
import org.keycloak.testsuite.rule.LDAPRule;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
|
||||||
*/
|
|
||||||
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
|
|
||||||
public class LDAPGroupMapperNoImportTest {
|
|
||||||
|
|
||||||
private static LDAPRule ldapRule = new LDAPRule();
|
|
||||||
|
|
||||||
private static ComponentModel ldapModel = null;
|
|
||||||
private static String descriptionAttrName = null;
|
|
||||||
|
|
||||||
|
|
||||||
static class GroupTestKeycloakSetup extends KeycloakRule.KeycloakSetup {
|
|
||||||
|
|
||||||
private final LDAPRule ldapRule;
|
|
||||||
|
|
||||||
ComponentModel ldapModel = null;
|
|
||||||
String descriptionAttrName = null;
|
|
||||||
|
|
||||||
|
|
||||||
public GroupTestKeycloakSetup(LDAPRule ldapRule) {
|
|
||||||
this.ldapRule = ldapRule;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
|
|
||||||
LDAPTestUtils.addLocalUser(manager.getSession(), appRealm, "mary", "mary@test.com", "password-app");
|
|
||||||
LDAPTestUtils.addLocalUser(manager.getSession(), appRealm, "john", "john@test.com", "password-app");
|
|
||||||
|
|
||||||
MultivaluedHashMap<String,String> ldapConfig = LDAPTestUtils.getLdapRuleConfig(ldapRule);
|
|
||||||
ldapConfig.putSingle(LDAPConstants.SYNC_REGISTRATIONS, "true");
|
|
||||||
ldapConfig.putSingle(LDAPConstants.EDIT_MODE, UserStorageProvider.EditMode.WRITABLE.toString());
|
|
||||||
UserStorageProviderModel model = new UserStorageProviderModel();
|
|
||||||
model.setLastSync(0);
|
|
||||||
model.setChangedSyncPeriod(-1);
|
|
||||||
model.setFullSyncPeriod(-1);
|
|
||||||
model.setName("test-ldap");
|
|
||||||
model.setPriority(0);
|
|
||||||
model.setProviderId(LDAPStorageProviderFactory.PROVIDER_NAME);
|
|
||||||
model.setConfig(ldapConfig);
|
|
||||||
model.setImportEnabled(false);
|
|
||||||
|
|
||||||
ldapModel = appRealm.addComponentModel(model);
|
|
||||||
LDAPStorageProvider ldapFedProvider = LDAPTestUtils.getLdapProvider(session, ldapModel);
|
|
||||||
descriptionAttrName = ldapFedProvider.getLdapIdentityStore().getConfig().isActiveDirectory() ? "displayName" : "description";
|
|
||||||
|
|
||||||
// Add group mapper
|
|
||||||
LDAPTestUtils.addOrUpdateGroupMapper(appRealm, ldapModel, LDAPGroupMapperMode.LDAP_ONLY, descriptionAttrName);
|
|
||||||
|
|
||||||
// Remove all LDAP groups
|
|
||||||
LDAPTestUtils.removeAllLDAPGroups(session, appRealm, ldapModel, "groupsMapper");
|
|
||||||
|
|
||||||
// Add some groups for testing
|
|
||||||
LDAPObject group1 = LDAPTestUtils.createLDAPGroup(manager.getSession(), appRealm, ldapModel, "group1", descriptionAttrName, "group1 - description");
|
|
||||||
LDAPObject group11 = LDAPTestUtils.createLDAPGroup(manager.getSession(), appRealm, ldapModel, "group11");
|
|
||||||
LDAPObject group12 = LDAPTestUtils.createLDAPGroup(manager.getSession(), appRealm, ldapModel, "group12", descriptionAttrName, "group12 - description");
|
|
||||||
|
|
||||||
LDAPObject defaultGroup1 = LDAPTestUtils.createLDAPGroup(manager.getSession(), appRealm, ldapModel, "defaultGroup1", descriptionAttrName, "Default Group1 - description");
|
|
||||||
LDAPObject defaultGroup11 = LDAPTestUtils.createLDAPGroup(manager.getSession(), appRealm, ldapModel, "defaultGroup11");
|
|
||||||
LDAPObject defaultGroup12 = LDAPTestUtils.createLDAPGroup(manager.getSession(), appRealm, ldapModel, "defaultGroup12", descriptionAttrName, "Default Group12 - description");
|
|
||||||
|
|
||||||
LDAPUtils.addMember(ldapFedProvider, MembershipType.DN, LDAPConstants.MEMBER, "not-used", group1, group11, false);
|
|
||||||
LDAPUtils.addMember(ldapFedProvider, MembershipType.DN, LDAPConstants.MEMBER, "not-used", group1, group12, true);
|
|
||||||
|
|
||||||
LDAPUtils.addMember(ldapFedProvider, MembershipType.DN, LDAPConstants.MEMBER, "not-used", defaultGroup1, defaultGroup11, false);
|
|
||||||
LDAPUtils.addMember(ldapFedProvider, MembershipType.DN, LDAPConstants.MEMBER, "not-used", defaultGroup1, defaultGroup12, true);
|
|
||||||
|
|
||||||
// Sync LDAP groups to Keycloak DB
|
|
||||||
ComponentModel mapperModel = LDAPTestUtils.getSubcomponentByName(appRealm, ldapModel, "groupsMapper");
|
|
||||||
new GroupLDAPStorageMapperFactory().create(session, mapperModel).syncDataFromFederationProviderToKeycloak(appRealm);
|
|
||||||
|
|
||||||
appRealm.addDefaultGroup(KeycloakModelUtils.findGroupByPath(appRealm, "/defaultGroup1/defaultGroup11"));
|
|
||||||
appRealm.addDefaultGroup(KeycloakModelUtils.findGroupByPath(appRealm, "/defaultGroup1/defaultGroup12"));
|
|
||||||
|
|
||||||
// Delete all LDAP users
|
|
||||||
LDAPTestUtils.removeAllLDAPUsers(ldapFedProvider, appRealm);
|
|
||||||
|
|
||||||
// Add some LDAP users for testing (because these are added directly to LDAP, they will not be added to the default groups defined above)
|
|
||||||
LDAPObject john = LDAPTestUtils.addLDAPUser(ldapFedProvider, appRealm, "johnkeycloak", "John", "Doe", "john@email.org", null, "1234");
|
|
||||||
LDAPTestUtils.updateLDAPPassword(ldapFedProvider, john, "Password1");
|
|
||||||
|
|
||||||
LDAPObject mary = LDAPTestUtils.addLDAPUser(ldapFedProvider, appRealm, "marykeycloak", "Mary", "Kelly", "mary@email.org", null, "5678");
|
|
||||||
LDAPTestUtils.updateLDAPPassword(ldapFedProvider, mary, "Password1");
|
|
||||||
|
|
||||||
postSetup(appRealm, ldapFedProvider);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void postSetup(RealmModel appRealm, LDAPStorageProvider ldapProvider) {
|
|
||||||
LDAPGroupMapperNoImportTest.ldapModel = this.ldapModel;
|
|
||||||
LDAPGroupMapperNoImportTest.descriptionAttrName = this.descriptionAttrName;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private static KeycloakRule keycloakRule = new KeycloakRule(new GroupTestKeycloakSetup(ldapRule));
|
|
||||||
|
|
||||||
@ClassRule
|
|
||||||
public static TestRule chain = RuleChain
|
|
||||||
.outerRule(ldapRule)
|
|
||||||
.around(keycloakRule);
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void test01ReadGroupMappings() {
|
|
||||||
KeycloakSession session = keycloakRule.startSession();
|
|
||||||
try {
|
|
||||||
RealmModel appRealm = session.realms().getRealmByName("test");
|
|
||||||
ComponentModel mapperModel = LDAPTestUtils.getSubcomponentByName(appRealm, ldapModel, "groupsMapper");
|
|
||||||
LDAPTestUtils.updateGroupMapperConfigOptions(mapperModel, GroupMapperConfig.MODE, LDAPGroupMapperMode.LDAP_ONLY.toString());
|
|
||||||
appRealm.updateComponent(mapperModel);
|
|
||||||
|
|
||||||
LDAPStorageProvider ldapProvider = LDAPTestUtils.getLdapProvider(session, ldapModel);
|
|
||||||
GroupLDAPStorageMapper groupMapper = LDAPTestUtils.getGroupMapper(mapperModel, ldapProvider, appRealm);
|
|
||||||
|
|
||||||
LDAPObject maryLdap = ldapProvider.loadLDAPUserByUsername(appRealm, "marykeycloak");
|
|
||||||
groupMapper.addGroupMappingInLDAP(appRealm, KeycloakModelUtils.findGroupByPath(appRealm, "/group1"), maryLdap);
|
|
||||||
groupMapper.addGroupMappingInLDAP(appRealm, KeycloakModelUtils.findGroupByPath(appRealm, "/group1/group11"), maryLdap);
|
|
||||||
} finally {
|
|
||||||
keycloakRule.stopSession(session, true);
|
|
||||||
}
|
|
||||||
session = keycloakRule.startSession();
|
|
||||||
try {
|
|
||||||
session.userCache().clear();
|
|
||||||
System.out.println("starting test01ReadGroupMappings");
|
|
||||||
RealmModel appRealm = session.realms().getRealmByName("test");
|
|
||||||
|
|
||||||
GroupModel group1 = KeycloakModelUtils.findGroupByPath(appRealm, "/group1");
|
|
||||||
Assert.assertNotNull(group1);
|
|
||||||
GroupModel group11 = KeycloakModelUtils.findGroupByPath(appRealm, "/group1/group11");
|
|
||||||
Assert.assertNotNull(group11);
|
|
||||||
GroupModel group12 = KeycloakModelUtils.findGroupByPath(appRealm, "/group1/group12");
|
|
||||||
Assert.assertNotNull(group12);
|
|
||||||
|
|
||||||
|
|
||||||
UserModel mary = session.users().getUserByUsername("marykeycloak", appRealm);
|
|
||||||
// make sure we are in no-import mode
|
|
||||||
Assert.assertNull(session.userLocalStorage().getUserByUsername("marykeycloak", appRealm));
|
|
||||||
// Assert that mary has both LDAP and DB mapped groups
|
|
||||||
Set<GroupModel> maryGroups = mary.getGroups();
|
|
||||||
Assert.assertEquals(2, maryGroups.size());
|
|
||||||
Assert.assertTrue(maryGroups.contains(group1));
|
|
||||||
Assert.assertTrue(maryGroups.contains(group11));
|
|
||||||
|
|
||||||
// Check through userProvider
|
|
||||||
List<UserModel> group1Members = session.users().getGroupMembers(appRealm, group1, 0, 10);
|
|
||||||
List<UserModel> group11Members = session.users().getGroupMembers(appRealm, group11, 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());
|
|
||||||
|
|
||||||
// Delete role mappings directly in LDAP
|
|
||||||
LDAPStorageProvider ldapProvider = LDAPTestUtils.getLdapProvider(session, ldapModel);
|
|
||||||
ComponentModel mapperModel = LDAPTestUtils.getSubcomponentByName(appRealm,ldapModel, "groupsMapper");
|
|
||||||
GroupLDAPStorageMapper groupMapper = LDAPTestUtils.getGroupMapper(mapperModel, ldapProvider, appRealm);
|
|
||||||
LDAPObject maryLdap = ldapProvider.loadLDAPUserByUsername(appRealm, "marykeycloak");
|
|
||||||
deleteGroupMappingsInLDAP(groupMapper, maryLdap, "group1");
|
|
||||||
deleteGroupMappingsInLDAP(groupMapper, maryLdap, "group11");
|
|
||||||
} finally {
|
|
||||||
keycloakRule.stopSession(session, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void test02WriteGroupMappings() {
|
|
||||||
KeycloakSession session = keycloakRule.startSession();
|
|
||||||
try {
|
|
||||||
RealmModel appRealm = session.realms().getRealmByName("test");
|
|
||||||
|
|
||||||
ComponentModel mapperModel = LDAPTestUtils.getSubcomponentByName(appRealm, ldapModel, "groupsMapper");
|
|
||||||
LDAPTestUtils.updateGroupMapperConfigOptions(mapperModel, GroupMapperConfig.MODE, LDAPGroupMapperMode.LDAP_ONLY.toString());
|
|
||||||
appRealm.updateComponent(mapperModel);
|
|
||||||
|
|
||||||
UserModel john = session.users().getUserByUsername("johnkeycloak", appRealm);
|
|
||||||
UserModel mary = session.users().getUserByUsername("marykeycloak", appRealm);
|
|
||||||
|
|
||||||
// make sure we are in no-import mode
|
|
||||||
Assert.assertNull(session.userLocalStorage().getUserByUsername("johnkeycloak", appRealm));
|
|
||||||
Assert.assertNull(session.userLocalStorage().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);
|
|
||||||
} finally {
|
|
||||||
keycloakRule.stopSession(session, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
session = keycloakRule.startSession();
|
|
||||||
try {
|
|
||||||
session.userCache().clear(); // clear cache to make sure we're reloading from LDAP.
|
|
||||||
RealmModel appRealm = session.realms().getRealmByName("test");
|
|
||||||
GroupModel group1 = KeycloakModelUtils.findGroupByPath(appRealm, "/group1");
|
|
||||||
GroupModel group11 = KeycloakModelUtils.findGroupByPath(appRealm, "/group1/group11");
|
|
||||||
GroupModel group12 = KeycloakModelUtils.findGroupByPath(appRealm, "/group1/group12");
|
|
||||||
|
|
||||||
UserModel john = session.users().getUserByUsername("johnkeycloak", appRealm);
|
|
||||||
UserModel mary = session.users().getUserByUsername("marykeycloak", appRealm);
|
|
||||||
|
|
||||||
// make sure we are in no-import mode
|
|
||||||
Assert.assertNull(session.userLocalStorage().getUserByUsername("johnkeycloak", appRealm));
|
|
||||||
Assert.assertNull(session.userLocalStorage().getUserByUsername("marykeycloak", appRealm));
|
|
||||||
|
|
||||||
// 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(group11);
|
|
||||||
mary.leaveGroup(group12);
|
|
||||||
} finally {
|
|
||||||
keycloakRule.stopSession(session, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
session = keycloakRule.startSession();
|
|
||||||
try {
|
|
||||||
session.userCache().clear(); // clear cache to make sure we're reloading from LDAP.
|
|
||||||
RealmModel appRealm = session.realms().getRealmByName("test");
|
|
||||||
|
|
||||||
UserModel john = session.users().getUserByUsername("johnkeycloak", appRealm);
|
|
||||||
UserModel mary = session.users().getUserByUsername("marykeycloak", appRealm);
|
|
||||||
|
|
||||||
// make sure we are in no-import mode
|
|
||||||
Assert.assertNull(session.userLocalStorage().getUserByUsername("johnkeycloak", appRealm));
|
|
||||||
Assert.assertNull(session.userLocalStorage().getUserByUsername("marykeycloak", appRealm));
|
|
||||||
session.userCache().clear(); // clear cache to make sure we're reloading from LDAP.
|
|
||||||
Set<GroupModel> johnGroups = john.getGroups();
|
|
||||||
Assert.assertEquals(0, johnGroups.size());
|
|
||||||
Set<GroupModel> maryGroups = mary.getGroups();
|
|
||||||
Assert.assertEquals(0, maryGroups.size());
|
|
||||||
|
|
||||||
} finally {
|
|
||||||
keycloakRule.stopSession(session, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void test03_newUserDefaultGroupsNoImportModeTest() throws Exception {
|
|
||||||
|
|
||||||
// Check user group memberships
|
|
||||||
KeycloakSession session = keycloakRule.startSession();
|
|
||||||
try {
|
|
||||||
RealmModel appRealm = session.realms().getRealmByName("test");
|
|
||||||
|
|
||||||
UserModel rob = session.users().addUser(appRealm, "robkeycloak");
|
|
||||||
// make sure we are in no-import mode
|
|
||||||
Assert.assertNull(session.userLocalStorage().getUserByUsername("robkeycloak", appRealm));
|
|
||||||
|
|
||||||
GroupModel defaultGroup11 = KeycloakModelUtils.findGroupByPath(appRealm, "/defaultGroup1/defaultGroup11");
|
|
||||||
Assert.assertNotNull(defaultGroup11);
|
|
||||||
|
|
||||||
GroupModel defaultGroup12 = KeycloakModelUtils.findGroupByPath(appRealm, "/defaultGroup1/defaultGroup12");
|
|
||||||
Assert.assertNotNull(defaultGroup12);
|
|
||||||
|
|
||||||
GroupModel group1 = KeycloakModelUtils.findGroupByPath(appRealm, "/group1");
|
|
||||||
Assert.assertNotNull(group1);
|
|
||||||
GroupModel group11 = KeycloakModelUtils.findGroupByPath(appRealm, "/group1/group11");
|
|
||||||
Assert.assertNotNull(group11);
|
|
||||||
GroupModel group12 = KeycloakModelUtils.findGroupByPath(appRealm, "/group1/group12");
|
|
||||||
Assert.assertNotNull(group12);
|
|
||||||
|
|
||||||
// 4 - Check through userProvider
|
|
||||||
List<UserModel> defaultGroup11Members = session.users().getGroupMembers(appRealm, defaultGroup11, 0, 10);
|
|
||||||
List<UserModel> defaultGroup12Members = session.users().getGroupMembers(appRealm, defaultGroup12, 0, 10);
|
|
||||||
|
|
||||||
Assert.assertEquals(1, defaultGroup11Members.size());
|
|
||||||
Assert.assertEquals("robkeycloak", defaultGroup11Members.get(0).getUsername());
|
|
||||||
Assert.assertEquals(1, defaultGroup12Members.size());
|
|
||||||
Assert.assertEquals("robkeycloak", defaultGroup12Members.get(0).getUsername());
|
|
||||||
|
|
||||||
|
|
||||||
Set<GroupModel> groups = rob.getGroups();
|
|
||||||
Assert.assertTrue(groups.contains(defaultGroup11));
|
|
||||||
Assert.assertTrue(groups.contains(defaultGroup12));
|
|
||||||
Assert.assertFalse(groups.contains(group1));
|
|
||||||
Assert.assertFalse(groups.contains(group11));
|
|
||||||
Assert.assertFalse(groups.contains(group12));
|
|
||||||
} finally {
|
|
||||||
keycloakRule.stopSession(session, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private void deleteGroupMappingsInLDAP(GroupLDAPStorageMapper groupMapper, LDAPObject ldapUser, String groupName) {
|
|
||||||
LDAPObject ldapGroup = groupMapper.loadLDAPGroupByName(groupName);
|
|
||||||
groupMapper.deleteGroupMappingInLDAP(ldapUser, ldapGroup);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,112 +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.storage.ldap.noimport;
|
|
||||||
|
|
||||||
import org.junit.Assert;
|
|
||||||
import org.junit.Before;
|
|
||||||
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.common.util.MultivaluedHashMap;
|
|
||||||
import org.keycloak.component.ComponentModel;
|
|
||||||
import org.keycloak.models.ClientModel;
|
|
||||||
import org.keycloak.models.KeycloakSession;
|
|
||||||
import org.keycloak.models.LDAPConstants;
|
|
||||||
import org.keycloak.models.RealmModel;
|
|
||||||
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.storage.UserStorageProvider;
|
|
||||||
import org.keycloak.storage.UserStorageProviderModel;
|
|
||||||
import org.keycloak.storage.ldap.LDAPStorageProvider;
|
|
||||||
import org.keycloak.storage.ldap.LDAPStorageProviderFactory;
|
|
||||||
import org.keycloak.storage.ldap.idm.model.LDAPObject;
|
|
||||||
import org.keycloak.testsuite.OAuthClient;
|
|
||||||
import org.keycloak.testsuite.federation.storage.ldap.LDAPExampleServlet;
|
|
||||||
import org.keycloak.testsuite.federation.storage.ldap.LDAPMultipleAttributesTest;
|
|
||||||
import org.keycloak.testsuite.federation.storage.ldap.LDAPTestUtils;
|
|
||||||
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 LDAPMultipleAttributesNoImportTest extends LDAPMultipleAttributesTest {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void checkUserAndImportMode(KeycloakSession session, RealmModel realm, String username, String expectedFirstName, String expectedLastName, String expectedEmail, String expectedPostalCode) {
|
|
||||||
UserModel user = session.users().getUserByUsername(username, realm);
|
|
||||||
Assert.assertNull(session.userLocalStorage().getUserByUsername(username, realm));
|
|
||||||
LDAPTestUtils.assertLoaded(user, username, expectedFirstName, expectedLastName, expectedEmail, expectedPostalCode);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void checkImportMode(KeycloakSession session, RealmModel realm, UserModel user) {
|
|
||||||
Assert.assertNull(session.userLocalStorage().getUserById(user.getId(), realm));
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Before
|
|
||||||
public void setNoImportMode() throws Exception {
|
|
||||||
KeycloakSession session = keycloakRule.startSession();
|
|
||||||
try {
|
|
||||||
session.userCache().clear();
|
|
||||||
RealmModel appRealm = session.realms().getRealmByName("test");
|
|
||||||
ldapModel.setImportEnabled(false);
|
|
||||||
appRealm.updateComponent(ldapModel);
|
|
||||||
|
|
||||||
} finally {
|
|
||||||
keycloakRule.stopSession(session, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testModel() {
|
|
||||||
super.testModel();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void ldapPortalEndToEndTest() {
|
|
||||||
super.ldapPortalEndToEndTest();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
@ -1,989 +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.storage.ldap.noimport;
|
|
||||||
|
|
||||||
import org.jboss.logging.Logger;
|
|
||||||
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.admin.client.Keycloak;
|
|
||||||
import org.keycloak.admin.client.resource.RealmResource;
|
|
||||||
import org.keycloak.common.util.MultivaluedHashMap;
|
|
||||||
import org.keycloak.component.ComponentModel;
|
|
||||||
import org.keycloak.credential.CredentialModel;
|
|
||||||
import org.keycloak.models.Constants;
|
|
||||||
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.RoleModel;
|
|
||||||
import org.keycloak.models.UserCredentialModel;
|
|
||||||
import org.keycloak.models.UserModel;
|
|
||||||
import org.keycloak.models.utils.KeycloakModelUtils;
|
|
||||||
import org.keycloak.representations.AccessToken;
|
|
||||||
import org.keycloak.representations.idm.CredentialRepresentation;
|
|
||||||
import org.keycloak.representations.idm.UserRepresentation;
|
|
||||||
import org.keycloak.services.managers.RealmManager;
|
|
||||||
import org.keycloak.storage.ReadOnlyException;
|
|
||||||
import org.keycloak.storage.StorageId;
|
|
||||||
import org.keycloak.storage.UserStorageProvider;
|
|
||||||
import org.keycloak.storage.UserStorageProviderModel;
|
|
||||||
import org.keycloak.storage.ldap.LDAPConfig;
|
|
||||||
import org.keycloak.storage.ldap.LDAPStorageProvider;
|
|
||||||
import org.keycloak.storage.ldap.LDAPStorageProviderFactory;
|
|
||||||
import org.keycloak.storage.ldap.idm.model.LDAPObject;
|
|
||||||
import org.keycloak.storage.ldap.mappers.FullNameLDAPStorageMapper;
|
|
||||||
import org.keycloak.storage.ldap.mappers.FullNameLDAPStorageMapperFactory;
|
|
||||||
import org.keycloak.storage.ldap.mappers.HardcodedLDAPGroupStorageMapper;
|
|
||||||
import org.keycloak.storage.ldap.mappers.HardcodedLDAPGroupStorageMapperFactory;
|
|
||||||
import org.keycloak.storage.ldap.mappers.HardcodedLDAPRoleStorageMapper;
|
|
||||||
import org.keycloak.storage.ldap.mappers.HardcodedLDAPRoleStorageMapperFactory;
|
|
||||||
import org.keycloak.storage.ldap.mappers.LDAPStorageMapper;
|
|
||||||
import org.keycloak.storage.ldap.mappers.UserAttributeLDAPStorageMapper;
|
|
||||||
import org.keycloak.testsuite.ApiUtil;
|
|
||||||
import org.keycloak.testsuite.OAuthClient;
|
|
||||||
import org.keycloak.testsuite.federation.storage.ldap.LDAPTestUtils;
|
|
||||||
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.openqa.selenium.WebDriver;
|
|
||||||
|
|
||||||
import javax.ws.rs.core.Response;
|
|
||||||
import java.util.LinkedList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.MASTER;
|
|
||||||
import static org.junit.Assert.assertEquals;
|
|
||||||
import static org.keycloak.models.AdminRoles.ADMIN;
|
|
||||||
import static org.keycloak.testsuite.Constants.AUTH_SERVER_ROOT;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
|
||||||
*/
|
|
||||||
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
|
|
||||||
public class LDAPProvidersIntegrationNoImportTest {
|
|
||||||
|
|
||||||
private static final Logger log = Logger.getLogger(LDAPProvidersIntegrationNoImportTest.class);
|
|
||||||
|
|
||||||
private static LDAPRule ldapRule = new LDAPRule();
|
|
||||||
|
|
||||||
private static ComponentModel ldapModel = null;
|
|
||||||
|
|
||||||
|
|
||||||
private static KeycloakRule keycloakRule = new KeycloakRule(new KeycloakRule.KeycloakSetup() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
|
|
||||||
LDAPTestUtils.addLocalUser(manager.getSession(), appRealm, "marykeycloak", "mary@test.com", "password-app");
|
|
||||||
|
|
||||||
MultivaluedHashMap<String,String> ldapConfig = LDAPTestUtils.getLdapRuleConfig(ldapRule);
|
|
||||||
ldapConfig.putSingle(LDAPConstants.SYNC_REGISTRATIONS, "true");
|
|
||||||
ldapConfig.putSingle(LDAPConstants.EDIT_MODE, UserStorageProvider.EditMode.WRITABLE.toString());
|
|
||||||
UserStorageProviderModel model = new UserStorageProviderModel();
|
|
||||||
model.setLastSync(0);
|
|
||||||
model.setChangedSyncPeriod(-1);
|
|
||||||
model.setFullSyncPeriod(-1);
|
|
||||||
model.setName("test-ldap");
|
|
||||||
model.setPriority(0);
|
|
||||||
model.setProviderId(LDAPStorageProviderFactory.PROVIDER_NAME);
|
|
||||||
model.setConfig(ldapConfig);
|
|
||||||
model.setImportEnabled(false);
|
|
||||||
|
|
||||||
ldapModel = appRealm.addComponentModel(model);
|
|
||||||
LDAPTestUtils.addZipCodeLDAPMapper(appRealm, ldapModel);
|
|
||||||
|
|
||||||
// Delete all LDAP users and add some new for testing
|
|
||||||
LDAPStorageProvider ldapFedProvider = LDAPTestUtils.getLdapProvider(session, ldapModel);
|
|
||||||
LDAPTestUtils.removeAllLDAPUsers(ldapFedProvider, appRealm);
|
|
||||||
|
|
||||||
LDAPObject john = LDAPTestUtils.addLDAPUser(ldapFedProvider, appRealm, "johnkeycloak", "John", "Doe", "john@email.org", null, "1234");
|
|
||||||
LDAPTestUtils.updateLDAPPassword(ldapFedProvider, john, "Password1");
|
|
||||||
|
|
||||||
LDAPObject existing = LDAPTestUtils.addLDAPUser(ldapFedProvider, appRealm, "existing", "Existing", "Foo", "existing@email.org", null, "5678");
|
|
||||||
|
|
||||||
appRealm.getClientByClientId("test-app").setDirectAccessGrantsEnabled(true);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
@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);
|
|
||||||
//
|
|
||||||
// }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* KEYCLOAK-3986
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
@Test
|
|
||||||
public void testSyncRegistrationOff() {
|
|
||||||
KeycloakSession session = keycloakRule.startSession();
|
|
||||||
try {
|
|
||||||
RealmManager manager = new RealmManager(session);
|
|
||||||
RealmModel appRealm = manager.getRealm("test");
|
|
||||||
UserStorageProviderModel newModel = new UserStorageProviderModel(ldapModel);
|
|
||||||
newModel.getConfig().putSingle(LDAPConstants.SYNC_REGISTRATIONS, "false");
|
|
||||||
appRealm.updateComponent(newModel);
|
|
||||||
UserModel newUser1 = session.users().addUser(appRealm, "newUser1");
|
|
||||||
Assert.assertTrue(StorageId.isLocalStorage(newUser1));
|
|
||||||
} finally {
|
|
||||||
keycloakRule.stopSession(session, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void caseInSensitiveImport() {
|
|
||||||
KeycloakSession session = keycloakRule.startSession();
|
|
||||||
try {
|
|
||||||
RealmManager manager = new RealmManager(session);
|
|
||||||
RealmModel appRealm = manager.getRealm("test");
|
|
||||||
LDAPStorageProvider ldapFedProvider = LDAPTestUtils.getLdapProvider(session, ldapModel);
|
|
||||||
LDAPObject jbrown2 = LDAPTestUtils.addLDAPUser(ldapFedProvider, appRealm, "JBrown2", "John", "Brown2", "jbrown2@email.org", null, "1234");
|
|
||||||
LDAPTestUtils.updateLDAPPassword(ldapFedProvider, jbrown2, "Password1");
|
|
||||||
LDAPObject jbrown3 = LDAPTestUtils.addLDAPUser(ldapFedProvider, appRealm, "jbrown3", "John", "Brown3", "JBrown3@email.org", null, "1234");
|
|
||||||
LDAPTestUtils.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 testLDAPUserImportOnCreationOrLogin() {
|
|
||||||
|
|
||||||
KeycloakSession session = keycloakRule.startSession();
|
|
||||||
RealmModel appRealm = new RealmManager(session).getRealmByName("test");
|
|
||||||
LDAPStorageProvider ldapProvider = LDAPTestUtils.getLdapProvider(session, ldapModel);
|
|
||||||
LDAPConfig config = ldapProvider.getLdapIdentityStore().getConfig();
|
|
||||||
|
|
||||||
// Make sure mary is gone
|
|
||||||
LDAPTestUtils.removeLDAPUserByUsername(ldapProvider, appRealm, config, "maryjane");
|
|
||||||
|
|
||||||
|
|
||||||
// Create the user in LDAP and register him
|
|
||||||
//
|
|
||||||
LDAPObject mary = LDAPTestUtils.addLDAPUser(ldapProvider, appRealm, "maryjane", "mary", "yram", "mj@testing.redhat.cz", null, "12398");
|
|
||||||
LDAPTestUtils.updateLDAPPassword(ldapProvider, mary, "Password1");
|
|
||||||
|
|
||||||
try {
|
|
||||||
|
|
||||||
// Log in and out of the user
|
|
||||||
loginSuccessAndLogout("maryjane", "Password1");
|
|
||||||
|
|
||||||
// Delete LDAP User
|
|
||||||
LDAPTestUtils.removeLDAPUserByUsername(ldapProvider, appRealm, config, "maryjane");
|
|
||||||
|
|
||||||
// Make sure the deletion took place.
|
|
||||||
List<UserModel> deletedUsers = session.users().searchForUser("mary yram", appRealm);
|
|
||||||
Assert.assertTrue(deletedUsers.isEmpty());
|
|
||||||
|
|
||||||
} finally {
|
|
||||||
keycloakRule.stopSession(session, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void caseInsensitiveSearch() {
|
|
||||||
KeycloakSession session = keycloakRule.startSession();
|
|
||||||
try {
|
|
||||||
RealmManager manager = new RealmManager(session);
|
|
||||||
RealmModel appRealm = manager.getRealm("test");
|
|
||||||
LDAPStorageProvider ldapFedProvider = LDAPTestUtils.getLdapProvider(session, ldapModel);
|
|
||||||
LDAPObject jbrown4 = LDAPTestUtils.addLDAPUser(ldapFedProvider, appRealm, "JBrown4", "John", "Brown4", "jbrown4@email.org", null, "1234");
|
|
||||||
LDAPTestUtils.updateLDAPPassword(ldapFedProvider, jbrown4, "Password1");
|
|
||||||
LDAPObject jbrown5 = LDAPTestUtils.addLDAPUser(ldapFedProvider, appRealm, "jbrown5", "John", "Brown5", "JBrown5@Email.org", null, "1234");
|
|
||||||
LDAPTestUtils.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.removeComponent(ldapModel);
|
|
||||||
Assert.assertEquals(0, appRealm.getComponents(appRealm.getId(), UserStorageProvider.class.getName()).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.setId(null);
|
|
||||||
ldapModel = appRealm.addComponentModel(ldapModel);
|
|
||||||
LDAPTestUtils.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.assertFalse(StorageId.isLocalStorage(user));
|
|
||||||
Assert.assertEquals(StorageId.providerId(user.getId()), ldapModel.getId());
|
|
||||||
Assert.assertEquals("registerusersuccess2", user.getUsername());
|
|
||||||
Assert.assertEquals("firstName", user.getFirstName());
|
|
||||||
Assert.assertEquals("lastName", user.getLastName());
|
|
||||||
Assert.assertTrue(user.isEnabled());
|
|
||||||
} finally {
|
|
||||||
keycloakRule.stopSession(session, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testCaseSensitiveAttributeName() {
|
|
||||||
KeycloakSession session = keycloakRule.startSession();
|
|
||||||
|
|
||||||
try {
|
|
||||||
RealmModel appRealm = new RealmManager(session).getRealmByName("test");
|
|
||||||
|
|
||||||
LDAPStorageProvider ldapFedProvider = LDAPTestUtils.getLdapProvider(session, ldapModel);
|
|
||||||
LDAPObject johnZip = LDAPTestUtils.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
|
|
||||||
ComponentModel currentZipMapper = LDAPTestUtils.getSubcomponentByName(appRealm, ldapModel, "zipCodeMapper");
|
|
||||||
appRealm.removeComponent(currentZipMapper);
|
|
||||||
LDAPTestUtils.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");
|
|
||||||
LDAPStorageProvider ldapFedProvider = LDAPTestUtils.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 = LDAPTestUtils.addLDAPUser(ldapFedProvider, appRealm, "john,comma", "John", "Comma", "johncomma@email.org", null, "12387");
|
|
||||||
LDAPTestUtils.updateLDAPPassword(ldapFedProvider, johnComma, "Password1");
|
|
||||||
|
|
||||||
LDAPObject johnPlus = LDAPTestUtils.addLDAPUser(ldapFedProvider, appRealm, "john+plus,comma", "John", "Plus", "johnplus@email.org", null, "12387");
|
|
||||||
LDAPTestUtils.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 // don't think we should support this, bburke
|
|
||||||
public void testDirectLDAPUpdate() {
|
|
||||||
KeycloakSession session = keycloakRule.startSession();
|
|
||||||
|
|
||||||
try {
|
|
||||||
RealmModel appRealm = new RealmManager(session).getRealmByName("test");
|
|
||||||
|
|
||||||
LDAPStorageProvider ldapFedProvider = LDAPTestUtils.getLdapProvider(session, ldapModel);
|
|
||||||
LDAPObject johnDirect = LDAPTestUtils.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
|
|
||||||
ComponentModel zipMapper = LDAPTestUtils.getSubcomponentByName(appRealm, ldapModel, "zipCodeMapper");
|
|
||||||
zipMapper.getConfig().putSingle(UserAttributeLDAPStorageMapper.ALWAYS_READ_VALUE_FROM_LDAP, "true");
|
|
||||||
appRealm.updateComponent(zipMapper);
|
|
||||||
|
|
||||||
// Update lastName mapper to read the value from Keycloak DB
|
|
||||||
ComponentModel lastNameMapper = LDAPTestUtils.getSubcomponentByName(appRealm, ldapModel, "last name");
|
|
||||||
lastNameMapper.getConfig().putSingle(UserAttributeLDAPStorageMapper.ALWAYS_READ_VALUE_FROM_LDAP, "false");
|
|
||||||
appRealm.updateComponent(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();
|
|
||||||
ComponentModel 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)
|
|
||||||
LDAPStorageProvider ldapFedProvider = LDAPTestUtils.getLdapProvider(session, ldapModel);
|
|
||||||
LDAPTestUtils.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 = LDAPTestUtils.getSubcomponentByName(appRealm, ldapModel, "first name");
|
|
||||||
String ldapFirstNameAttributeName = firstNameMapper.getConfig().getFirst(UserAttributeLDAPStorageMapper.LDAP_ATTRIBUTE);
|
|
||||||
appRealm.removeComponent(firstNameMapper);
|
|
||||||
|
|
||||||
ComponentModel fullNameMapperModel = KeycloakModelUtils.createComponentModel("full name", ldapModel.getId(), FullNameLDAPStorageMapperFactory.PROVIDER_ID, LDAPStorageMapper.class.getName(),
|
|
||||||
FullNameLDAPStorageMapper.LDAP_FULL_NAME_ATTRIBUTE, ldapFirstNameAttributeName,
|
|
||||||
FullNameLDAPStorageMapper.READ_ONLY, "false");
|
|
||||||
appRealm.addComponentModel(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
|
|
||||||
LDAPTestUtils.assertUserImported(session.users(), appRealm, "fullname", "James", "Dee", "fullname@email.org", "4578");
|
|
||||||
|
|
||||||
} 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
|
|
||||||
LDAPTestUtils.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
|
|
||||||
ComponentModel fullNameMapperModel = LDAPTestUtils.getSubcomponentByName(appRealm, ldapModel, "full name");
|
|
||||||
appRealm.removeComponent(fullNameMapperModel);
|
|
||||||
|
|
||||||
firstNameMapper.setId(null);
|
|
||||||
appRealm.addComponentModel(firstNameMapper);
|
|
||||||
} finally {
|
|
||||||
keycloakRule.stopSession(session, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testHardcodedRoleMapper() {
|
|
||||||
KeycloakSession session = keycloakRule.startSession();
|
|
||||||
ComponentModel 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));
|
|
||||||
|
|
||||||
ComponentModel hardcodedMapperModel = KeycloakModelUtils.createComponentModel("hardcoded role", ldapModel.getId(), HardcodedLDAPRoleStorageMapperFactory.PROVIDER_ID, LDAPStorageMapper.class.getName(),
|
|
||||||
HardcodedLDAPRoleStorageMapper.ROLE, "hardcoded-role");
|
|
||||||
appRealm.addComponentModel(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
|
|
||||||
ComponentModel hardcodedMapperModel = LDAPTestUtils.getSubcomponentByName(appRealm, ldapModel, "hardcoded role");
|
|
||||||
appRealm.removeComponent(hardcodedMapperModel);
|
|
||||||
} finally {
|
|
||||||
keycloakRule.stopSession(session, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testHardcodedGroupMapper() {
|
|
||||||
KeycloakSession session = keycloakRule.startSession();
|
|
||||||
ComponentModel firstNameMapper = null;
|
|
||||||
|
|
||||||
try {
|
|
||||||
RealmModel appRealm = new RealmManager(session).getRealmByName("test");
|
|
||||||
GroupModel hardcodedGroup = appRealm.createGroup("hardcoded-group", "hardcoded-group");
|
|
||||||
|
|
||||||
// assert that user "johnkeycloak" doesn't have hardcoded group
|
|
||||||
UserModel john = session.users().getUserByUsername("johnkeycloak", appRealm);
|
|
||||||
Assert.assertFalse(john.isMemberOf(hardcodedGroup));
|
|
||||||
|
|
||||||
ComponentModel hardcodedMapperModel = KeycloakModelUtils.createComponentModel("hardcoded group", ldapModel.getId(), HardcodedLDAPGroupStorageMapperFactory.PROVIDER_ID, LDAPStorageMapper.class.getName(),
|
|
||||||
HardcodedLDAPGroupStorageMapper.GROUP, "hardcoded-group");
|
|
||||||
appRealm.addComponentModel(hardcodedMapperModel);
|
|
||||||
} finally {
|
|
||||||
keycloakRule.stopSession(session, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
session = keycloakRule.startSession();
|
|
||||||
try {
|
|
||||||
RealmModel appRealm = new RealmManager(session).getRealmByName("test");
|
|
||||||
GroupModel hardcodedGroup = appRealm.getGroupById("hardcoded-group");
|
|
||||||
|
|
||||||
// Assert user is successfully imported in Keycloak DB now with correct firstName and lastName
|
|
||||||
UserModel john = session.users().getUserByUsername("johnkeycloak", appRealm);
|
|
||||||
Assert.assertTrue(john.isMemberOf(hardcodedGroup));
|
|
||||||
|
|
||||||
// Can't remove user from hardcoded role
|
|
||||||
try {
|
|
||||||
john.leaveGroup(hardcodedGroup);
|
|
||||||
Assert.fail("Didn't expected to leave group");
|
|
||||||
} catch (ModelException expected) {
|
|
||||||
}
|
|
||||||
|
|
||||||
// Revert mappers
|
|
||||||
ComponentModel hardcodedMapperModel = LDAPTestUtils.getSubcomponentByName(appRealm, ldapModel, "hardcoded group");
|
|
||||||
appRealm.removeComponent(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) {
|
|
||||||
LDAPStorageProvider ldapFedProvider = LDAPTestUtils.getLdapProvider(session, ldapModel);
|
|
||||||
LDAPTestUtils.addLDAPUser(ldapFedProvider, appRealm, "marykeycloak", "Mary1", "Kelly1", "mary1@email.org", null, "123");
|
|
||||||
LDAPTestUtils.addLDAPUser(ldapFedProvider, appRealm, "mary-duplicatemail", "Mary2", "Kelly2", "mary@test.com", null, "123");
|
|
||||||
LDAPObject marynoemail = LDAPTestUtils.addLDAPUser(ldapFedProvider, appRealm, "marynoemail", "Mary1", "Kelly1", null, null, "123");
|
|
||||||
LDAPTestUtils.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");
|
|
||||||
|
|
||||||
UserStorageProviderModel model = new UserStorageProviderModel(ldapModel);
|
|
||||||
model.getConfig().putSingle(LDAPConstants.EDIT_MODE, UserStorageProvider.EditMode.READ_ONLY.toString());
|
|
||||||
appRealm.updateComponent(model);
|
|
||||||
UserModel user = session.users().getUserByUsername("johnkeycloak", appRealm);
|
|
||||||
Assert.assertNotNull(user);
|
|
||||||
try {
|
|
||||||
user.setEmail("error@error.com");
|
|
||||||
Assert.fail("should fail");
|
|
||||||
} catch (ReadOnlyException e) {
|
|
||||||
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
user.setLastName("Berk");
|
|
||||||
Assert.fail("should fail");
|
|
||||||
} catch (ReadOnlyException e) {
|
|
||||||
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
user.setFirstName("Bilbo");
|
|
||||||
Assert.fail("should fail");
|
|
||||||
} catch (ReadOnlyException e) {
|
|
||||||
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
UserCredentialModel cred = UserCredentialModel.password("PoopyPoop1", true);
|
|
||||||
session.userCredentialManager().updateCredential(appRealm, user, cred);
|
|
||||||
Assert.fail("should fail");
|
|
||||||
} catch (ReadOnlyException 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(UserStorageProvider.EditMode.WRITABLE.toString(), appRealm.getComponent(ldapModel.getId()).getConfig().getFirst(LDAPConstants.EDIT_MODE));
|
|
||||||
} finally {
|
|
||||||
keycloakRule.stopSession(session, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testRemoveFederatedUser() {
|
|
||||||
/*
|
|
||||||
{
|
|
||||||
KeycloakSession session = keycloakRule.startSession();
|
|
||||||
RealmModel appRealm = session.realms().getRealmByName("test");
|
|
||||||
UserModel user = session.users().getUserByUsername("registerUserSuccess2", appRealm);
|
|
||||||
keycloakRule.stopSession(session, true);
|
|
||||||
if (user == null) {
|
|
||||||
registerUserLdapSuccess();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
KeycloakSession session = keycloakRule.startSession();
|
|
||||||
try {
|
|
||||||
RealmModel appRealm = session.realms().getRealmByName("test");
|
|
||||||
UserModel user = session.users().getUserByUsername("registerUserSuccess2", appRealm);
|
|
||||||
Assert.assertNotNull(user);
|
|
||||||
Assert.assertFalse(StorageId.isLocalStorage(user));
|
|
||||||
Assert.assertEquals(StorageId.providerId(user.getId()), 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");
|
|
||||||
LDAPStorageProvider ldapProvider = LDAPTestUtils.getLdapProvider(session, ldapModel);
|
|
||||||
|
|
||||||
LDAPTestUtils.addLDAPUser(ldapProvider, appRealm, "username1", "John1", "Doel1", "user1@email.org", null, "121");
|
|
||||||
LDAPTestUtils.addLDAPUser(ldapProvider, appRealm, "username2", "John2", "Doel2", "user2@email.org", null, "122");
|
|
||||||
LDAPTestUtils.addLDAPUser(ldapProvider, appRealm, "username3", "John3", "Doel3", "user3@email.org", null, "123");
|
|
||||||
LDAPTestUtils.addLDAPUser(ldapProvider, appRealm, "username4", "John4", "Doel4", "user4@email.org", null, "124");
|
|
||||||
|
|
||||||
// Users are not at local store at this moment
|
|
||||||
Assert.assertNull(session.userLocalStorage().getUserByUsername("username1", appRealm));
|
|
||||||
Assert.assertNull(session.userLocalStorage().getUserByUsername("username2", appRealm));
|
|
||||||
Assert.assertNull(session.userLocalStorage().getUserByUsername("username3", appRealm));
|
|
||||||
Assert.assertNull(session.userLocalStorage().getUserByUsername("username4", appRealm));
|
|
||||||
|
|
||||||
UserModel user;
|
|
||||||
// search by username
|
|
||||||
user = session.users().searchForUser("username1", appRealm).get(0);
|
|
||||||
LDAPTestUtils.assertLoaded(user, "username1", "John1", "Doel1", "user1@email.org", "121");
|
|
||||||
|
|
||||||
// search by email
|
|
||||||
user = session.users().searchForUser("user2@email.org", appRealm).get(0);
|
|
||||||
LDAPTestUtils.assertLoaded(user, "username2", "John2", "Doel2", "user2@email.org", "122");
|
|
||||||
|
|
||||||
// search by lastName
|
|
||||||
user = session.users().searchForUser("Doel3", appRealm).get(0);
|
|
||||||
LDAPTestUtils.assertLoaded(user, "username3", "John3", "Doel3", "user3@email.org", "123");
|
|
||||||
|
|
||||||
// search by firstName + lastName
|
|
||||||
user = session.users().searchForUser("John4 Doel4", appRealm).get(0);
|
|
||||||
LDAPTestUtils.assertLoaded(user, "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().putSingle(LDAPConstants.CUSTOM_USER_SEARCH_FILTER, "(|(mail=user5@email.org)(mail=user6@email.org))");
|
|
||||||
appRealm.updateComponent(ldapModel);
|
|
||||||
} finally {
|
|
||||||
keycloakRule.stopSession(session, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
session = keycloakRule.startSession();
|
|
||||||
try {
|
|
||||||
LDAPStorageProvider ldapProvider = LDAPTestUtils.getLdapProvider(session, ldapModel);
|
|
||||||
RealmModel appRealm = session.realms().getRealmByName("test");
|
|
||||||
|
|
||||||
LDAPTestUtils.addLDAPUser(ldapProvider, appRealm, "username5", "John5", "Doel5", "user5@email.org", null, "125");
|
|
||||||
LDAPTestUtils.addLDAPUser(ldapProvider, appRealm, "username6", "John6", "Doel6", "user6@email.org", null, "126");
|
|
||||||
LDAPTestUtils.addLDAPUser(ldapProvider, appRealm, "username7", "John7", "Doel7", "user7@email.org", null, "127");
|
|
||||||
|
|
||||||
UserModel user;
|
|
||||||
// search by email
|
|
||||||
user = session.users().searchForUser("user5@email.org", appRealm).get(0);
|
|
||||||
LDAPTestUtils.assertLoaded(user, "username5", "John5", "Doel5", "user5@email.org", "125");
|
|
||||||
|
|
||||||
user = session.users().searchForUser("John6 Doel6", appRealm).get(0);
|
|
||||||
LDAPTestUtils.assertLoaded(user, "username6", "John6", "Doel6", "user6@email.org", "126");
|
|
||||||
|
|
||||||
Assert.assertTrue(session.users().searchForUser("user7@email.org", appRealm).isEmpty());
|
|
||||||
|
|
||||||
// Remove custom filter
|
|
||||||
ldapModel.getConfig().remove(LDAPConstants.CUSTOM_USER_SEARCH_FILTER);
|
|
||||||
appRealm.updateComponent(ldapModel);
|
|
||||||
} finally {
|
|
||||||
keycloakRule.stopSession(session, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// KEYCLOAK-5383
|
|
||||||
@Test
|
|
||||||
public void addUserThroughAdmin() {
|
|
||||||
Keycloak adminClient = Keycloak.getInstance(AUTH_SERVER_ROOT, MASTER, ADMIN, ADMIN, Constants.ADMIN_CLI_CLIENT_ID);
|
|
||||||
|
|
||||||
RealmResource realm = adminClient.realm("test");
|
|
||||||
|
|
||||||
UserRepresentation user = new UserRepresentation();
|
|
||||||
user.setUsername("addUserThroughAdmin");
|
|
||||||
user.setEnabled(true);
|
|
||||||
user.setCredentials(new LinkedList<>());
|
|
||||||
|
|
||||||
CredentialRepresentation cred = new CredentialRepresentation();
|
|
||||||
cred.setType(CredentialRepresentation.PASSWORD);
|
|
||||||
cred.setValue("password");
|
|
||||||
|
|
||||||
user.getCredentials().add(cred);
|
|
||||||
|
|
||||||
Response response = realm.users().create(user);
|
|
||||||
String userId = ApiUtil.getCreatedId(response);
|
|
||||||
|
|
||||||
loginPage.open();
|
|
||||||
loginPage.login("addUserThroughAdmin", "password");
|
|
||||||
|
|
||||||
Assert.assertEquals(AppPage.RequestType.AUTH_RESPONSE, appPage.getRequestType());
|
|
||||||
Assert.assertNotNull(oauth.getCurrentQuery().get(OAuth2Constants.CODE));
|
|
||||||
oauth.openLogout();
|
|
||||||
|
|
||||||
cred.setValue("password2");
|
|
||||||
realm.users().get(userId).resetPassword(cred);
|
|
||||||
|
|
||||||
loginPage.open();
|
|
||||||
loginPage.login("addUserThroughAdmin", "password2");
|
|
||||||
|
|
||||||
Assert.assertEquals(AppPage.RequestType.AUTH_RESPONSE, appPage.getRequestType());
|
|
||||||
Assert.assertNotNull(oauth.getCurrentQuery().get(OAuth2Constants.CODE));
|
|
||||||
oauth.openLogout();
|
|
||||||
|
|
||||||
adminClient.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,140 +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.rule;
|
|
||||||
|
|
||||||
import org.jboss.logging.Logger;
|
|
||||||
import org.junit.rules.TestRule;
|
|
||||||
import org.junit.runner.Description;
|
|
||||||
import org.junit.runners.model.Statement;
|
|
||||||
import org.keycloak.testsuite.federation.ldap.LDAPTestConfiguration;
|
|
||||||
import org.keycloak.util.ldap.LDAPEmbeddedServer;
|
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Properties;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This rule handles:
|
|
||||||
* - Reading of LDAP configuration from properties file
|
|
||||||
* - Eventually start+stop of LDAP embedded server.
|
|
||||||
* - Eventually allows to ignore the test if particular condition is not met. This allows to run specific tests just for some LDAP vendors
|
|
||||||
*
|
|
||||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
|
||||||
*/
|
|
||||||
public class LDAPRule implements TestRule {
|
|
||||||
|
|
||||||
private static final Logger logger = Logger.getLogger(LDAPRule.class);
|
|
||||||
|
|
||||||
public static final String LDAP_CONNECTION_PROPERTIES_LOCATION = "ldap/ldap-connection.properties";
|
|
||||||
|
|
||||||
protected LDAPTestConfiguration ldapTestConfiguration;
|
|
||||||
protected LDAPEmbeddedServer ldapEmbeddedServer;
|
|
||||||
|
|
||||||
private final LDAPRuleCondition condition;
|
|
||||||
|
|
||||||
|
|
||||||
public LDAPRule() {
|
|
||||||
this(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
public LDAPRule(LDAPRuleCondition condition) {
|
|
||||||
this.condition = condition;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Statement apply(Statement base, Description description) {
|
|
||||||
return new Statement() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void evaluate() throws Throwable {
|
|
||||||
boolean skipTest = before();
|
|
||||||
|
|
||||||
if (skipTest) {
|
|
||||||
logger.infof("Skip %s due to LDAPRuleCondition not met", description.getDisplayName());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
base.evaluate();
|
|
||||||
} finally {
|
|
||||||
after();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Return true if test should be skipped
|
|
||||||
protected boolean before() throws Throwable {
|
|
||||||
String connectionPropsLocation = getConnectionPropertiesLocation();
|
|
||||||
ldapTestConfiguration = LDAPTestConfiguration.readConfiguration(connectionPropsLocation);
|
|
||||||
|
|
||||||
if (condition != null && condition.skipTest(ldapTestConfiguration.getLDAPConfig())) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ldapTestConfiguration.isStartEmbeddedLdapServer()) {
|
|
||||||
ldapEmbeddedServer = createServer();
|
|
||||||
ldapEmbeddedServer.init();
|
|
||||||
ldapEmbeddedServer.start();
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
protected void after() {
|
|
||||||
try {
|
|
||||||
if (ldapEmbeddedServer != null) {
|
|
||||||
ldapEmbeddedServer.stop();
|
|
||||||
ldapEmbeddedServer = null;
|
|
||||||
ldapTestConfiguration = null;
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new RuntimeException("Error tearDown Embedded LDAP server.", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected String getConnectionPropertiesLocation() {
|
|
||||||
return LDAP_CONNECTION_PROPERTIES_LOCATION;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected LDAPEmbeddedServer createServer() {
|
|
||||||
Properties defaultProperties = new Properties();
|
|
||||||
defaultProperties.setProperty(LDAPEmbeddedServer.PROPERTY_DSF, LDAPEmbeddedServer.DSF_INMEMORY);
|
|
||||||
defaultProperties.setProperty(LDAPEmbeddedServer.PROPERTY_LDIF_FILE, "classpath:ldap/users.ldif");
|
|
||||||
|
|
||||||
return new LDAPEmbeddedServer(defaultProperties);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Map<String, String> getConfig() {
|
|
||||||
return ldapTestConfiguration.getLDAPConfig();
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getSleepTime() {
|
|
||||||
return ldapTestConfiguration.getSleepTime();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Allows to skip particular LDAP test just under specific conditions (eg. some test running just on Active Directory)
|
|
||||||
public interface LDAPRuleCondition {
|
|
||||||
|
|
||||||
boolean skipTest(Map<String, String> ldapConfig);
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,10 +0,0 @@
|
||||||
{
|
|
||||||
"realm": "test",
|
|
||||||
"resource": "ldap-portal",
|
|
||||||
"realm-public-key": "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB",
|
|
||||||
"auth-server-url": "http://localhost:8081/auth",
|
|
||||||
"ssl-required" : "external",
|
|
||||||
"credentials": {
|
|
||||||
"secret": "password"
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,26 +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.
|
|
||||||
#
|
|
||||||
|
|
||||||
idm.test.ldap.connection.url=ldap\://localhost\:10389
|
|
||||||
idm.test.ldap.base.dn=dc\=keycloak,dc\=org
|
|
||||||
idm.test.ldap.user.dn.suffix=ou\=People,dc\=keycloak,dc\=org
|
|
||||||
idm.test.ldap.start.embedded.ldap.server=true
|
|
||||||
idm.test.ldap.bind.dn=uid\=admin,ou\=system
|
|
||||||
idm.test.ldap.bind.credential=secret
|
|
||||||
idm.test.ldap.connection.pooling=true
|
|
||||||
idm.test.ldap.pagination=true
|
|
||||||
idm.test.ldap.batch.size.for.sync=3
|
|
|
@ -1,25 +0,0 @@
|
||||||
dn: dc=keycloak,dc=org
|
|
||||||
objectclass: dcObject
|
|
||||||
objectclass: organization
|
|
||||||
o: Keycloak
|
|
||||||
dc: Keycloak
|
|
||||||
|
|
||||||
dn: ou=People,dc=keycloak,dc=org
|
|
||||||
objectclass: top
|
|
||||||
objectclass: organizationalUnit
|
|
||||||
ou: People
|
|
||||||
|
|
||||||
dn: ou=RealmRoles,dc=keycloak,dc=org
|
|
||||||
objectclass: top
|
|
||||||
objectclass: organizationalUnit
|
|
||||||
ou: RealmRoles
|
|
||||||
|
|
||||||
dn: ou=FinanceRoles,dc=keycloak,dc=org
|
|
||||||
objectclass: top
|
|
||||||
objectclass: organizationalUnit
|
|
||||||
ou: FinanceRoles
|
|
||||||
|
|
||||||
dn: ou=Groups,dc=keycloak,dc=org
|
|
||||||
objectclass: top
|
|
||||||
objectclass: organizationalUnit
|
|
||||||
ou: Groups
|
|
|
@ -324,5 +324,35 @@
|
||||||
</plugins>
|
</plugins>
|
||||||
</build>
|
</build>
|
||||||
</profile>
|
</profile>
|
||||||
|
<profile>
|
||||||
|
<id>ldap</id>
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.codehaus.mojo</groupId>
|
||||||
|
<artifactId>exec-maven-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<mainClass>org.keycloak.util.ldap.LDAPEmbeddedServer</mainClass>
|
||||||
|
<classpathScope>test</classpathScope>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
</profile>
|
||||||
|
<profile>
|
||||||
|
<id>kerberos</id>
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.codehaus.mojo</groupId>
|
||||||
|
<artifactId>exec-maven-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<mainClass>org.keycloak.util.ldap.KerberosEmbeddedServer</mainClass>
|
||||||
|
<classpathScope>test</classpathScope>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
</profile>
|
||||||
</profiles>
|
</profiles>
|
||||||
</project>
|
</project>
|
||||||
|
|
|
@ -52,6 +52,7 @@ public class LDAPEmbeddedServer {
|
||||||
public static final String PROPERTY_BASE_DN = "ldap.baseDN";
|
public static final String PROPERTY_BASE_DN = "ldap.baseDN";
|
||||||
public static final String PROPERTY_BIND_HOST = "ldap.host";
|
public static final String PROPERTY_BIND_HOST = "ldap.host";
|
||||||
public static final String PROPERTY_BIND_PORT = "ldap.port";
|
public static final String PROPERTY_BIND_PORT = "ldap.port";
|
||||||
|
public static final String PROPERTY_BIND_LDAPS_PORT = "ldaps.port";
|
||||||
public static final String PROPERTY_LDIF_FILE = "ldap.ldif";
|
public static final String PROPERTY_LDIF_FILE = "ldap.ldif";
|
||||||
public static final String PROPERTY_SASL_PRINCIPAL = "ldap.saslPrincipal";
|
public static final String PROPERTY_SASL_PRINCIPAL = "ldap.saslPrincipal";
|
||||||
public static final String PROPERTY_DSF = "ldap.dsf";
|
public static final String PROPERTY_DSF = "ldap.dsf";
|
||||||
|
@ -59,6 +60,7 @@ public class LDAPEmbeddedServer {
|
||||||
private static final String DEFAULT_BASE_DN = "dc=keycloak,dc=org";
|
private static final String DEFAULT_BASE_DN = "dc=keycloak,dc=org";
|
||||||
private static final String DEFAULT_BIND_HOST = "localhost";
|
private static final String DEFAULT_BIND_HOST = "localhost";
|
||||||
private static final String DEFAULT_BIND_PORT = "10389";
|
private static final String DEFAULT_BIND_PORT = "10389";
|
||||||
|
private static final String DEFAULT_BIND_LDAPS_PORT = "10636";
|
||||||
private static final String DEFAULT_LDIF_FILE = "classpath:ldap/default-users.ldif";
|
private static final String DEFAULT_LDIF_FILE = "classpath:ldap/default-users.ldif";
|
||||||
private static final String PROPERTY_ENABLE_SSL = "enableSSL";
|
private static final String PROPERTY_ENABLE_SSL = "enableSSL";
|
||||||
private static final String PROPERTY_KEYSTORE_FILE = "keystoreFile";
|
private static final String PROPERTY_KEYSTORE_FILE = "keystoreFile";
|
||||||
|
@ -73,6 +75,7 @@ public class LDAPEmbeddedServer {
|
||||||
protected String baseDN;
|
protected String baseDN;
|
||||||
protected String bindHost;
|
protected String bindHost;
|
||||||
protected int bindPort;
|
protected int bindPort;
|
||||||
|
protected int bindLdapsPort;
|
||||||
protected String ldifFile;
|
protected String ldifFile;
|
||||||
protected String ldapSaslPrincipal;
|
protected String ldapSaslPrincipal;
|
||||||
protected String directoryServiceFactory;
|
protected String directoryServiceFactory;
|
||||||
|
@ -117,6 +120,8 @@ public class LDAPEmbeddedServer {
|
||||||
this.bindHost = readProperty(PROPERTY_BIND_HOST, DEFAULT_BIND_HOST);
|
this.bindHost = readProperty(PROPERTY_BIND_HOST, DEFAULT_BIND_HOST);
|
||||||
String bindPort = readProperty(PROPERTY_BIND_PORT, DEFAULT_BIND_PORT);
|
String bindPort = readProperty(PROPERTY_BIND_PORT, DEFAULT_BIND_PORT);
|
||||||
this.bindPort = Integer.parseInt(bindPort);
|
this.bindPort = Integer.parseInt(bindPort);
|
||||||
|
String bindLdapsPort = readProperty(PROPERTY_BIND_LDAPS_PORT, DEFAULT_BIND_LDAPS_PORT);
|
||||||
|
this.bindLdapsPort = Integer.parseInt(bindLdapsPort);
|
||||||
this.ldifFile = readProperty(PROPERTY_LDIF_FILE, DEFAULT_LDIF_FILE);
|
this.ldifFile = readProperty(PROPERTY_LDIF_FILE, DEFAULT_LDIF_FILE);
|
||||||
this.ldapSaslPrincipal = readProperty(PROPERTY_SASL_PRINCIPAL, null);
|
this.ldapSaslPrincipal = readProperty(PROPERTY_SASL_PRINCIPAL, null);
|
||||||
this.directoryServiceFactory = readProperty(PROPERTY_DSF, DEFAULT_DSF);
|
this.directoryServiceFactory = readProperty(PROPERTY_DSF, DEFAULT_DSF);
|
||||||
|
@ -219,15 +224,15 @@ public class LDAPEmbeddedServer {
|
||||||
ldapServer.setSearchBaseDn(this.baseDN);
|
ldapServer.setSearchBaseDn(this.baseDN);
|
||||||
|
|
||||||
// Read the transports
|
// Read the transports
|
||||||
Transport ldaps = new TcpTransport(this.bindHost, this.bindPort, 3, 50);
|
Transport ldap = new TcpTransport(this.bindHost, this.bindPort, 3, 50);
|
||||||
|
ldapServer.addTransports( ldap );
|
||||||
if (enableSSL) {
|
if (enableSSL) {
|
||||||
|
Transport ldaps = new TcpTransport(this.bindHost, this.bindLdapsPort, 3, 50);
|
||||||
ldaps.setEnableSSL(true);
|
ldaps.setEnableSSL(true);
|
||||||
ldapServer.setKeystoreFile(keystoreFile);
|
ldapServer.setKeystoreFile(keystoreFile);
|
||||||
ldapServer.setCertificatePassword(certPassword);
|
ldapServer.setCertificatePassword(certPassword);
|
||||||
Transport ldap = new TcpTransport(this.bindHost, 10389, 3, 50);
|
|
||||||
ldapServer.addTransports( ldap );
|
|
||||||
}
|
|
||||||
ldapServer.addTransports( ldaps );
|
ldapServer.addTransports( ldaps );
|
||||||
|
}
|
||||||
|
|
||||||
// Associate the DS to this LdapServer
|
// Associate the DS to this LdapServer
|
||||||
ldapServer.setDirectoryService( directoryService );
|
ldapServer.setDirectoryService( directoryService );
|
||||||
|
|
Loading…
Reference in a new issue