Package org.olat.basesecurity

Source Code of org.olat.basesecurity.AuthHelper

/**
* 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.basesecurity;

import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.Set;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpSession;

import org.olat.commons.rss.RSSUtil;
import org.olat.core.commons.chiefcontrollers.BaseChiefControllerCreator;
import org.olat.core.commons.fullWebApp.BaseFullWebappController;
import org.olat.core.commons.fullWebApp.BaseFullWebappControllerParts;
import org.olat.core.dispatcher.DispatcherAction;
import org.olat.core.gui.GUIInterna;
import org.olat.core.gui.UserRequest;
import org.olat.core.gui.WindowManager;
import org.olat.core.gui.Windows;
import org.olat.core.gui.components.Window;
import org.olat.core.gui.control.ChiefController;
import org.olat.core.gui.control.Controller;
import org.olat.core.gui.control.WindowControl;
import org.olat.core.gui.control.creator.ControllerCreator;
import org.olat.core.gui.media.RedirectMediaResource;
import org.olat.core.gui.render.StringOutput;
import org.olat.core.gui.render.URLBuilder;
import org.olat.core.id.Identity;
import org.olat.core.id.Roles;
import org.olat.core.id.User;
import org.olat.core.id.UserConstants;
import org.olat.core.logging.AssertException;
import org.olat.core.logging.OLog;
import org.olat.core.logging.Tracing;
import org.olat.core.logging.activity.OlatLoggingAction;
import org.olat.core.logging.activity.ThreadLocalUserActivityLogger;
import org.olat.core.util.Encoder;
import org.olat.core.util.SessionInfo;
import org.olat.core.util.UserSession;
import org.olat.core.util.WebappHelper;
import org.olat.core.util.i18n.I18nManager;
import org.olat.core.util.i18n.I18nModule;
import org.olat.core.util.prefs.Preferences;
import org.olat.login.AuthBFWCParts;
import org.olat.login.GuestBFWCParts;
import org.olat.login.OLATAuthenticationController;
import org.olat.util.logging.activity.LoggingResourceable;

/**
* Description: <br>
*
* @author Felix Jost
*/
public class AuthHelper {
  /**
   * <code>LOGOUT_PAGE</code>
   */
  public static final String LOGOUT_PAGE = "logout.html";
  public  static final int LOGIN_OK = 0;
  private static final int LOGIN_FAILED = 1;
  private static final int LOGIN_DENIED = 2;
  public  static final int LOGIN_NOTAVAILABLE = 3;

  private static final int MAX_SESSION_NO_LIMIT = 0;

  private static boolean loginBlocked = false;
 
  /** whether or not requests to dmz (except those coming via 'switch-to-node' cluster feature) are
   * rejected hence resulting the browser to go to another node.
   * Note: this is not configurable currently as it's more of a runtime choice to change this to true
   */
  private static boolean rejectDMZRequests = false;
  private static int maxSessions = MAX_SESSION_NO_LIMIT;
 
  private static OLog log = Tracing.createLoggerFor(AuthHelper.class);

  /**
   * Used by DMZDispatcher to do regular logins and by ShibbolethDispatcher
   * which is somewhat special because logins are handled asynchronuous ->
   * therefore a dedicated dispatcher is needed which also has to have access to
   * the doLogin() method.
   *
   * @param identity
   * @param authProvider
   * @param ureq
   * @return True if success, false otherwise.
   */
  public static int doLogin(Identity identity, String authProvider, UserRequest ureq) {
    int initializeStatus = initializeLogin(identity, authProvider, ureq);
    if (initializeStatus != LOGIN_OK) {
      return initializeStatus; // login not successfull
    }
   
    // do logging
    ThreadLocalUserActivityLogger.log(OlatLoggingAction.OLAT_LOGIN, AuthHelper.class, LoggingResourceable.wrap(identity));
   
    // brasato:: fix it
    // successfull login, reregister window
    ChiefController occ;
    if(ureq.getUserSession().getRoles().isGuestOnly()){
      occ = createGuestHome(ureq);
    }else{
      occ = createAuthHome(ureq);
    }
 
    Window currentWindow = occ.getWindow();
    currentWindow.setUriPrefix(WebappHelper.getServletContextPath() + DispatcherAction.PATH_AUTHENTICATED);
    Windows.getWindows(ureq).registerWindow(currentWindow);
 
    // redirect to AuthenticatedDispatcher
    // IMPORTANT: windowID has changed due to re-registering current window -> do not use ureq.getWindowID() to build new URLBuilder.
    URLBuilder ubu = new URLBuilder(WebappHelper.getServletContextPath() + DispatcherAction.PATH_AUTHENTICATED, currentWindow.getInstanceId(), "1", null)
    StringOutput sout = new StringOutput(30);
    ubu.buildURI(sout, null, null);
    ureq.getDispatchResult().setResultingMediaResource(new RedirectMediaResource(sout.toString()));
   
    return LOGIN_OK;
  }

  private static ChiefController createGuestHome(UserRequest ureq) {
    if (!ureq.getUserSession().isAuthenticated()) throw new AssertException("not authenticated!");

    BaseChiefControllerCreator bbc = new BaseChiefControllerCreator();
    bbc.setContentControllerCreator(/*this is later injected by spring*/new ControllerCreator() {
      public Controller createController(UserRequest lureq, WindowControl lwControl) {
        BaseFullWebappControllerParts guestSitesAndNav = new GuestBFWCParts();
        return new BaseFullWebappController(lureq, lwControl, guestSitesAndNav );
      }
    });

    ChiefController cc = bbc.createChiefController(ureq);
    Windows.getWindows(ureq.getUserSession()).setAttribute("AUTHCHIEFCONTROLLER", cc);
    Tracing.logDebug("set session-attribute 'AUTHCHIEFCONTROLLER'", AuthHelper.class);
    return cc;
  }

  /**
   * @param ureq
   * @return chiefcontroller
   */
  private static ChiefController createAuthHome(UserRequest ureq) {
    if (!ureq.getUserSession().isAuthenticated()) throw new AssertException("not authenticated!");

    BaseChiefControllerCreator bbc = new BaseChiefControllerCreator();
    bbc.setContentControllerCreator(/*this is later injected by spring*/new ControllerCreator() {
      public Controller createController(UserRequest lureq, WindowControl lwControl) {
        BaseFullWebappControllerParts authSitesAndNav = new AuthBFWCParts();
        return new BaseFullWebappController(lureq, lwControl, authSitesAndNav );
      }
    });

    ChiefController cc = bbc.createChiefController(ureq);
    Windows.getWindows(ureq.getUserSession()).setAttribute("AUTHCHIEFCONTROLLER", cc);
    Tracing.logDebug("set session-attribute 'AUTHCHIEFCONTROLLER'", AuthHelper.class);
    return cc;
  }

  /**
   * Logs in as anonymous user using the given language key. If the current
   * installation does not support this language, the systems default language
   * is used instead
   *
   * @param ureq The user request
   * @param lang The language of the anonymous user or null if system default should be used
   * @return true if login was successful, false otherwise
   */
  public static int doAnonymousLogin(UserRequest ureq, Locale locale) {
    Set<String> supportedLanguages = I18nModule.getEnabledLanguageKeys();
    if ( locale == null || ! supportedLanguages.contains(locale.toString()) ) {
      locale = I18nModule.getDefaultLocale();
    }
    Identity guestIdent = ManagerFactory.getManager().getAndUpdateAnonymousUserForLanguage(locale);
    int loginStatus = doLogin(guestIdent, OLATAuthenticationController.PROVIDER_OLAT, ureq);
    return loginStatus;
  }

  /**
   * ONLY for authentication provider OLAT Authenticate Identity and do the
   * necessary work. Returns true if successfull, false otherwise.
   *
   * @param identity
   * @param authProvider
   * @param ureq
   * @return boolean
   */
  private static int initializeLogin(Identity identity, String authProvider, UserRequest ureq) {
    // continue only if user has login permission.
    if (identity == null) return LOGIN_FAILED;
    //test if a user may not logon, since he/she is in the PERMISSION_LOGON
    if (!ManagerFactory.getManager().isIdentityVisible(identity.getName())) {
      Tracing.logAudit("was denied login", AuthHelper.class);
      return LOGIN_DENIED;     
    }
    // if the user sending the cookie did not log out and we are logging in
    // again, then we need to make sure everything is cleaned up. we cleanup in all cases.
    UserSession usess = ureq.getUserSession();
    // prepare for a new user: clear all the instance vars of the userSession
    // note: does not invalidate the session, since it is reused
    usess.signOffAndClear();
    // init the UserSession for the new User
    // we can set the identity and finish the log in process
    usess.setIdentity(identity);
    setRolesFor(identity, usess);
   
    // check if loginDenied or maxSession (only for non-admin)
    if ( (loginBlocked && !usess.getRoles().isOLATAdmin())
        || ( ((maxSessions != MAX_SESSION_NO_LIMIT) && (UserSession.getUserSessionsCnt() >= maxSessions)) && !usess.getRoles().isOLATAdmin() ) ) {
      Tracing.logAudit("Login was blocked for username=" + usess.getIdentity().getName() + ", loginBlocked=" + loginBlocked + " NbrOfSessions=" + UserSession.getUserSessionsCnt() , AuthHelper.class);
      usess.signOffAndClear();
      return LOGIN_NOTAVAILABLE;
    }
   
    // set authprovider
    //usess.getIdentityEnvironment().setAuthProvider(authProvider);
   
    //set the language
    usess.setLocale( I18nManager.getInstance().getLocaleOrDefault(identity.getUser().getPreferences().getLanguage()) );
    // update fontsize in users session globalsettings
    Windows.getWindows(ureq).getWindowManager().setFontSize(Integer.parseInt(identity.getUser().getPreferences().getFontsize() ));   
    // put users personal rss token into session
    RSSUtil.putPersonalRssTokenInSession(ureq);
    // calculate session info and attach it to the user session
    setSessionInfoFor(identity, authProvider, ureq);
    //confirm signedOn
    usess.signOn();
    // set users web delivery mode
    setAjaxModeFor(ureq);
    // update web delivery mode in session info
    ureq.getUserSession().getSessionInfo().setWebModeFromUreq(ureq);
    return LOGIN_OK;
  }

  /**
   * Persists the given user and creates an identity for it
   *
   * @param loginName
   * @param pwd null: no OLAT authentication is generated. If not null, the password will be
   * encrypted and and an OLAT authentication is generated.
   * @param newUser unpersisted user
   * @return Identity
   */
  public static Identity createAndPersistIdentityAndUser(String loginName, String pwd, User newUser) {
    Identity ident = null;
    if (pwd == null) {
      // when no password is used the provider must be set to null to not generate
      // an OLAT authentication token. See method doku.
      ident = ManagerFactory.getManager().createAndPersistIdentityAndUser(loginName, newUser, null, null, null);
     } else {
      ident = ManagerFactory.getManager().createAndPersistIdentityAndUser(loginName, newUser,
      OLATAuthenticationController.PROVIDER_OLAT, loginName, Encoder.encrypt(pwd));
    }
    // TODO: Tracing message
    return ident;
  }

  /**
   * Persists the given user, creates an identity for it and adds the user to
   * the users system group
   *
   * @param loginName
   * @param pwd null: no OLAT authentication is generated. If not null, the password will be
   * encrypted and and an OLAT authentication is generated.
   * @param newUser unpersisted users
   * @return Identity
   */
  public static Identity createAndPersistIdentityAndUserWithUserGroup(String loginName, String pwd, User newUser) {
    Identity ident = createAndPersistIdentityAndUser(loginName, pwd, newUser);
    // Add user to system users group
    Manager securityManager = ManagerFactory.getManager();
    SecurityGroup olatuserGroup = securityManager.findSecurityGroupByName(Constants.GROUP_OLATUSERS);
    securityManager.addIdentityToSecurityGroup(ident, olatuserGroup);
    return ident;
  }

  /**
   * This is a convenience method to log out. IMPORTANT: This method initiates a
   * redirect and RETURN. Make sure you return the call hierarchy gracefully.
   * Most of all, don't touch HttpServletRequest or the Session after you call
   * this method.
   *
   * @param ureq
   */
  public static void doLogout(UserRequest ureq) {
    //clear session settings of replayable urls / load performance mode
    GUIInterna.setLoadPerformanceMode(null);
    String lang = I18nManager.getInstance().getLocaleKey(ureq.getLocale());
    HttpSession session = ureq.getHttpReq().getSession(false);
    //session.removeAttribute(SessionListener.SESSIONLISTENER_KEY);
    //TODO: i assume tomcat, after s.invalidate(), lets the GC do the work
    // if not, then do a s.removeAttribute....
    // next line fires a valueunbound event to UserSession, which does some
    // stuff on logout
    if (session != null) {
      try{
        session.invalidate();
        deleteShibsessionCookie(ureq);
      } catch(IllegalStateException ise) {
        // thrown when session already invalidated. fine. ignore.
      }
    }
   
    // redirect to logout page in dmz realm
    ureq.getDispatchResult().setResultingMediaResource(
      new RedirectMediaResource(WebappHelper.getServletContextPath() + "/?lang=" + lang));
  }

  private static void deleteShibsessionCookie(UserRequest ureq) {
    //  try to delete the "shibsession" cookie for this ureq, if any found
    Cookie[] cookies = ureq.getHttpReq().getCookies();
    Cookie cookie = null;
    if (cookies != null) {
      for (int i = 0; i < cookies.length; i++) {           
        /*if(log.isDebug()) {
          log.info("found cookie with name: " + cookies[i].getName() + " and value: " + cookies[i].getValue());
        }*/
        if (cookies[i].getName().indexOf("shibsession")!=-1) { //contains "shibsession"
          cookie = cookies[i];
          break;
        }
      }
    }
    if(cookie!=null) {
      //A zero value causes the cookie to be deleted.
      cookie.setMaxAge(0);
      //cookie.setMaxAge(-1); //TODO: LD: check this out as well
      cookie.setPath("/");
      ureq.getHttpResp().addCookie(cookie);         
      if(log.isDebug()) {
        log.info("AuthHelper - shibsession cookie deleted");
      }         
    }
  }

  /**
   * Set AJAX / Web 2.0 based on User GUI-Preferences and configuration.
   * If the "ajax feature" checkbox in the user settings is enabled, turn on ajax (do not care about which browser)
   * @param ureq
   */
  private static void setAjaxModeFor(UserRequest ureq) {
    Preferences prefs = ureq.getUserSession().getGuiPreferences();
    Boolean ajaxOn = (Boolean) ureq.getUserSession().getGuiPreferences().get(WindowManager.class, "ajax-beta-on");
    Boolean web2aEnabled = (Boolean) prefs.get(WindowManager.class, "web2a-beta-on");
    // first check for web2a mode, then for ajax mode
    if (web2aEnabled != null && web2aEnabled.booleanValue()) {
      Windows.getWindows(ureq).getWindowManager().setForScreenReader(true);     
    } else {
      //if user does not have an gui preference it will be only enabled if globally on and browser is capable
      if (ajaxOn != null) {
        Windows.getWindows(ureq).getWindowManager().setAjaxEnabled(ajaxOn.booleanValue());
      } else {     
        // enable ajax if olat configured and browser matching
        Windows.getWindows(ureq).getWindowManager().setAjaxWanted(ureq, true);
      }
    }   
  }

  /**
   * Build session info
   * @param identity
   * @param authProvider
   * @param ureq
   */
  public static void setSessionInfoFor(Identity identity, String authProvider, UserRequest ureq) {
    HttpSession session = ureq.getHttpReq().getSession();
    SessionInfo sinfo = new SessionInfo(identity.getName(), session);
    sinfo.setFirstname(identity.getUser().getProperty(UserConstants.FIRSTNAME, ureq.getLocale()));
    sinfo.setLastname(identity.getUser().getProperty(UserConstants.LASTNAME, ureq.getLocale()));
    sinfo.setFromIP(ureq.getHttpReq().getRemoteAddr());
    sinfo.setFromFQN(ureq.getHttpReq().getRemoteAddr());
    try {
      InetAddress[] iaddr = InetAddress.getAllByName(ureq.getHttpReq().getRemoteAddr());
      if (iaddr.length > 0) sinfo.setFromFQN(iaddr[0].getHostName());
    } catch (UnknownHostException e) {
      //       ok, already set IP as FQDN
    }
    sinfo.setAuthProvider(authProvider);
    sinfo.setUserAgent(ureq.getHttpReq().getHeader("User-Agent"));
    sinfo.setSecure(ureq.getHttpReq().isSecure());
    sinfo.setLastClickTime();
    // set session info for this session
    UserSession usess = ureq.getUserSession();
    usess.setSessionInfo(sinfo);
    // For Usertracking, let the User object know about some desired/specified infos from the sessioninfo
    Map<String,String> sessionInfoForUsertracking = new HashMap<String, String>();
    sessionInfoForUsertracking.put("language", usess.getLocale().toString());
    sessionInfoForUsertracking.put("authprovider", authProvider);
    sessionInfoForUsertracking.put("iswebdav", String.valueOf(sinfo.isWebDAV()));
    usess.getIdentityEnvironment().setAttributes(sessionInfoForUsertracking);
   
  }

  /**
   * Set the roles (admin, author, guest)
   * @param identity
   * @param usess
   */
  private static void setRolesFor(Identity identity, UserSession usess) {
    Roles roles = ManagerFactory.getManager().getRoles(identity);
    usess.setRoles(roles);
  }
 
  public static void setLoginBlocked(boolean newLoginBlocked) {
    loginBlocked = newLoginBlocked;
  }
 
  public static boolean isLoginBlocked() {
    return loginBlocked;
  }
 
  public static void setRejectDMZRequests(boolean newRejectDMZRequests) {
    rejectDMZRequests = newRejectDMZRequests;
  }
 
  public static boolean isRejectDMZRequests() {
    return rejectDMZRequests;
  }
 
  public static void setMaxSessions(int maxSession) {
    maxSessions  = maxSession;
  }

  public static int getMaxSessions() {
    return maxSessions;
  }
 
}
TOP

Related Classes of org.olat.basesecurity.AuthHelper

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.