Package org.olat.login

Source Code of org.olat.login.LoginModule

/**
* OLAT - Online Learning and Training<br>
* http://www.olat.org
* <p>
* Licensed under the Apache License, Version 2.0 (the "License"); <br>
* you may not use this file except in compliance with the License.<br>
* You may obtain a copy of the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing,<br>
* software distributed under the License is distributed on an "AS IS" BASIS, <br>
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br>
* See the License for the specific language governing permissions and <br>
* limitations under the License.
* <p>
* Copyright (c) since 2004 at Multimedia- & E-Learning Services (MELS),<br>
* University of Zurich, Switzerland.
* <p>
*/

package org.olat.login;

import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;

import org.olat.admin.sysinfo.InfoMessageManager;
import org.olat.core.commons.fullWebApp.util.GlobalStickyMessage;
import org.olat.core.configuration.OLATModule;
import org.olat.core.logging.StartupException;
import org.olat.core.logging.Tracing;
import org.olat.core.util.cache.n.CacheWrapper;
import org.olat.core.util.coordinate.CoordinatorManager;
import org.olat.login.auth.AuthenticationProvider;
import org.olat.properties.Property;
import org.olat.properties.PropertyManager;

import com.anthonyeden.lib.config.Configuration;

/**
* Initial Date:  04.08.2004
*
* @author Mike Stock
*/
public class LoginModule implements OLATModule {

  private static final String CONF_AUTHPROVIDER = "AuthProvider";
  private static final String CONF_ATTACK = "AttackPrevention";
  private static final String CONF_ATTACK_ENABLED = "enabled";
  private static final String CONF_ATTACK_MAXATTEMPTS = "maxattempts";
  private static final String CONF_ATTACK_TIMEOUTMIN = "timeoutmin";
  private static final String CONF_GUESTLINKS = "GuestLoginLinks";
  private static final String CONF_GUESTLINKS_ENABLED = "enabled";
  private static final String ALLOW_LOGIN_USING_EMAIL = "allowLoginUsingEmail";

  private static HashMap authenticationProviders;
  private static boolean attackPreventionEnabled = false;
  private static int attackPreventionMaxAttempts;
  private static int attackPreventionTimeout;
  private static boolean guestLoginLinksEnabled = true;
  private static CacheWrapper failedLoginCache;
  private static String defaultProviderName;
  private static boolean allowLoginUsingEmail = true;
 
  /**
   * @see org.olat.core.configuration.OLATModule#init(com.anthonyeden.lib.config.Configuration)
   */
  public void init(Configuration moduleConfig) {
    // fetch authentication providers
    List authProviders = moduleConfig.getChildren(CONF_AUTHPROVIDER);
    Iterator iter = authProviders.iterator();
    authenticationProviders = new HashMap(authProviders.size());
    while (iter.hasNext()) {
      Configuration authProviderConfig = (Configuration)iter.next();
      AuthenticationProvider authProvider = new AuthenticationProvider(authProviderConfig);
      if (!authProvider.isEnabled()) continue;
      authenticationProviders.put(authProvider.getName(), authProvider);
      Tracing.logInfo("Added authentication Provider: name='"
        + authProvider.getName() + "' enabled='" + (authProvider.isEnabled() ? "yes" : "no") + "'.", LoginModule.class);
    }
    Configuration defProviderConf = moduleConfig.getChild("DefaultAuthProvider");
    if (defProviderConf == null)
      throw new StartupException("No DefaultAuthProvider defined. Please fix.");
    defaultProviderName = defProviderConf.getAttribute("name");
    if (defaultProviderName == null)
      throw new StartupException("No DefaultAuthProvider defined. Please fix.");
   
    AuthenticationProvider defaultProvider = getAuthenticationProvider(defaultProviderName);
    if (defaultProvider == null || !defaultProvider.isEnabled())
      throw new StartupException("Defined DefaultAuthProvider::" + defaultProviderName + " not existent or not enabled. Please fix.");
    Tracing.logInfo("Using default authentication provider '" + defaultProviderName + "'.", LoginModule.class);
   
    // check attack prevention
    Configuration attack_conf = moduleConfig.getChild(CONF_ATTACK);
    if (attack_conf != null) {
      String attack_enabled = attack_conf.getAttribute(CONF_ATTACK_ENABLED);
      if (attack_enabled != null &&
          (attack_enabled.toLowerCase().equals("true") || attack_enabled.toLowerCase().equals("yes"))) {
        attackPreventionEnabled = true;
        String attack_maxattempts = attack_conf.getAttribute(CONF_ATTACK_MAXATTEMPTS);
        String attack_timeoutmin = attack_conf.getAttribute(CONF_ATTACK_TIMEOUTMIN);
        try {
          attackPreventionMaxAttempts = Integer.parseInt(attack_maxattempts);
          attackPreventionTimeout = Integer.parseInt(attack_timeoutmin);
        } catch (NumberFormatException nfe) {
          throw new StartupException("Attribute 'attempts' and/or 'timeoutmin' of config Parameter AttackPrevention are either missing or not a number. Please fix!");
        }
        // configure timed cache default params: refresh 1 minute, timeout according to configuration
        failedLoginCache = CoordinatorManager.getCoordinator().getCacher().getOrCreateCache(this.getClass(), "blockafterfailedattempts");
       
        Tracing.logInfo("Attack prevention enabled. Max number of attempts: " + attack_maxattempts + ", timeout: " + attack_timeoutmin + " minutes.", LoginModule.class);
      } else {
        attackPreventionEnabled = false;
        Tracing.logInfo("Attack prevention is disabled.", LoginModule.class);
      }
    }
   
    Configuration guestLinkConf = moduleConfig.getChild(CONF_GUESTLINKS);
    if (guestLinkConf != null) {
      String enabled = guestLinkConf.getAttribute(CONF_GUESTLINKS_ENABLED);
      if (enabled != null &&   (enabled.toLowerCase().equals("true") || enabled.toLowerCase().equals("yes"))) {
        guestLoginLinksEnabled = true;
        Tracing.logInfo("Guest login links on login page enabled", LoginModule.class);
      } else {
        guestLoginLinksEnabled = false;
        Tracing.logInfo("Guest login links on login page disabled or not properly configured. Check your olat_config.xml for element " + CONF_GUESTLINKS, LoginModule.class);
      }
    }

    /*
     * ensure that the infomessage property exists on the system
     */
    PropertyManager pm = PropertyManager.getInstance();
    Property p = pm.findProperty(null, null, null, "_o3_", "InfoMsg");
    if (p == null) {
      p =  pm.createPropertyInstance(null,  null,  null,  "_o3_", "InfoMsg", null, null, null, InfoMessageManager.EMPTY_MESSAGE);
      pm.saveProperty(p);
    }
    /*
     * ensure that the GlobalStickyMessage is initialized and registered to listen
     * -> OLAT-4168
     */
    GlobalStickyMessage.getInstance();
 
    /*
     * OLAT-4339 Allow login using email address. Configurable.
     */
    String configLoginByEmail = moduleConfig.getChildValue(ALLOW_LOGIN_USING_EMAIL);
    allowLoginUsingEmail = configLoginByEmail.equalsIgnoreCase("true");
  }

  /**
   * @see org.olat.core.configuration.OLATModule#destroy()
   */
  public void destroy() {
    //any caches are destroyed by the coordinator, we do not need to take care here.
  }

  /**
   * @return The configured default login provider.
   */
  public static String getDefaultProviderName() {
    return defaultProviderName;
  }
 
  /**
   * @param provider
   * @return AuthenticationProvider implementation.
   */
  public static AuthenticationProvider getAuthenticationProvider(String provider) {
    return (AuthenticationProvider)authenticationProviders.get(provider);
  }
 
  /**
   * @return Collection of available AuthenticationProviders
   */
  public static Collection getAuthenticationProviders() {
    return authenticationProviders.values();
  }
 
  /**
   * Must be called upon each login attempt. Returns true
   * if number of login attempts has reached the set limit.
   * @param login
   * @return True if further logins will be prevented (i.e. max attempts reached).
   */
  public static final boolean registerFailedLoginAttempt(String login) {
    if (!attackPreventionEnabled) return false;
    Integer numAttempts = (Integer)failedLoginCache.get(login);
   
    if (numAttempts == null) { // create new entry
      numAttempts = new Integer(1);
    } else { // update entry
      numAttempts = new Integer(numAttempts.intValue() + 1);
    }
    // do not use putSilent(...) here, since failed login attempts should propagate to all cluster nodes
    // o_clusterREVIEW todo: this is fine, however loading the data (numAttempts == null) ... should be via db e.g properties table,
    // otherwise it cannot be clustersafe
    failedLoginCache.update(login, numAttempts);
   
    return (numAttempts.intValue() > attackPreventionMaxAttempts);
  }
 
  /**
   * Clear all failed login attempts for a given login.
   * @param login
   */
  public static final void clearFailedLoginAttempts(String login) {
    if (!attackPreventionEnabled) return;
    //EHCacheManager.getInstance().removeFromCache(failedLoginCache, login);
    failedLoginCache.remove(login);
  }
 
  /**
   * Tells wether a login is blocked to prevent brute force attacks or not.
   * @param login
   * @return True if login is blocked by attack prevention mechanism
   */
  public static final boolean isLoginBlocked(String login) {
    if (!attackPreventionEnabled) return false;
    //Integer numAttempts = (Integer)EHCacheManager.getInstance().get(failedLoginCache, login);
    Integer numAttempts = (Integer)failedLoginCache.get(login);
   
    if (numAttempts == null) return false;
    else return (numAttempts.intValue() > attackPreventionMaxAttempts);
  }
 
  /**
   * @return True if guest login kinks must be shown on login screen, false
   *         otherwhise
   */
  public static final boolean isGuestLoginLinksEnabled() {
    return guestLoginLinksEnabled;
  }
 
  /**
   * @return Number of minutes a login gets blocked after too many attempts.
   */
  public static Integer getAttackPreventionTimeoutMin() {
    return new Integer(attackPreventionTimeout);
  }
 
  /**
   * @return True if login with email is allowed (set in olat_config.xml)
   */
  public static boolean allowLoginUsingEmail() {
    return allowLoginUsingEmail;
  }
}
TOP

Related Classes of org.olat.login.LoginModule

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.