KEYCLOAK-2659 Allow sync all roles even if there are more than 1000

This commit is contained in:
mposolda 2016-03-14 09:37:31 +01:00
parent 2d188068c4
commit e24ce91e81
4 changed files with 48 additions and 28 deletions

View file

@ -19,6 +19,7 @@ package org.keycloak.federation.ldap;
import java.util.Collection; import java.util.Collection;
import java.util.HashSet; import java.util.HashSet;
import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
@ -229,6 +230,45 @@ public class LDAPUtils {
} }
/**
* Load all LDAP objects corresponding to given query. We will load them paginated, so we allow to bypass the limitation of 1000
* maximum loaded objects in single query in MSAD
*
* @param ldapQuery
* @param ldapProvider
* @return
*/
public static List<LDAPObject> loadAllLDAPObjects(LDAPQuery ldapQuery, LDAPFederationProvider ldapProvider) {
LDAPConfig ldapConfig = ldapProvider.getLdapIdentityStore().getConfig();
boolean pagination = ldapConfig.isPagination();
if (pagination) {
// For now reuse globally configured batch size in LDAP provider page
int pageSize = ldapConfig.getBatchSizeForSync();
List<LDAPObject> result = new LinkedList<>();
boolean nextPage = true;
while (nextPage) {
ldapQuery.setLimit(pageSize);
final List<LDAPObject> currentPageGroups = ldapQuery.getResultList();
result.addAll(currentPageGroups);
nextPage = ldapQuery.getPaginationContext() != null;
}
return result;
} else {
// LDAP pagination not available. Do everything in single transaction
return ldapQuery.getResultList();
}
}
/**
* Validate configured customFilter matches the requested format
*
* @param customFilter
* @throws FederationConfigValidationException
*/
public static void validateCustomLdapFilter(String customFilter) throws FederationConfigValidationException { public static void validateCustomLdapFilter(String customFilter) throws FederationConfigValidationException {
if (customFilter != null) { if (customFilter != null) {

View file

@ -343,28 +343,7 @@ public class GroupLDAPFederationMapper extends AbstractLDAPFederationMapper impl
// Send LDAP query to retrieve all groups // Send LDAP query to retrieve all groups
protected List<LDAPObject> getAllLDAPGroups() { protected List<LDAPObject> getAllLDAPGroups() {
LDAPQuery ldapGroupQuery = createGroupQuery(); LDAPQuery ldapGroupQuery = createGroupQuery();
return LDAPUtils.loadAllLDAPObjects(ldapGroupQuery, ldapProvider);
LDAPConfig ldapConfig = ldapProvider.getLdapIdentityStore().getConfig();
boolean pagination = ldapConfig.isPagination();
if (pagination) {
// For now reuse globally configured batch size in LDAP provider page
int pageSize = ldapConfig.getBatchSizeForSync();
List<LDAPObject> result = new LinkedList<>();
boolean nextPage = true;
while (nextPage) {
ldapGroupQuery.setLimit(pageSize);
final List<LDAPObject> currentPageGroups = ldapGroupQuery.getResultList();
result.addAll(currentPageGroups);
nextPage = ldapGroupQuery.getPaginationContext() != null;
}
return result;
} else {
// LDAP pagination not available. Do everything in single transaction
return ldapGroupQuery.getResultList();
}
} }

View file

@ -88,9 +88,9 @@ public class GroupLDAPFederationMapperFactory extends AbstractLDAPFederationMapp
for (MembershipType membershipType : MembershipType.values()) { for (MembershipType membershipType : MembershipType.values()) {
membershipTypes.add(membershipType.toString()); membershipTypes.add(membershipType.toString());
} }
ProviderConfigProperty membershipType = createConfigProperty(RoleMapperConfig.MEMBERSHIP_ATTRIBUTE_TYPE, "Membership Attribute Type", ProviderConfigProperty membershipType = createConfigProperty(GroupMapperConfig.MEMBERSHIP_ATTRIBUTE_TYPE, "Membership Attribute Type",
"DN means that LDAP role has it's members declared in form of their full DN. For example 'member: uid=john,ou=users,dc=example,dc=com' . " + "DN means that LDAP group has it's members declared in form of their full DN. For example 'member: uid=john,ou=users,dc=example,dc=com' . " +
"UID means that LDAP role has it's members declared in form of pure user uids. For example 'memberUid: john' .", "UID means that LDAP group has it's members declared in form of pure user uids. For example 'memberUid: john' .",
ProviderConfigProperty.LIST_TYPE, membershipTypes); ProviderConfigProperty.LIST_TYPE, membershipTypes);
configProperties.add(membershipType); configProperties.add(membershipType);
@ -165,6 +165,7 @@ public class GroupLDAPFederationMapperFactory extends AbstractLDAPFederationMapp
defaultValues.put(GroupMapperConfig.PRESERVE_GROUP_INHERITANCE, "true"); defaultValues.put(GroupMapperConfig.PRESERVE_GROUP_INHERITANCE, "true");
defaultValues.put(GroupMapperConfig.MEMBERSHIP_LDAP_ATTRIBUTE, LDAPConstants.MEMBER); defaultValues.put(GroupMapperConfig.MEMBERSHIP_LDAP_ATTRIBUTE, LDAPConstants.MEMBER);
defaultValues.put(GroupMapperConfig.MEMBERSHIP_ATTRIBUTE_TYPE, MembershipType.DN.toString());
String mode = config.getEditMode() == UserFederationProvider.EditMode.WRITABLE ? LDAPGroupMapperMode.LDAP_ONLY.toString() : LDAPGroupMapperMode.READ_ONLY.toString(); String mode = config.getEditMode() == UserFederationProvider.EditMode.WRITABLE ? LDAPGroupMapperMode.LDAP_ONLY.toString() : LDAPGroupMapperMode.READ_ONLY.toString();
defaultValues.put(GroupMapperConfig.MODE, mode); defaultValues.put(GroupMapperConfig.MODE, mode);

View file

@ -122,9 +122,9 @@ public class RoleLDAPFederationMapper extends AbstractLDAPFederationMapper imple
logger.debugf("Syncing roles from LDAP into Keycloak DB. Mapper is [%s], LDAP provider is [%s]", mapperModel.getName(), ldapProvider.getModel().getDisplayName()); logger.debugf("Syncing roles from LDAP into Keycloak DB. Mapper is [%s], LDAP provider is [%s]", mapperModel.getName(), ldapProvider.getModel().getDisplayName());
// Send LDAP query // Send LDAP query to load all roles
LDAPQuery ldapQuery = createRoleQuery(); LDAPQuery ldapRoleQuery = createRoleQuery();
List<LDAPObject> ldapRoles = ldapQuery.getResultList(); List<LDAPObject> ldapRoles = LDAPUtils.loadAllLDAPObjects(ldapRoleQuery, ldapProvider);
RoleContainerModel roleContainer = getTargetRoleContainer(); RoleContainerModel roleContainer = getTargetRoleContainer();
String rolesRdnAttr = config.getRoleNameLdapAttribute(); String rolesRdnAttr = config.getRoleNameLdapAttribute();