From 13a748a93d59a088b3942051aa16e44c3f9e3840 Mon Sep 17 00:00:00 2001
From: srosse <stephane.rosse@frentix.com>
Date: Fri, 14 Dec 2018 08:37:17 +0100
Subject: [PATCH] OO-3721: add user with self-registration to additional
 organisation

Add a second configurable organisation where the user lands after
self-registration
---
 .../RegistrationAdminController.java          | 46 ++++++++++++-
 .../registration/RegistrationManager.java     | 65 ++++++++++++-------
 .../olat/registration/RegistrationModule.java | 16 +++++
 .../_i18n/LocalStrings_de.properties          |  1 +
 .../_i18n/LocalStrings_en.properties          |  1 +
 5 files changed, 102 insertions(+), 27 deletions(-)

diff --git a/src/main/java/org/olat/registration/RegistrationAdminController.java b/src/main/java/org/olat/registration/RegistrationAdminController.java
index c2b22f160ca..54fabbedc66 100644
--- a/src/main/java/org/olat/registration/RegistrationAdminController.java
+++ b/src/main/java/org/olat/registration/RegistrationAdminController.java
@@ -23,6 +23,8 @@ package org.olat.registration;
 import java.util.ArrayList;
 import java.util.List;
 
+import org.olat.basesecurity.OrganisationService;
+import org.olat.basesecurity.OrganisationStatus;
 import org.olat.core.gui.UserRequest;
 import org.olat.core.gui.components.form.ValidationError;
 import org.olat.core.gui.components.form.flexible.FormItem;
@@ -37,6 +39,7 @@ import org.olat.core.gui.control.Controller;
 import org.olat.core.gui.control.WindowControl;
 import org.olat.core.gui.translator.Translator;
 import org.olat.core.helpers.Settings;
+import org.olat.core.id.Organisation;
 import org.olat.core.util.StringHelper;
 import org.olat.user.UserPropertiesConfig;
 import org.olat.user.propertyhandlers.Generic127CharTextPropertyHandler;
@@ -49,7 +52,8 @@ import org.springframework.beans.factory.annotation.Autowired;
  * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
  */
 public class RegistrationAdminController extends FormBasicController {
-	
+
+	private SingleSelection organisationsEl;
 	private MultipleSelectionElement registrationElement;
 	private MultipleSelectionElement registrationLinkElement;
 	private MultipleSelectionElement registrationLoginElement;
@@ -72,6 +76,8 @@ public class RegistrationAdminController extends FormBasicController {
 	@Autowired
 	private RegistrationManager registrationManager;
 	@Autowired
+	private OrganisationService organisationService;
+	@Autowired
 	private UserPropertiesConfig userPropertiesConfig;
 	private final Translator userPropTranslator;
 	
@@ -125,6 +131,8 @@ public class RegistrationAdminController extends FormBasicController {
 		registrationLinkElement.addActionListener(FormEvent.ONCHANGE);
 		registrationLinkElement.select("on", registrationModule.isSelfRegistrationLinkEnabled());
 		
+		initOrganisationsEl(settingsContainer);
+		
 		validUntilGuiEl = uifactory.addTextElement("admin.registration.valid.until.gui", 20, registrationModule.getValidUntilHoursGui().toString(), settingsContainer);
 		validUntilGuiEl.setMandatory(true);
 		validUntilRestEl = uifactory.addTextElement("admin.registration.valid.until.rest", 20, registrationModule.getValidUntilHoursRest().toString(), settingsContainer);
@@ -183,6 +191,27 @@ public class RegistrationAdminController extends FormBasicController {
 		updateUI();	
 	}
 	
+	private void initOrganisationsEl(FormLayoutContainer formLayout) {
+		List<Organisation> organisations = organisationService.getOrganisations(OrganisationStatus.notDelete());
+		Organisation registrationOrg = registrationManager.getOrganisationForRegistration();
+		String registrationOrgKey = registrationOrg.getKey().toString();
+		
+		String[] theKeys = new String[organisations.size()];
+		String[] theValues = new String[organisations.size()];
+		for(int i=organisations.size(); i-->0; ) {
+			Organisation organisation = organisations.get(i);
+			theKeys[i] = organisation.getKey().toString();
+			theValues[i] = organisation.getDisplayName();
+		}
+		organisationsEl = uifactory.addDropdownSingleselect("organisations", "admin.registrationOrganisation", formLayout, theKeys, theValues);
+		for(int i=theKeys.length; i-->0; ) {
+			if(theKeys[i].equals(registrationOrgKey)) {
+				organisationsEl.select(theKeys[i], true);
+				break;
+			}
+		}
+	}
+	
 	@Override
 	protected void doDispose() {
 		//
@@ -212,6 +241,7 @@ public class RegistrationAdminController extends FormBasicController {
 		boolean  enableMain = registrationElement.isSelected(0);
 		registrationLinkElement.setEnabled(enableMain);
 		registrationLoginElement.setEnabled(enableMain);
+		organisationsEl.setEnabled(enableMain);
 		
 		boolean example = enableMain && registrationLinkElement.isSelected(0);
 		exampleElement.setVisible(example);
@@ -229,7 +259,7 @@ public class RegistrationAdminController extends FormBasicController {
 
 	@Override
 	protected boolean validateFormLogic(UserRequest ureq) {
-		boolean allOk = true;
+		boolean allOk = super.validateFormLogic(ureq);
 		
 		allOk &= validateInteger(validUntilGuiEl, 1);
 		allOk &= validateInteger(validUntilRestEl, 1);
@@ -265,8 +295,14 @@ public class RegistrationAdminController extends FormBasicController {
 				}
 			}
 		}
+		
+		organisationsEl.clearError();
+		if(organisationsEl.isEnabled() && !organisationsEl.isOneSelected()) {
+			organisationsEl.setErrorKey("form.legende.mandatory", null);
+			allOk &= false;
+		}
 
-		return allOk && super.validateFormLogic(ureq);
+		return allOk;
 	}
 	
 	private boolean validateInteger(TextElement el, int min) {
@@ -297,6 +333,10 @@ public class RegistrationAdminController extends FormBasicController {
 		registrationModule.setSelfRegistrationLinkEnabled(registrationLinkElement.isSelected(0));
 		registrationModule.setSelfRegistrationLoginEnabled(registrationLoginElement.isSelected(0));
 		
+		if(organisationsEl.isOneSelected()) {
+			registrationModule.setselfRegistrationOrganisationKey(organisationsEl.getSelectedKey());
+		}
+		
 		Integer validUntilHoursGui = Integer.parseInt(validUntilGuiEl.getValue());
 		registrationModule.setValidUntilHoursGui(validUntilHoursGui);
 		Integer validUntilHoursRest = Integer.parseInt(validUntilRestEl.getValue());
diff --git a/src/main/java/org/olat/registration/RegistrationManager.java b/src/main/java/org/olat/registration/RegistrationManager.java
index b5ccd2158e3..25c29416c1e 100644
--- a/src/main/java/org/olat/registration/RegistrationManager.java
+++ b/src/main/java/org/olat/registration/RegistrationManager.java
@@ -44,11 +44,15 @@ import javax.mail.internet.InternetAddress;
 import javax.mail.internet.MimeMessage;
 
 import org.olat.basesecurity.BaseSecurity;
+import org.olat.basesecurity.OrganisationRoles;
+import org.olat.basesecurity.OrganisationService;
+import org.olat.basesecurity.model.OrganisationRefImpl;
 import org.olat.core.CoreSpringFactory;
 import org.olat.core.commons.persistence.DB;
 import org.olat.core.gui.translator.Translator;
 import org.olat.core.helpers.Settings;
 import org.olat.core.id.Identity;
+import org.olat.core.id.Organisation;
 import org.olat.core.id.User;
 import org.olat.core.id.UserConstants;
 import org.olat.core.logging.OLog;
@@ -101,6 +105,21 @@ public class RegistrationManager implements UserDataDeletable, UserDataExportabl
 	private PropertyManager propertyManager;
 	@Autowired
 	private RegistrationModule registrationModule;
+	@Autowired
+	private OrganisationService organisationService;
+	
+	public Organisation getOrganisationForRegistration() {
+		String key = registrationModule.getSelfRegistrationOrganisationKey();
+		
+		Organisation organisation = null;
+		if(StringHelper.containsNonWhitespace(key) && !"default".equals(key) && StringHelper.isLong(key)) {
+			organisation = organisationService.getOrganisation(new OrganisationRefImpl(Long.valueOf(key)));
+		}
+		if(organisation == null) {
+			organisation = organisationService.getDefaultOrganisation();
+		}
+		return organisation;
+	}
 
 
 	public boolean validateEmailUsername(String email) {
@@ -165,17 +184,24 @@ public class RegistrationManager implements UserDataDeletable, UserDataExportabl
 	}
 
 	/**
-	 * creates a new user and identity with the data of the temporary key (email) and other
-	 * supplied user data (within myUser)
+	 * Creates a new user and identity with the data of the temporary key (email) and other
+	 * supplied user data (within myUser). The user will be added to the default organisation
+	 * and an other one if this is configured as such.
 	 * 
 	 * @param login Login name
 	 * @param pwd Password
-	 * @param myUser Not yet persisted user object
+	 * @param user Not yet persisted user object
 	 * @param tk Temporary key
 	 * @return the newly created subject or null
 	 */
-	public Identity createNewUserAndIdentityFromTemporaryKey(String login, String pwd, User myUser, TemporaryKey tk) {
-		Identity identity = securityManager.createAndPersistIdentityAndUserWithDefaultProviderAndUserGroup(login, null, pwd, myUser, null);
+	public Identity createNewUserAndIdentityFromTemporaryKey(String login, String pwd, User user, TemporaryKey tk) {
+		Organisation organisation = getOrganisationForRegistration();
+		Identity identity = securityManager
+				.createAndPersistIdentityAndUserWithDefaultProviderAndUserGroup(login, null, pwd, user, organisation);
+		if(!OrganisationService.DEFAULT_ORGANISATION_IDENTIFIER.equals(organisation.getIdentifier())) {
+			Organisation defOrganisation = organisationService.getDefaultOrganisation();
+			organisationService.addMember(defOrganisation, identity, OrganisationRoles.user);
+		}
 		if (identity == null) {
 			return null;
 		}
@@ -348,15 +374,10 @@ public class RegistrationManager implements UserDataDeletable, UserDataExportabl
 	 * @return the found temporary key or null if none is found
 	 */
 	public List<TemporaryKey> loadTemporaryKeyByAction(String action) {
-		List<TemporaryKey> tks = dbInstance.getCurrentEntityManager()
+		return dbInstance.getCurrentEntityManager()
 				.createNamedQuery("loadTemporaryKeyByRegAction", TemporaryKey.class)
 				.setParameter("action", action)
 				.getResultList();
-		if (tks.size() > 0) {
-			return tks;
-		} else {
-			return null;
-		}
 	}
 
 	/**
@@ -408,14 +429,12 @@ public class RegistrationManager implements UserDataDeletable, UserDataExportabl
 		
 		RegistrationManager rm = CoreSpringFactory.getImpl(RegistrationManager.class);
 		List<TemporaryKey> tk = rm.loadTemporaryKeyByAction(RegistrationManager.EMAIL_CHANGE);
-		if (tk != null) {
-			for (TemporaryKey temporaryKey : tk) {
-				XStream xml = XStreamHelper.createXStreamInstance();
-				@SuppressWarnings("unchecked")
-				Map<String, String> mails = (Map<String, String>) xml.fromXML(temporaryKey.getEmailAddress());
-				if (emailAddress.equalsIgnoreCase(mails.get("changedEMail"))) {
-					return true;
-				}
+		for (TemporaryKey temporaryKey : tk) {
+			XStream xml = XStreamHelper.createXStreamInstance();
+			@SuppressWarnings("unchecked")
+			Map<String, String> mails = (Map<String, String>) xml.fromXML(temporaryKey.getEmailAddress());
+			if (emailAddress.equalsIgnoreCase(mails.get("changedEMail"))) {
+				return true;
 			}
 		}
 		return isRegistrationPending(emailAddress);
@@ -423,11 +442,9 @@ public class RegistrationManager implements UserDataDeletable, UserDataExportabl
 
 	public boolean isRegistrationPending(String emailAddress) {
 		List<TemporaryKey> temporaryKeys = loadTemporaryKeyByAction(RegistrationManager.REGISTRATION);
-		if (temporaryKeys != null) {
-			for (TemporaryKey temporaryKey : temporaryKeys) {
-				if (emailAddress.equalsIgnoreCase(temporaryKey.getEmailAddress())) {
-					return true;
-				}
+		for (TemporaryKey temporaryKey : temporaryKeys) {
+			if (emailAddress.equalsIgnoreCase(temporaryKey.getEmailAddress())) {
+				return true;
 			}
 		}
 		return false;
diff --git a/src/main/java/org/olat/registration/RegistrationModule.java b/src/main/java/org/olat/registration/RegistrationModule.java
index 772b075ddd4..1d4300a9b5d 100644
--- a/src/main/java/org/olat/registration/RegistrationModule.java
+++ b/src/main/java/org/olat/registration/RegistrationModule.java
@@ -67,6 +67,8 @@ public class RegistrationModule extends AbstractSpringModule {
 	private Integer validUntilHoursGui;
 	@Value("${registration.valid.hours.rest}")
 	private Integer validUntilHoursRest;
+	@Value("${registration.organisation.key:default}")
+	private String selfRegistrationOrganisationKey;
 	
 	@Value("${registration.enableNotificationEmail}")
 	private boolean registrationNotificationEmailEnabled;
@@ -240,6 +242,15 @@ public class RegistrationModule extends AbstractSpringModule {
 		return additionaLinkText;
 	}
 
+	public String getSelfRegistrationOrganisationKey() {
+		return selfRegistrationOrganisationKey;
+	}
+	
+	public void setselfRegistrationOrganisationKey(String key) {
+		selfRegistrationOrganisationKey = key;
+		setStringProperty("registration.organisation.key", key, true);
+	}
+	
 	@Override
 	public void init() {
 		//registration enabled/disabled
@@ -259,6 +270,11 @@ public class RegistrationModule extends AbstractSpringModule {
 		if(StringHelper.containsNonWhitespace(loginEnabledObj)) {
 			selfRegistrationLoginEnabled = "true".equals(loginEnabledObj);
 		}
+
+		String organisationObj = getStringPropertyValue("registration.organisation.key", false);
+		if(StringHelper.containsNonWhitespace(organisationObj)) {
+			selfRegistrationOrganisationKey = organisationObj;
+		}
 		
 		int validUntilHoursGuiInt = getIntPropertyValue("registration.valid.hours.gui");
 		if (validUntilHoursGuiInt > 0) {
diff --git a/src/main/java/org/olat/registration/_i18n/LocalStrings_de.properties b/src/main/java/org/olat/registration/_i18n/LocalStrings_de.properties
index 22c97810824..9e9e76a7447 100644
--- a/src/main/java/org/olat/registration/_i18n/LocalStrings_de.properties
+++ b/src/main/java/org/olat/registration/_i18n/LocalStrings_de.properties
@@ -19,6 +19,7 @@ admin.registration.title=Selbstregistrierung
 admin.registration.valid.until.gui=G\u00fcltigkeitsdauer in Stunden (GUI)
 admin.registration.valid.until.rest=G\u00fcltigkeitsdauer in Stunden (REST)
 admin.registrationLinkExample=Beispielcode
+admin.registrationOrganisation=Zus\u00E4tzliche Organisation
 disclaimer.acknowledged=<b>Ich habe die Nutzungsbedingungen gelesen, verstanden und stimme ihnen zu.</b>
 disclaimer.additionalcheckbox=<b>Ich bin mit der Datenspeicherung einverstanden.</b>
 disclaimer.additionalcheckbox2=<b>Ich bin mit dem Haftungsausschluss einverstanden.</b>
diff --git a/src/main/java/org/olat/registration/_i18n/LocalStrings_en.properties b/src/main/java/org/olat/registration/_i18n/LocalStrings_en.properties
index 985bd3d9a7f..a51dbd82fce 100644
--- a/src/main/java/org/olat/registration/_i18n/LocalStrings_en.properties
+++ b/src/main/java/org/olat/registration/_i18n/LocalStrings_en.properties
@@ -19,6 +19,7 @@ admin.registration.title=Self-registration
 admin.registration.valid.until.gui=Validity period in hours (GUI)
 admin.registration.valid.until.rest=Validity period in hours (REST)
 admin.registrationLinkExample=Example code
+admin.registrationOrganisation=Additional organisation
 disclaimer.acknowledged=<b>I have read your terms of use, do understand and agree.</b>
 disclaimer.additionalcheckbox=<b>I agree on the terms of data storage</b>
 disclaimer.additionalcheckbox2=<b>I agree with the disclaimer</b>
-- 
GitLab