Package org.olat.shibboleth

Source Code of org.olat.shibboleth.ShibbolethRegistrationController

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

import java.util.HashMap;
import java.util.Locale;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.olat.basesecurity.AuthHelper;
import org.olat.basesecurity.Authentication;
import org.olat.basesecurity.Constants;
import org.olat.basesecurity.Manager;
import org.olat.basesecurity.ManagerFactory;
import org.olat.basesecurity.SecurityGroup;
import org.olat.core.commons.chiefcontrollers.LanguageChangedEvent;
import org.olat.core.commons.fullWebApp.LayoutMain3ColsController;
import org.olat.core.dispatcher.DispatcherAction;
import org.olat.core.gui.UserRequest;
import org.olat.core.gui.components.Component;
import org.olat.core.gui.components.form.Form;
import org.olat.core.gui.components.velocity.VelocityContainer;
import org.olat.core.gui.control.ChiefController;
import org.olat.core.gui.control.Controller;
import org.olat.core.gui.control.ControllerEventListener;
import org.olat.core.gui.control.DefaultController;
import org.olat.core.gui.control.Event;
import org.olat.core.gui.control.LocaleChangedEvent;
import org.olat.core.gui.control.WindowControl;
import org.olat.core.gui.translator.PackageTranslator;
import org.olat.core.gui.translator.Translator;
import org.olat.core.id.Identity;
import org.olat.core.id.User;
import org.olat.core.id.UserConstants;
import org.olat.core.logging.AssertException;
import org.olat.core.util.UserSession;
import org.olat.core.util.Util;
import org.olat.core.util.WebappHelper;
import org.olat.dispatcher.LocaleNegotiator;
import org.olat.login.OLATAuthenticationController;
import org.olat.registration.DisclaimerController;
import org.olat.registration.LanguageChooserController;
import org.olat.registration.RegistrationManager;
import org.olat.shibboleth.util.OLATUserfieldsMapper;
import org.olat.user.UserManager;

/**
* Initial Date:  09.08.2004
*
* @author Mike Stock
*
* Comment:
* User wants ShibbolethAuthentication
* - Basic flow:
* System asks User for username and create olataccount with ShibbolethAuthentication
* Branches:
* 1. no email in shibbolethAttributesMap
*     - System asks for emailaddress (no institutionalEmail is set !!!)
* 2. no email in shibbolethAttributesMap and User already exists in System
*     - System asks for password (no institutionalEmail is set !!!)
*    
*/

public class ShibbolethRegistrationController extends DefaultController implements ControllerEventListener {

  private static final String PACKAGE = Util.getPackageName(ShibbolethModule.class);
  private static final String VELOCITY_ROOT = Util.getPackageVelocityRoot(PACKAGE);
  private static final String KEY_SHIBATTRIBUTES = "shibattr";
  private static final String KEY_SHIBUNIQUEID = "shibuid";
 
  private VelocityContainer mainContainer;
  private ShibbolethRegistrationForm regForm;
  private ShibbolethMigrationForm migrationForm;
  private ShibbolethRegistrationWithEmailForm regWithEmailForm;
  private DisclaimerController dclController;
  private LanguageChooserController languageChooserController;
 
  private Translator translator;
  private Map<String,String> shibbolethAttributesMap;
  private String shibbolethUniqueID;
 
  private int state;
  private static final int STATE_UNDEFINED = 0;
  private static final int STATE_NEW_SHIB_USER = 1;
  private static final int STATE_MIGRATED_SHIB_USER = 2;
  private OLATUserfieldsMapper userMapping;
 
  private boolean hasEmailInShibAttr;
 
  /**
   * Implements the shibboleth registration workflow.
   * @param ureq
   * @param wControl
   */
  public ShibbolethRegistrationController(UserRequest ureq, WindowControl wControl) {
    super(wControl);

    translator = new PackageTranslator(PACKAGE, ureq.getLocale());
    shibbolethAttributesMap = (Map<String,String>)ureq.getUserSession().getEntry(KEY_SHIBATTRIBUTES);
    shibbolethUniqueID = (String)ureq.getUserSession().getEntry(KEY_SHIBUNIQUEID);
   
    if (shibbolethUniqueID == null) {     
      ChiefController msgcc = MessageWindowController.createMessageChiefController(ureq,
          new AssertException("ShibbolethRegistrationController was unable to fetch ShibbolethUniqueID from session."), translator.translate("error.shibboleth.generic"), null);
      msgcc.getWindow().dispatchRequest(ureq, true);
      return;
    }

    if (shibbolethAttributesMap == null)
      throw new AssertException("ShibbolethRegistrationController was unable to fetch ShibbolethAttribuitesMap from session.");

    userMapping = new OLATUserfieldsMapper(shibbolethAttributesMap);
    hasEmailInShibAttr = (userMapping.getEMail() == null) ? false : true;
   
    Locale locale = (Locale)ureq.getUserSession().getEntry(LocaleNegotiator.NEGOTIATED_LOCALE);
    if(locale == null) {
      String preferedLanguage = userMapping.getPreferedLanguage();
      if(preferedLanguage == null) {
        locale = LocaleNegotiator.getPreferedLocale(ureq);
      } else {
        locale = LocaleNegotiator.getNegotiatedLocale(preferedLanguage);
        if(locale == null) {
          locale = LocaleNegotiator.getPreferedLocale(ureq);
        }
      }
    }
    ureq.getUserSession().setLocale(locale);
    ureq.getUserSession().putEntry(LocaleNegotiator.NEGOTIATED_LOCALE, locale);
   
    translator = new PackageTranslator(PACKAGE, ureq.getLocale());
    mainContainer = new VelocityContainer("main", VELOCITY_ROOT + "/langchooser.html", translator, this);
 
    languageChooserController = new LanguageChooserController(ureq, wControl, false);
    languageChooserController.addControllerListener(this);
    mainContainer.put("select.language", languageChooserController.getInitialComponent());
    mainContainer.contextPut("languageCode", locale.getLanguage());

    regForm = new ShibbolethRegistrationForm("regForm", translator);
   
    regForm.addListener(this);
    mainContainer.put("regForm", regForm);

    dclController = new DisclaimerController(ureq, getWindowControl());
    dclController.addControllerListener(this);
    mainContainer.put("dclComp", dclController.getInitialComponent());

    state = STATE_UNDEFINED;
   
    // load view in layout
    LayoutMain3ColsController layoutCtr = new LayoutMain3ColsController(ureq, getWindowControl(), null, null, mainContainer, null);
    setInitialComponent(layoutCtr.getInitialComponent());
  }
 
  /**
   * Put shibboleth attributes map in reqest for later usage.
   * @param req
   * @param attributes
   */
  public static final void putShibAttributes(HttpServletRequest req, Map<String,String> attributes) {
    UserSession.getUserSession(req).putEntry(KEY_SHIBATTRIBUTES, attributes);
  }
 
  /**
   * Put shibboleth unique identifier in request for later usage.
   * @param req
   * @param uniqueID
   */
  public static final void putShibUniqueID(HttpServletRequest req, String uniqueID) {
    UserSession.getUserSession(req).putEntry(KEY_SHIBUNIQUEID, uniqueID);
  }

  /**
   * @see org.olat.core.gui.control.DefaultController#event(org.olat.core.gui.UserRequest, org.olat.core.gui.components.Component, org.olat.core.gui.control.Event)
   */
  public void event(UserRequest ureq, Component source, Event event) {
    if (source == regForm) {
      if (event == Form.EVNT_VALIDATION_OK) {
        String choosenLogin = regForm.getLogin();
        Manager secMgr = ManagerFactory.getManager();
        Identity identity = secMgr.findIdentityByName(choosenLogin);

       
        if (identity == null) { // ok, create new user
          if (!hasEmailInShibAttr){
            regWithEmailForm = new ShibbolethRegistrationWithEmailForm("regWithEmailForm", translator, choosenLogin);
            regWithEmailForm.addListener(this);
            mainContainer.put("regWithEmailForm", regWithEmailForm);
            mainContainer.setPage(VELOCITY_ROOT + "/registerwithemail.html");
          } else { // there is an emailaddress
            state = STATE_NEW_SHIB_USER;
            mainContainer.setPage(VELOCITY_ROOT + "/disclaimer.html");
          }
        } else { // offer identity migration, if OLAT provider exists
          Authentication auth = secMgr.findAuthentication(identity, OLATAuthenticationController.PROVIDER_OLAT);         
          if (auth == null) { // no OLAT provider, migration not possible...
            getWindowControl().setError(translator.translate("sr.error.loginexists", new String[] {WebappHelper.getMailConfig("mailSupport")}));
          else { // OLAT provider exists, offer migration...
            migrationForm = new ShibbolethMigrationForm("migrationForm", translator, auth);
            migrationForm.addListener(this);
            mainContainer.put("migrationForm", migrationForm);
            mainContainer.setPage(VELOCITY_ROOT + "/migration.html");
          }
        }
      }
    } else if (source == regWithEmailForm){
      if (event == Form.EVNT_FORM_CANCELLED) {
        mainContainer.setPage(VELOCITY_ROOT + "/register.html");
      } else if (event == Form.EVNT_VALIDATION_OK) {
        state = STATE_NEW_SHIB_USER;
        mainContainer.setPage(VELOCITY_ROOT + "/disclaimer.html");
      }   
    } else if (source == migrationForm) {
      if (event == Form.EVNT_FORM_CANCELLED) {
        mainContainer.setPage(VELOCITY_ROOT + "/register.html");
      } else if (event == Form.EVNT_VALIDATION_OK) {
        state = STATE_MIGRATED_SHIB_USER;
        mainContainer.setPage(VELOCITY_ROOT + "/disclaimer.html");
      }
    } else if (event instanceof LocaleChangedEvent) {
      LocaleChangedEvent lce = (LocaleChangedEvent)event;
      Locale newLocale = lce.getNewLocale();
      translator.setLocale(newLocale);
      dclController.changeLocale(newLocale);
    }
  }

  /**
   * @see org.olat.core.gui.control.DefaultController#event(org.olat.core.gui.UserRequest, org.olat.core.gui.control.Controller, org.olat.core.gui.control.Event)
   */
  public void event(UserRequest ureq, Controller source, Event event) {
    if (source == languageChooserController) {
      if (event == Event.DONE_EVENT) { // language choosed
        mainContainer.setPage(VELOCITY_ROOT + "/register.html");
        ureq.getUserSession().removeEntry(LocaleNegotiator.NEGOTIATED_LOCALE);
      } else if (event instanceof LanguageChangedEvent) {
        LanguageChangedEvent lcev = (LanguageChangedEvent)event;
        translator.setLocale(lcev.getNewLocale());
        dclController.changeLocale(lcev.getNewLocale());
      }
    } else if (source == dclController) {
      if (event == Event.DONE_EVENT) { // disclaimer accepted...
        if (state == STATE_NEW_SHIB_USER) { // ...proceed and create user
          Manager secMgr = ManagerFactory.getManager();
          String choosenLogin = regForm.getLogin();
          // check if login has been taken by another user in the meantime...
          Identity identity = secMgr.findIdentityByName(choosenLogin);
          if (identity != null) {
            getWindowControl().setError(translator.translate("sr.login.meantimetaken"));
            mainContainer.setPage(VELOCITY_ROOT + "/register.html");
            state = STATE_UNDEFINED;
            return;
          }

          String email;
          if(!hasEmailInShibAttr) email = regWithEmailForm.getEmail();
          else email = userMapping.getEMail();
          User user = UserManager.getInstance().findUserByEmail(email);
         
          if (user != null) {
            // error, email already exists. should actually not happen if OLAT Authenticator has
            // been set after removing shibboleth authenticator
            getWindowControl().setError(translator.translate("sr.error.emailexists", new String[] {WebappHelper.getMailConfig("mailSupport")}));
            mainContainer.setPage(VELOCITY_ROOT + "/register.html");
            state = STATE_UNDEFINED;
            return;
          }

          String firstName = userMapping.getFirstName();
          String lastName = userMapping.getLastName();
          user = UserManager.getInstance().createUser(firstName, lastName, email);
          user.setProperty(UserConstants.INSTITUTIONALNAME, userMapping.getInstitutionalName());
          if(hasEmailInShibAttr){
            user.setProperty(UserConstants.INSTITUTIONALEMAIL, userMapping.getInstitutionalEMail());
          }
          user.setProperty(UserConstants.INSTITUTIONALUSERIDENTIFIER, userMapping.getInstitutionalUserIdentifier());
          identity = secMgr.createAndPersistIdentityAndUser(choosenLogin, user, ShibbolethDispatcher.PROVIDER_SHIB, shibbolethUniqueID, null);
          SecurityGroup olatUserGroup = secMgr.findSecurityGroupByName(Constants.GROUP_OLATUSERS);
          secMgr.addIdentityToSecurityGroup(identity, olatUserGroup);
          // tell system that this user did accept the disclaimer
          RegistrationManager.getInstance().setHasConfirmedDislaimer(identity);
          doLogin(identity, ureq);
          return;
        } else if (state == STATE_MIGRATED_SHIB_USER) { // ...proceed and migrate user
          // create additional authentication
          Authentication auth = migrationForm.getAuthentication();
          Identity authenticationedIdentity = auth.getIdentity();
          Manager secMgr = ManagerFactory.getManager();
          secMgr.createAndPersistAuthentication(authenticationedIdentity, ShibbolethDispatcher.PROVIDER_SHIB, shibbolethUniqueID, null);
         
          // update user profile
          User user = authenticationedIdentity.getUser();
          String s = userMapping.getFirstName();
          if (s != null) user.setProperty(UserConstants.FIRSTNAME, s);
          s = userMapping.getLastName();
          if (s != null) user.setProperty(UserConstants.LASTNAME, s);
          s = userMapping.getInstitutionalName();
          if (s != null) user.setProperty(UserConstants.INSTITUTIONALNAME, s);   
          s = userMapping.getInstitutionalEMail();
          if (s != null) user.setProperty(UserConstants.INSTITUTIONALEMAIL, s);
          s = userMapping.getInstitutionalUserIdentifier();
          if (s != null) user.setProperty(UserConstants.INSTITUTIONALUSERIDENTIFIER, s);
          UserManager.getInstance().updateUser(user);
          doLogin(authenticationedIdentity, ureq);
          return;
        }
      } else if (event == Event.CANCELLED_EVENT) {
        mainContainer.setPage(VELOCITY_ROOT + "/register.html");
        getWindowControl().setError(translator.translate("sr.error.disclaimer"));
      }
    }
  }

  private void doLogin(Identity identity, UserRequest ureq) {
    int loginStatus = AuthHelper.doLogin(identity, ShibbolethDispatcher.PROVIDER_SHIB, ureq);
    if (loginStatus != AuthHelper.LOGIN_OK) {
      //REVIEW:2010-01-11:revisited:pb: do not redirect if already MediaResource is set before
      //ureq.getDispatchResult().setResultingMediaResource(resultingMediaResource);
      //instead set the media resource accordingly
      //pb -> provide a DispatcherAction.getDefaultDispatcherRedirectMediaresource();
      //to be used here. (and some more places like CatalogController.
      DispatcherAction.redirectToDefaultDispatcher(ureq.getHttpResp()); // error, redirect to login screen
      return;
    }
    // successfull login
    ureq.getUserSession().getIdentityEnvironment().addAttributes(
        ShibbolethModule.getAttributeTranslator().translateAttributesMap(shibbolethAttributesMap));
  }
 
  /**
   *
   * @see org.olat.core.gui.control.DefaultController#doDispose(boolean)
   */
  protected void doDispose() {
    if (dclController != null) {
      dclController.dispose();
      dclController = null;
    }
   
    if (languageChooserController != null) {
      languageChooserController.dispose();
      languageChooserController = null;
    }
  }

}
TOP

Related Classes of org.olat.shibboleth.ShibbolethRegistrationController

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.