Bug 682474 - Lightning hides Thunderbird master password prompt + multiple password prompts. r=MakeMyDay a=philipp BETA_60_CONTINUATION
authorPhilipp Kewisch <mozilla@kewis.ch>
Thu, 24 Nov 2016 02:10:03 +0100
branchBETA_60_CONTINUATION
changeset 31598 d382c7a166210f1feff33ae14b424390540da6f6
parent 31597 2bc3eb38e9674628f6b15043f4dbb6d2d0770b72
child 31599 c842a84286d31c811107b1a7ae92da18a2f66b41
push id2295
push usermozilla@jorgk.com
push dateFri, 24 Aug 2018 18:24:52 +0000
treeherdercomm-beta@5a5c21ea76a6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersMakeMyDay, philipp
bugs682474
Bug 682474 - Lightning hides Thunderbird master password prompt + multiple password prompts. r=MakeMyDay a=philipp
calendar/base/modules/utils/calAuthUtils.jsm
calendar/providers/caldav/calDavCalendar.js
calendar/providers/gdata/modules/gdataSession.jsm
--- a/calendar/base/modules/utils/calAuthUtils.jsm
+++ b/calendar/base/modules/utils/calAuthUtils.jsm
@@ -114,16 +114,20 @@ var calauth = {
         // nsICancelable asyncPromptAuth(in nsIChannel aChannel,
         //                               in nsIAuthPromptCallback aCallback,
         //                               in nsISupports aContext,
         //                               in uint32_t level,
         //                               in nsIAuthInformation authInfo);
         asyncPromptAuth(aChannel, aCallback, aContext, aLevel, aAuthInfo) {
             let self = this;
             let promptlistener = {
+                onPromptStartAsync: function(callback) {
+                    callback.onAuthResult(this.onPromptStart());
+                },
+
                 onPromptStart: function() {
                     let res = self.promptAuth(aChannel, aLevel, aAuthInfo);
                     if (res) {
                         gAuthCache.setAuthInfo(hostKey, aAuthInfo);
                         this.onPromptAuthAvailable();
                         return true;
                     }
 
--- a/calendar/providers/caldav/calDavCalendar.js
+++ b/calendar/providers/caldav/calDavCalendar.js
@@ -387,17 +387,17 @@ calDavCalendar.prototype = {
         let origArgs = arguments;
         let self = this;
 
         if (usesGoogleOAuth && (
               !this.oauth.accessToken ||
               this.oauth.tokenExpires - OAUTH_GRACE_TIME < (new Date()).getTime())) {
             // The token has expired, we need to reauthenticate first
             cal.LOG("CalDAV: OAuth token expired or empty, refreshing");
-            this.oauth.connect(authSuccess, aFailureFunc, true, true);
+            this.oauthConnect(authSuccess, aFailureFunc, true);
         } else {
             // Either not Google OAuth, or the token is still valid.
             authSuccess();
         }
     },
 
     //
     // calICalendar interface
@@ -1548,16 +1548,44 @@ calDavCalendar.prototype = {
      * @see calProviderUtils.jsm
      */
     getInterface: cal.provider.InterfaceRequestor_getInterface,
 
     //
     // Helper functions
     //
 
+    oauthConnect: function(authSuccessCb, authFailureCb, aRefresh=false) {
+        // Use the async prompter to avoid multiple master password prompts
+        let self = this;
+        let promptlistener = {
+            onPromptStartAsync: function(callback) {
+                this.onPromptAuthAvailable(callback);
+            },
+            onPromptAuthAvailable: function(callback) {
+                self.oauth.connect(() => {
+                    authSuccessCb();
+                    if (callback) {
+                        callback.onAuthResult(true);
+                    }
+                }, () => {
+                    authFailureCb();
+                    if (callback) {
+                        callback.onAuthResult(false);
+                    }
+                }, true, aRefresh);
+            },
+            onPromptCanceled: authFailureCb,
+            onPromptStart: function() {}
+        };
+        let asyncprompter = Components.classes["@mozilla.org/messenger/msgAsyncPrompter;1"]
+                                      .getService(Components.interfaces.nsIMsgAsyncPrompter);
+        asyncprompter.queueAsyncAuthPrompt(self.uri.spec, false, promptlistener);
+    },
+
     /**
      * Sets up any needed prerequisites regarding authentication. 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.
      *
      * setupAuthentication                         * You are here
      * checkDavResourceType
@@ -1571,36 +1599,16 @@ calDavCalendar.prototype = {
         function authSuccess() {
             self.checkDavResourceType(aChangeLogListener);
         }
         function authFailed() {
             self.setProperty("disabled", "true");
             self.setProperty("auto-enabled", "true");
             self.completeCheckServerInfo(aChangeLogListener, Components.results.NS_ERROR_FAILURE);
         }
-        function connect() {
-            // Use the async prompter to avoid multiple master password prompts
-            let promptlistener = {
-                onPromptStart: function() {
-                    // Usually this function should be synchronous. The OAuth
-                    // connection itself is asynchronous, but if a master
-                    // password is prompted it will block on that.
-                    this.onPromptAuthAvailable();
-                    return true;
-                },
-
-                onPromptAuthAvailable: function() {
-                    self.oauth.connect(authSuccess, authFailed, true);
-                },
-                onPromptCanceled: authFailed
-            };
-            let asyncprompter = Components.classes["@mozilla.org/messenger/msgAsyncPrompter;1"]
-                                          .getService(Components.interfaces.nsIMsgAsyncPrompter);
-            asyncprompter.queueAsyncAuthPrompt(self.uri.spec, false, promptlistener);
-        }
         if (this.mUri.host == "apidata.googleusercontent.com") {
             if (!this.oauth) {
                 let sessionId = this.id;
                 let pwMgrId = "Google CalDAV v2";
                 let authTitle = cal.l10n.getAnyString(
                     "global", "commonDialogs", "EnterUserPasswordFor2", [this.name]
                 );
                 this.oauth = new OAuth2(OAUTH_BASE_URI, OAUTH_SCOPE,
@@ -1652,17 +1660,17 @@ calDavCalendar.prototype = {
                 // master password prompt will show just the buttons and
                 // possibly hang. If we postpone until the window is loaded,
                 // all is well.
                 setTimeout(function postpone() { // eslint-disable-line func-names
                     let win = cal.window.getCalendarWindow();
                     if (!win || win.document.readyState != "complete") {
                         setTimeout(postpone, 0);
                     } else {
-                        connect();
+                        self.oauthConnect(authSuccess, authFailed);
                     }
                 }, 0);
             }
         } else {
             authSuccess();
         }
     },
 
--- a/calendar/providers/gdata/modules/gdataSession.jsm
+++ b/calendar/providers/gdata/modules/gdataSession.jsm
@@ -271,28 +271,34 @@ calGoogleSession.prototype = {
                 }
                 deferred.reject(new Components.Exception(error));
             }.bind(this);
 
             let connect = function() {
                 // Use the async prompter to avoid multiple master password prompts
                 let self = this;
                 let promptlistener = {
-                    onPromptStart: function() {
-                        // Usually this function should be synchronous. The OAuth
-                        // connection itself is asynchronous, but if a master
-                        // password is prompted it will block on that.
-                        this.onPromptAuthAvailable();
-                        return true;
+                    onPromptStartAsync: function(callback) {
+                        this.onPromptAuthAvailable(callback);
                     },
-
-                    onPromptAuthAvailable: function() {
-                        self.oauth.connect(authSuccess, authFailed, true, false);
+                    onPromptAuthAvailable: function(callback) {
+                        self.oauth.connect(() => {
+                            authSuccess();
+                            if (callback) {
+                                callback.onAuthResult(true);
+                            }
+                        }, () => {
+                            authFailed();
+                            if (callback) {
+                                callback.onAuthResult(false);
+                            }
+                        }, true);
                     },
-                    onPromptCanceled: authFailed
+                    onPromptCanceled: authFailed,
+                    onPromptStart: function() {}
                 };
                 let asyncprompter = Components.classes["@mozilla.org/messenger/msgAsyncPrompter;1"]
                                               .getService(Components.interfaces.nsIMsgAsyncPrompter);
                 asyncprompter.queueAsyncAuthPrompt("googleapi://" + this.id, false, promptlistener);
             }.bind(this);
 
             if (accessToken) {
                 deferred.resolve(accessToken);