use of org.keycloak.storage.ldap.idm.model.LDAPObject in project keycloak by keycloak.
the class LDAPGroupMapperSyncWithGroupsPathTest method test01_syncWithGroupInheritance.
@Test
public void test01_syncWithGroupInheritance() {
testingClient.server().run(session -> {
LDAPTestContext ctx = LDAPTestContext.init(session);
RealmModel realm = ctx.getRealm();
String descriptionAttrName = LDAPTestUtils.getGroupDescriptionLDAPAttrName(ctx.getLdapProvider());
ComponentModel mapperModel = LDAPTestUtils.getSubcomponentByName(realm, ctx.getLdapModel(), "groupsMapper");
LDAPStorageProvider ldapProvider = LDAPTestUtils.getLdapProvider(session, ctx.getLdapModel());
GroupLDAPStorageMapper groupMapper = LDAPTestUtils.getGroupMapper(mapperModel, ldapProvider, realm);
// KEYCLOAK-11415 - This test requires the group mapper to be configured with preserve group inheritance
// set to 'true' (the default setting). If preservation of group inheritance isn't configured, some of
// the previous test(s) failed to cleanup properly. Check the requirement as part of running the test
Assert.assertEquals(mapperModel.getConfig().getFirst("preserve.group.inheritance"), "true");
// Sync groups with inheritance
SynchronizationResult syncResult = new GroupLDAPStorageMapperFactory().create(session, mapperModel).syncDataFromFederationProviderToKeycloak(realm);
LDAPTestAsserts.assertSyncEquals(syncResult, 3, 0, 0, 0);
// Assert groups are imported to keycloak including their inheritance from LDAP
GroupModel kcGroup1 = KeycloakModelUtils.findGroupByPath(realm, LDAP_GROUPS_PATH + "/group1");
Assert.assertNull(KeycloakModelUtils.findGroupByPath(realm, LDAP_GROUPS_PATH + "/group11"));
Assert.assertNull(KeycloakModelUtils.findGroupByPath(realm, LDAP_GROUPS_PATH + "/group12"));
GroupModel kcGroup11 = KeycloakModelUtils.findGroupByPath(realm, LDAP_GROUPS_PATH + "/group1/group11");
GroupModel kcGroup12 = KeycloakModelUtils.findGroupByPath(realm, LDAP_GROUPS_PATH + "/group1/group12");
Assert.assertEquals(2, kcGroup1.getSubGroupsStream().count());
Assert.assertEquals("group1 - description", kcGroup1.getFirstAttribute(descriptionAttrName));
Assert.assertNull(kcGroup11.getFirstAttribute(descriptionAttrName));
Assert.assertEquals("group12 - description", kcGroup12.getFirstAttribute(descriptionAttrName));
// Update description attributes in LDAP
LDAPObject group1 = groupMapper.loadLDAPGroupByName("group1");
group1.setSingleAttribute(descriptionAttrName, "group1 - changed description");
ldapProvider.getLdapIdentityStore().update(group1);
LDAPObject group12 = groupMapper.loadLDAPGroupByName("group12");
group12.setAttribute(descriptionAttrName, null);
ldapProvider.getLdapIdentityStore().update(group12);
// Sync and assert groups updated
syncResult = new GroupLDAPStorageMapperFactory().create(session, mapperModel).syncDataFromFederationProviderToKeycloak(realm);
LDAPTestAsserts.assertSyncEquals(syncResult, 0, 3, 0, 0);
// Assert attributes changed in keycloak
kcGroup1 = KeycloakModelUtils.findGroupByPath(realm, LDAP_GROUPS_PATH + "/group1");
kcGroup12 = KeycloakModelUtils.findGroupByPath(realm, LDAP_GROUPS_PATH + "/group1/group12");
Assert.assertEquals("group1 - changed description", kcGroup1.getFirstAttribute(descriptionAttrName));
Assert.assertNull(kcGroup12.getFirstAttribute(descriptionAttrName));
});
}
use of org.keycloak.storage.ldap.idm.model.LDAPObject in project keycloak by keycloak.
the class LDAPGroupMapperSyncWithGroupsPathTest method afterImportTestRealm.
@Override
protected void afterImportTestRealm() {
testingClient.server().run(session -> {
LDAPTestContext ctx = LDAPTestContext.init(session);
RealmModel appRealm = ctx.getRealm();
String descriptionAttrName = LDAPTestUtils.getGroupDescriptionLDAPAttrName(ctx.getLdapProvider());
// Create groups path
GroupModel parentGroup = appRealm.createGroup("Applications");
appRealm.createGroup("App1", parentGroup);
// Add group mapper
LDAPTestUtils.addOrUpdateGroupMapper(appRealm, ctx.getLdapModel(), LDAPGroupMapperMode.LDAP_ONLY, descriptionAttrName, GroupMapperConfig.LDAP_GROUPS_PATH, LDAP_GROUPS_PATH);
// Remove all LDAP groups
LDAPTestUtils.removeAllLDAPGroups(session, appRealm, ctx.getLdapModel(), "groupsMapper");
// Add some groups for testing
LDAPObject group1 = LDAPTestUtils.createLDAPGroup(session, appRealm, ctx.getLdapModel(), "group1", descriptionAttrName, "group1 - description");
LDAPObject group11 = LDAPTestUtils.createLDAPGroup(session, appRealm, ctx.getLdapModel(), "group11");
LDAPObject group12 = LDAPTestUtils.createLDAPGroup(session, appRealm, ctx.getLdapModel(), "group12", descriptionAttrName, "group12 - description");
LDAPUtils.addMember(ctx.getLdapProvider(), MembershipType.DN, LDAPConstants.MEMBER, "not-used", group1, group11);
LDAPUtils.addMember(ctx.getLdapProvider(), MembershipType.DN, LDAPConstants.MEMBER, "not-used", group1, group12);
});
}
use of org.keycloak.storage.ldap.idm.model.LDAPObject in project keycloak by keycloak.
the class LDAPAccountRestApiTest method afterImportTestRealm.
@Override
protected void afterImportTestRealm() {
testingClient.server().run(session -> {
LDAPTestContext ctx = LDAPTestContext.init(session);
RealmModel appRealm = ctx.getRealm();
// Delete all LDAP users and add some new for testing
LDAPTestUtils.removeAllLDAPUsers(ctx.getLdapProvider(), appRealm);
LDAPObject john = LDAPTestUtils.addLDAPUser(ctx.getLdapProvider(), appRealm, "johnkeycloak", "John", "Doe", "john@email.org", null, "1234");
LDAPTestUtils.updateLDAPPassword(ctx.getLdapProvider(), john, "Password1");
});
}
use of org.keycloak.storage.ldap.idm.model.LDAPObject in project keycloak by keycloak.
the class GroupLDAPStorageMapper method syncFlatGroupStructure.
private void syncFlatGroupStructure(RealmModel realm, SynchronizationResult syncResult, Map<String, LDAPObject> ldapGroupsMap) {
Set<String> visitedGroupIds = new HashSet<>();
// Just add flat structure of groups with all groups at groups path
LDAPConfig ldapConfig = ldapProvider.getLdapIdentityStore().getConfig();
final int groupsPerTransaction = ldapConfig.getBatchSizeForSync();
Set<Map.Entry<String, LDAPObject>> entries = ldapGroupsMap.entrySet();
for (Iterator<Map.Entry<String, LDAPObject>> it = entries.iterator(); it.hasNext(); ) {
KeycloakModelUtils.runJobInTransaction(ldapProvider.getSession().getKeycloakSessionFactory(), session -> {
// KEYCLOAK-8253 The retrieval of the current realm to operate at, was intentionally left
// outside the following for loop! This prevents the scenario, when LDAP group sync time
// initially improves, but during the time (after ~20K groups are synced) degrades again
// due to the realm cache being bloated with huge amount of (temporary) realm entities
RealmModel currentRealm = session.realms().getRealm(realm.getId());
// List of group path groups known to the whole transaction
Map<String, GroupModel> transactionGroupPathGroups = getKcSubGroups(currentRealm, null).collect(Collectors.toMap(GroupModel::getName, Function.identity()));
for (int i = 0; i < groupsPerTransaction && it.hasNext(); i++) {
Map.Entry<String, LDAPObject> groupEntry = it.next();
String groupName = groupEntry.getKey();
GroupModel kcExistingGroup = transactionGroupPathGroups.get(groupName);
if (kcExistingGroup != null) {
syncExistingGroup(kcExistingGroup, groupEntry, syncResult, visitedGroupIds, groupName);
} else {
syncNonExistingGroup(realm, groupEntry, syncResult, visitedGroupIds, groupName);
}
}
});
}
// Possibly remove keycloak groups, which don't exist in LDAP
if (config.isDropNonExistingGroupsDuringSync()) {
dropNonExistingKcGroups(realm, syncResult, visitedGroupIds);
}
}
use of org.keycloak.storage.ldap.idm.model.LDAPObject in project keycloak by keycloak.
the class GroupLDAPStorageMapper method processKeycloakGroupMembershipsSyncToLDAP.
// Update memberships of group in LDAP based on subgroups from KC. Do it recursively
private void processKeycloakGroupMembershipsSyncToLDAP(GroupModel kcGroup, Map<String, LDAPObject> ldapGroupsMap) {
LDAPObject ldapGroup = ldapGroupsMap.get(kcGroup.getName());
Set<LDAPDn> toRemoveSubgroupsDNs = getLDAPSubgroups(ldapGroup);
// Not applicable for groups, but needs to be here
String membershipUserLdapAttrName = getMembershipUserLdapAttribute();
// Add LDAP subgroups, which are KC subgroups
Set<GroupModel> kcSubgroups = kcGroup.getSubGroupsStream().collect(Collectors.toSet());
for (GroupModel kcSubgroup : kcSubgroups) {
LDAPObject ldapSubgroup = ldapGroupsMap.get(kcSubgroup.getName());
if (!toRemoveSubgroupsDNs.remove(ldapSubgroup.getDn())) {
// if the group is not in the ldap group => add it
LDAPUtils.addMember(ldapProvider, MembershipType.DN, config.getMembershipLdapAttribute(), membershipUserLdapAttrName, ldapGroup, ldapSubgroup);
}
}
// Remove LDAP subgroups, which are not members in KC anymore
for (LDAPDn toRemoveDN : toRemoveSubgroupsDNs) {
LDAPObject fakeGroup = new LDAPObject();
fakeGroup.setDn(toRemoveDN);
LDAPUtils.deleteMember(ldapProvider, MembershipType.DN, config.getMembershipLdapAttribute(), membershipUserLdapAttrName, ldapGroup, fakeGroup);
}
for (GroupModel kcSubgroup : kcSubgroups) {
processKeycloakGroupMembershipsSyncToLDAP(kcSubgroup, ldapGroupsMap);
}
}
Aggregations