You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openmeetings.apache.org by so...@apache.org on 2020/10/17 04:05:55 UTC

[openmeetings] branch master updated: [OPENMEETINGS-2481] cancelation email works as expected

This is an automated email from the ASF dual-hosted git repository.

solomax pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/openmeetings.git


The following commit(s) were added to refs/heads/master by this push:
     new adabede  [OPENMEETINGS-2481] cancelation email works as expected
adabede is described below

commit adabede9e5f42fec4f804929b682a675cae71bad
Author: Maxim Solodovnik <so...@gmail.com>
AuthorDate: Sat Oct 17 11:05:39 2020 +0700

    [OPENMEETINGS-2481] cancelation email works as expected
---
 .../apache/openmeetings/core/mail/MailHandler.java |  2 +-
 .../db/dao/calendar/AppointmentDao.java            | 20 +++++++----
 .../db/dao/room/IInvitationManager.java            |  2 +-
 .../openmeetings/db/entity/basic/MailMessage.java  | 27 +++++++++++++--
 .../service/room/InvitationManager.java            | 19 +++++-----
 .../openmeetings/util/OpenmeetingsVariables.java   |  2 +-
 .../apache/openmeetings/util/mail/IcalHandler.java | 40 +++++++++++++++++++---
 7 files changed, 86 insertions(+), 26 deletions(-)

diff --git a/openmeetings-core/src/main/java/org/apache/openmeetings/core/mail/MailHandler.java b/openmeetings-core/src/main/java/org/apache/openmeetings/core/mail/MailHandler.java
index 3fbcc18..5e42772 100644
--- a/openmeetings-core/src/main/java/org/apache/openmeetings/core/mail/MailHandler.java
+++ b/openmeetings-core/src/main/java/org/apache/openmeetings/core/mail/MailHandler.java
@@ -98,7 +98,7 @@ public class MailHandler {
 		BodyPart iCalContent = new MimeBodyPart();
 		iCalContent.addHeader("content-class", "urn:content-classes:calendarmessage");
 		iCalContent.setDataHandler(new DataHandler(new ByteArrayDataSource(new ByteArrayInputStream(m.getIcs()),
-				"text/calendar; charset=UTF-8; method=REQUEST")));
+				"text/calendar; charset=UTF-8; method=" + m.getIcsMethod())));
 		multiBody.addBodyPart(iCalContent);
 		BodyPart body = new MimeBodyPart();
 		body.setContent(multiBody);
diff --git a/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/calendar/AppointmentDao.java b/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/calendar/AppointmentDao.java
index a4b7c8d..988bc2e 100644
--- a/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/calendar/AppointmentDao.java
+++ b/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/calendar/AppointmentDao.java
@@ -34,10 +34,12 @@ import javax.persistence.PersistenceContext;
 import javax.persistence.Query;
 import javax.persistence.TypedQuery;
 
+import org.apache.commons.lang3.StringUtils;
 import org.apache.openmeetings.db.dao.IDataProviderDao;
 import org.apache.openmeetings.db.dao.basic.ConfigurationDao;
 import org.apache.openmeetings.db.dao.room.IInvitationManager;
 import org.apache.openmeetings.db.dao.room.RoomDao;
+import org.apache.openmeetings.db.dto.calendar.AppointmentDTO;
 import org.apache.openmeetings.db.entity.calendar.Appointment;
 import org.apache.openmeetings.db.entity.calendar.Appointment.Reminder;
 import org.apache.openmeetings.db.entity.calendar.MeetingMember;
@@ -100,10 +102,13 @@ public class AppointmentDao implements IDataProviderDao<Appointment>{
 		}
 		a.setRoom(roomDao.update(r, userId));
 		final boolean newApp = a.getId() == null;
-		Appointment a0 = null;
+		AppointmentDTO a0 = null;
 		Set<Long> mmIds = Set.of();
 		if (sendmails && !newApp) {
-			a0 = get(a.getId());
+			Appointment prev = get(a.getId());
+			if (prev != null) {
+				a0 = new AppointmentDTO(prev);
+			}
 			mmIds = meetingMemberDao.getMeetingMemberIdsByAppointment(a.getId());
 		}
 		if (newApp) {
@@ -116,11 +121,12 @@ public class AppointmentDao implements IDataProviderDao<Appointment>{
 		}
 		if (sendmails) {
 			// update meeting members
-			boolean sendMail = a0 == null || !a0.getTitle().equals(a.getTitle()) ||
-					!(a0.getDescription() != null ? a0.getDescription().equals(a.getDescription()) : true) ||
-					!(a0.getLocation() != null ? a0.getLocation().equals(a.getLocation()) : true) ||
-					!a0.getStart().equals(a.getStart()) ||
-					!a0.getEnd().equals(a.getEnd());
+			boolean sendMail = a0 == null
+					|| !StringUtils.equals(a0.getTitle(), a.getTitle())
+					|| !StringUtils.equals(a0.getDescription(), a.getDescription())
+					|| !StringUtils.equals(a0.getLocation(), a.getLocation())
+					|| !a0.getStart().getTime().equals(a.getStart())
+					|| !a0.getEnd().getTime().equals(a.getEnd());
 			List<MeetingMember> mmList = a.getMeetingMembers();
 			if (mmList != null){
 				for (MeetingMember mm : mmList) {
diff --git a/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/room/IInvitationManager.java b/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/room/IInvitationManager.java
index 6b2dc50..2fd0c34 100644
--- a/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/room/IInvitationManager.java
+++ b/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/room/IInvitationManager.java
@@ -43,5 +43,5 @@ public interface IInvitationManager {
 			User createdBy, Long languageId, Date gmtTimeStart, Date gmtTimeEnd
 			, Appointment appointment);
 
-	void sendInvitationLink(Invitation i, MessageType type, String subject, String message, boolean ical, String baseUrl) throws Exception;
+	void sendInvitationLink(Invitation i, MessageType type, String subject, String message, boolean ical, String baseUrl);
 }
diff --git a/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/basic/MailMessage.java b/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/basic/MailMessage.java
index 1e2e2b8..9478061 100644
--- a/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/basic/MailMessage.java
+++ b/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/basic/MailMessage.java
@@ -18,6 +18,8 @@
  */
 package org.apache.openmeetings.db.entity.basic;
 
+import java.io.IOException;
+
 import javax.persistence.Column;
 import javax.persistence.Entity;
 import javax.persistence.EnumType;
@@ -30,6 +32,12 @@ import javax.persistence.NamedQuery;
 import javax.persistence.Table;
 
 import org.apache.openmeetings.db.entity.HistoricalEntity;
+import org.apache.openmeetings.util.mail.IcalHandler;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import net.fortuna.ical4j.model.property.Method;
+import net.fortuna.ical4j.validate.ValidationException;
 
 @Entity
 @NamedQuery(name = "getMailMessageById", query = "SELECT m FROM MailMessage m WHERE m.id = :id")
@@ -42,6 +50,7 @@ import org.apache.openmeetings.db.entity.HistoricalEntity;
 @Table(name = "email_queue")
 public class MailMessage extends HistoricalEntity {
 	private static final long serialVersionUID = 1L;
+	private static final Logger log = LoggerFactory.getLogger(MailMessage.class);
 
 	public enum Status {
 		NONE, SENDING, ERROR, DONE
@@ -70,6 +79,9 @@ public class MailMessage extends HistoricalEntity {
 	@Column(name = "ics")
 	private byte[] ics;
 
+	@Column(name = "ics_method")
+	private String icsMethod;
+
 	@Column(name = "status", nullable = false)
 	@Enumerated(EnumType.STRING)
 	private Status status = Status.NONE;
@@ -89,12 +101,19 @@ public class MailMessage extends HistoricalEntity {
 		this(recipients, replyTo, subject, body, null);
 	}
 
-	public MailMessage(String recipients, String replyTo, String subject, String body, byte[] ics) {
+	public MailMessage(String recipients, String replyTo, String subject, String body, IcalHandler ical) {
 		this.recipients = recipients;
 		this.replyTo = replyTo;
 		this.subject = subject;
 		this.body = body;
-		this.ics = ics;
+		if (ical != null) {
+			this.icsMethod = ical.getMethod().getValue();
+			try {
+				this.ics = ical.toByteArray();
+			} catch (ValidationException|IOException e) {
+				log.error("Unexpected error while getting ICS", e);
+			}
+		}
 	}
 
 	@Override
@@ -170,4 +189,8 @@ public class MailMessage extends HistoricalEntity {
 	public void setLastError(String lastError) {
 		this.lastError = lastError;
 	}
+
+	public String getIcsMethod() {
+		return icsMethod == null ? Method.REQUEST.getValue() : icsMethod;
+	}
 }
diff --git a/openmeetings-service/src/main/java/org/apache/openmeetings/service/room/InvitationManager.java b/openmeetings-service/src/main/java/org/apache/openmeetings/service/room/InvitationManager.java
index 5a36f1f..34ae0bc 100644
--- a/openmeetings-service/src/main/java/org/apache/openmeetings/service/room/InvitationManager.java
+++ b/openmeetings-service/src/main/java/org/apache/openmeetings/service/room/InvitationManager.java
@@ -73,11 +73,10 @@ public class InvitationManager implements IInvitationManager {
 	 * @param mm - attendee being processed
 	 * @param type - type of the message
 	 * @param ical - should iCal appoinment be attached to message
-	 * @throws Exception in case of error happens during sending
 	 */
-	private void sendInvitionLink(Appointment a, MeetingMember mm, MessageType type, boolean ical) throws Exception	{
+	private void sendInvitionLink(Appointment a, MeetingMember mm, MessageType type, boolean ical) {
 		User owner = a.getOwner();
-		String invitorName = owner.getFirstname() + " " + owner.getLastname();
+		String invitorName = owner.getDisplayName();
 		TimeZone tz = getTimeZone(mm.getUser());
 		SubjectEmailTemplate t;
 		switch (type) {
@@ -96,7 +95,7 @@ public class InvitationManager implements IInvitationManager {
 	}
 
 	@Override
-	public void sendInvitationLink(Invitation i, MessageType type, String subject, String message, boolean ical, String baseUrl) throws Exception {
+	public void sendInvitationLink(Invitation i, MessageType type, String subject, String message, boolean ical, String baseUrl) {
 		final String invitationLink;
 		if (type != MessageType.CANCEL) {
 			IApplication app = ensureApplication(1L);
@@ -120,16 +119,18 @@ public class InvitationManager implements IInvitationManager {
 			}
 			IcalHandler handler = new IcalHandler(MessageType.CANCEL == type ? IcalHandler.ICAL_METHOD_CANCEL : IcalHandler.ICAL_METHOD_REQUEST)
 					.createVEvent(getTimeZone(owner).getID(), a.getStart(), a.getEnd(), a.getTitle())
-					.setLocation(a.getLocation())
-					.setDescription(desc)
+					.addOrganizer(replyToEmail, owner.getDisplayName())
 					.setUid(a.getIcalId())
+					.addAttendee(email, i.getInvitee().getDisplayName(), isOwner)
+					.setCreated(a.getInserted())
+					.setDescription(desc)
+					.setModified(a.getUpdated())
+					.setLocation(a.getLocation())
 					.setSequence(0)
-					.addOrganizer(replyToEmail, owner.getDisplayName())
-					.addAttendee(email, i.getInvitee().getLogin(), isOwner)
 					.build();
 
 			log.debug(handler.toString());
-			mailHandler.send(new MailMessage(email, replyToEmail, subject, template, handler.toByteArray()));
+			mailHandler.send(new MailMessage(email, replyToEmail, subject, template, handler));
 		} else {
 			mailHandler.send(email, replyToEmail, subject, template);
 		}
diff --git a/openmeetings-util/src/main/java/org/apache/openmeetings/util/OpenmeetingsVariables.java b/openmeetings-util/src/main/java/org/apache/openmeetings/util/OpenmeetingsVariables.java
index 0b9fc15..d08d9b7 100644
--- a/openmeetings-util/src/main/java/org/apache/openmeetings/util/OpenmeetingsVariables.java
+++ b/openmeetings-util/src/main/java/org/apache/openmeetings/util/OpenmeetingsVariables.java
@@ -119,7 +119,7 @@ public class OpenmeetingsVariables {
 	public static final String DEFAULT_APP_NAME = "OpenMeetings";
 	public static final String DEFAULT_CONTEXT_NAME = "openmeetings";
 	public static final long DEFAULT_MAX_UPLOAD_SIZE = 100 * 1024 * 1024L; // 100MB
-	public static final String DEFAULT_BASE_URL = "http://localhost:5080/openmeetings/";
+	public static final String DEFAULT_BASE_URL = "https://localhost:5443/openmeetings/";
 	public static final String DEFAULT_SIP_CONTEXT = "rooms";
 	public static final String DEFAULT_CSP_FONT = "https://fonts.gstatic.com";
 	public static final String DEFAULT_CSP_STYLE = "https://fonts.googleapis.com/css";
diff --git a/openmeetings-util/src/main/java/org/apache/openmeetings/util/mail/IcalHandler.java b/openmeetings-util/src/main/java/org/apache/openmeetings/util/mail/IcalHandler.java
index ff9e558..8314358 100644
--- a/openmeetings-util/src/main/java/org/apache/openmeetings/util/mail/IcalHandler.java
+++ b/openmeetings-util/src/main/java/org/apache/openmeetings/util/mail/IcalHandler.java
@@ -22,6 +22,7 @@ import static org.apache.openmeetings.util.mail.MailUtil.MAILTO;
 
 import java.io.ByteArrayOutputStream;
 import java.io.FileOutputStream;
+import java.io.IOException;
 import java.net.URI;
 import java.util.Date;
 import java.util.NoSuchElementException;
@@ -37,11 +38,16 @@ import net.fortuna.ical4j.model.TimeZoneRegistry;
 import net.fortuna.ical4j.model.TimeZoneRegistryFactory;
 import net.fortuna.ical4j.model.component.VEvent;
 import net.fortuna.ical4j.model.parameter.Cn;
+import net.fortuna.ical4j.model.parameter.CuType;
 import net.fortuna.ical4j.model.parameter.PartStat;
 import net.fortuna.ical4j.model.parameter.Role;
+import net.fortuna.ical4j.model.parameter.Rsvp;
+import net.fortuna.ical4j.model.parameter.XParameter;
 import net.fortuna.ical4j.model.property.Attendee;
 import net.fortuna.ical4j.model.property.CalScale;
+import net.fortuna.ical4j.model.property.Created;
 import net.fortuna.ical4j.model.property.Description;
+import net.fortuna.ical4j.model.property.LastModified;
 import net.fortuna.ical4j.model.property.Location;
 import net.fortuna.ical4j.model.property.Method;
 import net.fortuna.ical4j.model.property.Organizer;
@@ -51,6 +57,7 @@ import net.fortuna.ical4j.model.property.Status;
 import net.fortuna.ical4j.model.property.Transp;
 import net.fortuna.ical4j.model.property.Uid;
 import net.fortuna.ical4j.model.property.Version;
+import net.fortuna.ical4j.validate.ValidationException;
 
 /**
  *
@@ -86,7 +93,7 @@ public class IcalHandler {
 		log.debug("Icalhandler method type : {}", method);
 
 		icsCalendar = new Calendar();
-		icsCalendar.getProperties().add(new ProdId("-//Events Calendar//iCal4j 1.0//EN"));
+		icsCalendar.getProperties().add(new ProdId("-//Apache Openmeetings//OM Calendar//EN"));
 		icsCalendar.getProperties().add(Version.VERSION_2_0);
 		icsCalendar.getProperties().add(CalScale.GREGORIAN);
 		icsCalendar.getProperties().add(method);
@@ -106,11 +113,21 @@ public class IcalHandler {
 		end.setTimeZone(timeZone);
 
 		meeting = new VEvent(start, end, name);
-		meeting.getProperties().add(Method.CANCEL == method ? Transp.TRANSPARENT : Transp.OPAQUE);
+		meeting.getProperties().add(Transp.OPAQUE);
 		meeting.getProperties().add(Status.VEVENT_CONFIRMED);
 		return this;
 	}
 
+	public IcalHandler setCreated(Date date) {
+		meeting.getProperties().add(new Created(new DateTime(date)));
+		return this;
+	}
+
+	public IcalHandler setModified(Date date) {
+		meeting.getProperties().add(new LastModified(new DateTime(date == null ? new Date() : date)));
+		return this;
+	}
+
 	public IcalHandler setDescription(String description) {
 		meeting.getProperties().add(new Description(description));
 		return this;
@@ -144,8 +161,15 @@ public class IcalHandler {
 
 	public IcalHandler addAttendee(String email, String display, boolean chair) {
 		Attendee uno = new Attendee(URI.create(MAILTO + email));
+		uno.getParameters().add(CuType.INDIVIDUAL);
 		uno.getParameters().add(chair ? Role.CHAIR : Role.REQ_PARTICIPANT);
-		uno.getParameters().add(Method.CANCEL == method ? PartStat.DECLINED : PartStat.ACCEPTED);
+		if (Method.CANCEL == method) {
+			uno.getParameters().add(PartStat.DECLINED);
+		} else {
+			uno.getParameters().add(chair ? PartStat.ACCEPTED : PartStat.NEEDS_ACTION);
+			uno.getParameters().add(Rsvp.TRUE);
+		}
+		uno.getParameters().add(new XParameter("X-NUM-GUESTS", "0"));
 		uno.getParameters().add(new Cn(display));
 		meeting.getProperties().add(uno);
 		return this;
@@ -157,6 +181,10 @@ public class IcalHandler {
 		return this;
 	}
 
+	public Method getMethod() {
+		return method;
+	}
+
 	/**
 	 * Write iCal to File
 	 *
@@ -179,10 +207,12 @@ public class IcalHandler {
 	 * Get IcalBody as ByteArray
 	 *
 	 * @return - calendar in ICS format as byte[]
-	 * @throws Exception
+	 * @throws IOException
 	 *             - in case of error during writing to byte array
+	 * @throws ValidationException
+	 *             - in case of invalid calendar properties
 	 */
-	public byte[] toByteArray() throws Exception {
+	public byte[] toByteArray() throws ValidationException, IOException {
 		ByteArrayOutputStream bout = new ByteArrayOutputStream();
 		CalendarOutputter outputter = new CalendarOutputter();
 		outputter.output(icsCalendar, bout);