Avoid returning duplicated users in LDAP and unsynced
Closes #24141 Signed-off-by: rmartinc <rmartinc@redhat.com>
This commit is contained in:
parent
50c49990a6
commit
42f0488d76
2 changed files with 34 additions and 2 deletions
|
@ -27,6 +27,7 @@ import java.util.LinkedHashSet;
|
|||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.util.function.Function;
|
||||
|
@ -382,8 +383,13 @@ public class LDAPStorageProvider implements UserStorageProvider,
|
|||
searchLDAP(realm, search, firstResult, maxResults) :
|
||||
searchLDAPByAttributes(realm, params, firstResult, maxResults);
|
||||
|
||||
return StreamsUtil.paginatedStream(result.filter(filterLocalUsers(realm)), firstResult, maxResults)
|
||||
.map(ldapObject -> importUserFromLDAP(session, realm, ldapObject));
|
||||
if (model.isImportEnabled()) {
|
||||
result = result.filter(filterLocalUsers(realm));
|
||||
}
|
||||
return StreamsUtil.paginatedStream(
|
||||
result.map(ldapObject -> importUserFromLDAP(session, realm, ldapObject, false))
|
||||
.filter(Objects::nonNull),
|
||||
firstResult, maxResults);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -619,6 +625,10 @@ public class LDAPStorageProvider implements UserStorageProvider,
|
|||
}
|
||||
|
||||
protected UserModel importUserFromLDAP(KeycloakSession session, RealmModel realm, LDAPObject ldapUser) {
|
||||
return importUserFromLDAP(session, realm, ldapUser, true);
|
||||
}
|
||||
|
||||
protected UserModel importUserFromLDAP(KeycloakSession session, RealmModel realm, LDAPObject ldapUser, boolean duplicates) {
|
||||
String ldapUsername = LDAPUtils.getUsername(ldapUser, ldapIdentityStore.getConfig());
|
||||
LDAPUtils.checkUuid(ldapUser, ldapIdentityStore.getConfig());
|
||||
|
||||
|
@ -633,6 +643,10 @@ public class LDAPStorageProvider implements UserStorageProvider,
|
|||
if (UserStorageUtil.userCache(session) != null) {
|
||||
UserStorageUtil.userCache(session).evict(realm, existingLocalUser);
|
||||
}
|
||||
if (!duplicates) {
|
||||
// if duplicates are not wanted return null
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
imported = UserStoragePrivateUtil.userLocalStorage(session).addUser(realm, ldapUsername);
|
||||
}
|
||||
|
|
|
@ -1182,6 +1182,24 @@ public class LDAPProvidersIntegrationTest extends AbstractLDAPTest {
|
|||
Assert.assertNotNull(session.users().getUserByUsername(appRealm, "johnkeycloak"));
|
||||
});
|
||||
|
||||
// change username
|
||||
testingClient.server().run(session -> {
|
||||
LDAPTestContext ctx = LDAPTestContext.init(session);
|
||||
RealmModel appRealm = ctx.getRealm();
|
||||
UserModel user = session.users().getUserByUsername(appRealm, "johnkeycloak");
|
||||
|
||||
// change username locally
|
||||
user.setUsername("johnkeycloak-renamed");
|
||||
});
|
||||
|
||||
// check user is found just once
|
||||
List<UserRepresentation> users = testRealm().users().search("johnkeycloak", 0, 2);
|
||||
Assert.assertEquals("More than one user is found", 1, users.size());
|
||||
List<ComponentRepresentation> components = testRealm().components().query(
|
||||
testRealm().toRepresentation().getId(), UserStorageProvider.class.getName(), "test-ldap");
|
||||
Assert.assertEquals("LDAP component not found", 1, users.size());
|
||||
Assert.assertEquals(components.iterator().next().getId(), users.iterator().next().getFederationLink());
|
||||
|
||||
// Revert
|
||||
testingClient.server().run(session -> {
|
||||
LDAPTestContext ctx = LDAPTestContext.init(session);
|
||||
|
|
Loading…
Reference in a new issue