Bug 1546606 - Add a CalDAV calendar URI redirect dialog. r=Fallen
authorPaul Morris <paul@thunderbird.net>
Thu, 09 Apr 2020 13:52:26 +0300
changeset 38760 1295426fff19b2b7e7da26f0a3d1baf0a295e543
parent 38759 b5b3dc5fdf701ccfc324a24c8efad79a4a474ed2
child 38761 11272b25eeab56e35b66cad74023887720bab6f3
push id401
push userclokep@gmail.com
push dateMon, 01 Jun 2020 20:41:59 +0000
reviewersFallen
bugs1546606
Bug 1546606 - Add a CalDAV calendar URI redirect dialog. r=Fallen
calendar/base/content/dialogs/calendar-uri-redirect-dialog.js
calendar/base/content/dialogs/calendar-uri-redirect-dialog.xhtml
calendar/base/jar.mn
calendar/locales/en-US/calendar/calendar-uri-redirect-dialog.ftl
calendar/providers/caldav/CalDavCalendar.jsm
calendar/providers/caldav/modules/CalDavRequest.jsm
new file mode 100644
--- /dev/null
+++ b/calendar/base/content/dialogs/calendar-uri-redirect-dialog.js
@@ -0,0 +1,26 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/* exported onLoad */
+
+function onLoad() {
+  let { calendarName, originalURI, targetURI } = window.arguments[0];
+
+  document.l10n.setAttributes(
+    document.getElementById("calendar-uri-redirect-description"),
+    "calendar-uri-redirect-description",
+    { calendarName }
+  );
+
+  document.getElementById("originalURI").value = originalURI;
+  document.getElementById("targetURI").value = targetURI;
+}
+
+document.addEventListener("dialogaccept", () => {
+  window.arguments[0].returnValue = true;
+});
+
+document.addEventListener("dialogcancel", () => {
+  window.arguments[0].returnValue = false;
+});
new file mode 100644
--- /dev/null
+++ b/calendar/base/content/dialogs/calendar-uri-redirect-dialog.xhtml
@@ -0,0 +1,35 @@
+<?xml version="1.0"?>
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+   - License, v. 2.0. If a copy of the MPL was not distributed with this
+   - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+
+<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
+
+<window windowtype="Calendar:URIRedirect"
+        onload="onLoad()"
+        xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+        xmlns:html="http://www.w3.org/1999/xhtml"
+        data-l10n-id="calendar-uri-redirect-window">
+
+  <dialog id="calendar-uri-redirect-dialog"
+          buttons="accept,cancel">
+
+    <html:link rel="localization" href="calendar/calendar-uri-redirect-dialog.ftl"/>
+
+    <script src="chrome://calendar/content/calendar-uri-redirect-dialog.js"/>
+
+    <vbox>
+      <description id="calendar-uri-redirect-description"
+                   data-l10n-id="calendar-uri-redirect-description"
+                   data-l10n-args='{"calendarName": ""}'/>
+      <separator />
+      <description data-l10n-id="calendar-uri-redirect-original-uri-label"/>
+      <label id="originalURI" />
+      <separator />
+      <description data-l10n-id="calendar-uri-redirect-target-uri-label"/>
+      <label id="targetURI" />
+      <separator />
+    </vbox>
+
+  </dialog>
+</window>
--- a/calendar/base/jar.mn
+++ b/calendar/base/jar.mn
@@ -73,16 +73,18 @@ calendar.jar:
     content/calendar-providerUninstall-dialog.js                (content/dialogs/calendar-providerUninstall-dialog.js)
     content/calendar-providerUninstall-dialog.xhtml             (content/dialogs/calendar-providerUninstall-dialog.xhtml)
     content/calendar-subscriptions-dialog.css                   (content/dialogs/calendar-subscriptions-dialog.css)
     content/calendar-subscriptions-dialog.js                    (content/dialogs/calendar-subscriptions-dialog.js)
     content/calendar-subscriptions-dialog.xhtml                 (content/dialogs/calendar-subscriptions-dialog.xhtml)
     content/calendar-summary-dialog.js                          (content/dialogs/calendar-summary-dialog.js)
     content/calendar-summary-dialog.xhtml                       (content/dialogs/calendar-summary-dialog.xhtml)
     content/calendar-summary-dialog.css                         (content/dialogs/calendar-summary-dialog.css)
+    content/calendar-uri-redirect-dialog.xhtml                  (content/dialogs/calendar-uri-redirect-dialog.xhtml)
+    content/calendar-uri-redirect-dialog.js                     (content/dialogs/calendar-uri-redirect-dialog.js)
     content/chooseCalendarDialog.js                             (content/dialogs/chooseCalendarDialog.js)
     content/chooseCalendarDialog.xhtml                          (content/dialogs/chooseCalendarDialog.xhtml)
     content/import-export.js                                    (content/import-export.js)
     content/preferences/alarms.js                               (content/preferences/alarms.js)
     content/preferences/categories.js                           (content/preferences/categories.js)
     content/preferences/editCategory.js                         (content/preferences/editCategory.js)
     content/preferences/editCategory.xhtml                      (content/preferences/editCategory.xhtml)
     content/preferences/general.js                              (content/preferences/general.js)
new file mode 100644
--- /dev/null
+++ b/calendar/locales/en-US/calendar/calendar-uri-redirect-dialog.ftl
@@ -0,0 +1,14 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+calendar-uri-redirect-window =
+  .title = Calendar URI Redirect
+
+calendar-uri-redirect-description =
+  The server is redirecting the URI for the calendar "{ $calendarName }".
+  Accept the redirect and start using the new URI for this calendar?
+
+calendar-uri-redirect-original-uri-label = Current URI:
+
+calendar-uri-redirect-target-uri-label = Redirecting to new URI:
--- a/calendar/providers/caldav/CalDavCalendar.jsm
+++ b/calendar/providers/caldav/CalDavCalendar.jsm
@@ -1392,25 +1392,49 @@ CalDavCalendar.prototype = {
     };
     let asyncprompter = Cc["@mozilla.org/messenger/msgAsyncPrompter;1"].getService(
       Ci.nsIMsgAsyncPrompter
     );
     asyncprompter.queueAsyncAuthPrompt(self.uri.spec, false, promptlistener);
   },
 
   /**
-   * Helper to check if the given response has had its url redirected, and if so prompt the user
-   * if they want to adapt the URL.
+   * Called when a response has had its URL redirected. Shows a dialog
+   * to allow the user to accept or reject the redirect. If they accept,
+   * change the calendar's URI to the target URI of the redirect.
    *
-   * @param {CalDavResponseBase} response         The response to check.
-   * @return {Boolean}                            False, if the calendar should be disabled
+   * @param {PropfindResponse} response - Response to handle. Typically a
+   *                                      PropfindResponse but could be any
+   *                                      subclass of CalDavResponseBase.
+   * @return {boolean} True if the user accepted the redirect.
+   *                   False, if the calendar should be disabled.
    */
-  checkRedirect(response) {
-    // TODO: the following is temporary just to help with debugging tests.
-    return true;
+  openUriRedirectDialog(response) {
+    let args = {
+      calendarName: this.name,
+      originalURI: response.nsirequest.originalURI.spec,
+      targetURI: response.uri.spec,
+      returnValue: false,
+    };
+
+    cal.window
+      .getCalendarWindow()
+      .openDialog(
+        "chrome://calendar/content/calendar-uri-redirect-dialog.xhtml",
+        "Calendar:URIRedirectDialog",
+        "chrome,modal,titlebar,resizable,centerscreen",
+        args
+      );
+
+    if (args.returnValue) {
+      this.uri = response.uri;
+      this.setProperty("uri", response.uri.spec);
+    }
+
+    return args.returnValue;
   },
 
   /**
    * Checks that the calendar URI exists and is a CalDAV calendar. This is the beginning of a
    * chain of asynchronous calls. This function will, when done, call the next function related to
    * checking resource type, server capabilties, etc.
    *
    * checkDavResourceType                        * You are here
@@ -1430,18 +1454,18 @@ CalDavCalendar.prototype = {
       "C:supported-calendar-component-set",
       "CS:getctag",
     ]);
 
     request.commit().then(
       response => {
         cal.LOG(`CalDAV: Status ${response.status} on initial PROPFIND for calendar ${this.name}`);
 
-        // Follow redirects if they happend, otherwise disable the calendar
-        if (!this.checkRedirect(response)) {
+        // If the URI was redirected, and the user rejects the redirect, disable the calendar.
+        if (response.redirected && !this.openUriRedirectDialog(response)) {
           this.setProperty("disabled", "true");
           this.completeCheckServerInfo(aChangeLogListener, Cr.NS_ERROR_ABORT);
           return;
         }
 
         if (response.clientError) {
           // 4xx codes, which is either an authentication failure or something like method not
           // allowed. This is a failure worth disabling the calendar.
--- a/calendar/providers/caldav/modules/CalDavRequest.jsm
+++ b/calendar/providers/caldav/modules/CalDavRequest.jsm
@@ -610,17 +610,17 @@ class DeleteItemResponse extends ItemRes
   /** If the response has a success code */
   get ok() {
     // Accepting 404 as success because then the item is already deleted
     return this.status == 204 || this.status == 200 || this.status == 404;
   }
 }
 
 /**
- * A dav PROPFIND request to retrieve specific properties of a dav resource
+ * A dav PROPFIND request to retrieve specific properties of a dav resource.
  */
 class CalDavPropfindRequest extends CalDavRequestBase {
   /**
    * Constructs a propfind request
    *
    * @param {CalDavSession} aSession                  The session to use for this request
    * @param {calICalendar} aCalendar                  The calendar this request belongs to
    * @param {nsIURI} aUri                             The uri to request