From 31a25dc6b0545eb9bcb215990c8a71f1792f61f8 Mon Sep 17 00:00:00 2001
From: Brad Rubenstein <brad@wbr.tech>
Date: Sat, 10 Nov 2018 02:35:42 -0800
Subject: [PATCH] Customize presentation of accept/decline buttons in iMip mail

Fix Issue #11230
Only present accept/decline button links in iMip mail for REQUEST, not CANCEL or others.

Fix Issue #12156
Implement config setting "dav.invitation_link_recipients", to control
which invitation recipients see accept/decline button links.  The
default, for public internet facing servers, is to always include
them.  For a server on a private intranet, this setting can be set
to the email addresses or email domains of users whose browsers can
access the nextcloud server referenced by those accept/decline
button links. It can also be set to "false" to exclude the links
from all requests.

Signed-off-by: Brad Rubenstein <brad@wbr.tech>
---
 apps/dav/lib/CalDAV/Schedule/IMipPlugin.php | 42 +++++++++++++++++++--
 config/config.sample.php                    | 27 +++++++++++++
 2 files changed, 65 insertions(+), 4 deletions(-)

diff --git a/apps/dav/lib/CalDAV/Schedule/IMipPlugin.php b/apps/dav/lib/CalDAV/Schedule/IMipPlugin.php
index 3ff3ed0c569..4375c081d55 100644
--- a/apps/dav/lib/CalDAV/Schedule/IMipPlugin.php
+++ b/apps/dav/lib/CalDAV/Schedule/IMipPlugin.php
@@ -144,11 +144,11 @@ class IMipPlugin extends SabreIMipPlugin {
 
 		$summary = $iTipMessage->message->VEVENT->SUMMARY;
 
-		if (parse_url($iTipMessage->sender, PHP_URL_SCHEME) !== 'mailto') {
+		if (strcasecmp(parse_url($iTipMessage->sender, PHP_URL_SCHEME), 'mailto') !== 0) {
 			return;
 		}
 
-		if (parse_url($iTipMessage->recipient, PHP_URL_SCHEME) !== 'mailto') {
+		if (strcasecmp(parse_url($iTipMessage->recipient, PHP_URL_SCHEME), 'mailto') !== 0) {
 			return;
 		}
 
@@ -239,9 +239,44 @@ class IMipPlugin extends SabreIMipPlugin {
 			$meetingAttendeeName, $meetingInviteeName);
 		$this->addBulletList($template, $l10n, $meetingWhen, $meetingLocation,
 			$meetingDescription, $meetingUrl);
-		$this->addResponseButtons($template, $l10n, $iTipMessage, $lastOccurrence);
+
+
+		// Only add response buttons to invitation requests: Fix Issue #11230
+		if ($method == self::METHOD_REQUEST) {
+
+			/*
+			** Only offer invitation accept/reject buttons, which link back to the
+			** nextcloud server, to recipients who can access the nextcloud server via
+			** their internet/intranet.  Issue #12156
+			**
+			** For nextcloud servers accessible to the public internet, the default
+			** "dav.invitation_link_recipients" value "true" (all recipients) is appropriate.
+			**
+			** When the nextcloud server is restricted behind a firewall, accessible
+			** only via an internal network or via vpn, you can set "dav.invitation_link_recipients"
+			** to the email address or email domain, or array of addresses or domains,
+			** of recipients who can access the server.
+			**
+			** To deliver URL's always, set invitation_link_recipients to boolean "true".
+			** To suppress URL's entirely, set invitation_link_recipients to boolean "false".
+			*/
+
+			$recipientDomain = substr(strrchr($recipient, "@"), 1);
+			$invitationLinkRecipients = $this->config->getSystemValue('dav.invitation_link_recipients', true);
+			if (is_array($invitationLinkRecipients)) {
+				$invitationLinkRecipients = array_map('strtolower', $invitationLinkRecipients); // for case insensitive in_array
+			}
+			if ($invitationLinkRecipients === true
+				 || (is_string($invitationLinkRecipients) && strcasecmp($recipient, $invitationLinkRecipients) === 0)
+				 || (is_string($invitationLinkRecipients) && strcasecmp($recipientDomain, $invitationLinkRecipients) === 0)
+				 || (is_array($invitationLinkRecipients) && in_array(strtolower($recipient), $invitationLinkRecipients))
+				 || (is_array($invitationLinkRecipients) && in_array(strtolower($recipientDomain), $invitationLinkRecipients))) {
+				$this->addResponseButtons($template, $l10n, $iTipMessage, $lastOccurrence);
+			}
+		}
 
 		$template->addFooter();
+
 		$message->useTemplate($template);
 
 		$attachment = $this->mailer->createAttachment(
@@ -447,7 +482,6 @@ class IMipPlugin extends SabreIMipPlugin {
 			$template->setSubject('Invitation: ' . $summary);
 			$template->addHeading($l10n->t('%1$s invited you to »%2$s«', [$inviteeName, $summary]), $l10n->t('Hello %s,', [$attendeeName]));
 		}
-
 	}
 
 	/**
diff --git a/config/config.sample.php b/config/config.sample.php
index 9c3cc470995..5f1eee4e945 100644
--- a/config/config.sample.php
+++ b/config/config.sample.php
@@ -1696,6 +1696,33 @@ $CONFIG = array(
 	'/^Microsoft-WebDAV-MiniRedir/', // Windows webdav drive
 ),
 
+/**
+* The caldav server sends invitation emails to invitees, attaching the ICS
+* file for the invitation.  It also may include, in the body of the e-mail,
+* invitation accept/reject web links referencing URL's that point to the nextcloud server.
+*
+* Although any recipient can read and reply to the ICS file via the iMip protocol,
+* we must only present the web links to recipients who can access the nextcloud
+* web server via their internet/intranet.
+*
+* When your nextcloud server is restricted behind a firewall, accessible
+* only via an internal network or via vpn, you can set "dav.invitation_link_recipients"
+* to the email address or email domain, or array of addresses or domains,
+* of recipients who can access the server. Only those recipients will get web links. External
+* users can accept/reject invitations by emailing back ICS files containing appropriate
+* messages, using the iMip protocol. Many mail clients support this functionality.
+*
+* To suppress iMip web links entirely, set dav.invitation_link_recipients to false.
+* To deliver iMip web links always, set dav.invitation_link_recipients to true.
+*
+* Examples:
+*   'dav.invitation_link_recipients' => 'internal.example.com',
+*   'dav.invitation_link_recipients' => array( 'internal.example.com', 'pat@roadwarrior.example.com' ),
+*   'dav.invitation_link_recipients' => false,
+*
+*/
+'dav.invitation_link_recipients' => '*', // always include accept/reject server links in iMip emails
+
 /**
  * By default there is on public pages a link shown that allows users to
  * learn about the "simple sign up" - see https://nextcloud.com/signup/
-- 
GitLab