Backed out changeset 18fc7a8887b9 (bug 1544596) for test failures in testLocalICS.js. a=backout
authorJorg K <jorgk@jorgk.com>
Fri, 14 Jun 2019 09:43:44 +0200
changeset 35863 ae1624177e2cf555a9d1f35bcae4c2e6287545bc
parent 35862 18fc7a8887b9dd8cb2e92fb74597393750bfaa82
child 35864 acbf665ac19174b273e9cf4c76a14b6c1e341be8
push id392
push userclokep@gmail.com
push dateMon, 02 Sep 2019 20:17:19 +0000
reviewersbackout
bugs1544596
backs out18fc7a8887b9dd8cb2e92fb74597393750bfaa82
Backed out changeset 18fc7a8887b9 (bug 1544596) for test failures in testLocalICS.js. a=backout
calendar/base/content/dialogs/calendar-properties-dialog.js
calendar/base/content/dialogs/calendar-properties-dialog.xul
calendar/base/modules/utils/calAuthUtils.jsm
calendar/base/modules/utils/calProviderUtils.jsm
calendar/providers/caldav/calDavCalendar.js
calendar/resources/content/calendarCreation.js
calendar/resources/content/calendarCreation.xul
--- a/calendar/base/content/dialogs/calendar-properties-dialog.js
+++ b/calendar/base/content/dialogs/calendar-properties-dialog.js
@@ -23,23 +23,16 @@ function onLoad() {
     gCalendar = window.arguments[0].calendar;
     let calColor = gCalendar.getProperty("color");
 
     document.getElementById("calendar-name").value = gCalendar.name;
     document.getElementById("calendar-color").value = calColor || "#A8C2E1";
     document.getElementById("calendar-uri").value = gCalendar.uri.spec;
     document.getElementById("read-only").checked = gCalendar.readOnly;
 
-    if (gCalendar.getProperty("capabilities.username.supported") === true) {
-        document.getElementById("calendar-username").value = gCalendar.getProperty("username");
-        document.getElementById("calendar-username-row").hidden = false;
-    } else {
-        document.getElementById("calendar-username-row").hidden = true;
-    }
-
     // Set up refresh interval
     initRefreshInterval();
 
     // Set up the cache field
     let cacheBox = document.getElementById("cache");
     let canCache = (gCalendar.getProperty("cache.supported") !== false);
     let alwaysCache = gCalendar.getProperty("cache.always");
     if (!canCache || alwaysCache) {
@@ -82,21 +75,16 @@ function onLoad() {
  */
 function onAcceptDialog() {
     // Save calendar name
     gCalendar.name = document.getElementById("calendar-name").value;
 
     // Save calendar color
     gCalendar.setProperty("color", document.getElementById("calendar-color").value);
 
-    // Save calendar user
-    if (gCalendar.getProperty("capabilities.username.supported") === true) {
-        gCalendar.setProperty("username", document.getElementById("calendar-username").value);
-    }
-
     // Save readonly state
     gCalendar.readOnly = document.getElementById("read-only").checked;
 
     // Save supressAlarms
     gCalendar.setProperty("suppressAlarms", !document.getElementById("fire-alarms").checked);
 
     // Save refresh interval
     if (gCalendar.canRefresh) {
--- a/calendar/base/content/dialogs/calendar-properties-dialog.xul
+++ b/calendar/base/content/dialogs/calendar-properties-dialog.xul
@@ -5,17 +5,16 @@
 
 <?xml-stylesheet href="chrome://global/skin/global.css" type="text/css"?>
 <?xml-stylesheet href="chrome://calendar-common/skin/calendar-properties-dialog.css" type="text/css"?>
 
 <!DOCTYPE dialog
 [
     <!ENTITY % dtd1 SYSTEM "chrome://calendar/locale/global.dtd" > %dtd1;
     <!ENTITY % dtd2 SYSTEM "chrome://calendar/locale/calendar.dtd" > %dtd2;
-    <!ENTITY % dtd3 SYSTEM "chrome://calendar/locale/calendarCreation.dtd" > %dtd3;
 ]>
 
 <dialog
     id="calendar-properties-dialog-2"
     windowtype="Calendar:PropertiesDialog"
     title="&calendar.server.dialog.title.edit;"
     buttons="accept,cancel,extra1"
     buttonlabelextra1="&calendarproperties.unsubscribe.label;"
@@ -56,24 +55,16 @@
                disable-with-calendar="true"
                control="calendar-color"/>
           <hbox align="center">
             <html:input id="calendar-color"
                         type="color"
                         disable-with-calendar="true"/>
           </hbox>
       </row>
-      <row id="calendar-username-row"
-           align="center">
-        <label value="&locationpage.username.label;"
-               disable-with-calendar="true"
-               control="calendar-username"/>
-        <textbox id="calendar-username"
-                 disable-with-calendar="true"/>
-      </row>
       <row id="calendar-uri-row" align="center">
         <label value="&calendarproperties.location.label;"
                disable-with-calendar="true"
                control="calendar-uri"/>
         <!-- XXX Make location field readonly until Bug 315307 is fixed -->
         <textbox id="calendar-uri" readonly="true" disable-with-calendar="true"/>
       </row>
       <row id="calendar-refreshInterval-row" align="center">
--- a/calendar/base/modules/utils/calAuthUtils.jsm
+++ b/calendar/base/modules/utils/calAuthUtils.jsm
@@ -11,121 +11,16 @@ XPCOMUtils.defineLazyModuleGetter(this, 
  * Authentication tools and prompts, mostly for providers
  */
 
 // NOTE: This module should not be loaded directly, it is available when including
 // calUtils.jsm under the cal.auth namespace.
 
 this.EXPORTED_SYMBOLS = ["calauth"]; /* exported calauth */
 
-/**
- * The userContextId of nsIHttpChannel is currently implemented as a uint32, so
- * the ContainerMap defined below must not return Ids greater then the allowed
- * range of a uint32.
-*/
-const MAX_CONTAINER_ID = Math.pow(2, 32)-1;
-
-/**
- * A map that handles userContextIds and usernames and provides unique Ids for
- * different usernames.
- */
-class ContainerMap extends Map {
-    /**
-     * Create a container map with a given range of userContextIds.
-     *
-     * @param {Number} min        The lower range limit of userContextIds to be
-     *                            used.
-     * @param {Number} max        The upper range limit of userContextIds to be
-     *                            used.
-     * @param {?Object} iterable  Optional parameter which is passed to the
-     *                            constructor of Map. See definition of Map
-     *                            for more details.
-     */
-    constructor(min = 0, max = MAX_CONTAINER_ID, iterable) {
-        super(iterable);
-        this.order = [];
-        this.inverted = {};
-        this.min = min;
-        // The userConextId is a uint32, limit accordingly.
-        this.max = Math.max(max, MAX_CONTAINER_ID);
-        if (this.min > this.max) {
-            throw new RangeError("[ContainerMap] The provided min value " +
-              "(" + this.min + ") must not be greater than the provided " +
-              "max value (" + this.max + ")");
-        }
-    }
-
-    /**
-     * Check if the allowed userContextId range is fully used.
-     */
-    get full() {
-        return this.size > (this.max - this.min);
-    }
-
-    /**
-     * Add a new username to the map.
-     *
-     * @param {String} username - The username to be added.
-     * @return {Number} The userContextId assigned to the given username.
-     */
-    _add(username) {
-        let nextUserContextId;
-        if (this.full) {
-            let oldestUsernameEntry = this.order.shift();
-            nextUserContextId = this.get(oldestUsernameEntry);
-            this.delete(oldestUsernameEntry);
-        } else {
-            nextUserContextId = this.min + this.size;
-        }
-
-        Services.clearData.deleteDataFromOriginAttributesPattern(
-          { userContextId: nextUserContextId },
-        );
-        this.order.push(username);
-        this.set(username, nextUserContextId);
-        this.inverted[nextUserContextId] = username;
-        return nextUserContextId;
-    }
-
-    /**
-     * Look up the userContextId for the given username. Create a new one,
-     * if the username is not yet known.
-     *
-     * @param {String} username        The username for which the userContextId
-     *                                 is to be looked up.
-     * @return {Number}                The userContextId which is assigned to
-     *                                 the provided username.
-     */
-    getUserContextIdForUsername(username) {
-        if (this.has(username)) {
-            return this.get(username);
-        } else {
-            return this._add(username);
-        }
-    }
-
-    /**
-     * Look up the username for the given userContextId. Return empty string
-     * if not found.
-     *
-     * @param {Number} userContextId        The userContextId for which the
-     *                                      username is to be to looked up.
-     * @return {String}                     The username mapped to the given
-     *                                      userContextId.
-     */
-    getUsernameForUserContextId(userContextId) {
-        if (this.inverted.hasOwnProperty(userContextId)) {
-            return this.inverted[userContextId];
-        } else {
-            return "";
-        }
-    }
-}
-
-
 var calauth = {
     /**
      * Calendar Auth prompt implementation. This instance of the auth prompt should
      * be used by providers and other components that handle authentication using
      * nsIAuthPrompt2 and friends.
      *
      * This implementation guarantees there are no request loops when an invalid
      * password is stored in the login-manager.
@@ -145,36 +40,31 @@ var calauth = {
          * @property {?String} username     The found username
          * @property {?String} password     The found password
          */
 
         /**
          * Retrieve password information from the login manager
          *
          * @param {String} aPasswordRealm       The realm to retrieve password info for
-         * @param {String} aRequestedUser       The username to look up.
          * @return {PasswordInfo}               The retrieved password information
          */
-        getPasswordInfo(aPasswordRealm, aRequestedUser) {
-            // Prefill aRequestedUser, so it will be used in the prompter.
-            let username = aRequestedUser;
+        getPasswordInfo(aPasswordRealm) {
+            let username;
             let password;
             let found = false;
 
             let logins = Services.logins.findLogins(aPasswordRealm.prePath, null, aPasswordRealm.realm);
-            for (let login of logins) {
-                if (!aRequestedUser || aRequestedUser == login.username) {
-                    username = login.username;
-                    password = login.password;
-                    found = true;
-                    break;
-                }
+            if (logins.length) {
+                username = logins[0].username;
+                password = logins[0].password;
+                found = true;
             }
             if (found) {
-                let keyStr = aPasswordRealm.prePath + ":" + aPasswordRealm.realm + ":" + aRequestedUser;
+                let keyStr = aPasswordRealm.prePath + ":" + aPasswordRealm.realm;
                 let now = new Date();
                 // Remove the saved password if it was already returned less
                 // than 60 seconds ago. The reason for the timestamp check is that
                 // nsIHttpChannel can call the nsIAuthPrompt2 interface
                 // again in some situation. ie: When using Digest auth token
                 // expires.
                 if (this.mReturnedLogins[keyStr] &&
                     now.getTime() - this.mReturnedLogins[keyStr].getTime() < 60000) {
@@ -202,18 +92,17 @@ var calauth = {
             let port = aChannel.URI.port;
             if (port == -1) {
                 let handler = Services.io.getProtocolHandler(aChannel.URI.scheme)
                                          .QueryInterface(Ci.nsIProtocolHandler);
                 port = handler.defaultPort;
             }
             hostRealm.passwordRealm = aChannel.URI.host + ":" + port + " (" + aAuthInfo.realm + ")";
 
-            let requestedUser = cal.auth.containerMap.getUsernameForUserContextId(aChannel.loadInfo.originAttributes.userContextId);
-            let pwInfo = this.getPasswordInfo(hostRealm, requestedUser);
+            let pwInfo = this.getPasswordInfo(hostRealm);
             aAuthInfo.username = pwInfo.username;
             if (pwInfo && pwInfo.found) {
                 aAuthInfo.password = pwInfo.password;
                 return true;
             } else {
                 let savePasswordLabel = null;
                 if (Services.prefs.getBoolPref("signon.rememberSignons", true)) {
                     savePasswordLabel = cal.l10n.getAnyString("passwordmgr",
@@ -267,18 +156,17 @@ var calauth = {
                 },
 
                 onPromptCanceled: function() {
                     gAuthCache.retrieveAuthInfo(hostKey);
                     aCallback.onAuthCancelled(aContext, true);
                 }
             };
 
-            let requestedUser = cal.auth.containerMap.getUsernameForUserContextId(aChannel.loadInfo.originAttributes.userContextId);
-            let hostKey = aChannel.URI.prePath + ":" + aAuthInfo.realm + ":" + requestedUser;
+            let hostKey = aChannel.URI.prePath + ":" + aAuthInfo.realm;
             gAuthCache.planForAuthInfo(hostKey);
 
             let queuePrompt = function() {
                 let asyncprompter = Cc["@mozilla.org/messenger/msgAsyncPrompter;1"]
                                       .getService(Ci.nsIMsgAsyncPrompter);
                 asyncprompter.queueAsyncAuthPrompt(hostKey, false, promptlistener);
             };
 
@@ -380,23 +268,21 @@ var calauth = {
         }
 
         try {
             let logins = Services.logins.findLogins(origin, null, aRealm);
 
             let newLoginInfo = Cc["@mozilla.org/login-manager/loginInfo;1"]
                                  .createInstance(Ci.nsILoginInfo);
             newLoginInfo.init(origin, null, aRealm, aUsername, aPassword, "", "");
-            for (let login of logins) {
-                if (aUsername == login.username) {
-                    Services.logins.modifyLogin(login, newLoginInfo);
-                    return;
-                }
+            if (logins.length > 0) {
+                Services.logins.modifyLogin(logins[0], newLoginInfo);
+            } else {
+                Services.logins.addLogin(newLoginInfo);
             }
-            Services.logins.addLogin(newLoginInfo);
         } catch (exc) {
             // Only show the message if its not an abort, which can happen if
             // the user canceled the master password dialog
             cal.ASSERT(exc.result == Cr.NS_ERROR_ABORT, exc);
         }
     },
 
     /**
@@ -451,28 +337,17 @@ var calauth = {
                     Services.logins.removeLogin(loginInfo);
                     return true;
                 }
             }
         } catch (exc) {
             // If no logins are found, fall through to the return statement below.
         }
         return false;
-    },
-
-    /**
-     * A map which maps usernames to userContextIds, reserving a range
-     * of 20000 - 29999 for userContextIds to be used within lightning.
-     *
-     * @param {Number} min        The lower range limit of userContextIds to be
-     *                            used.
-     * @param {Number} max        The upper range limit of userContextIds to be
-     *                            used.
-     */
-    containerMap: new ContainerMap(20000, 29999)
+    }
 };
 
 // Cache for authentication information since onAuthInformation in the prompt
 // listener is called without further information. If the password is not
 // saved, there is no way to retrieve it. We use ref counting to avoid keeping
 // the password in memory longer than needed.
 var gAuthCache = {
     _authInfoCache: new Map(),
--- a/calendar/base/modules/utils/calProviderUtils.jsm
+++ b/calendar/base/modules/utils/calProviderUtils.jsm
@@ -31,39 +31,20 @@ var calprovider = {
      *                                                            string will be converted to an
      *                                                            input stream.
      * @param {String} aContentType                             Value for Content-Type header, if any
      * @param {nsIInterfaceRequestor} aNotificationCallbacks    Calendar using channel
      * @param {?nsIChannel} aExisting                           An existing channel to modify (optional)
      * @return {nsIChannel}                                     The prepared channel
      */
     prepHttpChannel: function(aUri, aUploadData, aContentType, aNotificationCallbacks, aExisting=null) {
-        let originAttributes = {};
-
-        // The current nsIHttpChannel implementation separates connections only
-        // by hosts, which causes issues with cookies and password caching for
-        // two or more simultaneous connections to the same host and different
-        // authenticated users. This can be solved by providing the additional
-        // userContextId, which also separates connections (a.k.a. containers).
-        // Connections for userA @ server1 and userA @ server2 can exist in the
-        // same container, as nsIHttpChannel will separate them. Connections
-        // for userA @ server1 and userB @ server1 however must be placed into
-        // different containers. It is therefore sufficient to add individual
-        // userContextIds per username.
-
-        let calendar = cal.wrapInstance(aNotificationCallbacks, Ci.calICalendar);
-        if (calendar && calendar.getProperty("capabilities.username.supported") === true) {
-            originAttributes.userContextId = cal.auth.containerMap
-                .getUserContextIdForUsername(calendar.getProperty("username"));
-        }
-
         // We cannot use a system principal here since the connection setup will fail if
         // same-site cookie protection is enabled in TB and server-side.
         let principal = aExisting ? null
-                                  : Services.scriptSecurityManager.createCodebasePrincipal(aUri, originAttributes);
+                                  : Services.scriptSecurityManager.createCodebasePrincipal(aUri, {});
         let channel = aExisting || Services.io.newChannelFromURI(aUri,
                                                                  null,
                                                                  principal,
                                                                  null,
                                                                  Ci.nsILoadInfo.SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL,
                                                                  Ci.nsIContentPolicy.TYPE_OTHER);
         let httpchannel = channel.QueryInterface(Ci.nsIHttpChannel);
 
--- a/calendar/providers/caldav/calDavCalendar.js
+++ b/calendar/providers/caldav/calDavCalendar.js
@@ -566,18 +566,16 @@ calDavCalendar.prototype = {
                 } // else use outbound email-based iTIP (from cal.provider.BaseClass)
                 break;
             case "capabilities.tasks.supported":
                 return this.supportedItemTypes.includes("VTODO");
             case "capabilities.events.supported":
                 return this.supportedItemTypes.includes("VEVENT");
             case "capabilities.autoschedule.supported":
                 return this.hasAutoScheduling;
-            case "capabilities.username.supported":
-                return true;
         }
         return this.__proto__.__proto__.getProperty.apply(this, arguments);
     },
 
     promptOverwrite: function(aMethod, aItem, aListener, aOldItem) {
         let overwrite = cal.provider.promptOverwrite(aMethod, aItem, aListener, aOldItem);
         if (overwrite) {
             if (aMethod == CALDAV_MODIFY_ITEM) {
--- a/calendar/resources/content/calendarCreation.js
+++ b/calendar/resources/content/calendarCreation.js
@@ -108,18 +108,16 @@ function onSelectProvider(type) {
     let cache = document.getElementById("cache");
     let tempCal;
     try {
         tempCal = Cc["@mozilla.org/calendar/calendar;1?type=" + type].createInstance(Ci.calICalendar);
     } catch (e) {
         // keep tempCal undefined if the calendar can not be created
     }
 
-    document.getElementById("calendar-username-row").hidden = !(tempCal && tempCal.getProperty("capabilities.username.supported") === true);
-
     if (tempCal && tempCal.getProperty("cache.always")) {
         cache.oldValue = cache.checked;
         cache.checked = true;
         cache.disabled = true;
     } else {
         if (cache.oldValue !== undefined) {
             cache.checked = cache.oldValue;
             cache.oldValue = undefined;
@@ -209,20 +207,16 @@ function doCreateCalendar() {
 
     gCalendar.name = cal_name;
     gCalendar.setProperty("color", cal_color);
     if (!gCalendar.getProperty("cache.always")) {
         gCalendar.setProperty("cache.enabled", gCalendar.getProperty("cache.supported") === false
                                                ? false : document.getElementById("cache").checked);
     }
 
-    if (gCalendar.getProperty("capabilities.username.supported") === true) {
-        gCalendar.setProperty("username", document.getElementById("calendar-username").value);
-    }
-
     if (!document.getElementById("fire-alarms").checked) {
         gCalendar.setProperty("suppressAlarms", true);
     }
 
     cal.getCalendarManager().registerCalendar(gCalendar);
     return true;
 }
 
--- a/calendar/resources/content/calendarCreation.xul
+++ b/calendar/resources/content/calendarCreation.xul
@@ -50,20 +50,16 @@
         <row>
           <label value="&calendarproperties.format.label;" control="calendar-format"/>
           <radiogroup id="calendar-format" onselect="onSelectProvider(this.value)">
             <radio value="ics" label="&calendarproperties.webdav.label;" selected="true" />
             <radio value="caldav" label="&calendarproperties.caldav.label;"/>
             <radio id="wcap-radio" value="wcap" label="&calendarproperties.wcap.label;"/>
           </radiogroup>
         </row>
-        <row id="calendar-username-row" align="center">
-          <label value="&locationpage.username.label;" control="calendar-username"/>
-          <textbox id="calendar-username"/>
-        </row>
         <row align="center">
           <label value="&calendarproperties.location.label;" control="calendar-uri"/>
           <textbox is="search-textbox" id="calendar-uri"
                    required="true"
                    oninput="checkRequired();"/>
         </row>
         <row>
           <label/>