Search in sources :

Example 51 with LDAPObject

use of org.keycloak.storage.ldap.idm.model.LDAPObject in project keycloak by keycloak.

the class LDAPAccountTest method updateProfileWithAttributePresent.

// KEYCLOAK-15634
@Test
public void updateProfileWithAttributePresent() {
    RealmResource testRealm = adminClient.realm("test");
    assertEquals(getAccountThemeName(), testRealm.toRepresentation().getAccountTheme());
    UserRepresentation userRepBefore = ApiUtil.findUserByUsername(testRealm, "keycloak-15634");
    assertNull("User should not exist", userRepBefore);
    testingClient.server().run(session -> {
        LDAPTestContext ctx = LDAPTestContext.init(session);
        RealmModel appRealm = ctx.getRealm();
        LDAPStorageProvider ldapFedProvider = LDAPTestUtils.getLdapProvider(session, ctx.getLdapModel());
        ldapFedProvider.getModel().put(LDAPConstants.EDIT_MODE, UserStorageProvider.EditMode.UNSYNCED.toString());
        appRealm.updateComponent(ldapFedProvider.getModel());
        LDAPObject testUser = LDAPTestUtils.addLDAPUser(ctx.getLdapProvider(), appRealm, "keycloak-15634", "firstName", "lastName", "keycloak-15634@test.local", null, "1234");
        LDAPTestUtils.updateLDAPPassword(ctx.getLdapProvider(), testUser, PASSWORD);
    });
    // Check our test user is ok before updating profile
    userRepBefore = ApiUtil.findUserByUsername(testRealm, "keycloak-15634");
    assertEquals("Test user should have an email address set", "keycloak-15634@test.local", userRepBefore.getEmail());
    assertTrue("Test user should have the LDAP_ID attribute set", userRepBefore.getAttributes().containsKey("LDAP_ID"));
    assertFalse("Test user should not have locale attribute set", userRepBefore.getAttributes().containsKey("locale"));
    personalInfoPage.navigateTo();
    loginPage.assertCurrent();
    loginPage.form().login("keycloak-15634", "password");
    personalInfoPage.assertCurrent();
    assertEquals("keycloak-15634@test.local", personalInfoPage.getEmail());
    // Trigger the JS involved in KEYCLOAK-15634
    personalInfoPage.setEmail("keycloak-15634@domain.local");
    personalInfoPage.clickSave();
    // Check if updateProfile went well and if user is still there
    UserRepresentation userRepAfter = ApiUtil.findUserByUsername(testRealm, "keycloak-15634");
    assertNotNull("Test user should still be there", userRepAfter);
    assertEquals("Email should have been updated", "keycloak-15634@domain.local", userRepAfter.getEmail());
    assertTrue("LDAP_ID attribute should still be there", userRepAfter.getAttributes().containsKey("LDAP_ID"));
    // Clean up
    ApiUtil.removeUserByUsername(testRealm, "keycloak-15634");
    testingClient.server().run(session -> {
        LDAPTestContext ctx = LDAPTestContext.init(session);
        RealmModel appRealm = ctx.getRealm();
        LDAPTestUtils.removeAllLDAPUsers(ctx.getLdapProvider(), appRealm);
    });
}
Also used : RealmModel(org.keycloak.models.RealmModel) RealmResource(org.keycloak.admin.client.resource.RealmResource) LDAPTestContext(org.keycloak.testsuite.federation.ldap.LDAPTestContext) LDAPStorageProvider(org.keycloak.storage.ldap.LDAPStorageProvider) LDAPObject(org.keycloak.storage.ldap.idm.model.LDAPObject) Test(org.junit.Test)

Example 52 with LDAPObject

use of org.keycloak.storage.ldap.idm.model.LDAPObject in project keycloak by keycloak.

the class LdapManyGroupsInitializerCommand method doRunCommand.

@Override
protected void doRunCommand(KeycloakSession session) {
    String realmName = getArg(0);
    String groupsDn = getArg(1);
    int startOffsetTopGroups = getIntArg(2);
    int topGroupsCount = getIntArg(3);
    int subgroupsInEveryGroup = getIntArg(4);
    RealmModel realm = session.realms().getRealmByName(realmName);
    List<ComponentModel> components = realm.getComponentsStream(realm.getId(), UserStorageProvider.class.getName()).collect(Collectors.toList());
    if (components.size() != 1) {
        log.errorf("Expected 1 LDAP Provider, but found: %d providers", components.size());
        throw new HandledException();
    }
    ComponentModel ldapModel = components.get(0);
    // Check that street mapper exists. It's required for now, so that "street" attribute is written to the LDAP
    ComponentModel groupMapperModel = getMapperModel(realm, ldapModel, "groupsMapper");
    // Create groups
    for (int i = startOffsetTopGroups; i < startOffsetTopGroups + topGroupsCount; i++) {
        final int iFinal = i;
        KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession kcSession) -> {
            LDAPStorageProvider ldapProvider = (LDAPStorageProvider) session.getProvider(UserStorageProvider.class, ldapModel);
            RealmModel appRealm = session.realms().getRealmByName(realmName);
            GroupLDAPStorageMapper groupMapper = (GroupLDAPStorageMapper) session.getProvider(LDAPStorageMapper.class, groupMapperModel);
            Set<String> childGroupDns = new HashSet<>();
            for (int j = 0; j < subgroupsInEveryGroup; j++) {
                String groupName = "group-" + iFinal + "-" + j;
                LDAPObject createdGroup = groupMapper.createLDAPGroup(groupName, new HashMap<>());
                childGroupDns.add(createdGroup.getDn().toString());
            }
            String topGroupName = "group-" + iFinal;
            Map<String, Set<String>> groupAttrs = new HashMap<>();
            groupAttrs.put("member", new HashSet<>(childGroupDns));
            groupMapper.createLDAPGroup(topGroupName, groupAttrs);
        });
    }
}
Also used : LDAPStorageMapper(org.keycloak.storage.ldap.mappers.LDAPStorageMapper) GroupLDAPStorageMapper(org.keycloak.storage.ldap.mappers.membership.group.GroupLDAPStorageMapper) LDAPStorageProvider(org.keycloak.storage.ldap.LDAPStorageProvider) RealmModel(org.keycloak.models.RealmModel) UserStorageProvider(org.keycloak.storage.UserStorageProvider) KeycloakSession(org.keycloak.models.KeycloakSession) ComponentModel(org.keycloak.component.ComponentModel) LDAPObject(org.keycloak.storage.ldap.idm.model.LDAPObject) GroupLDAPStorageMapper(org.keycloak.storage.ldap.mappers.membership.group.GroupLDAPStorageMapper)

Example 53 with LDAPObject

use of org.keycloak.storage.ldap.idm.model.LDAPObject in project keycloak by keycloak.

the class LdapManyObjectsInitializerCommand method doRunCommand.

@Override
protected void doRunCommand(KeycloakSession session) {
    String realmName = getArg(0);
    String groupsDn = getArg(1);
    int startOffsetUsers = getIntArg(2);
    int countUsers = getIntArg(3);
    int batchCount = 100;
    int startOffsetGroups = getIntArg(4);
    int countGroups = getIntArg(5);
    RealmModel realm = session.realms().getRealmByName(realmName);
    List<ComponentModel> components = realm.getComponentsStream(realm.getId(), UserStorageProvider.class.getName()).collect(Collectors.toList());
    if (components.size() != 1) {
        log.errorf("Expected 1 LDAP Provider, but found: %d providers", components.size());
        throw new HandledException();
    }
    ComponentModel ldapModel = components.get(0);
    // Check that street mapper exists. It's required for now, so that "street" attribute is written to the LDAP
    getMapperModel(realm, ldapModel, "streetMapper");
    ComponentModel groupMapperModel = getMapperModel(realm, ldapModel, "groupsMapper");
    // Create users
    Set<String> createdUserDNs = new HashSet<>();
    BatchTaskRunner.runInBatches(startOffsetUsers, countUsers, batchCount, session.getKeycloakSessionFactory(), (KeycloakSession kcSession, int firstIt, int countInIt) -> {
        LDAPStorageProvider ldapProvider = (LDAPStorageProvider) session.getProvider(UserStorageProvider.class, ldapModel);
        RealmModel appRealm = session.realms().getRealmByName(realmName);
        for (int i = firstIt; i < firstIt + countInIt; i++) {
            String username = "user-" + i;
            String firstName = "John-" + i;
            String lastName = "Doe-" + i;
            String email = "user" + i + "@email.cz";
            LDAPObject createdUser = addLDAPUser(ldapProvider, appRealm, username, firstName, lastName, email, groupsDn, startOffsetGroups, countGroups);
            createdUserDNs.add(createdUser.getDn().toString());
        }
        log.infof("Created LDAP users from: %d to %d", firstIt, firstIt + countInIt - 1);
    });
    // Create groups
    BatchTaskRunner.runInBatches(startOffsetGroups, countGroups, batchCount, session.getKeycloakSessionFactory(), (KeycloakSession kcSession, int firstIt, int countInIt) -> {
        LDAPStorageProvider ldapProvider = (LDAPStorageProvider) session.getProvider(UserStorageProvider.class, ldapModel);
        RealmModel appRealm = session.realms().getRealmByName(realmName);
        GroupLDAPStorageMapper groupMapper = (GroupLDAPStorageMapper) session.getProvider(LDAPStorageMapper.class, groupMapperModel);
        for (int i = firstIt; i < firstIt + countInIt; i++) {
            String groupName = "group" + i;
            Map<String, Set<String>> groupAttrs = new HashMap<>();
            groupAttrs.put("member", new HashSet<>(createdUserDNs));
            groupMapper.createLDAPGroup(groupName, groupAttrs);
        }
        log.infof("Created LDAP groups from: %d to %d", firstIt, firstIt + countInIt - 1);
    });
}
Also used : LDAPStorageMapper(org.keycloak.storage.ldap.mappers.LDAPStorageMapper) GroupLDAPStorageMapper(org.keycloak.storage.ldap.mappers.membership.group.GroupLDAPStorageMapper) Set(java.util.Set) HashSet(java.util.HashSet) HashMap(java.util.HashMap) LDAPStorageProvider(org.keycloak.storage.ldap.LDAPStorageProvider) RealmModel(org.keycloak.models.RealmModel) UserStorageProvider(org.keycloak.storage.UserStorageProvider) KeycloakSession(org.keycloak.models.KeycloakSession) ComponentModel(org.keycloak.component.ComponentModel) LDAPObject(org.keycloak.storage.ldap.idm.model.LDAPObject) GroupLDAPStorageMapper(org.keycloak.storage.ldap.mappers.membership.group.GroupLDAPStorageMapper) HashSet(java.util.HashSet)

Example 54 with LDAPObject

use of org.keycloak.storage.ldap.idm.model.LDAPObject in project keycloak by keycloak.

the class LDAPStorageProviderFactory method importLdapUsers.

protected SynchronizationResult importLdapUsers(KeycloakSessionFactory sessionFactory, final String realmId, final ComponentModel fedModel, List<LDAPObject> ldapUsers) {
    final SynchronizationResult syncResult = new SynchronizationResult();
    class BooleanHolder {

        private boolean value = true;
    }
    final BooleanHolder exists = new BooleanHolder();
    for (final LDAPObject ldapUser : ldapUsers) {
        try {
            // Process each user in it's own transaction to avoid global fail
            KeycloakModelUtils.runJobInTransaction(sessionFactory, new KeycloakSessionTask() {

                @Override
                public void run(KeycloakSession session) {
                    LDAPStorageProvider ldapFedProvider = (LDAPStorageProvider) session.getProvider(UserStorageProvider.class, fedModel);
                    RealmModel currentRealm = session.realms().getRealm(realmId);
                    session.getContext().setRealm(currentRealm);
                    String username = LDAPUtils.getUsername(ldapUser, ldapFedProvider.getLdapIdentityStore().getConfig());
                    exists.value = true;
                    LDAPUtils.checkUuid(ldapUser, ldapFedProvider.getLdapIdentityStore().getConfig());
                    UserModel currentUserLocal = session.userLocalStorage().getUserByUsername(currentRealm, username);
                    Optional<UserModel> userModelOptional = session.userLocalStorage().searchForUserByUserAttributeStream(currentRealm, LDAPConstants.LDAP_ID, ldapUser.getUuid()).findFirst();
                    if (!userModelOptional.isPresent() && currentUserLocal == null) {
                        // Add new user to Keycloak
                        exists.value = false;
                        ldapFedProvider.importUserFromLDAP(session, currentRealm, ldapUser);
                        syncResult.increaseAdded();
                    } else {
                        UserModel currentUser = userModelOptional.isPresent() ? userModelOptional.get() : currentUserLocal;
                        if ((fedModel.getId().equals(currentUser.getFederationLink())) && (ldapUser.getUuid().equals(currentUser.getFirstAttribute(LDAPConstants.LDAP_ID)))) {
                            // Update keycloak user
                            LDAPMappersComparator ldapMappersComparator = new LDAPMappersComparator(ldapFedProvider.getLdapIdentityStore().getConfig());
                            currentRealm.getComponentsStream(fedModel.getId(), LDAPStorageMapper.class.getName()).sorted(ldapMappersComparator.sortDesc()).forEachOrdered(mapperModel -> {
                                LDAPStorageMapper ldapMapper = ldapFedProvider.getMapperManager().getMapper(mapperModel);
                                ldapMapper.onImportUserFromLDAP(ldapUser, currentUser, currentRealm, false);
                            });
                            UserCache userCache = session.userCache();
                            if (userCache != null) {
                                userCache.evict(currentRealm, currentUser);
                            }
                            logger.debugf("Updated user from LDAP: %s", currentUser.getUsername());
                            syncResult.increaseUpdated();
                        } else {
                            logger.warnf("User with ID '%s' is not updated during sync as he already exists in Keycloak database but is not linked to federation provider '%s'", ldapUser.getUuid(), fedModel.getName());
                            syncResult.increaseFailed();
                        }
                    }
                }
            });
        } catch (ModelException me) {
            logger.error("Failed during import user from LDAP", me);
            syncResult.increaseFailed();
            // Remove user if we already added him during this transaction
            if (!exists.value) {
                KeycloakModelUtils.runJobInTransaction(sessionFactory, new KeycloakSessionTask() {

                    @Override
                    public void run(KeycloakSession session) {
                        LDAPStorageProvider ldapFedProvider = (LDAPStorageProvider) session.getProvider(UserStorageProvider.class, fedModel);
                        RealmModel currentRealm = session.realms().getRealm(realmId);
                        session.getContext().setRealm(currentRealm);
                        String username = null;
                        try {
                            username = LDAPUtils.getUsername(ldapUser, ldapFedProvider.getLdapIdentityStore().getConfig());
                        } catch (ModelException ignore) {
                        }
                        if (username != null) {
                            UserModel existing = session.userLocalStorage().getUserByUsername(currentRealm, username);
                            if (existing != null) {
                                UserCache userCache = session.userCache();
                                if (userCache != null) {
                                    userCache.evict(currentRealm, existing);
                                }
                                session.userLocalStorage().removeUser(currentRealm, existing);
                            }
                        }
                    }
                });
            }
        }
    }
    return syncResult;
}
Also used : SPNEGOAuthenticator(org.keycloak.federation.kerberos.impl.SPNEGOAuthenticator) FullNameLDAPStorageMapperFactory(org.keycloak.storage.ldap.mappers.FullNameLDAPStorageMapperFactory) Date(java.util.Date) LDAPStorageMapper(org.keycloak.storage.ldap.mappers.LDAPStorageMapper) Config(org.keycloak.Config) FullNameLDAPStorageMapper(org.keycloak.storage.ldap.mappers.FullNameLDAPStorageMapper) ProviderConfigurationBuilder(org.keycloak.provider.ProviderConfigurationBuilder) LDAPConstants(org.keycloak.models.LDAPConstants) Map(java.util.Map) ComponentModel(org.keycloak.component.ComponentModel) CredentialRepresentation(org.keycloak.representations.idm.CredentialRepresentation) UserStorageProviderModel(org.keycloak.storage.UserStorageProviderModel) UserAttributeLDAPStorageMapperFactory(org.keycloak.storage.ldap.mappers.UserAttributeLDAPStorageMapperFactory) UserStorageProviderFactory(org.keycloak.storage.UserStorageProviderFactory) HardcodedLDAPAttributeMapper(org.keycloak.storage.ldap.mappers.HardcodedLDAPAttributeMapper) HardcodedLDAPAttributeMapperFactory(org.keycloak.storage.ldap.mappers.HardcodedLDAPAttributeMapperFactory) RealmModel(org.keycloak.models.RealmModel) LDAPConfigDecorator(org.keycloak.storage.ldap.mappers.LDAPConfigDecorator) CredentialHelper(org.keycloak.utils.CredentialHelper) CommonKerberosConfig(org.keycloak.federation.kerberos.CommonKerberosConfig) Collectors(java.util.stream.Collectors) LDAPObject(org.keycloak.storage.ldap.idm.model.LDAPObject) ImportSynchronization(org.keycloak.storage.user.ImportSynchronization) List(java.util.List) UserAttributeLDAPStorageMapper(org.keycloak.storage.ldap.mappers.UserAttributeLDAPStorageMapper) KerberosUsernamePasswordAuthenticator(org.keycloak.federation.kerberos.impl.KerberosUsernamePasswordAuthenticator) KeycloakSessionFactory(org.keycloak.models.KeycloakSessionFactory) Optional(java.util.Optional) Condition(org.keycloak.storage.ldap.idm.query.Condition) ComponentValidationException(org.keycloak.component.ComponentValidationException) KeycloakModelUtils(org.keycloak.models.utils.KeycloakModelUtils) Logger(org.jboss.logging.Logger) ProviderConfigProperty(org.keycloak.provider.ProviderConfigProperty) Function(java.util.function.Function) LDAPIdentityStore(org.keycloak.storage.ldap.idm.store.ldap.LDAPIdentityStore) UserModel(org.keycloak.models.UserModel) AuthenticationExecutionModel(org.keycloak.models.AuthenticationExecutionModel) KeycloakSessionTask(org.keycloak.models.KeycloakSessionTask) LDAPQueryConditionsBuilder(org.keycloak.storage.ldap.idm.query.internal.LDAPQueryConditionsBuilder) KerberosConstants(org.keycloak.common.constants.KerberosConstants) UserStorageProvider(org.keycloak.storage.UserStorageProvider) LDAPMappersComparator(org.keycloak.storage.ldap.mappers.LDAPMappersComparator) KerberosServerSubjectAuthenticator(org.keycloak.federation.kerberos.impl.KerberosServerSubjectAuthenticator) KeycloakSession(org.keycloak.models.KeycloakSession) LDAPQuery(org.keycloak.storage.ldap.idm.query.internal.LDAPQuery) UserCache(org.keycloak.models.cache.UserCache) MSADUserAccountControlStorageMapperFactory(org.keycloak.storage.ldap.mappers.msad.MSADUserAccountControlStorageMapperFactory) ModelException(org.keycloak.models.ModelException) SynchronizationResult(org.keycloak.storage.user.SynchronizationResult) LDAPStorageMapper(org.keycloak.storage.ldap.mappers.LDAPStorageMapper) FullNameLDAPStorageMapper(org.keycloak.storage.ldap.mappers.FullNameLDAPStorageMapper) UserAttributeLDAPStorageMapper(org.keycloak.storage.ldap.mappers.UserAttributeLDAPStorageMapper) Optional(java.util.Optional) LDAPMappersComparator(org.keycloak.storage.ldap.mappers.LDAPMappersComparator) ModelException(org.keycloak.models.ModelException) UserCache(org.keycloak.models.cache.UserCache) RealmModel(org.keycloak.models.RealmModel) UserModel(org.keycloak.models.UserModel) UserStorageProvider(org.keycloak.storage.UserStorageProvider) KeycloakSessionTask(org.keycloak.models.KeycloakSessionTask) KeycloakSession(org.keycloak.models.KeycloakSession) LDAPObject(org.keycloak.storage.ldap.idm.model.LDAPObject) SynchronizationResult(org.keycloak.storage.user.SynchronizationResult)

Example 55 with LDAPObject

use of org.keycloak.storage.ldap.idm.model.LDAPObject in project keycloak by keycloak.

the class LDAPUtils method addUserToLDAP.

/**
 * @param ldapProvider
 * @param realm
 * @param user
 * @return newly created LDAPObject with all the attributes, uuid and DN properly set
 */
public static LDAPObject addUserToLDAP(LDAPStorageProvider ldapProvider, RealmModel realm, UserModel user) {
    LDAPObject ldapUser = new LDAPObject();
    LDAPIdentityStore ldapStore = ldapProvider.getLdapIdentityStore();
    LDAPConfig ldapConfig = ldapStore.getConfig();
    ldapUser.setRdnAttributeName(ldapConfig.getRdnLdapAttribute());
    ldapUser.setObjectClasses(ldapConfig.getUserObjectClasses());
    LDAPMappersComparator ldapMappersComparator = new LDAPMappersComparator(ldapConfig);
    realm.getComponentsStream(ldapProvider.getModel().getId(), LDAPStorageMapper.class.getName()).sorted(ldapMappersComparator.sortAsc()).forEachOrdered(mapperModel -> {
        LDAPStorageMapper ldapMapper = ldapProvider.getMapperManager().getMapper(mapperModel);
        ldapMapper.onRegisterUserToLDAP(ldapUser, user, realm);
    });
    LDAPUtils.computeAndSetDn(ldapConfig, ldapUser);
    ldapStore.add(ldapUser);
    return ldapUser;
}
Also used : LDAPIdentityStore(org.keycloak.storage.ldap.idm.store.ldap.LDAPIdentityStore) LDAPStorageMapper(org.keycloak.storage.ldap.mappers.LDAPStorageMapper) LDAPMappersComparator(org.keycloak.storage.ldap.mappers.LDAPMappersComparator) LDAPObject(org.keycloak.storage.ldap.idm.model.LDAPObject)

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