use of org.keycloak.storage.ldap.idm.model.LDAPObject in project keycloak by keycloak.
the class GroupLDAPStorageMapper method getHighestPredecessorNotExistentInLdap.
// Recursively check if parent group exists in LDAP. If yes, then return current group. If not, then recursively call this method
// for the predecessor. Result is the highest group, which doesn't yet exist in LDAP (and hence requires sync to LDAP)
private GroupModel getHighestPredecessorNotExistentInLdap(GroupModel groupsPathGroup, GroupModel group) {
GroupModel parentGroup = group.getParent();
if (parentGroup == groupsPathGroup) {
return group;
}
LDAPObject ldapGroup = loadLDAPGroupByName(parentGroup.getName());
if (ldapGroup != null) {
// Parent exists in LDAP. Let's return current group
return group;
} else {
// Parent doesn't exist in LDAP. Let's recursively go up.
return getHighestPredecessorNotExistentInLdap(groupsPathGroup, parentGroup);
}
}
use of org.keycloak.storage.ldap.idm.model.LDAPObject in project keycloak by keycloak.
the class GroupLDAPStorageMapper method addGroupMappingInLDAP.
public void addGroupMappingInLDAP(RealmModel realm, GroupModel kcGroup, LDAPObject ldapUser) {
String groupName = kcGroup.getName();
LDAPObject ldapGroup = loadLDAPGroupByName(groupName);
if (ldapGroup == null) {
// Needs to partially sync Keycloak groups to LDAP
if (config.isPreserveGroupsInheritance()) {
GroupModel groupsPathGroup = getKcGroupsPathGroup(realm);
GroupModel highestGroupToSync = getHighestPredecessorNotExistentInLdap(groupsPathGroup, kcGroup);
logger.debugf("Will sync group '%s' and it's subgroups from DB to LDAP", highestGroupToSync.getName());
Map<String, LDAPObject> syncedLDAPGroups = new HashMap<>();
processKeycloakGroupSyncToLDAP(highestGroupToSync, syncedLDAPGroups, new HashSet<>(), new SynchronizationResult());
processKeycloakGroupMembershipsSyncToLDAP(highestGroupToSync, syncedLDAPGroups);
ldapGroup = loadLDAPGroupByName(groupName);
// Finally update LDAP membership in the parent group
if (highestGroupToSync.getParent() != groupsPathGroup) {
LDAPObject ldapParentGroup = loadLDAPGroupByName(highestGroupToSync.getParent().getName());
LDAPUtils.addMember(ldapProvider, MembershipType.DN, config.getMembershipLdapAttribute(), getMembershipUserLdapAttribute(), ldapParentGroup, ldapGroup);
}
} else {
// No care about group inheritance. Let's just sync current group
logger.debugf("Will sync group '%s' from DB to LDAP", groupName);
processKeycloakGroupSyncToLDAP(kcGroup, new HashMap<>(), new HashSet<>(), new SynchronizationResult());
ldapGroup = loadLDAPGroupByName(groupName);
}
}
String membershipUserLdapAttrName = getMembershipUserLdapAttribute();
LDAPUtils.addMember(ldapProvider, config.getMembershipTypeLdapAttribute(), config.getMembershipLdapAttribute(), membershipUserLdapAttrName, ldapGroup, ldapUser);
}
use of org.keycloak.storage.ldap.idm.model.LDAPObject in project keycloak by keycloak.
the class GroupLDAPStorageMapper method syncDataFromFederationProviderToKeycloak.
// Sync from Ldap to KC
@Override
public SynchronizationResult syncDataFromFederationProviderToKeycloak(RealmModel realm) {
SynchronizationResult syncResult = new SynchronizationResult() {
@Override
public String getStatus() {
return String.format("%d imported groups, %d updated groups, %d removed groups", getAdded(), getUpdated(), getRemoved());
}
};
logger.debugf("Syncing groups from LDAP into Keycloak DB. Mapper is [%s], LDAP provider is [%s]", mapperModel.getName(), ldapProvider.getModel().getName());
// Get all LDAP groups
List<LDAPObject> ldapGroups = getAllLDAPGroups(config.isPreserveGroupsInheritance());
// Convert to internal format
Map<String, LDAPObject> ldapGroupsMap = new HashMap<>();
List<GroupTreeResolver.Group> ldapGroupsRep = new LinkedList<>();
convertGroupsToInternalRep(ldapGroups, ldapGroupsMap, ldapGroupsRep);
// Now we have list of LDAP groups. Let's form the tree (if needed)
if (config.isPreserveGroupsInheritance()) {
try {
List<GroupTreeResolver.GroupTreeEntry> groupTrees = new GroupTreeResolver().resolveGroupTree(ldapGroupsRep, config.isIgnoreMissingGroups());
updateKeycloakGroupTree(realm, groupTrees, ldapGroupsMap, syncResult);
} catch (GroupTreeResolver.GroupTreeResolveException gre) {
throw new ModelException("Couldn't resolve groups from LDAP. Fix LDAP or skip preserve inheritance. Details: " + gre.getMessage(), gre);
}
} else {
syncFlatGroupStructure(realm, syncResult, ldapGroupsMap);
}
syncFromLDAPPerformedInThisTransaction = true;
return syncResult;
}
use of org.keycloak.storage.ldap.idm.model.LDAPObject in project keycloak by keycloak.
the class GroupLDAPStorageMapper method convertGroupsToInternalRep.
private void convertGroupsToInternalRep(List<LDAPObject> ldapGroups, Map<String, LDAPObject> ldapGroupsMap, List<GroupTreeResolver.Group> ldapGroupsRep) {
String groupsRdnAttr = config.getGroupNameLdapAttribute();
for (LDAPObject ldapGroup : ldapGroups) {
String groupName = ldapGroup.getAttributeAsString(groupsRdnAttr);
if (config.isPreserveGroupsInheritance()) {
Set<String> subgroupNames = new HashSet<>();
for (LDAPDn groupDn : getLDAPSubgroups(ldapGroup)) {
String subGroupName = groupDn.getFirstRdn().getAttrValue(groupsRdnAttr);
subgroupNames.add(subGroupName);
}
ldapGroupsRep.add(new GroupTreeResolver.Group(groupName, subgroupNames));
}
ldapGroupsMap.put(groupName, ldapGroup);
}
}
use of org.keycloak.storage.ldap.idm.model.LDAPObject in project keycloak by keycloak.
the class LDAPStorageProvider method searchLDAP.
protected List<LDAPObject> searchLDAP(RealmModel realm, Map<String, String> attributes) {
List<LDAPObject> results = new ArrayList<LDAPObject>();
if (attributes.containsKey(UserModel.USERNAME)) {
try (LDAPQuery ldapQuery = LDAPUtils.createQueryForUserSearch(this, realm)) {
LDAPQueryConditionsBuilder conditionsBuilder = new LDAPQueryConditionsBuilder();
// Mapper should replace "username" in parameter name with correct LDAP mapped attribute
Condition usernameCondition = conditionsBuilder.equal(UserModel.USERNAME, attributes.get(UserModel.USERNAME), EscapeStrategy.NON_ASCII_CHARS_ONLY);
ldapQuery.addWhereCondition(usernameCondition);
List<LDAPObject> ldapObjects = ldapQuery.getResultList();
results.addAll(ldapObjects);
}
}
if (attributes.containsKey(UserModel.EMAIL)) {
try (LDAPQuery ldapQuery = LDAPUtils.createQueryForUserSearch(this, realm)) {
LDAPQueryConditionsBuilder conditionsBuilder = new LDAPQueryConditionsBuilder();
// Mapper should replace "email" in parameter name with correct LDAP mapped attribute
Condition emailCondition = conditionsBuilder.equal(UserModel.EMAIL, attributes.get(UserModel.EMAIL), EscapeStrategy.NON_ASCII_CHARS_ONLY);
ldapQuery.addWhereCondition(emailCondition);
List<LDAPObject> ldapObjects = ldapQuery.getResultList();
results.addAll(ldapObjects);
}
}
if (attributes.containsKey(UserModel.FIRST_NAME) || attributes.containsKey(UserModel.LAST_NAME)) {
try (LDAPQuery ldapQuery = LDAPUtils.createQueryForUserSearch(this, realm)) {
LDAPQueryConditionsBuilder conditionsBuilder = new LDAPQueryConditionsBuilder();
// Mapper should replace parameter with correct LDAP mapped attributes
if (attributes.containsKey(UserModel.FIRST_NAME)) {
ldapQuery.addWhereCondition(conditionsBuilder.equal(UserModel.FIRST_NAME, attributes.get(UserModel.FIRST_NAME), EscapeStrategy.NON_ASCII_CHARS_ONLY));
}
if (attributes.containsKey(UserModel.LAST_NAME)) {
ldapQuery.addWhereCondition(conditionsBuilder.equal(UserModel.LAST_NAME, attributes.get(UserModel.LAST_NAME), EscapeStrategy.NON_ASCII_CHARS_ONLY));
}
List<LDAPObject> ldapObjects = ldapQuery.getResultList();
results.addAll(ldapObjects);
}
}
return results;
}
Aggregations