Search in sources :

Example 1 with LDAPObject

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));
    });
}
Also used : RealmModel(org.keycloak.models.RealmModel) ComponentModel(org.keycloak.component.ComponentModel) LDAPStorageProvider(org.keycloak.storage.ldap.LDAPStorageProvider) GroupModel(org.keycloak.models.GroupModel) LDAPObject(org.keycloak.storage.ldap.idm.model.LDAPObject) GroupLDAPStorageMapperFactory(org.keycloak.storage.ldap.mappers.membership.group.GroupLDAPStorageMapperFactory) SynchronizationResult(org.keycloak.storage.user.SynchronizationResult) GroupLDAPStorageMapper(org.keycloak.storage.ldap.mappers.membership.group.GroupLDAPStorageMapper) Test(org.junit.Test)

Example 2 with LDAPObject

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);
    });
}
Also used : RealmModel(org.keycloak.models.RealmModel) GroupModel(org.keycloak.models.GroupModel) LDAPObject(org.keycloak.storage.ldap.idm.model.LDAPObject)

Example 3 with LDAPObject

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");
    });
}
Also used : RealmModel(org.keycloak.models.RealmModel) LDAPObject(org.keycloak.storage.ldap.idm.model.LDAPObject)

Example 4 with LDAPObject

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);
    }
}
Also used : GroupModel(org.keycloak.models.GroupModel) RealmModel(org.keycloak.models.RealmModel) LDAPConfig(org.keycloak.storage.ldap.LDAPConfig) LDAPObject(org.keycloak.storage.ldap.idm.model.LDAPObject) HashMap(java.util.HashMap) Map(java.util.Map) HashSet(java.util.HashSet)

Example 5 with LDAPObject

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);
    }
}
Also used : LDAPObject(org.keycloak.storage.ldap.idm.model.LDAPObject) GroupModel(org.keycloak.models.GroupModel) LDAPDn(org.keycloak.storage.ldap.idm.model.LDAPDn)

Aggregations

LDAPObject (org.keycloak.storage.ldap.idm.model.LDAPObject)105 RealmModel (org.keycloak.models.RealmModel)61 Test (org.junit.Test)38 LDAPStorageProvider (org.keycloak.storage.ldap.LDAPStorageProvider)37 ComponentModel (org.keycloak.component.ComponentModel)35 UserModel (org.keycloak.models.UserModel)28 GroupModel (org.keycloak.models.GroupModel)18 SynchronizationResult (org.keycloak.storage.user.SynchronizationResult)16 GroupLDAPStorageMapper (org.keycloak.storage.ldap.mappers.membership.group.GroupLDAPStorageMapper)14 ModelException (org.keycloak.models.ModelException)11 LDAPDn (org.keycloak.storage.ldap.idm.model.LDAPDn)10 LDAPQuery (org.keycloak.storage.ldap.idm.query.internal.LDAPQuery)10 HashMap (java.util.HashMap)9 AbstractAuthTest (org.keycloak.testsuite.AbstractAuthTest)8 HashSet (java.util.HashSet)7 List (java.util.List)7 CachedUserModel (org.keycloak.models.cache.CachedUserModel)7 LDAPConfig (org.keycloak.storage.ldap.LDAPConfig)7 LDAPStorageMapper (org.keycloak.storage.ldap.mappers.LDAPStorageMapper)7 Map (java.util.Map)6