From bc558468098872661aac782b0d1bf16fa1316d12 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A5var=20N=C3=B8vik?= Date: Mon, 23 Oct 2023 23:19:25 +0200 Subject: [PATCH] Fixes a NullPointerException after import validation (#20151) * Fixes a NullPointerException after import validation If the import validation (when getting a user by email) returns null, indicating that the user entity should be removed from local storage, an email equality check results in a NullPointerException. This commit fixes this issue by explicitly checking for null. Closes #20150 --------- Co-authored-by: Michal Hajas --- .../keycloak/storage/UserStorageManager.java | 2 +- .../testsuite/model/user/UserSyncTest.java | 28 ++++++++++++++++++- 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/model/legacy-private/src/main/java/org/keycloak/storage/UserStorageManager.java b/model/legacy-private/src/main/java/org/keycloak/storage/UserStorageManager.java index 2c82afb6d4..6356da6d59 100755 --- a/model/legacy-private/src/main/java/org/keycloak/storage/UserStorageManager.java +++ b/model/legacy-private/src/main/java/org/keycloak/storage/UserStorageManager.java @@ -389,7 +389,7 @@ public class UserStorageManager extends AbstractStorageManager { UserStorageProviderModel providerModel = new UserStorageProviderModel(realm.getComponent(userFederationId)); - return new UserStorageSyncManager().syncAllUsers(session.getKeycloakSessionFactory(), realm.getId(), providerModel); + return UserStorageSyncManager.syncAllUsers(session.getKeycloakSessionFactory(), realm.getId(), providerModel); }); long end = System.currentTimeMillis(); long timeNeeded = end - start; @@ -142,6 +142,32 @@ public class UserSyncTest extends KeycloakModelTest { assertThat(withRealm(realmId, (session, realm) -> UserStoragePrivateUtil.userLocalStorage(session).getUsersCount(realm)), is(NUMBER_OF_USERS)); } + @Test + public void testRemovedLDAPUserShouldNotFailGetUserByEmail() { + withRealm(realmId, (session, realm) -> { + UserStorageProviderModel providerModel = new UserStorageProviderModel(realm.getComponent(userFederationId)); + // disable cache + providerModel.setCachePolicy(CacheableStorageProviderModel.CachePolicy.NO_CACHE); + realm.updateComponent(providerModel); + + ComponentModel ldapModel = LDAPTestUtils.getLdapProviderModel(realm); + LDAPStorageProvider ldapFedProvider = LDAPTestUtils.getLdapProvider(session, ldapModel); + LDAPTestUtils.addLDAPUser(ldapFedProvider, realm, "user", "UserFN", "UserLN", "user@email.org", "userStreet", "1450"); + return null; + }); + + assertThat(withRealm(realmId, (session, realm) -> session.users().getUserByEmail(realm, "user@email.org")), is(notNullValue())); + + withRealm(realmId, (session, realm) -> { + ComponentModel ldapModel = LDAPTestUtils.getLdapProviderModel(realm); + LDAPStorageProvider ldapFedProvider = LDAPTestUtils.getLdapProvider(session, ldapModel); + LDAPTestUtils.removeLDAPUserByUsername(ldapFedProvider, realm, ldapFedProvider.getLdapIdentityStore().getConfig(), "user"); + return null; + }); + + assertThat(withRealm(realmId, (session, realm) -> session.users().getUserByEmail(realm, "user@email.org")), is(nullValue())); + } + @Test public void testAlwaysReadValueFromLDAPWorksWithNoCachePolicy() { // Create mapper from sn to a new user attribute