From e30d0d4b34784517f570251a813ec8a76a96d3d8 Mon Sep 17 00:00:00 2001
From: srosse <stephane.rosse@frentix.com>
Date: Thu, 13 Dec 2018 16:36:54 +0100
Subject: [PATCH] OO-3717: in registration flow, place disclaimer before asking
 email

---
 .../login/OLATAuthenticationController.java   |   1 +
 .../registration/DisclaimerController.java    |  31 +-
 .../DisclaimerFormController.java             |   7 +-
 .../olat/registration/EmailSendingForm.java   |  22 +-
 .../LanguageChooserController.java            |  17 +-
 .../RegistrationAdminController.java          |  20 +-
 .../registration/RegistrationController.java  | 386 +++++++++---------
 7 files changed, 238 insertions(+), 246 deletions(-)

diff --git a/src/main/java/org/olat/login/OLATAuthenticationController.java b/src/main/java/org/olat/login/OLATAuthenticationController.java
index 2b26918e72a..8279840daa8 100644
--- a/src/main/java/org/olat/login/OLATAuthenticationController.java
+++ b/src/main/java/org/olat/login/OLATAuthenticationController.java
@@ -149,6 +149,7 @@ public class OLATAuthenticationController extends AuthenticationController imple
 		
 		subController = new RegistrationController(ureq, getWindowControl());
 		listenTo(subController);
+		
 		cmc = new CloseableModalController(getWindowControl(), translate("close"), subController.getInitialComponent());
 		listenTo(cmc);
 		cmc.activate();
diff --git a/src/main/java/org/olat/registration/DisclaimerController.java b/src/main/java/org/olat/registration/DisclaimerController.java
index 17de3a8a5b4..5b474cfdc30 100644
--- a/src/main/java/org/olat/registration/DisclaimerController.java
+++ b/src/main/java/org/olat/registration/DisclaimerController.java
@@ -99,7 +99,7 @@ public class DisclaimerController extends BasicController {
 		listenTo(disclaimerFormController);
 		
 		main = createVelocityContainer("disclaimer");
-		main.put("dclform", this.disclaimerFormController.getInitialComponent());
+		main.put("dclform", disclaimerFormController.getInitialComponent());
 		
 		// add optinal download link, see class comments in DisclaimerFormController
 		// Add the additional link to the form (depending on the configuration)
@@ -108,38 +108,35 @@ public class DisclaimerController extends BasicController {
 			disclaimerDir.mkdirs();
 			VFSContainer disclaimerContainer = new LocalFolderImpl(disclaimerDir);
 			String i18nIfiedFilename = translate("disclaimer.filedownloadurl");
-			this.downloadFile = (VFSLeaf)disclaimerContainer.resolve(i18nIfiedFilename);
-			if (this.downloadFile != null) {
-				this.downloadLink = LinkFactory.createLink("disclaimer.additionallinktext", main, this);
-				this.downloadLink.setTarget("_blank");
+			downloadFile = (VFSLeaf)disclaimerContainer.resolve(i18nIfiedFilename);
+			if (downloadFile != null) {
+				downloadLink = LinkFactory.createLink("disclaimer.additionallinktext", main, this);
+				downloadLink.setTarget("_blank");
 				
 				if (i18nIfiedFilename.toLowerCase().endsWith(".pdf")) {
-					this.downloadLink.setIconLeftCSS("o_icon o_icon-fw o_filetype_pdf");
+					downloadLink.setIconLeftCSS("o_icon o_icon-fw o_filetype_pdf");
 				} else if (i18nIfiedFilename.toLowerCase().endsWith(".html") || i18nIfiedFilename.toLowerCase().endsWith(".htm")) {
-					this.downloadLink.setIconLeftCSS("o_icon o_icon-fw o_filetype_html");
+					downloadLink.setIconLeftCSS("o_icon o_icon-fw o_filetype_html");
 				} else if (i18nIfiedFilename.toLowerCase().endsWith(".doc")) {
-					this.downloadLink.setIconLeftCSS("o_icon o_icon-fw o_filetype_doc");
+					downloadLink.setIconLeftCSS("o_icon o_icon-fw o_filetype_doc");
 				}
 			}
 		}
 		putInitialPanel(main);
 	}
 
-	/**
-	 * @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)
-	 */
 	@Override
 	public void event(UserRequest ureq, Component source, Event event) {
-		if (source == this.downloadLink) {
-			ureq.getDispatchResult().setResultingMediaResource(new VFSMediaResource(this.downloadFile));
+		if (source == downloadLink) {
+			ureq.getDispatchResult().setResultingMediaResource(new VFSMediaResource(downloadFile));
 			// Prevent "do not press reload" message.
-			this.downloadLink.setDirty(false);
+			downloadLink.setDirty(false);
 		}
 	}
 	
 	@Override
 	protected void event(UserRequest ureq, Controller source, Event event) {
-		if (source == this.disclaimerFormController) {
+		if (source == disclaimerFormController) {
 			if (event == Event.CANCELLED_EVENT) {
 				fireEvent(ureq, Event.CANCELLED_EVENT);
 			} else if (event == Event.DONE_EVENT) {
@@ -175,10 +172,6 @@ public class DisclaimerController extends BasicController {
 		main.put("dclform", this.disclaimerFormController.getInitialComponent());
 	}
 	
-	/**
-	 * 
-	 * @see org.olat.core.gui.control.DefaultController#doDispose(boolean)
-	 */
 	@Override
 	protected void doDispose() {
 		//
diff --git a/src/main/java/org/olat/registration/DisclaimerFormController.java b/src/main/java/org/olat/registration/DisclaimerFormController.java
index 04695bd02af..b1db7873ce9 100644
--- a/src/main/java/org/olat/registration/DisclaimerFormController.java
+++ b/src/main/java/org/olat/registration/DisclaimerFormController.java
@@ -51,8 +51,10 @@ public class DisclaimerFormController extends FormBasicController {
 	private static final String ACKNOWLEDGE_CHECKBOX_NAME = "acknowledge_checkbox";
 	private static final String ADDITIONAL_CHECKBOX_NAME = "additional_checkbox";
 	private static final String ADDITIONAL_CHECKBOX_2_NAME = "additional_checkbox_2";
+	
 	protected MultipleSelectionElement acceptCheckbox;
-	protected MultipleSelectionElement additionalCheckbox, additionalCheckbox2;
+	protected MultipleSelectionElement additionalCheckbox;
+	protected MultipleSelectionElement additionalCheckbox2;
 	private boolean readOnly;
 
 	@Autowired
@@ -118,9 +120,10 @@ public class DisclaimerFormController extends FormBasicController {
 			final FormLayoutContainer buttonLayout = FormLayoutContainer.createButtonLayout("buttonLayout", getTranslator());
 			formLayout.add(buttonLayout);
 			buttonLayout.setElementCssClass("o_sel_disclaimer_buttons");
-			uifactory.addFormSubmitButton(DCL_ACCEPT, NLS_DISCLAIMER_OK, buttonLayout);
+
 			FormCancel cancelButton = uifactory.addFormCancelButton(NLS_DISCLAIMER_NOK, buttonLayout, ureq, getWindowControl());	
 			cancelButton.setI18nKey(NLS_DISCLAIMER_NOK);
+			uifactory.addFormSubmitButton(DCL_ACCEPT, NLS_DISCLAIMER_OK, buttonLayout);
 		}
 	}
 }
diff --git a/src/main/java/org/olat/registration/EmailSendingForm.java b/src/main/java/org/olat/registration/EmailSendingForm.java
index 795594a09d9..c931d137f2e 100644
--- a/src/main/java/org/olat/registration/EmailSendingForm.java
+++ b/src/main/java/org/olat/registration/EmailSendingForm.java
@@ -25,7 +25,6 @@
 
 package org.olat.registration;
 
-import org.olat.core.CoreSpringFactory;
 import org.olat.core.gui.UserRequest;
 import org.olat.core.gui.components.form.flexible.FormItemContainer;
 import org.olat.core.gui.components.form.flexible.elements.TextElement;
@@ -35,29 +34,25 @@ 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.util.mail.MailHelper;
+import org.springframework.beans.factory.annotation.Autowired;
 
 /**
- *  description of first registration form for email-address
+ *  Simple form to get an email address.
  * 
  * @author Sabina Jeger
  */
 public class EmailSendingForm extends FormBasicController {
 	
 	private TextElement mail;
-	private final RegistrationManager registrationManager;
+	
+	@Autowired
+	private RegistrationManager registrationManager;
 	
 	public EmailSendingForm(UserRequest ureq, WindowControl wControl) {
 		super(ureq, wControl);
-		
-		registrationManager = CoreSpringFactory.getImpl(RegistrationManager.class);
-		
 		initForm(ureq);
 	}
 
-	/**
-	 * Initialize the form
-	 */
-	
 	@Override
 	protected void initForm(FormItemContainer formLayout, Controller listener, UserRequest ureq) {
 		mail = uifactory.addTextElement("mail", "email.address", 255, "", formLayout);
@@ -66,8 +61,8 @@ public class EmailSendingForm extends FormBasicController {
 		// Button layout
 		final FormLayoutContainer buttonLayout = FormLayoutContainer.createButtonLayout("button_layout", getTranslator());
 		formLayout.add(buttonLayout);
-		uifactory.addFormSubmitButton("submit.speichernUndweiter", buttonLayout);
 		uifactory.addFormCancelButton("submit.cancel", buttonLayout, ureq, getWindowControl());
+		uifactory.addFormSubmitButton("submit.speichernUndweiter", buttonLayout);
 	}
 
 	protected String getEmailAddress() {
@@ -76,7 +71,7 @@ public class EmailSendingForm extends FormBasicController {
 	
 	@Override
 	public boolean validateFormLogic(UserRequest ureq) {
-		boolean allOk = true;
+		boolean allOk = super.validateFormLogic(ureq);
 		
 		if (mail.isEmpty("email.address.maynotbeempty")) {
 			allOk &= false;
@@ -93,9 +88,10 @@ public class EmailSendingForm extends FormBasicController {
 			allOk &= valid;
 		}
 
-		return allOk && super.validateFormLogic(ureq);
+		return allOk;
 	}
 
+	@Override
 	protected void formOK(UserRequest ureq) {
 		fireEvent(ureq, Event.DONE_EVENT);
 	}
diff --git a/src/main/java/org/olat/registration/LanguageChooserController.java b/src/main/java/org/olat/registration/LanguageChooserController.java
index 4c06a4c99f2..be60e895f5a 100644
--- a/src/main/java/org/olat/registration/LanguageChooserController.java
+++ b/src/main/java/org/olat/registration/LanguageChooserController.java
@@ -73,9 +73,6 @@ public class LanguageChooserController extends FormBasicController {
 		initForm(ureq);
 	}
 
-	/**
-	 * @see org.olat.core.gui.components.form.flexible.FormDefaultController#formOK(org.olat.core.gui.UserRequest)
-	 */
 	@Override
 	protected void formOK(UserRequest ureq) {
 		fireEvent(ureq, Event.DONE_EVENT);
@@ -86,11 +83,6 @@ public class LanguageChooserController extends FormBasicController {
 		fireEvent(ureq, Event.CANCELLED_EVENT);
 	}
 
-	/**
-	 * @see org.olat.core.gui.components.form.flexible.FormDefaultController#formInnerEvent(org.olat.core.gui.UserRequest,
-	 *      org.olat.core.gui.components.form.flexible.FormItem,
-	 *      org.olat.core.gui.components.form.flexible.FormEvent)
-	 */
 	@Override
 	protected void formInnerEvent(UserRequest ureq, FormItem source, FormEvent event) {
 		if(source == langs) {
@@ -118,10 +110,6 @@ public class LanguageChooserController extends FormBasicController {
 		return langs.getSelectedKey();
 	}
 
-	/**
-	 * @see org.olat.core.gui.components.form.flexible.FormDefaultController#initFormElements(org.olat.core.gui.components.form.flexible.FormItemContainer,
-	 *      org.olat.core.gui.control.Controller)
-	 */
 	@Override
 	protected void initForm(FormItemContainer formLayout, Controller listener, final UserRequest ureq) {
 		Map<String, String> languages = i18nManager.getEnabledLanguagesTranslated();
@@ -135,13 +123,10 @@ public class LanguageChooserController extends FormBasicController {
 
 		final FormLayoutContainer buttonLayout = FormLayoutContainer.createButtonLayout("buttonLayout", getTranslator());
 		formLayout.add(buttonLayout);
-		nextButton = uifactory.addFormSubmitButton("submit.weiter", buttonLayout);
 		uifactory.addFormCancelButton("cancel", buttonLayout, ureq, getWindowControl());
+		nextButton = uifactory.addFormSubmitButton("submit.weiter", buttonLayout);
 	}
 
-	/**
-	 * @see org.olat.core.gui.control.DefaultController#doDispose(boolean)
-	 */
 	@Override
 	protected void doDispose() {
 		langs = null;
diff --git a/src/main/java/org/olat/registration/RegistrationAdminController.java b/src/main/java/org/olat/registration/RegistrationAdminController.java
index d409adfc2b7..c2b22f160ca 100644
--- a/src/main/java/org/olat/registration/RegistrationAdminController.java
+++ b/src/main/java/org/olat/registration/RegistrationAdminController.java
@@ -23,7 +23,6 @@ package org.olat.registration;
 import java.util.ArrayList;
 import java.util.List;
 
-import org.olat.core.CoreSpringFactory;
 import org.olat.core.gui.UserRequest;
 import org.olat.core.gui.components.form.ValidationError;
 import org.olat.core.gui.components.form.flexible.FormItem;
@@ -42,6 +41,7 @@ import org.olat.core.util.StringHelper;
 import org.olat.user.UserPropertiesConfig;
 import org.olat.user.propertyhandlers.Generic127CharTextPropertyHandler;
 import org.olat.user.propertyhandlers.UserPropertyHandler;
+import org.springframework.beans.factory.annotation.Autowired;
 
 /**
  * Admin panel to configure the registration settings: should link appear on the login page...
@@ -64,24 +64,23 @@ public class RegistrationAdminController extends FormBasicController {
 	private FormLayoutContainer staticPropContainer;
 	
 	private static final String[] enableRegistrationKeys = new String[]{ "on" };
-	private static final String[] enableRegistrationValues = new String[1];
-	private String[] propertyKeys, propertyValues;
+	private String[] propertyKeys;
+	private String[] propertyValues;
 	
-	private final RegistrationModule registrationModule;
-	private final RegistrationManager registrationManager;
-	private final UserPropertiesConfig userPropertiesConfig;
+	@Autowired
+	private RegistrationModule registrationModule;
+	@Autowired
+	private RegistrationManager registrationManager;
+	@Autowired
+	private UserPropertiesConfig userPropertiesConfig;
 	private final Translator userPropTranslator;
 	
 	public RegistrationAdminController(UserRequest ureq, WindowControl wControl) {
 		super(ureq, wControl, "admin");
 		
-		registrationModule = CoreSpringFactory.getImpl(RegistrationModule.class);
-		registrationManager = CoreSpringFactory.getImpl(RegistrationManager.class);
-		userPropertiesConfig = CoreSpringFactory.getImpl(UserPropertiesConfig.class);
 		//decorate the translator
 		userPropTranslator = userPropertiesConfig.getTranslator(getTranslator());
 
-		enableRegistrationValues[0] = translate("admin.enableRegistration.on");
 		
 		List<UserPropertyHandler> allPropertyHandlers = userPropertiesConfig.getAllUserPropertyHandlers();
 		List<UserPropertyHandler> propertyHandlers = new ArrayList<>(allPropertyHandlers.size());
@@ -106,6 +105,7 @@ public class RegistrationAdminController extends FormBasicController {
 
 	@Override
 	protected void initForm(FormItemContainer formLayout, Controller listener, UserRequest ureq) {
+		String[] enableRegistrationValues = new String[] { translate("admin.enableRegistration.on") };
 
 		//settings
 		FormLayoutContainer settingsContainer = FormLayoutContainer.createDefaultFormLayout("settings", getTranslator());
diff --git a/src/main/java/org/olat/registration/RegistrationController.java b/src/main/java/org/olat/registration/RegistrationController.java
index cdf170a3da9..0c05a02072a 100644
--- a/src/main/java/org/olat/registration/RegistrationController.java
+++ b/src/main/java/org/olat/registration/RegistrationController.java
@@ -89,16 +89,18 @@ public class RegistrationController extends BasicController implements Activatea
 
 	private static final String SEPARATOR = "____________________________________________________________________\n";
 
-	private VelocityContainer myContent;	
 	private Panel regarea;
 	private Link loginButton;
+	private VelocityContainer myContent;	
+	
 	private WizardInfoController wizInfoController;
 	private DisclaimerController disclaimerController;
 	private EmailSendingForm emailSendForm;
 	private RegistrationForm2 registrationForm;
 	private LanguageChooserController langChooserController;
-	private String uniqueRegistrationKey;
+	
 	private TemporaryKey tempKey;
+	private String uniqueRegistrationKey;
 	
 	@Autowired
 	private I18nModule i18nModule;
@@ -118,7 +120,7 @@ public class RegistrationController extends BasicController implements Activatea
 	private RegistrationManager registrationManager;
 
 	/**
-	 * Controller implementing registration work flow.
+	 * Controller implementing registration workflow.
 	 * @param ureq
 	 * @param wControl
 	 */
@@ -162,13 +164,7 @@ public class RegistrationController extends BasicController implements Activatea
 			// 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);
-			}
+			displayLanguageChooserStep(ureq);
 			putInitialPanel(myContent);
 		} else {
 			// we check if given key is a valid temporary key
@@ -177,49 +173,9 @@ public class RegistrationController extends BasicController implements Activatea
 			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);
-				}
+				displayLanguageChooserStep(ureq);
 			} 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 = securityManager.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);
-				}
+				displayRegistrationForm2(ureq);
 			}
 			// load view in layout
 			LayoutMain3ColsController layoutCtr = new LayoutMain3ColsController(ureq, getWindowControl(), null, myContent, null);
@@ -254,21 +210,9 @@ public class RegistrationController extends BasicController implements Activatea
 		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
@@ -279,142 +223,213 @@ public class RegistrationController extends BasicController implements Activatea
 		}
 	}
 
-	/**
-	 * @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);
-				// 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 (registrationManager.isRegistrationPending(email) || UserManager.getInstance().isEmailAllowed(email)) {
-					TemporaryKey tk = null;
-					if (userModule.isEmailUnique()) {
-						tk = registrationManager.loadTemporaryKeyByEmail(email);
-					}
-					if (tk == null) {
-						tk = registrationManager.loadOrCreateTemporaryKeyByEmail(email, ip,
-								RegistrationManager.REGISTRATION, registrationModule.getValidUntilHoursGui());
-					}
-					myContent.contextPut("regKey", tk.getRegistrationKey());
-					
-					String link = serverpath + "/dmz/registration/index.html?key=" + tk.getRegistrationKey() + "&language=" + i18nModule.getLocaleKey(ureq.getLocale());
-					String[] bodyAttrs = new String[]{
-						serverpath,										//0
-						tk.getRegistrationKey(),						//1
-						i18nModule.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 {
-					// if users with this email address exists, they are informed.
-					List<Identity> identities = UserManager.getInstance().findIdentitiesByEmail(Collections.singletonList(email));
-					for (Identity identity: identities) {
-						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 (source == langChooserController) {
 			if (event == Event.DONE_EVENT) {
-				wizInfoController.setCurStep(2);
-				createEmailForm(ureq);
+				displayDisclaimer(ureq);
 				ureq.getUserSession().removeEntry(LocaleNegotiator.NEGOTIATED_LOCALE);
 			} else if (event == Event.CANCELLED_EVENT) {
-				ureq.getDispatchResult().setResultingMediaResource(new RedirectMediaResource(Settings.getServerContextPathURI()));
+				cancel(ureq);
 			} 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
+		} else if (source == disclaimerController) {
 			if (event == Event.DONE_EVENT) {
-				String lang = registrationForm.getLangKey();
-				// change language if different then current language
-				if (! lang.equals(i18nModule.getLocaleKey(ureq.getLocale()))) {
-					Locale loc = i18nManager.getLocaleOrDefault(lang);
-					ureq.getUserSession().setLocale(loc);
-					getTranslator().setLocale(loc);					
+				// finalize the registration by creating the user
+				displayEmailForm(ureq);
+			} else if (event == Event.CANCELLED_EVENT) {
+				cancel(ureq);
+			}
+		} else if (source == emailSendForm) {
+			if (event == Event.DONE_EVENT) { // form
+				boolean isMailSent = processEmail(ureq);
+				if (isMailSent) {
+					showInfo("email.sent");
+				} else {
+					showError("email.notsent");
 				}
-
-				
-				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()));
+				fireEvent(ureq, Event.CANCELLED_EVENT);
 			}
-		} else if (source == disclaimerController) {
+		}  else if (source == registrationForm) {
+			// Userdata entered
 			if (event == Event.DONE_EVENT) {
-				// finalize the registration by creating the user
 				Identity persitedIdentity = createNewUserAfterRegistration();
-				// display step5
-				displayFinalStep(persitedIdentity);
+				if(persitedIdentity == null) {
+					cancel(ureq);
+				} else {
+					displayFinalStep(persitedIdentity);
+				}
 			} else if (event == Event.CANCELLED_EVENT) {
-				ureq.getDispatchResult().setResultingMediaResource(new RedirectMediaResource(Settings.getServerContextPathURI()));
+				cancel(ureq);
 			}
+		} 
+	}
+	
+	private void cancel(UserRequest ureq) {
+		ureq.getDispatchResult().setResultingMediaResource(new RedirectMediaResource(Settings.getServerContextPathURI()));
+	}
+	
+	/**
+	 * Display the language chooser or jump to the email form if
+	 * not needed.
+	 * 
+	 * @param ureq The user request
+	 */
+	private void displayLanguageChooserStep(UserRequest ureq) {
+		if(i18nModule.getEnabledLanguageKeys().size() == 1) {
+			displayDisclaimer(ureq);
+		} else {
+			createLanguageForm(ureq, getWindowControl());
 		}
+	}
+	
+	/**
+	 * Display the disclaimer if enabled, else jump to the
+	 * email form.
+	 * 
+	 * @param ureq The user request
+	 */
+	private void displayDisclaimer(UserRequest ureq) {
+		if(registrationModule.isDisclaimerEnabled()) {
+			wizInfoController.setCurStep(2);
+			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 {
+			displayEmailForm(ureq);
+		}
+	}
+	
+	private void displayEmailForm(UserRequest ureq) {
+		wizInfoController.setCurStep(3);
 
+		removeAsListenerAndDispose(emailSendForm);
+		emailSendForm = new EmailSendingForm(ureq, getWindowControl());
+		listenTo(emailSendForm);
+		
+		myContent.contextPut("text", translate("step1.reg.text"));
+		regarea.setContent(emailSendForm.getInitialComponent());
+	}
+	
+	private boolean processEmail(UserRequest ureq) {
+		// validation
+		// was ok
+		wizInfoController.setCurStep(3);
+		// Email requested for tempkey
+		//save the fields somewhere
+		String email = emailSendForm.getEmailAddress();
+		myContent.contextPut("email", email);
+		myContent.contextPut("text", translate("step2.reg.text", email));
+		regarea.setVisible(false);
+		// 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 (registrationManager.isRegistrationPending(email) || userManager.isEmailAllowed(email)) {
+			TemporaryKey tk = null;
+			if (userModule.isEmailUnique()) {
+				tk = registrationManager.loadTemporaryKeyByEmail(email);
+			}
+			if (tk == null) {
+				tk = registrationManager.loadOrCreateTemporaryKeyByEmail(email, ip,
+						RegistrationManager.REGISTRATION, registrationModule.getValidUntilHoursGui());
+			}
+			myContent.contextPut("regKey", tk.getRegistrationKey());
+			
+			String link = serverpath + "/dmz/registration/index.html?key=" + tk.getRegistrationKey() + "&language=" + i18nModule.getLocaleKey(ureq.getLocale());
+			String[] bodyAttrs = new String[]{
+				serverpath,										//0
+				tk.getRegistrationKey(),						//1
+				i18nModule.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);
+			}
+			sendMessage(email, translate("reg.subject"), body);
+		} else {
+			// if users with this email address exists, they are informed.
+			List<Identity> identities = userManager.findIdentitiesByEmail(Collections.singletonList(email));
+			for (Identity identity: identities) {
+				String subject = translate("login.subject");
+				String body = translate("login.body", identity.getName()) + SEPARATOR + translate("reg.wherefrom", whereFromAttrs);
+				sendMessage(email, subject, body);
+			}
+		}
+		return isMailSent;
+	}
+	
+	private boolean sendMessage(String email, String subject, String body) {
+		boolean isMailSent = false;
+		
+		try {
+			MailBundle bundle = new MailBundle();
+			bundle.setTo(email);
+			bundle.setContent(subject, body);
+			boolean htmlBody = StringHelper.isHtml(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
+		}
+		
+		return isMailSent;
+	}
+	
+	private void displayRegistrationForm2(UserRequest ureq) {
+		wizInfoController.setCurStep(4);
+		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<>();
+		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", getWindowControl());
+				}
+			} else {
+				Identity identity = securityManager.findIdentityByName(proposedUsername);
+				if(identity != null) {
+					if(interceptor.allowChangeOfUsername()) {
+						createRegForm2(ureq, proposedUsername, true, false);
+					} else {
+						myContent = setErrorPage("reg.error.user_in_use", getWindowControl());
+					}
+				} else {
+					createRegForm2(ureq, proposedUsername, false, !interceptor.allowChangeOfUsername());
+				}
+			}
+		} else {
+			createRegForm2(ureq, null, false, false);
+		}
 	}
 
 	/**
@@ -439,7 +454,7 @@ public class RegistrationController extends BasicController implements Activatea
 		// show last screen
 		VelocityContainer finishVC = createVelocityContainer("finish");
 		
-		List<UserPropertyHandler> userPropertyHandlers = UserManager.getInstance().getUserPropertyHandlersFor(RegistrationForm2.USERPROPERTIES_FORM_IDENTIFIER, false);
+		List<UserPropertyHandler> userPropertyHandlers = userManager.getUserPropertyHandlersFor(RegistrationForm2.USERPROPERTIES_FORM_IDENTIFIER, false);
 		finishVC.contextPut("userPropertyHandlers", userPropertyHandlers);
 		finishVC.contextPut("user", persitedIdentity.getUser());
 		finishVC.contextPut("locale", getLocale());
@@ -461,8 +476,7 @@ public class RegistrationController extends BasicController implements Activatea
 	 */
 	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());
+		User volatileUser = userManager.createUser(registrationForm.getFirstName(), registrationForm.getLastName(), tempKey.getEmailAddress());
 		// set user configured language
 		Preferences preferences = volatileUser.getPreferences();
 
@@ -477,7 +491,7 @@ public class RegistrationController extends BasicController implements Activatea
 			return null;
 		} else {
 			// update other user properties from form
-			List<UserPropertyHandler> userPropertyHandlers = um.getUserPropertyHandlersFor(RegistrationForm2.USERPROPERTIES_FORM_IDENTIFIER, false);
+			List<UserPropertyHandler> userPropertyHandlers = userManager.getUserPropertyHandlersFor(RegistrationForm2.USERPROPERTIES_FORM_IDENTIFIER, false);
 			User persistedUser = persistedIdentity.getUser();
 			
 			//add eventually static value
@@ -501,7 +515,7 @@ public class RegistrationController extends BasicController implements Activatea
 				userPropertyHandler.updateUserFromFormItem(persistedUser, fi);
 			}
 			// persist changes in db
-			um.updateUserFromIdentity(persistedIdentity);
+			userManager.updateUserFromIdentity(persistedIdentity);
 			// send notification mail to sys admin
 			String notiEmail = CoreSpringFactory.getImpl(RegistrationModule.class).getRegistrationNotificationEmail();
 			if (notiEmail != null) {
-- 
GitLab