KEYCLOAK-2682 NPE when LDAP groups points to non-existent user

This commit is contained in:
mposolda 2016-03-22 12:26:29 +01:00
parent 705a598ce6
commit 4a06d7590e
2 changed files with 45 additions and 1 deletions

View file

@ -229,7 +229,9 @@ public class LDAPFederationProvider implements UserFederationProvider {
List<UserModel> result = new ArrayList<>();
for (String username : usernames) {
UserModel kcUser = session.users().getUserByUsername(username, realm);
if (!model.getId().equals(kcUser.getFederationLink())) {
if (kcUser == null) {
logger.warnf("User '%s' referenced by membership wasn't found in LDAP", username);
} else if (!model.getId().equals(kcUser.getFederationLink())) {
logger.warnf("Incorrect federation provider of user %s" + kcUser.getUsername());
} else {
result.add(kcUser);

View file

@ -31,6 +31,7 @@ import org.junit.runners.MethodSorters;
import org.keycloak.federation.ldap.LDAPFederationProvider;
import org.keycloak.federation.ldap.LDAPFederationProviderFactory;
import org.keycloak.federation.ldap.LDAPUtils;
import org.keycloak.federation.ldap.idm.model.LDAPDn;
import org.keycloak.federation.ldap.idm.model.LDAPObject;
import org.keycloak.federation.ldap.mappers.membership.LDAPGroupMapperMode;
import org.keycloak.federation.ldap.mappers.membership.MembershipType;
@ -302,6 +303,47 @@ public class LDAPGroupMapperTest {
}
}
// KEYCLOAK-2682
@Test
public void test04_groupReferencingNonExistentMember() {
KeycloakSession session = keycloakRule.startSession();
try {
RealmModel appRealm = session.realms().getRealmByName("test");
UserFederationMapperModel mapperModel = appRealm.getUserFederationMapperByName(ldapModel.getId(), "groupsMapper");
FederationTestUtils.updateGroupMapperConfigOptions(mapperModel, GroupMapperConfig.MODE, LDAPGroupMapperMode.LDAP_ONLY.toString());
appRealm.updateUserFederationMapper(mapperModel);
// 1 - Add some group to LDAP for testing
LDAPFederationProvider ldapProvider = FederationTestUtils.getLdapProvider(session, ldapModel);
GroupLDAPFederationMapper groupMapper = FederationTestUtils.getGroupMapper(mapperModel, ldapProvider, appRealm);
LDAPObject group2 = FederationTestUtils.createLDAPGroup(session, appRealm, ldapModel, "group2", descriptionAttrName, "group2 - description");
// 2 - Add one existing user rob to LDAP group
LDAPObject robLdap = ldapProvider.loadLDAPUserByUsername(appRealm, "robkeycloak");
LDAPUtils.addMember(ldapProvider, MembershipType.DN, LDAPConstants.MEMBER, group2, robLdap, false);
// 3 - Add non-existing user to LDAP group
LDAPDn nonExistentDn = LDAPDn.fromString(ldapProvider.getLdapIdentityStore().getConfig().getUsersDn());
nonExistentDn.addFirst(robLdap.getRdnAttributeName(), "nonexistent");
LDAPObject nonExistentLdapUser = new LDAPObject();
nonExistentLdapUser.setDn(nonExistentDn);
LDAPUtils.addMember(ldapProvider, MembershipType.DN, LDAPConstants.MEMBER, group2, nonExistentLdapUser, true);
// 4 - Check group members. Just existing user rob should be present
groupMapper.syncDataFromFederationProviderToKeycloak();
GroupModel kcGroup2 = KeycloakModelUtils.findGroupByPath(appRealm, "/group2");
List<UserModel> groupUsers = session.users().getGroupMembers(appRealm, kcGroup2, 0, 5);
Assert.assertEquals(1, groupUsers.size());
UserModel rob = groupUsers.get(0);
Assert.assertEquals("robkeycloak", rob.getUsername());
} finally {
keycloakRule.stopSession(session, false);
}
}
private void deleteGroupMappingsInLDAP(GroupLDAPFederationMapper groupMapper, LDAPObject ldapUser, String groupName) {
LDAPObject ldapGroup = groupMapper.loadLDAPGroupByName(groupName);
groupMapper.deleteGroupMappingInLDAP(ldapUser, ldapGroup);