Bug 1107388 - No auth prompt is shown when subscribing to CalDAV calendars [domWin.document is null]. r+a=philipp CLOSED TREE
authorMatthew Mecca <matthew.mecca@gmail.com>
Fri, 02 Jan 2015 13:11:43 +0100
changeset 25636 156340fdb85ed8ecabc17ea19eac5664d33f7790
parent 25635 57009cdbeca02c1b14527136f0ff2e03bbd7da70
child 25637 041dfe66d51ff1a66d29b86ea56b4295f8ea4bed
push id1850
push userclokep@gmail.com
push dateWed, 08 Mar 2017 19:29:12 +0000
treeherdercomm-esr52@028df196b2d9 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1107388
Bug 1107388 - No auth prompt is shown when subscribing to CalDAV calendars [domWin.document is null]. r+a=philipp CLOSED TREE
calendar/base/modules/calAuthUtils.jsm
calendar/base/modules/calProviderUtils.jsm
--- a/calendar/base/modules/calAuthUtils.jsm
+++ b/calendar/base/modules/calAuthUtils.jsm
@@ -10,18 +10,18 @@ Components.utils.import("resource://gre/
  * Authentication helper code
  */
 
 EXPORTED_SYMBOLS = ["cal"]; // even though it's defined in calUtils.jsm, import needs this
 cal.auth = {
     /**
      * Auth prompt implementation - Uses password manager if at all possible.
      */
-    Prompt: function calPrompt(aProvider) {
-        this.mProvider = aProvider;
+    Prompt: function calPrompt() {
+        this.mWindow = cal.getCalendarWindow();
         this.mReturnedLogins = {};
     },
 
     /**
      * Tries to get the username/password combination of a specific calendar name
      * from the password manager or asks the user.
      *
      * @param   in aTitle           The dialog title.
@@ -248,17 +248,17 @@ cal.auth.Prompt.prototype = {
         let pw = this.getPasswordInfo(hostRealm);
         aAuthInfo.username = pw.username;
         if (pw && pw.found) {
             aAuthInfo.password = pw.password;
             return true;
         } else {
             let prompter2 = Components.classes["@mozilla.org/embedcomp/window-watcher;1"]
                                       .getService(Components.interfaces.nsIPromptFactory)
-                                      .getPrompt(this.mProvider, Components.interfaces.nsIAuthPrompt2);
+                                      .getPrompt(this.mWindow, Components.interfaces.nsIAuthPrompt2);
             return prompter2.promptAuth(aChannel, aLevel, aAuthInfo);
         }
     },
 
     /**
      * Asynchronously prompt the user for a username and password.
      * This has largely the same semantics as promptAuth(),
      * but must return immediately after calling and return the entered
@@ -309,19 +309,30 @@ cal.auth.Prompt.prototype = {
                 gAuthCache.retrieveAuthInfo(hostKey);
                 aCallback.onAuthCancelled(aContext, true);
             }
         };
 
         let hostKey = aChannel.URI.prePath + ":" + aAuthInfo.realm;
         gAuthCache.planForAuthInfo(hostKey);
 
-        let asyncprompter = Components.classes["@mozilla.org/messenger/msgAsyncPrompter;1"]
-                                      .getService(Components.interfaces.nsIMsgAsyncPrompter);
-        asyncprompter.queueAsyncAuthPrompt(hostKey, false, promptlistener);
+        function queuePrompt() {
+            let asyncprompter = Components.classes["@mozilla.org/messenger/msgAsyncPrompter;1"]
+                                          .getService(Components.interfaces.nsIMsgAsyncPrompter);
+            asyncprompter.queueAsyncAuthPrompt(hostKey, false, promptlistener);
+        }
+
+        self.mWindow = cal.getCalendarWindow();
+
+        // the prompt will fail if we are too early
+        if (self.mWindow.document.readyState != "complete") {
+            self.mWindow.addEventListener("load", queuePrompt, true);
+        } else {
+            queuePrompt();
+        }
     }
 };
 
 // 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.
 let gAuthCache = {
--- a/calendar/base/modules/calProviderUtils.jsm
+++ b/calendar/base/modules/calProviderUtils.jsm
@@ -112,29 +112,27 @@ cal.InterfaceRequestor_getInterface = fu
     try {
         // Try to query the this object for the requested interface but don't
         // throw if it fails since that borks the network code.
         return this.QueryInterface(aIID);
     } catch (e) {
         // Support Auth Prompt Interfaces
         if (aIID.equals(Components.interfaces.nsIAuthPrompt2)) {
             if (!this.calAuthPrompt) {
-                this.calAuthPrompt = new cal.auth.Prompt(this);
+                this.calAuthPrompt = new cal.auth.Prompt();
             }
             return this.calAuthPrompt;
         } else if (aIID.equals(Components.interfaces.nsIAuthPromptProvider) ||
                    aIID.equals(Components.interfaces.nsIPrompt)) {
             return Services.ww.getNewPrompter(null);
         } else if (aIID.equals(Components.interfaces.nsIBadCertListener2)) {
             if (!this.badCertHandler) {
                 this.badCertHandler = new cal.BadCertHandler(this);
             }
             return this.badCertHandler;
-        } else if (aIID.equals(Components.interfaces.nsIWebNavigation)) {
-            return new cal.LoadContext();
         } else {
             Components.returnCode = e;
         }
     }
     return null;
 };
 
 /**
@@ -180,35 +178,16 @@ cal.BadCertHandler.prototype = {
         timer.initWithCallback(timerCallback,
                                0,
                                Components.interfaces.nsITimer.TYPE_ONE_SHOT);
         return true;
     }
 };
 
 /**
- * Implements an nsILoadContext that allows auth prompts to avoid using private
- * browsing without a parent DOM window
- */
-cal.LoadContext = function calLoadContext() {
-};
-cal.LoadContext.prototype = {
-    QueryInterface: XPCOMUtils.generateQI([Components.interfaces.nsISupports,
-                                           Components.interfaces.nsILoadContext]),
-    associatedWindow: null,
-    topWindow: null,
-    topFrameElement: null,
-    isAppOfType: function() false,
-    isContent: false,
-    usePrivateBrowsing: false,
-    isInBrowserElement: false,
-    appId: null
-};
-
-/**
  * Freebusy interval implementation. All parameters are optional.
  *
  * @param aCalId         The calendar id to set up with.
  * @param aFreeBusyType  The type from calIFreeBusyInterval.
  * @param aStart         The start of the interval.
  * @param aEnd           The end of the interval.
  * @return               The fresh calIFreeBusyInterval.
  */