Package org.olat.ldap

Source Code of org.olat.ldap.LDAPLoginModule

package org.olat.ldap;

import java.text.ParseException;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Map.Entry;

import org.olat.basesecurity.Manager;
import org.olat.basesecurity.ManagerFactory;
import org.olat.basesecurity.SecurityGroup;
import org.olat.core.CoreSpringFactory;
import org.olat.core.configuration.OLATModule;
import org.olat.core.extensions.ExtManager;
import org.olat.core.logging.OLog;
import org.olat.core.logging.StartupException;
import org.olat.core.logging.Tracing;
import org.olat.core.util.StringHelper;
import org.olat.ldap.ui.LDAPAdminExtension;
import org.quartz.CronTrigger;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;

import com.anthonyeden.lib.config.Configuration;
/**
* Description:
* This Module loads all needed configuration for the LDAP Login.
* All configuration is done in the spring olatextconfig.xml file.
* <p>
* LDAPLoginModule
* <p>
*
* @author maurus.rohrer@gmail.com
*/
public class LDAPLoginModule implements OLATModule {
  // Connection configuration
  private static String ldapUrl;
  private static boolean ldapEnabled;
  private static boolean activeDirectory;
  //SSL configuration
  private static boolean sslEnabled;
  private static String trustStoreLoc;
  private static String trustStorePass;
  private static String trustStoreTyp;
  // System user: used for getting all users and connection testing
  private static String systemDN;
  private static String systemPW;
  // List of bases where to find users
  private static List<String> ldapBases;
  // Use a valid ldap password and save it as olat password to reduce dependency
  // to LDAP server availability and allow WeDAV access
  private static boolean cacheLDAPPwdAsOLATPwdOnLogin;
  // When the system detects an LDAP user that does already exist in OLAT but is not marked
  // as LDAP user, the OLAT user can be converted to an LDAP managed user.
  // When enabling this feature you should make sure that you don't have a user 'administrator'
  // in your ldapBases (not a problem but not recommended)
  private static boolean convertExistingLocalUsersToLDAPUsers;
  // Users that have been created vial LDAP sync but now can't be found on the LDAP anymore
  // can be deleted automatically. If unsure, set to false and delete those users manually
  // in the user management.
  private static boolean deleteRemovedLDAPUsersOnSync;
  // LDAP sync will not delete users if more than deleteRemovedLDAPUserPercentage are found to be deleted.
  private static int deleteRemovedLDAPUsersPercentage;
  // Propagate the password changes onto the LDAP server
  private static boolean propagatePasswordChangedOnLdapServer;
  // Configuration for syncing user attributes
  private static String ldapUserObjectClass;
  private static String ldapUserCreatedTimestampAttribute;
  private static String ldapUserLastModifiedTimestampAttribute;
  private static String ldapUserPasswordAttribute;
  // Should users be created and synchronized automatically? If you set this
  // configuration to false, the users will be generated on-the-fly when they
  // log in
  private static boolean ldapSyncOnStartup;
  private static boolean ldapSyncCronSync;
  private static String ldapSyncCronSyncExpression;
  // User LDAP attributes to be synced and a map with the mandatory attributes
  private static Map<String, String> userAttrMap;
  private static Map<String, String> reqAttr;
  private static Set<String> syncOnlyOnCreateProperties;
  private static String[] userAttr;
  // Static user properties that should be added to user when syncing
  private static Map<String, String> staticUserProperties;
  private static OLog log = Tracing.createLoggerFor(LDAPLoginModule.class);

  /**
   * @see org.olat.core.configuration.OLATModule#init(com.anthonyeden.lib.config.Configuration)
   */
  public void init(Configuration moduleConfig) {
    // Check if LDAP is enabled
    if (!isLDAPEnabled()) {
      log.info("LDAP login is disabled");
      return;
    }
    // Create LDAP Security Group if not existing. Used to identify users that
    // have to be synced with LDAP
    Manager scrManager = ManagerFactory.getManager();
    LDAPLoginManager ldapManager = LDAPLoginManager.getInstance();
    SecurityGroup ldapGroup = scrManager.findSecurityGroupByName(LDAPConstants.SECURITY_GROUP_LDAP);
    if (ldapGroup == null) {
      ldapGroup = scrManager.createAndPersistNamedSecurityGroup(LDAPConstants.SECURITY_GROUP_LDAP);
    }
    // check for valid configuration
    if (!checkConfigParameterIsNotEmpty(ldapUrl)) return;
    if (!checkConfigParameterIsNotEmpty(systemDN)) return;
    if (!checkConfigParameterIsNotEmpty(systemPW)) return;
    if (ldapBases == null || ldapBases.size() == 0) {
      log
          .error("Missing configuration 'ldapBases'. Add at least one LDAP Base to the this configuration in olatextconfig.xml first. Disabling LDAP");
      setEnableLDAPLogins(false);
      return;
    }
    if (!checkConfigParameterIsNotEmpty(ldapUserObjectClass)) return;
    if (!checkConfigParameterIsNotEmpty(ldapUserCreatedTimestampAttribute)) return;
    if (!checkConfigParameterIsNotEmpty(ldapUserLastModifiedTimestampAttribute)) return;
    if (userAttrMap == null || userAttrMap.size() == 0) {
      log
          .error("Missing configuration 'userAttrMap'. Add at least the email propery to the this configuration in olatextconfig.xml first. Disabling LDAP");
      setEnableLDAPLogins(false);
      return;
    }
    if (reqAttr == null || reqAttr.size() == 0) {
      log
          .error("Missing configuration 'reqAttr'. Add at least the email propery to the this configuration in olatextconfig.xml first. Disabling LDAP");
      setEnableLDAPLogins(false);
      return;
    }
    // check if OLAT user properties is defined in olat_userconfig.xml, if not disable the LDAP module
    if(!LDAPHelper.checkIfOlatPropertiesExists(userAttrMap)){
      log.error("Invalid LDAP OLAT properties mapping configuration (userAttrMap). Disabling LDAP");
      setEnableLDAPLogins(false);
      return;
    }
    if(!LDAPHelper.checkIfOlatPropertiesExists(reqAttr)){
      log.error("Invalid LDAP OLAT properties mapping configuration (reqAttr). Disabling LDAP");
      setEnableLDAPLogins(false);
      return;
    }
    if(syncOnlyOnCreateProperties != null && !LDAPHelper.checkIfStaticOlatPropertiesExists(syncOnlyOnCreateProperties)){
      log.error("Invalid LDAP OLAT syncOnlyOnCreateProperties configuration. Disabling LDAP");
      setEnableLDAPLogins(false);
      return;
    }
    if( staticUserProperties != null && !LDAPHelper.checkIfStaticOlatPropertiesExists(staticUserProperties.keySet())){
      log.error("Invalid static OLAT properties configuration (staticUserProperties). Disabling LDAP");
      setEnableLDAPLogins(false);
      return;
    }
   
    // check SSL certifications, throws Startup Exception if certificate is not found
    if(isSslEnabled()){
      if (!LDAPHelper.checkServerCertValidity(0))
        throw new StartupException("LDAP enabled but no valid server certificate found. Please fix!");
      if (!LDAPHelper.checkServerCertValidity(30))
        log.warn("Server Certificate will expire in less than 30 days.");
    }
   
    // Check ldap connection
    if (ldapManager.bindSystem() == null) {
      // don't disable ldap, maybe just a temporary problem, but still report
      // problem in logfile
      log.warn("LDAP connection test failed during module initialization, edit config or contact network administrator");
    }
    // OK, everything finished checkes passed
    log.info("LDAP login is enabled");

    /*
     *
     */
   
    // Sync LDAP Users on Startup
    if (isLdapSyncOnStartup()) {
      initStartSyncJob(ldapManager);
    } else {
      log.info("LDAP start sync is disabled");
    }

    // Start LDAP cron sync job
    if (isLdapSyncCronSync()) {
      initCronSyncJob();
    } else {
      log.info("LDAP cron sync is disabled");
    }
   
    // Add admin console to admin site menu
    ExtManager extManager = ExtManager.getInstance();
    List<LDAPAdminExtension> extensions = extManager.getExtensions();
    extensions.add(new LDAPAdminExtension());
    extManager.setExtensions(extensions);
   
    // OK, everything finished checkes passed
    log.info("LDAP login is enabled");
  }

  /**
   * @see org.olat.core.configuration.OLATModule#destroy()
   */
  public void destroy() {
    // nothing to be destroyed
  }

  /**
   * Internal helper to sync users right away
   * @param ldapManager
   */
  private void initStartSyncJob(LDAPLoginManager ldapManager) {
    LDAPError errors = new LDAPError();
    if (ldapManager.doBatchSync(errors)) {
      log.info("LDAP start sync: users synced");
    } else {
      log.warn("LDAP start sync error: " + errors.get());
    }
  }

  /**
   * Internal helper to initialize the cron syncer job
   */
  private void initCronSyncJob() {
    //FIXME: move this to spring and add a delay otherwise the job may accesses the database and the database it not yet ready, see examples in spring with jobs
    // Use scheduler from spring config
    Scheduler scheduler = (Scheduler) CoreSpringFactory.getBean("schedulerFactoryBean");
    try {
      // Create job with cron trigger configuration
      JobDetail jobDetail = new JobDetail("LDAP_Cron_Syncer_Job", Scheduler.DEFAULT_GROUP, LDAPUserSynchronizerJob.class);
      CronTrigger trigger = new CronTrigger();
      trigger.setName("LDAP_Cron_Syncer_Trigger");
      trigger.setCronExpression(ldapSyncCronSyncExpression);
      // Schedule job now
      scheduler.scheduleJob(jobDetail, trigger);
      log.info("LDAP cron syncer is enabled with expression::" + ldapSyncCronSyncExpression);
    } catch (ParseException e) {
      setLdapSyncCronSync(false);
      log
          .error(
              "LDAP configuration in attribute 'ldapSyncCronSyncExpression' is not valid ("
                  + ldapSyncCronSyncExpression
                  + "). See http://quartz.sourceforge.net/javadoc/org/quartz/CronTrigger.html to learn more about the cron syntax. Disabling LDAP cron syncing",
              e);
    } catch (SchedulerException e) {
      log.error("Error while scheduling LDAP cron sync job. Disabling LDAP cron syncing", e);
    }
  }


  /**
   * Internal helper to check for emtpy config variables
   *
   * @param param
   * @return true: not empty; false: empty or null
   */
  private boolean checkConfigParameterIsNotEmpty(String param) {
    if (StringHelper.containsNonWhitespace(param)) {
      return true;
    } else {
      log.error("Missing configuration '" + param + "'. Add this configuration to olatextconfig.xml first. Disabling LDAP");
      setEnableLDAPLogins(false);
      return false;
    }
  }

  /*
   * Spring setter methods - don't use them to modify values at runtime!
   */
  public void setEnableLDAPLogins(boolean enableLDAPLogins) {
    ldapEnabled = enableLDAPLogins;
  }

  public void setSslEnabled(boolean sslEnabl) {
    sslEnabled = sslEnabl;
  }
 
  public void setActiveDirectory(boolean aDirectory) {
    activeDirectory = aDirectory;
  }
 
  public void setTrustStoreLocation(String trustStoreLocation){
    trustStoreLoc=trustStoreLocation.trim();
  }
  public void setTrustStorePwd(String trustStorePwd){
    trustStorePass=trustStorePwd.trim();
  }
 
  public void setTrustStoreType(String trustStoreType){
    trustStoreTyp= trustStoreType.trim();
  }

  public void setLdapSyncOnStartup(boolean ldapStartSyncs) {
    ldapSyncOnStartup = ldapStartSyncs;
  }

  public void setLdapUserObjectClass(String objectClass) {
    ldapUserObjectClass = objectClass.trim();
  }

  public void setLdapSystemDN(String ldapSystemDN) {
    systemDN = ldapSystemDN.trim();
  }

  public void setLdapSystemPW(String ldapSystemPW) {
    systemPW = ldapSystemPW.trim();
  }

  public void setLdapUrl(String ldapUrlConfig) {
    ldapUrl = ldapUrlConfig.trim();
  }

  public void setLdapBases(List<String> ldapBasesConfig) {
    ldapBases = ldapBasesConfig;
  }

  public void setUserAttributeMapper(Map<String, String> userAttributeMapper) {
    // trim map
    userAttrMap = new HashMap<String, String>();
    for (Entry<String, String>  entry : userAttributeMapper.entrySet()) {
      userAttrMap.put(entry.getKey().trim(), entry.getValue().trim());
    }   
    // optimizes for later usage
    userAttr = userAttrMap.keySet().toArray(new String[userAttrMap.size()]);
  }

  public void setReqAttrs(Map<String, String> reqAttrs) {
    // trim map
    reqAttr = new HashMap<String, String>();
    for (Entry<String, String>  entry : reqAttrs.entrySet()) {
      reqAttr.put(entry.getKey().trim(), entry.getValue().trim());
    }   
  }
 
  public void setSyncOnlyOnCreateProperties(Set<String> syncOnlyOnCreatePropertiesConfig) {
    // trim map
    syncOnlyOnCreateProperties = new HashSet<String>();
    for (String  value : syncOnlyOnCreatePropertiesConfig) {
      syncOnlyOnCreateProperties.add(value.trim());
    }   
  }

  public void setStaticUserProperties(Map<String, String> staticUserPropertiesMap) {
    // trim map
    staticUserProperties = new HashMap<String, String>();
    for (Entry<String, String>  entry : staticUserPropertiesMap.entrySet()) {
      staticUserProperties.put(entry.getKey().trim(), entry.getValue().trim());
    }   
  }

  public void setLdapUserLastModifiedTimestampAttribute(String ldapUserLastModifiedTimestampAttribute) {
    LDAPLoginModule.ldapUserLastModifiedTimestampAttribute = ldapUserLastModifiedTimestampAttribute.trim();
  }

  public void setLdapUserCreatedTimestampAttribute(String ldapUserCreatedTimestampAttribute) {
    LDAPLoginModule.ldapUserCreatedTimestampAttribute = ldapUserCreatedTimestampAttribute.trim();
  }
 
  public void setLdapUserPasswordAttribute(String userPasswordAttribute) {
    LDAPLoginModule.ldapUserPasswordAttribute = userPasswordAttribute;
  }

  public void setLdapSyncCronSync(boolean ldapSyncCronSync) {
    LDAPLoginModule.ldapSyncCronSync = ldapSyncCronSync;
  }

  public void setLdapSyncCronSyncExpression(String ldapSyncCronSyncExpression) {
    LDAPLoginModule.ldapSyncCronSyncExpression = ldapSyncCronSyncExpression.trim();
  }
 
  public void setCacheLDAPPwdAsOLATPwdOnLogin(boolean cacheLDAPPwdAsOLATPwdOnLogin) {
    LDAPLoginModule.cacheLDAPPwdAsOLATPwdOnLogin = cacheLDAPPwdAsOLATPwdOnLogin;
  }
 
  public void setConvertExistingLocalUsersToLDAPUsers(boolean convertExistingLocalUsersToLDAPUsers) {
    LDAPLoginModule.convertExistingLocalUsersToLDAPUsers = convertExistingLocalUsersToLDAPUsers;
  }

  public void setDeleteRemovedLDAPUsersOnSync(boolean deleteRemovedLDAPUsersOnSync) {
    LDAPLoginModule.deleteRemovedLDAPUsersOnSync = deleteRemovedLDAPUsersOnSync;
  }
 
  public void setDeleteRemovedLDAPUsersPercentage(int deleteRemovedLDAPUsersPercentage){
    LDAPLoginModule.deleteRemovedLDAPUsersPercentage = deleteRemovedLDAPUsersPercentage;
  }

  public void setPropagatePasswordChangedOnLdapServer(boolean propagatePasswordChangedOnServer) {
    LDAPLoginModule.propagatePasswordChangedOnLdapServer = propagatePasswordChangedOnServer;
  }

  /*
   * Getters
   */
  public static String getLdapSystemDN() {
    return systemDN;
  }

  public static String getLdapSystemPW() {
    return systemPW;
  }

  public static String getLdapUrl() {
    return ldapUrl;
  }

  public static List<String> getLdapBases() {
    return ldapBases;
  }

  public static String getLdapUserObjectClass() {
    return ldapUserObjectClass;
  }

  public static String getLdapUserLastModifiedTimestampAttribute() {
    return ldapUserLastModifiedTimestampAttribute;
  }

  public static String getLdapUserCreatedTimestampAttribute() {
    return ldapUserCreatedTimestampAttribute;
  }
 
  public static String getLdapUserPasswordAttribute() {
    return ldapUserPasswordAttribute;
  }

  /**
   * @return a map of user properties to set for each LDAP user or NULL if no
   *         such properties have to be set
   */
  public static Map<String, String> getStaticUserProperties() {
    return staticUserProperties;
  }

  public static Map<String, String> getUserAttributeMapper() {
    return userAttrMap;
  }

  public static String[] getUserAttrs() {
    return userAttr;
  }

  public static Map<String, String> getReqAttrs() {
    return reqAttr;
  }

  public static Set<String> getSyncOnlyOnCreateProperties() {
    return syncOnlyOnCreateProperties;
  }

  public static boolean isLDAPEnabled() {
    return ldapEnabled;
  }

  public static boolean isSslEnabled() {
    return sslEnabled;
  }
 
  public static boolean isActiveDirectory() {
    return activeDirectory;
  }
 
  public static String getTrustStoreLocation(){
    return trustStoreLoc;
  }
 
  public static String getTrustStorePwd(){
    return trustStorePass;
  }
 
  public static String getTrustStoreType(){
    return trustStoreTyp;
  }

  public static boolean isLdapSyncOnStartup() {
    return ldapSyncOnStartup;
  }

  public static boolean isLdapSyncCronSync() {
    return ldapSyncCronSync;
  }

  public static String getLdapSyncCronSyncExpression() {
    return ldapSyncCronSyncExpression;
  }

  public static boolean isCacheLDAPPwdAsOLATPwdOnLogin() {
    return cacheLDAPPwdAsOLATPwdOnLogin;
  }

  public static boolean isConvertExistingLocalUsersToLDAPUsers() {
    return convertExistingLocalUsersToLDAPUsers;
  }

  public static boolean isDeleteRemovedLDAPUsersOnSync() {
    return deleteRemovedLDAPUsersOnSync;
  }
 
  public static int getDeleteRemovedLDAPUsersPercentage(){
    return deleteRemovedLDAPUsersPercentage;
  }

  public static boolean isPropagatePasswordChangedOnLdapServer(){
    return propagatePasswordChangedOnLdapServer;
  }
}
TOP

Related Classes of org.olat.ldap.LDAPLoginModule

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.