EN · DE · RU · FR · ES

#507: LdapSlaveLoginHandler.java

projectforge-business/src/main/java/org/projectforge/business/ldap/LdapSlaveLoginHandler.java Type: Java · Role: LDAP Integration · Source: projectforge-business/src/main/java/org/projectforge/business/ldap/LdapSlaveLoginHandler.java 355 lines · 238 code · 97 comments · 20 blank
Source code file at projectforge-business/src/main/java/org/projectforge/business/ldap/LdapSlaveLoginHandler.java containing Java code for the LDAP Integration layer.

Code Structure

Package: org.projectforge.business.ldap

Classes: LdapSlaveLoginHandler

Enums: Mode

Extends: LdapLoginHandler

Methods (12): initialize, checkLogin, getAllGroups, getAllUsers, getUser, isPasswordChangeSupported, isWlanPasswordChangeSupported, afterUserGroupCacheRefresh, run, isRefreshInProgress, updateLdap, call

Fields (3): userGroupCache, mode, refreshInProgress

Imports: 15 packages

Source Code (abridged)

package org.projectforge.business.ldap;

import org.apache.commons.lang3.StringUtils;
import org.projectforge.business.login.LoginDefaultHandler;
import org.projectforge.business.login.LoginHandler;
import org.projectforge.business.login.LoginResult;
import org.projectforge.business.login.LoginResultStatus;
import org.projectforge.business.user.UserGroupCache;
import org.projectforge.framework.persistence.api.EntityCopyStatus;
import org.projectforge.framework.persistence.user.entities.GroupDO;
import org.projectforge.framework.persistence.user.entities.PFUserDO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.naming.NameNotFoundException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

/**
 * This LDAP login handler acts as a LDAP slave, meaning, that LDAP will be accessed in read-only mode. There are 3
 * modes available: simple, users and users-groups.
 * <h4>Simple mode</h4> The simple mode is assumed if no ldap managerUser is given in the config.xml.
 * <ul>
 * <li>Simple means that only username and password is checked, all other user settings such as assigned groups and user
 * name etc. are managed by ProjectForge.</li>
 * <li>No ldap user is needed for accessing users or groups of LDAP, only the user's login-name and password is checked
 * by trying to authenticate!</li>
 * <li>If a user is deactivated in LDAP the user has the possibility to work with ProjectForge unlimited as long as he
 * uses his stay-logged-in-method! (If not acceptable please use the normal user mode instead.)</li>
 * <li>For local users any LDAP setting is ignored.</li>
 * </ul>
 * <h4>Normal users mode</h4> The normal user mode is assumed if a ldap managerUser is given in the config.xml.
 * <ul>
 * <li>Normal means that username and password is checked and all other user settings such as user name etc. are read by
 * a given ldap manager user.</li>
 * <li>If a user is deleted in LDAP the user will be marked as deleted also in ProjectForge's data-base. Any login after
 * synchronizing isn't allowed (the stay-logged-in-feature fails also for deleted users).</li>
 * <li>For local users any LDAP setting is ignored.</li>
 * <li>All known ldap user fields of the users are synchronized (given name, surname, e-mail etc.).</li>
 * </ul>
 * <h4>Users-groups mode</h4> Not yet supported. No groups will be synchronized.
 *
 * @author Kai Reinhard (k.reinhard@micromata.de)
 */
@Service
public class LdapSlaveLoginHandler extends LdapLoginHandler {
  private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(LdapSlaveLoginHandler.class);

  @Autowired
  PFUserDOConverter pfUserDOConverter;

  @Autowired
  private UserGroupCache userGroupCache;

  enum Mode {
    SIMPLE, USERS, USER_GROUPS
  }

  private Mode mode;

  private boolean refreshInProgress;

  /**
   * Only for test cases.
   *
   * @param mode
   */
  void setMode(final Mode mode) {
    this.mode = mode;
  }

  /**
   * @see org.projectforge.business.ldap.LdapLoginHandler#initialize()
   */
  @Override
  public void initialize() {
    super.initialize();
    if (StringUtils.isBlank(ldapConfig.getManagerUser())) {
      mode = Mode.SIMPLE;
    } else if (StringUtils.isNotBlank(ldapConfig.getGroupBase())) {
      mode = Mode.USERS;// Mode.USER_GROUPS;
      log.warn("Groups aren't yet supported by this LDAP handler.");
    } else {
      mode = Mode.USERS;
    }
    switch (mode) {
      case SIMPLE:
        log.info("LDAP slave login handler works in mode 'simple'.");
        break;
      case USERS:
        log.info("LDAP slave login handler works in mode 'users'.");
        break;
      case USER_GROUPS:
        log.info("LDAP slave login handler works in mode 'user_groups'.");
        break;
    }
  }

  /**
   * Uses the standard implementation {@link LoginDefaultHandler#checkLogin(String, char[])} for local users. For all
   * other users a LDAP authentication is checked. If the LDAP authentication fails then
   * {@link LoginResultStatus#FAILED} is returned. If successful then {@link LoginResultStatus#SUCCESS} is returned with
   * the user settings of ProjectForge database. If the user doesn't yet exist in ProjectForge's data-base, it will be
   * created after and then returned.
   *
   * @see LoginHandler#checkLogin(String, char[])
   */
  @Override
  public LoginResult checkLogin(final String username, final char[] password) {
    PFUserDO user = userService.getInternalByUsername(username);
    if (user != null && user.getLocalUser()) {
      return loginDefaultHandler.checkLogin(username, password);
    }
    final LoginResult loginResult = new LoginResult();
    final String organizationalUnits = ldapConfig.getUserBase();
    final LdapUser ldapUser = ldapUserDao.authenticate(username, password, organizationalUnits);
    if (ldapUser == null) {
      log.info("User login failed: " + username);
// ... (truncated, total 333 lines)

Git History

868d6abb7 2025 -> 2026
63081666f Source file headers: 2024-> 2025.
3c42485eb Migration stuff in progress... (all tests of all packages: OK).
1b50060c3 BaseDao: renamed: get -> find, save -> insert, getList -> select, load -> select
87aaf6a5a Migration stuff in progress... BaseDao refactored (not yet finished) internal* methods renamed.