Something went wrong on our end
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
RegistrationController.java 20.33 KiB
/**
* 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.
* <hr>
* <a href="http://www.openolat.org">
* OpenOLAT - Online Learning and Training</a><br>
* This file has been modified by the OpenOLAT community. Changes are licensed
* under the Apache 2.0 license as the original file.
*/
package org.olat.registration;
import java.text.DateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import org.olat.basesecurity.AuthHelper;
import org.olat.basesecurity.BaseSecurityManager;
import org.olat.basesecurity.BaseSecurityModule;
import org.olat.core.CoreSpringFactory;
import org.olat.core.commons.chiefcontrollers.LanguageChangedEvent;
import org.olat.core.commons.fullWebApp.LayoutMain3ColsController;
import org.olat.core.dispatcher.DispatcherModule;
import org.olat.core.gui.UserRequest;
import org.olat.core.gui.components.Component;
import org.olat.core.gui.components.form.flexible.FormItem;
import org.olat.core.gui.components.link.Link;
import org.olat.core.gui.components.link.LinkFactory;
import org.olat.core.gui.components.panel.Panel;
import org.olat.core.gui.components.velocity.VelocityContainer;
import org.olat.core.gui.control.Controller;
import org.olat.core.gui.control.Event;
import org.olat.core.gui.control.WindowControl;
import org.olat.core.gui.control.controller.BasicController;
import org.olat.core.gui.control.generic.dtabs.Activateable2;
import org.olat.core.gui.control.generic.messages.MessageController;
import org.olat.core.gui.control.generic.messages.MessageUIFactory;
import org.olat.core.gui.control.generic.wizard.WizardInfoController;
import org.olat.core.gui.media.RedirectMediaResource;
import org.olat.core.helpers.Settings;
import org.olat.core.id.Identity;
import org.olat.core.id.Preferences;
import org.olat.core.id.User;
import org.olat.core.id.context.ContextEntry;
import org.olat.core.id.context.StateEntry;
import org.olat.core.util.StringHelper;
import org.olat.core.util.Util;
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.mail.MailBundle;
import org.olat.core.util.mail.MailManager;
import org.olat.core.util.mail.MailerResult;
import org.olat.dispatcher.LocaleNegotiator;
import org.olat.user.UserManager;
import org.olat.user.UserPropertiesConfig;
import org.olat.user.propertyhandlers.UserPropertyHandler;
import org.springframework.beans.factory.annotation.Autowired;
/**
* Description:<br>
* Controls the registration workflow.
*
* <P>
* @author Sabina Jeger
*/
public class RegistrationController extends BasicController implements Activateable2 {
private static final String SEPARATOR = "____________________________________________________________________\n";
private VelocityContainer myContent;
private Panel regarea;
private Link loginButton;
private WizardInfoController wizInfoController;
private DisclaimerController disclaimerController;
private EmailSendingForm emailSendForm;
private RegistrationForm2 registrationForm;
private LanguageChooserController langChooserController;
private String uniqueRegistrationKey;
private TemporaryKey tempKey;
@Autowired
private I18nManager i18nManager;
@Autowired
private UserManager userManager;
@Autowired
private MailManager mailManager;
@Autowired
private RegistrationModule registrationModule;
@Autowired
private RegistrationManager registrationManager;
/**
* Controller implementing registration work flow.
* @param ureq
* @param wControl
*/
public RegistrationController(UserRequest ureq, WindowControl wControl) {
super(ureq, wControl);
if (!registrationModule.isSelfRegistrationEnabled()) {
String contact = WebappHelper.getMailConfig("mailSupport");
String text = translate("reg.error.disabled.body", new String[]{ contact });
MessageController msg = MessageUIFactory.createWarnMessage(ureq, getWindowControl(), null, text);
LayoutMain3ColsController layoutCtr = new LayoutMain3ColsController(ureq, getWindowControl(), null, msg.getInitialComponent(), null);
listenTo(layoutCtr);
putInitialPanel(layoutCtr.getInitialComponent());
return;
}
// override language when not the same as in ureq and add fallback to
// property handler translator for user properties
String lang = ureq.getParameter("language");
if (lang == null) {
// support for legacy lang parameter
lang = ureq.getParameter("lang");
}
if (lang != null && ! lang.equals(i18nManager.getLocaleKey(getLocale()))) {
Locale loc = i18nManager.getLocaleOrDefault(lang);
ureq.getUserSession().setLocale(loc);
setLocale(loc, true);
setTranslator(userManager.getPropertyHandlerTranslator(Util.createPackageTranslator(this.getClass(), loc)));
} else {
// set fallback only
setTranslator(userManager.getPropertyHandlerTranslator(getTranslator()));
}
//construct content
myContent = createVelocityContainer("reg");
wizInfoController = new WizardInfoController(ureq, 5);
listenTo(wizInfoController);
myContent.put("regwizard", wizInfoController.getInitialComponent());
regarea = new Panel("regarea");
myContent.put("regarea", regarea);
uniqueRegistrationKey = ureq.getHttpReq().getParameter("key");
if (uniqueRegistrationKey == null || uniqueRegistrationKey.equals("")) {
// no temporary key is given, we assume step 1. If this is the case, we
// render in a modal dialog, no need to add the 3cols layout controller
// wrapper
//fxdiff FXOLAT-113: business path in DMZ
if(I18nModule.getEnabledLanguageKeys().size() == 1) {
wizInfoController.setCurStep(2);
createEmailForm(ureq);
} else {
createLanguageForm(ureq, wControl);
}
putInitialPanel(myContent);
} else {
// we check if given key is a valid temporary key
tempKey = registrationManager.loadTemporaryKeyByRegistrationKey(uniqueRegistrationKey);
// if key is not valid we redirect to first page
if (tempKey == null) {
// error, there should be an entry
showError("regkey.missingentry");
//fxdiff FXOLAT-113: business path in DMZ
if(I18nModule.getEnabledLanguageKeys().size() == 1) {
wizInfoController.setCurStep(2);
createEmailForm(ureq);
} else {
createLanguageForm(ureq, wControl);
}
} else {
wizInfoController.setCurStep(3);
myContent.contextPut("pwdhelp", translate("pwdhelp"));
myContent.contextPut("loginhelp", translate("loginhelp"));
myContent.contextPut("text", translate("step3.reg.text"));
myContent.contextPut("email", tempKey.getEmailAddress());
Map<String,String> userAttrs = new HashMap<String,String>();
userAttrs.put("email", tempKey.getEmailAddress());
if(registrationModule.getUsernamePresetBean() != null) {
UserNameCreationInterceptor interceptor = registrationModule.getUsernamePresetBean();
String proposedUsername = interceptor.getUsernameFor(userAttrs);
if(proposedUsername == null) {
if(interceptor.allowChangeOfUsername()) {
createRegForm2(ureq, null, false, false);
} else {
myContent = setErrorPage("reg.error.no_username", wControl);
}
} else {
Identity identity = BaseSecurityManager.getInstance().findIdentityByName(proposedUsername);
if(identity != null) {
if(interceptor.allowChangeOfUsername()) {
createRegForm2(ureq, proposedUsername, true, false);
} else {
myContent = setErrorPage("reg.error.user_in_use", wControl);
}
} else if (interceptor.allowChangeOfUsername()) {
createRegForm2(ureq, proposedUsername, false, false);
} else {
createRegForm2(ureq, proposedUsername, false, true);
}
}
} else {
createRegForm2(ureq, null, false, false);
}
}
// load view in layout
LayoutMain3ColsController layoutCtr = new LayoutMain3ColsController(ureq, getWindowControl(), null, myContent, null);
listenTo(layoutCtr);
putInitialPanel(layoutCtr.getInitialComponent());
}
}
public String getWizardTitle() {
return translate("step1.reg.title");
}
private VelocityContainer setErrorPage(String errorKey, WindowControl wControl) {
String error = getTranslator().translate(errorKey);
wControl.setError(error);
VelocityContainer errorContainer = createVelocityContainer("error");
errorContainer.contextPut("errorMsg", error);
return errorContainer;
}
private void createRegForm2(UserRequest ureq, String proposedUsername, boolean userInUse, boolean usernameReadonly) {
registrationForm = new RegistrationForm2(ureq, getWindowControl(), I18nManager.getInstance().getLocaleKey(getLocale()), proposedUsername, userInUse, usernameReadonly);
listenTo(registrationForm);
regarea.setContent(registrationForm.getInitialComponent());
}
private void createLanguageForm(UserRequest ureq, WindowControl wControl) {
removeAsListenerAndDispose(langChooserController);
langChooserController = new LanguageChooserController(ureq, wControl, true);
listenTo(langChooserController);
myContent.contextPut("text", translate("select.language.description"));
regarea.setContent(langChooserController.getInitialComponent());
}
/**
* just needed for creating EmailForm
*/
private void createEmailForm(UserRequest ureq) {
removeAsListenerAndDispose(emailSendForm);
emailSendForm = new EmailSendingForm(ureq, getWindowControl());
listenTo(emailSendForm);
myContent.contextPut("text", translate("step1.reg.text"));
regarea.setContent(emailSendForm.getInitialComponent());
}
@Override
public void activate(UserRequest ureq, List<ContextEntry> entries, StateEntry state) {
if(entries == null || entries.isEmpty()) return;
}
@Override
public void event(UserRequest ureq, Component source, Event event) {
if(source == loginButton) {
Identity persistedIdentity = (Identity)loginButton.getUserObject();
doLogin(ureq, persistedIdentity);
}
}
/**
* @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)
*/
@Override
public void event(UserRequest ureq, Controller source, Event event) {
if (source == emailSendForm) {
if (event == Event.DONE_EVENT) { // form
// validation
// was ok
wizInfoController.setCurStep(2);
// Email requested for tempkey
//save the fields somewhere
String email = emailSendForm.getEmailAddress();
myContent.contextPut("email", email);
myContent.contextPut("text", translate("step2.reg.text", email));
//ef.setVisible(false);
regarea.setVisible(false);
// look for user in "Person" and "user" tables
boolean foundUser = UserManager.getInstance().userExist(email);
// get remote address
String ip = ureq.getHttpReq().getRemoteAddr();
String serverpath = Settings.getServerContextPathURI();
String today = DateFormat.getDateInstance(DateFormat.LONG, ureq.getLocale()).format(new Date());
String[] whereFromAttrs = new String[]{
serverpath, today, ip
};
boolean isMailSent = false;
if (!foundUser) {
TemporaryKey tk = registrationManager.loadTemporaryKeyByEmail(email);
if (tk == null) tk = registrationManager.createTemporaryKeyByEmail(email, ip, RegistrationManager.REGISTRATION);
myContent.contextPut("regKey", tk.getRegistrationKey());
String link = serverpath + "/dmz/registration/index.html?key=" + tk.getRegistrationKey() + "&language=" + i18nManager.getLocaleKey(ureq.getLocale());
String[] bodyAttrs = new String[]{
serverpath, //0
tk.getRegistrationKey(), //1
i18nManager.getLocaleKey(ureq.getLocale()), //2
"<a href=\"" + link + "\">" + link + "</a>" //3
};
String body = translate("reg.body", bodyAttrs);
boolean htmlBody = StringHelper.isHtml(body);
if(!htmlBody) {
body += SEPARATOR + translate("reg.wherefrom", whereFromAttrs);
}
try {
MailBundle bundle = new MailBundle();
bundle.setTo(email);
bundle.setContent(translate("reg.subject"), body);
MailerResult result = mailManager.sendExternMessage(bundle, null, htmlBody);
if (result.isSuccessful()) {
isMailSent = true;
}
} catch (Exception e) {
// nothing to do, emailSent flag is false, errors will be reported to user
}
} else {
// a user exists, this is an error in the registration page
// send email
Identity identity = UserManager.getInstance().findIdentityByEmail(email);
String body = translate("login.body", identity.getName()) + SEPARATOR + translate("reg.wherefrom", whereFromAttrs);
try {
MailBundle bundle = new MailBundle();
bundle.setTo(email);
bundle.setContent(translate("login.subject"), body);
MailerResult result = mailManager.sendExternMessage(bundle, null, true);
if (result.isSuccessful()) {
isMailSent = true;
}
} catch (Exception e) {
// nothing to do, emailSent flag is false, errors will be reported to user
}
}
if (isMailSent) {
showInfo("email.sent");
} else {
showError("email.notsent");
}
} else if (event == Event.CANCELLED_EVENT) {
fireEvent(ureq, Event.CANCELLED_EVENT);
}
} else if (source == langChooserController) {
if (event == Event.DONE_EVENT) {
wizInfoController.setCurStep(2);
createEmailForm(ureq);
ureq.getUserSession().removeEntry(LocaleNegotiator.NEGOTIATED_LOCALE);
} else if (event == Event.CANCELLED_EVENT) {
ureq.getDispatchResult().setResultingMediaResource(new RedirectMediaResource(Settings.getServerContextPathURI()));
} else if (event instanceof LanguageChangedEvent) {
LanguageChangedEvent lcev = (LanguageChangedEvent)event;
setLocale(lcev.getNewLocale(), true);
myContent.contextPut("text", translate("select.language.description"));
}
} else if (source == registrationForm) {
// Userdata entered
if (event == Event.DONE_EVENT) {
String lang = registrationForm.getLangKey();
// change language if different then current language
if (! lang.equals(I18nManager.getInstance().getLocaleKey(ureq.getLocale()))) {
Locale loc = I18nManager.getInstance().getLocaleOrDefault(lang);
ureq.getUserSession().setLocale(loc);
getTranslator().setLocale(loc);
}
wizInfoController.setCurStep(4);
myContent.contextPut("pwdhelp", "");
myContent.contextPut("loginhelp", "");
myContent.contextPut("text", translate("step4.reg.text"));
removeAsListenerAndDispose(disclaimerController);
disclaimerController = new DisclaimerController(ureq, getWindowControl());
listenTo(disclaimerController);
regarea.setContent(disclaimerController.getInitialComponent());
} else if (event == Event.CANCELLED_EVENT) {
ureq.getDispatchResult().setResultingMediaResource(new RedirectMediaResource(Settings.getServerContextPathURI()));
}
} else if (source == disclaimerController) {
if (event == Event.DONE_EVENT) {
// finalize the registration by creating the user
Identity persitedIdentity = createNewUserAfterRegistration();
// display step5
displayFinalStep(persitedIdentity);
} else if (event == Event.CANCELLED_EVENT) {
ureq.getDispatchResult().setResultingMediaResource(new RedirectMediaResource(Settings.getServerContextPathURI()));
}
}
}
/**
* OO-92
*
* displays the final step of the registration process. (step5)<br />
* see also _content/finish.html
*
* @param user
* The newly created User from which to display information
*
*/
private void displayFinalStep(Identity persitedIdentity){
// set wizard step to 5
wizInfoController.setCurStep(5);
// hide the text we don't need anymore
myContent.contextPut("pwdhelp", "");
myContent.contextPut("loginhelp", "");
myContent.contextPut("text", "");
// show last screen
VelocityContainer finishVC = createVelocityContainer("finish");
List<UserPropertyHandler> userPropertyHandlers = UserManager.getInstance().getUserPropertyHandlersFor(RegistrationForm2.USERPROPERTIES_FORM_IDENTIFIER, false);
finishVC.contextPut("userPropertyHandlers", userPropertyHandlers);
finishVC.contextPut("user", persitedIdentity.getUser());
finishVC.contextPut("locale", getLocale());
finishVC.contextPut("username", registrationForm.getLogin());
finishVC.contextPut("text", getTranslator().translate("step5.reg.text", new String[]{ registrationForm.getLogin() }));
loginButton = LinkFactory.createButton("form.login", finishVC, this);
loginButton.setCustomEnabledLinkCSS("btn btn-primary");
loginButton.setUserObject(persitedIdentity);
finishVC.put("loginhref", loginButton);
regarea.setContent(finishVC);
}
/**
* OO-92
* this will finally create the user, set all it's userproperties
*
* @return User the newly created, persisted User Object
*/
private Identity createNewUserAfterRegistration() {
// create user with mandatory fields from registration-form
UserManager um = UserManager.getInstance();
User volatileUser = um.createUser(registrationForm.getFirstName(), registrationForm.getLastName(), tempKey.getEmailAddress());
// set user configured language
Preferences preferences = volatileUser.getPreferences();
preferences.setLanguage(registrationForm.getLangKey());
volatileUser.setPreferences(preferences);
// create an identity with the given username / pwd and the user object
String login = registrationForm.getLogin();
String pwd = registrationForm.getPassword();
Identity persistedIdentity = registrationManager.createNewUserAndIdentityFromTemporaryKey(login, pwd, volatileUser, tempKey);
if (persistedIdentity == null) {
showError("user.notregistered");
return null;
} else {
// update other user properties from form
List<UserPropertyHandler> userPropertyHandlers = um.getUserPropertyHandlersFor(RegistrationForm2.USERPROPERTIES_FORM_IDENTIFIER, false);
User persistedUser = persistedIdentity.getUser();
//add eventually static value
UserPropertiesConfig userPropertiesConfig = CoreSpringFactory.getImpl(UserPropertiesConfig.class);
if(registrationModule.isStaticPropertyMappingEnabled()) {
String propertyName = registrationModule.getStaticPropertyMappingName();
String propertyValue = registrationModule.getStaticPropertyMappingValue();
if(StringHelper.containsNonWhitespace(propertyName)
&& StringHelper.containsNonWhitespace(propertyValue)
&& userPropertiesConfig.getPropertyHandler(propertyName) != null) {
try {
persistedUser.setProperty(propertyName, propertyValue);
} catch (Exception e) {
logError("Cannot set the static property value", e);
}
}
}
for (UserPropertyHandler userPropertyHandler : userPropertyHandlers) {
FormItem fi = registrationForm.getPropFormItem(userPropertyHandler.getName());
userPropertyHandler.updateUserFromFormItem(persistedUser, fi);
}
// persist changes in db
um.updateUserFromIdentity(persistedIdentity);
// send notification mail to sys admin
String notiEmail = CoreSpringFactory.getImpl(RegistrationModule.class).getRegistrationNotificationEmail();
if (notiEmail != null) {
registrationManager.sendNewUserNotificationMessage(notiEmail, persistedIdentity);
}
// tell system that this user did accept the disclaimer
registrationManager.setHasConfirmedDislaimer(persistedIdentity);
return persistedIdentity;
}
}
private void doLogin(UserRequest ureq, Identity persistedIdentity) {
int loginStatus = AuthHelper.doLogin(persistedIdentity, BaseSecurityModule.getDefaultAuthProviderIdentifier(), ureq);
if (loginStatus == AuthHelper.LOGIN_OK) {
//youppi
} else if (loginStatus == AuthHelper.LOGIN_NOTAVAILABLE){
DispatcherModule.redirectToDefaultDispatcher(ureq.getHttpResp());
} else {
getWindowControl().setError(translate("login.error", WebappHelper.getMailConfig("mailReplyTo")));
}
}
protected void doDispose() {
//
}
}