From 27eec418bf81289684ebeec9ebc9756fc84f0227 Mon Sep 17 00:00:00 2001
From: uhensler <urs.hensler@frentix.com>
Date: Fri, 13 Sep 2019 15:04:38 +0200
Subject: [PATCH] OO-4168: Participants are only allowed to send e-mails to
 coaches/owners

...but not to the other participants
---
 .../org/olat/core/util/mail/ContactList.java  |  4 --
 .../course/nodes/co/COToolController.java     | 45 +++++++++++++------
 .../nodes/co/COToolRecipientsController.java  | 33 +++++++++++++-
 .../nodes/co/_i18n/LocalStrings_de.properties |  4 +-
 4 files changed, 64 insertions(+), 22 deletions(-)

diff --git a/src/main/java/org/olat/core/util/mail/ContactList.java b/src/main/java/org/olat/core/util/mail/ContactList.java
index a6d532605c2..b3fd4f55be9 100644
--- a/src/main/java/org/olat/core/util/mail/ContactList.java
+++ b/src/main/java/org/olat/core/util/mail/ContactList.java
@@ -66,10 +66,6 @@ public class ContactList {
 	//container for addresses contributed as identites
 	private Map<Long, Identity> identiEmails = new HashMap<>();
 	private boolean emailPrioInstitutional = false;
-
-	public ContactList() {
-		//
-	}
 	
 	/**
 	 * A ContacList must have at least a name != null, matching ^[^;,:]*$
diff --git a/src/main/java/org/olat/course/nodes/co/COToolController.java b/src/main/java/org/olat/course/nodes/co/COToolController.java
index 60784427c9e..46188289ff2 100644
--- a/src/main/java/org/olat/course/nodes/co/COToolController.java
+++ b/src/main/java/org/olat/course/nodes/co/COToolController.java
@@ -36,11 +36,11 @@ import org.olat.core.id.Identity;
 import org.olat.core.util.mail.ContactList;
 import org.olat.core.util.mail.ContactMessage;
 import org.olat.course.groupsandrights.CourseGroupManager;
+import org.olat.course.nodes.co.COToolRecipientsController.Config;
 import org.olat.course.nodes.co.COToolRecipientsController.Recipients;
 import org.olat.course.nodes.members.MembersHelpers;
 import org.olat.course.run.userview.UserCourseEnvironment;
 import org.olat.modules.co.ContactFormController;
-import org.olat.repository.RepositoryEntry;
 import org.olat.repository.RepositoryService;
 import org.springframework.beans.factory.annotation.Autowired;
 
@@ -52,44 +52,61 @@ import org.springframework.beans.factory.annotation.Autowired;
  */
 public class COToolController extends BasicController {
 
+	private static final Recipients[] PARTICIPANT_RECIPIENTS = new Recipients[] {Recipients.owners, Recipients.coaches};
+
 	private final ContactFormController emailCtrl;
 	private final COToolRecipientsController recipientCtrl;
 	
-	private final RepositoryEntry courseRepositoryEntry;
 	private final CourseGroupManager courseGroupManager;
 
 	@Autowired
 	private RepositoryService repositoryService;
 
+	private VelocityContainer mainVC;
+
 	public COToolController(UserRequest ureq, WindowControl wControl, UserCourseEnvironment userCourseEnv) {
 		super(ureq, wControl);
-		courseGroupManager = userCourseEnv.getCourseEnvironment().getCourseGroupManager();
-		this.courseRepositoryEntry = userCourseEnv.getCourseEnvironment().getCourseGroupManager().getCourseEntry();
+		this.courseGroupManager = userCourseEnv.getCourseEnvironment().getCourseGroupManager();
 		
-		VelocityContainer mainVC = createVelocityContainer("tool");
+		mainVC = createVelocityContainer("tool");
 		
-		recipientCtrl = new COToolRecipientsController(ureq, wControl);
+		Config recipientCtrlConfig = createRecipientCtrlConfigs(userCourseEnv);
+		recipientCtrl = new COToolRecipientsController(ureq, wControl, recipientCtrlConfig);
 		listenTo(recipientCtrl);
 		mainVC.put("recipients", recipientCtrl.getInitialComponent());
 		
 		ContactMessage cmsg = new ContactMessage(getIdentity());
-		Set<Recipients> recipients = recipientCtrl.getSelectedRecipients();
-		for (ContactList recipientList : getRecipientsLists(recipients)) {
-			cmsg.addEmailTo(recipientList);
-		}
+		// Empty contact lists are rejected by the constructor of the ContactMessage.
+		// So we use a dummy list to have at least one recipient and set the real
+		// contacts lists in a second step.
+		ContactList dummyList = new ContactList("dummy");
+		dummyList.add(getIdentity());
+		cmsg.addEmailTo(dummyList);
 		emailCtrl = new ContactFormController(ureq, getWindowControl(), false, false, false, cmsg, null);
 		emailCtrl.setContactFormTitle(null);
+		Set<Recipients> recipients = recipientCtrl.getSelectedRecipients();
+		doSetReciepients(recipients);
 		listenTo(emailCtrl);
 		mainVC.put("email", emailCtrl.getInitialComponent());
 		
 		putInitialPanel(mainVC);
 	}
 
+	private Config createRecipientCtrlConfigs(UserCourseEnvironment userCourseEnv) {
+		if (userCourseEnv.isAdmin() || userCourseEnv.isCoach()) {
+			return new Config(true, Recipients.values());
+		}
+		return new Config(false, PARTICIPANT_RECIPIENTS);
+	}
+
 	@Override
 	protected void event(UserRequest ureq, Controller source, Event event) {
 		if (source == recipientCtrl && event == FormEvent.CHANGED_EVENT) {
 			Set<Recipients> recipients = recipientCtrl.getSelectedRecipients();
 			doSetReciepients(recipients);
+		} else if (source == emailCtrl && (event == Event.DONE_EVENT || event == Event.FAILED_EVENT)) {
+			recipientCtrl.setReadOnly();
+			mainVC.setDirty(true);
 		}
 		super.event(ureq, source, event);
 	}
@@ -114,21 +131,21 @@ public class COToolController extends BasicController {
 	}
 	
 	private ContactList getOwnersContactList() {
-		ContactList cl = new ContactList(translate("form.message.chckbx.owners"));
-		List<Identity> identities = MembersHelpers.getOwners(repositoryService, courseRepositoryEntry);
+		ContactList cl = new ContactList(translate("tool.recipients.owners"));
+		List<Identity> identities = MembersHelpers.getOwners(repositoryService, courseGroupManager.getCourseEntry());
 		cl.addAllIdentites(identities);
 		return cl;
 	}
 	
 	private ContactList getCoachesContactList() {
-		ContactList cl = new ContactList(translate("form.message.chckbx.coaches"));
+		ContactList cl = new ContactList(translate("tool.recipients.coaches"));
 		Collection<Identity> identities = courseGroupManager.getCoaches();
 		cl.addAllIdentites(identities);
 		return cl;
 	}
 	
 	private ContactList getParticipantsContactList() {
-		ContactList cl = new ContactList(translate("form.message.chckbx.partips"));
+		ContactList cl = new ContactList(translate("tool.recipients.participants"));
 		Collection<Identity> identities = courseGroupManager.getParticipants();
 		cl.addAllIdentites(identities);
 		return cl;
diff --git a/src/main/java/org/olat/course/nodes/co/COToolRecipientsController.java b/src/main/java/org/olat/course/nodes/co/COToolRecipientsController.java
index 469f1be5299..cc49a7a1fbd 100644
--- a/src/main/java/org/olat/course/nodes/co/COToolRecipientsController.java
+++ b/src/main/java/org/olat/course/nodes/co/COToolRecipientsController.java
@@ -60,9 +60,12 @@ public class COToolRecipientsController extends FormBasicController {
 	}
 	
 	private MultipleSelectionElement recipientsEl;
+
+	private final Config config;
 	
-	public COToolRecipientsController(UserRequest ureq, WindowControl wControl) {
+	public COToolRecipientsController(UserRequest ureq, WindowControl wControl, Config config) {
 		super(ureq, wControl);
+		this.config = config;
 		initForm(ureq);
 	}
 	
@@ -83,10 +86,17 @@ public class COToolRecipientsController extends FormBasicController {
 			recipientKV.add(entry(recipient.name(), translate(recipient.getI18nKey())));
 		}
 		recipientsEl = uifactory.addCheckboxesHorizontal("tool.recipients", formLayout, recipientKV.keys(), recipientKV.values());
-		recipientsEl.select(Recipients.owners.name(), true);
+		recipientsEl.setEnabled(config.isRecipientsEnabled());
+		for (Recipients recipients : config.getInitialRecipients()) {
+			recipientsEl.select(recipients.name(), true);
+		}
 		recipientsEl.addActionListener(FormEvent.ONCHANGE);
 	}
 
+	public void setReadOnly() {
+		recipientsEl.setEnabled(false);
+	}
+
 	@Override
 	protected void formInnerEvent(UserRequest ureq, FormItem source, FormEvent event) {
 		if (source == recipientsEl) {
@@ -120,5 +130,24 @@ public class COToolRecipientsController extends FormBasicController {
 	protected void doDispose() {
 		//
 	}
+	
+	static class Config {
+		
+		private final boolean recipientsEnabled;
+		private final Recipients[] initialRecipients;
+		
+		Config(boolean recipientsEnabled, Recipients[] recipients) {
+			this.recipientsEnabled = recipientsEnabled;
+			this.initialRecipients = recipients;
+		}
+
+		private boolean isRecipientsEnabled() {
+			return recipientsEnabled;
+		}
+
+		private Recipients[] getInitialRecipients() {
+			return initialRecipients;
+		}
+	}
 
 }
diff --git a/src/main/java/org/olat/course/nodes/co/_i18n/LocalStrings_de.properties b/src/main/java/org/olat/course/nodes/co/_i18n/LocalStrings_de.properties
index 3444376085c..d5c79f69f59 100755
--- a/src/main/java/org/olat/course/nodes/co/_i18n/LocalStrings_de.properties
+++ b/src/main/java/org/olat/course/nodes/co/_i18n/LocalStrings_de.properties
@@ -46,7 +46,7 @@ popupchoosegroups=Gruppen aus Gruppenmanagement w\u00E4hlen
 recipients=Externe Empf\u00E4nger
 tool.recipients=Empf\u00E4nger
 tool.recipients.coaches=Betreuer
-tool.recipients.participants=Kursbesitzer
+tool.recipients.participants=Teilnehmer
 tool.recipients.mandatory=Sie m\u00FCssen mindestens eine Option ausw\u00E4hlen.
-tool.recipients.owners=Teilnehmer
+tool.recipients.owners=Kursbesitzer
 tool.title=E-Mail
-- 
GitLab