diff --git a/federation/ldap/src/main/java/org/keycloak/storage/ldap/LDAPStorageProvider.java b/federation/ldap/src/main/java/org/keycloak/storage/ldap/LDAPStorageProvider.java
index d8653de170..e77df53622 100755
--- a/federation/ldap/src/main/java/org/keycloak/storage/ldap/LDAPStorageProvider.java
+++ b/federation/ldap/src/main/java/org/keycloak/storage/ldap/LDAPStorageProvider.java
@@ -17,6 +17,17 @@
package org.keycloak.storage.ldap;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.naming.AuthenticationException;
+
import org.jboss.logging.Logger;
import org.keycloak.common.constants.KerberosConstants;
import org.keycloak.component.ComponentModel;
@@ -33,14 +44,15 @@ import org.keycloak.models.KeycloakSession;
import org.keycloak.models.LDAPConstants;
import org.keycloak.models.ModelDuplicateException;
import org.keycloak.models.ModelException;
-import org.keycloak.models.utils.ReadOnlyUserModelDelegate;
import org.keycloak.models.RealmModel;
import org.keycloak.models.RoleModel;
import org.keycloak.models.UserCredentialModel;
-import org.keycloak.models.UserModel;
import org.keycloak.models.UserManager;
+import org.keycloak.models.UserModel;
import org.keycloak.models.cache.UserCache;
import org.keycloak.models.credential.PasswordUserCredentialModel;
+import org.keycloak.models.utils.KeycloakModelUtils;
+import org.keycloak.models.utils.ReadOnlyUserModelDelegate;
import org.keycloak.storage.ReadOnlyException;
import org.keycloak.storage.StorageId;
import org.keycloak.storage.UserStorageProvider;
@@ -62,16 +74,6 @@ import org.keycloak.storage.user.UserLookupProvider;
import org.keycloak.storage.user.UserQueryProvider;
import org.keycloak.storage.user.UserRegistrationProvider;
-import javax.naming.AuthenticationException;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
/**
* @author Marek Posolda
* @author Bill Burke
@@ -216,7 +218,30 @@ public class LDAPStorageProvider implements UserStorageProvider,
@Override
public List searchForUserByUserAttribute(String attrName, String attrValue, RealmModel realm) {
- return Collections.EMPTY_LIST;
+ LDAPQuery ldapQuery = LDAPUtils.createQueryForUserSearch(this, realm);
+ LDAPQueryConditionsBuilder conditionsBuilder = new LDAPQueryConditionsBuilder();
+
+ Condition attrCondition = conditionsBuilder.equal(attrName, attrValue, EscapeStrategy.DEFAULT);
+ ldapQuery.addWhereCondition(attrCondition);
+
+ List ldapObjects = ldapQuery.getResultList();
+
+ if (ldapObjects == null || ldapObjects.isEmpty()) {
+ return Collections.emptyList();
+ }
+
+ List searchResults =new LinkedList();
+
+ for (LDAPObject ldapUser : ldapObjects) {
+ String ldapUsername = LDAPUtils.getUsername(ldapUser, this.ldapIdentityStore.getConfig());
+ if (session.userLocalStorage().getUserByUsername(ldapUsername, realm) == null) {
+ UserModel imported = importUserFromLDAP(session, realm, ldapUser);
+ searchResults.add(imported);
+ }
+ }
+
+ return searchResults;
+
}
public boolean synchronizeRegistrations() {
diff --git a/testsuite/integration-deprecated/src/test/java/org/keycloak/testsuite/federation/storage/ldap/LDAPProvidersIntegrationTest.java b/testsuite/integration-deprecated/src/test/java/org/keycloak/testsuite/federation/storage/ldap/LDAPProvidersIntegrationTest.java
index a9546ed0ec..f9a95d1747 100755
--- a/testsuite/integration-deprecated/src/test/java/org/keycloak/testsuite/federation/storage/ldap/LDAPProvidersIntegrationTest.java
+++ b/testsuite/integration-deprecated/src/test/java/org/keycloak/testsuite/federation/storage/ldap/LDAPProvidersIntegrationTest.java
@@ -17,6 +17,14 @@
package org.keycloak.testsuite.federation.storage.ldap;
+import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.MASTER;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.keycloak.models.AdminRoles.ADMIN;
+import static org.keycloak.testsuite.Constants.AUTH_SERVER_ROOT;
+
+import java.util.List;
+
import org.jboss.logging.Logger;
import org.junit.Assert;
import org.junit.Before;
@@ -33,13 +41,6 @@ import org.keycloak.common.util.MultivaluedHashMap;
import org.keycloak.component.ComponentModel;
import org.keycloak.credential.CredentialModel;
import org.keycloak.models.Constants;
-import org.keycloak.storage.ReadOnlyException;
-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.models.KeycloakSession;
import org.keycloak.models.LDAPConstants;
import org.keycloak.models.ModelException;
@@ -50,6 +51,13 @@ import org.keycloak.models.UserModel;
import org.keycloak.models.utils.KeycloakModelUtils;
import org.keycloak.representations.AccessToken;
import org.keycloak.services.managers.RealmManager;
+import org.keycloak.storage.ReadOnlyException;
+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.HardcodedLDAPAttributeMapper;
@@ -71,13 +79,6 @@ import org.keycloak.testsuite.rule.WebResource;
import org.keycloak.testsuite.rule.WebRule;
import org.openqa.selenium.WebDriver;
-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 Marek Posolda
*/
@@ -1088,5 +1089,46 @@ public class LDAPProvidersIntegrationTest {
keycloakRule.stopSession(session, false);
}
}
+
+
+ @Test
+ public void testSearchByAttributes() {
+ KeycloakSession session = keycloakRule.startSession();
+ final String ATTRIBUTE = "postal_code";
+ final String ATTRIBUTE_VALUE = "80330340";
+ try {
+ RealmModel appRealm = session.realms().getRealmByName("test");
+ LDAPStorageProvider ldapProvider = LDAPTestUtils.getLdapProvider(session, ldapModel);
+
+ LDAPTestUtils.addLDAPUser(ldapProvider, appRealm, "username8", "John8", "Doel8", "user8@email.org", null, ATTRIBUTE_VALUE);
+ LDAPTestUtils.addLDAPUser(ldapProvider, appRealm, "username9", "John9", "Doel9", "user9@email.org", null, ATTRIBUTE_VALUE);
+ LDAPTestUtils.addLDAPUser(ldapProvider, appRealm, "username10", "John10", "Doel10", "user10@email.org", null, "1210");
+
+ // Users are not at local store at this moment
+ Assert.assertNull(session.userLocalStorage().getUserByUsername("username8", appRealm));
+ Assert.assertNull(session.userLocalStorage().getUserByUsername("username9", appRealm));
+ Assert.assertNull(session.userLocalStorage().getUserByUsername("username10", appRealm));
+
+ // search for user by attribute
+ List users = ldapProvider.searchForUserByUserAttribute(ATTRIBUTE, ATTRIBUTE_VALUE, appRealm);
+ assertEquals(2, users.size());
+ assertNotNull(users.get(0).getAttribute(ATTRIBUTE));
+ assertEquals(1, users.get(0).getAttribute(ATTRIBUTE).size());
+ assertEquals(ATTRIBUTE_VALUE, users.get(0).getAttribute(ATTRIBUTE).get(0));
+
+ assertNotNull(users.get(1).getAttribute(ATTRIBUTE));
+ assertEquals(1, users.get(1).getAttribute(ATTRIBUTE).size());
+ assertEquals(ATTRIBUTE_VALUE, users.get(1).getAttribute(ATTRIBUTE).get(0));
+
+ // user are now imported to local store
+ LDAPTestUtils.assertUserImported(session.userLocalStorage(), appRealm, "username8", "John8", "Doel8", "user8@email.org", ATTRIBUTE_VALUE);
+ LDAPTestUtils.assertUserImported(session.userLocalStorage(), appRealm, "username9", "John9", "Doel9", "user9@email.org", ATTRIBUTE_VALUE);
+ // but the one not looked up is not
+ Assert.assertNull(session.userLocalStorage().getUserByUsername("username10", appRealm));
+
+ } finally {
+ keycloakRule.stopSession(session, true);
+ }
+ }
}