More work. Having server issues. Sadfaces.
authorShawn Wilsher <me@shawnwilsher.com>
Thu, 29 Oct 2009 21:23:26 -0700
changeset 22 6b3e075d0bd837c10ca84e271e80ae8e85ce1ccb
parent 21 7aa4baf393ffe37c7672e93e507e94ddaef38a82
child 23 c975360db19914599e53f32c8011e8d5b7c6f824
push id13
push usersdwilsh@shawnwilsher.com
push dateFri, 30 Oct 2009 23:05:59 +0000
More work. Having server issues. Sadfaces.
content/reply.js
resource/BugzillaAPI.jsm
resource/BugzillaHelper.jsm
--- a/content/reply.js
+++ b/content/reply.js
@@ -1,29 +1,26 @@
 Components.utils.import("resource://bugzilla-helper/BugzillaAPI.jsm");
+Components.utils.import("resource://bugzilla-helper/BugzillaHelper.jsm");
 
 ////////////////////////////////////////////////////////////////////////////////
 //// Constants
 
 // DEBUG constants
-/*
 const kServer = new BugzillaServer(
   "https://api-dev.bugzilla.mozilla.org/stage/0.1/",
   "75:B2:EF:89:81:51:8F:99:13:DC:BF:44:47:0E:A9:8D"
 );
-const kBugzillaURI = "https://bugzilla-stage-tip.mozilla.org/";
-*/
 
+/*
 const kServer = new BugzillaServer(
   "https://api-dev.bugzilla.mozilla.org/0.1/",
   "75:B2:EF:89:81:51:8F:99:13:DC:BF:44:47:0E:A9:8D"
 );
-
-const kBugzillaURI = "https://bugzilla.mozilla.org/";
-const kBugzillaRealm = "bugzilla-helper";
+*/
 
 ////////////////////////////////////////////////////////////////////////////////
 //// Dialog Controller
 
 var ReplyDialog = {
   initialize: function RD_initialize()
   {
     let label = document.getElementById("comment-label");
@@ -35,93 +32,35 @@ var ReplyDialog = {
     });
     comment.value = lines.join("\n") + "\n";
     comment.focus();
   },
 
   onAccept: function RD_onAccept()
   {
     let bugID = window.arguments[0];
-    let [username, password, store] = this.getLoginInformation();
+    let [username, password, store] = Helper.getLoginInformation();
     // XXX handle incorrect auth
     let auth = new BugzillaAuth(username, password);
-    let callback = function(aResponseCode, aResponse, aComment, aIsPrivate) {
-      if (aResponseCode == 200) {
-        if (store)
-          ReplyDialog.storePassword(username, password);
-        return;
-      }
-      // We had something unexpected.  Tell the user.
-      alert("Got HTTP/" + aResponseCode + "\n" + aResponse + "\n for comment" +
-            aComment);
+    let comment = document.getElementById("comment").value;
+    let isPrivate = document.getElementById("private").checked;
+    let callback = Helper.commentCallback;
+    let context = {
+      bug: bugID,
+      auth: auth,
+      comment: comment,
+      isPrivate: isPrivate,
     };
 
-    BugzillaAPI.addComment(kServer, bugID, auth, comment, isPrivate, callback);
+    BugzillaAPI.addComment(kServer, bugID, auth, comment, isPrivate, callback,
+                           context);
     // TODO add to activity manager
     return true;
   },
 
-  getLoginInformation: function RD_getLoginInformation()
-  {
-    // NOTE this isn't my actually password.  I changed it on the staging server
-    // to be something weak.
-    let shouldStore = false;
-    let [username, password] = this.getStoredPassword();
-    if (!username || !password) {
-      shouldStore = true;
-      [username, password] = this.promptForPassword();
-    }
-
-    return [username, password, shouldStore];
-  },
-
-  getStoredPassword: function RD_getStoredPassword()
-  {
-    let lm = Components.classes["@mozilla.org/login-manager;1"]
-                       .getService(Components.interfaces.nsILoginManager);
-    let logins = lm.findLogins({}, kBugzillaURI, null, kBugzillaRealm);
-    if (!logins.length)
-      return [null, null];
-    return [logins[0].username, logins[0].password];
-  },
-
-  promptForPassword: function RD_promptForPassword()
-  {
-    let ps = Components.classes["@mozilla.org/network/default-prompt;1"]
-                       .getService(Components.interfaces.nsIAuthPrompt);
-    let username = { value: null };
-    let password = { value: null };
-    let result = ps.promptUsernameAndPassword(
-      "Bugzilla Authentication",
-      "We'll need your bugzilla username and password to carry on.",
-      kBugzillaRealm,
-      Components.interfaces.nsIAuthPrompt.SAVE_PASSWORD_PERMANENTLY,
-      username,
-      password
-    );
-    if (!result)
-      return [null, null];
-
-    return [username.value, password.value];
-  },
-
-  storePassword: function RD_storePassword(aUsername,
-                                           aPassword)
-  {
-    // Create the login.
-    let l = Components.classes["@mozilla.org/login-manager/loginInfo;1"]
-                      .createInstance(Components.interfaces.nsILoginInfo);
-    l.init(kBugzillaURI, null, kBugzillaRealm, aUsername, aPassword, "", "");
-
-    // And store it.
-    let lm = Components.classes["@mozilla.org/login-manager;1"]
-                       .getService(Components.interfaces.nsILoginManager);
-    lm.addLogin(l);
-  },
-
   togglePrivate: function RD_togglePrivate()
   {
     let textbox = document.getElementById("comment");
     let checkbox = document.getElementById("private");
     textbox.className = checkbox.checked ? "private" : "";
   },
 };
 
--- a/resource/BugzillaAPI.jsm
+++ b/resource/BugzillaAPI.jsm
@@ -47,24 +47,16 @@ let EXPORTED_SYMBOLS = [
 
 ////////////////////////////////////////////////////////////////////////////////
 //// Constants
 
 const Cc = Components.classes;
 const Ci = Components.interfaces;
 const Cr = Components.results;
 
-///////////////////////////////////////////////////////////////////////////////
-//// Service Constructors
-
-let XMLHttpRequest = Components.constructor(
-  "@mozilla.org/xmlextras/xmlhttprequest;1",
-  "nsIXMLHttpRequest"
-);
-
 ////////////////////////////////////////////////////////////////////////////////
 //// BugzillaAPI
 
 const BugzillaAPI = {
   /**
    * Adds a comment to the specified bug.
    *
    * @param aServer
@@ -77,49 +69,50 @@ const BugzillaAPI = {
    *        The text of the comment to add to aBugNumber.
    * @param aIsPrivate
    *        Indicates if this comment should be marked as private or not.
    * @param aCallback
    *        The function to call on error or completion with the following
    *        arguments:
    *        aResponseCode - the HTTP response code from the request
    *        aResponse     - the body of the HTTP response
-   *        aComment      - the comment that was sent
-   *        aIsPrivate    - indicating if the comment was private or not
+   *        aContext      - the context given to the original function call
+   * @param aContext [optional]
+   *        An object to be passed back to the callback.
    */
   addComment: function BAPI_addComment(aServer,
                                        aBugNumber,
                                        aAuth,
                                        aComment,
                                        aIsPrivate,
-                                       aCallback)
+                                       aCallback,
+                                       aContext)
   {
     if (!(aServer instanceof BugzillaServer)) {
       throw new Components.Exception(
         "Server must be a BugzillaServer object",
         Cr.NS_ERROR_INVALID_ARG,
         Components.stack.caller
       );
     }
     if (!(aAuth instanceof BugzillaAuth)) {
       throw new Components.Exception(
         "Authentication must be a BugzillaAuth object",
         Cr.NS_ERROR_INVALID_ARG,
         Components.stack.caller
       );
     }
 
-    let uri = aServer.uri + "bug/" + aBugNumber + "/comment?" +
-              aAuth.getAuthString();
+    let uri = aServer.uri + "bug/" + aBugNumber + "/comment?" + aAuth.authString;
     let data = JSON.stringify({
       is_private: aIsPrivate ? 1 : 0,
       text: aComment,
     });
     let callback = function(aResponseCode, aResponse) {
-      aCallback(aResponseCode, aResponse, aComment, aIsPrivate);
+      aCallback(aResponseCode, aResponse, aContext);
     };
 
     performRequest(aServer, uri, callback, data);
   },
 };
 
 ////////////////////////////////////////////////////////////////////////////////
 //// BugzillaServer
@@ -193,17 +186,18 @@ BugzillaAuth.prototype = {
  */
 function UntrustedHttpsRequest(aFingerprint)
 {
   if (!aFingerprint) {
     throw new Components.Exception("Must provide an MD5 fingerprint!",
                                    Cr.NS_ERROR_INVALID_ARG,
                                    Components.stack.caller);
   }
-  let req = new XMLHttpRequest();
+  let req = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"].
+            createInstance(Ci.nsIXMLHttpRequest);
   this.__proto__.__proto__ = req;
   this._wrappedOpen = req.open;
   this._callback._fingerprint = aFingerprint;
 }
 
 UntrustedHttpsRequest.prototype = {
   //////////////////////////////////////////////////////////////////////////////
   //// UntrustedHttpsRequest
@@ -256,17 +250,19 @@ UntrustedHttpsRequest.prototype = {
 
   //////////////////////////////////////////////////////////////////////////////
   //// XMLHttpRequest
 
   open: function UHR_open(aMethod, aURI)
   {
     // We want to make sure that the certificate will be added, so we open up
     // another request now to the address.
-    let req = new XMLHttpRequest();
+
+    let req = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"].
+              createInstance(Ci.nsIXMLHttpRequest);
     req.open("HEAD", aURI, false);
     req.channel.notificationCallbacks = this._callback;
     try {
       req.send(null);
     }
     catch (e) {
       // Unconditionally catch the exception about the load failing.
     }
@@ -300,17 +296,20 @@ UntrustedHttpsRequest.prototype = {
 function performRequest(aServer,
                         aURI,
                         aCallback,
                         aData)
 {
   // TODO handle offline
   let req = new UntrustedHttpsRequest(aServer.fingerprint);
   let type = aData ? "POST" : "GET";
+  Components.utils.reportError(aURI);
   req.open(type, aURI, true);
   req.overrideMimeType("application/json");
   req.setRequestHeader("Accept", "application/json");
   req.onreadystatechange = function(aEvent) {
+    Components.utils.reportError(req.readyState + "\n" + req.status);
     if (req.readyState == 4)
       aCallback(req.status, req.responseText);
   };
+  Components.utils.reportError(aData);
   req.send(aData);
 }
new file mode 100644
--- /dev/null
+++ b/resource/BugzillaHelper.jsm
@@ -0,0 +1,137 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ * vim: sw=2 ts=2 sts=2 et filetype=javascript
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Bugzilla Helper JS module code.
+ *
+ * The Initial Developer of the Original Code is
+ * Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Shawn Wilsher <me@shawnwilsher.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+Components.utils.import("resource://bugzilla-helper/BugzillaAPI.jsm");
+
+let EXPORTED_SYMBOLS = [
+  "Helper",
+];
+
+////////////////////////////////////////////////////////////////////////////////
+//// Constants
+
+const Cc = Components.classes;
+const Ci = Components.interfaces;
+const Cr = Components.results;
+
+// DEBUG constants
+const kBugzillaURI = "https://bugzilla-stage-tip.mozilla.org/";
+
+/*
+const kBugzillaURI = "https://bugzilla.mozilla.org/";
+*/
+const kBugzillaRealm = "bugzilla-helper";
+
+////////////////////////////////////////////////////////////////////////////////
+//// Dialog Controller
+
+const Helper = {
+  commentCallback: function H_commentHandler(aResponseCode,
+                                             aResponse,
+                                             aContext)
+  {
+    if (aResponseCode == 200) {
+      if (store)
+        Helper.storePassword(username, password);
+      return;
+    }
+    // We had something unexpected.  Tell the user.
+    // XXX dispatch to notification box (id="mail-notification-box" in parent)
+    Components.utils.reportError("Got HTTP/" + aResponseCode + "\n" +
+                                 aResponse + "\n for comment" + aContext.comment);
+  },
+
+  getLoginInformation: function H_getLoginInformation()
+  {
+    // NOTE this isn't my actually password.  I changed it on the staging server
+    // to be something weak.
+    let shouldStore = false;
+    let [username, password] = Helper.getStoredPassword();
+    if (!username || !password) {
+      shouldStore = true;
+      [username, password] = Helper.promptForPassword();
+    }
+
+    return [username, password, shouldStore];
+  },
+
+  getStoredPassword: function H_getStoredPassword()
+  {
+    let lm = Components.classes["@mozilla.org/login-manager;1"]
+                       .getService(Components.interfaces.nsILoginManager);
+    let logins = lm.findLogins({}, kBugzillaURI, null, kBugzillaRealm);
+    if (!logins.length)
+      return [null, null];
+    return [logins[0].username, logins[0].password];
+  },
+
+  promptForPassword: function H_promptForPassword()
+  {
+    let ps = Components.classes["@mozilla.org/network/default-prompt;1"]
+                       .getService(Components.interfaces.nsIAuthPrompt);
+    let username = { value: null };
+    let password = { value: null };
+    let result = ps.promptUsernameAndPassword(
+      "Bugzilla Authentication",
+      "We'll need your bugzilla username and password to carry on.",
+      kBugzillaRealm,
+      Components.interfaces.nsIAuthPrompt.SAVE_PASSWORD_PERMANENTLY,
+      username,
+      password
+    );
+    if (!result)
+      return [null, null];
+
+    return [username.value, password.value];
+  },
+
+  storePassword: function H_storePassword(aUsername,
+                                          aPassword)
+  {
+    // Create the login.
+    let l = Components.classes["@mozilla.org/login-manager/loginInfo;1"]
+                      .createInstance(Components.interfaces.nsILoginInfo);
+    l.init(kBugzillaURI, null, kBugzillaRealm, aUsername, aPassword, "", "");
+
+    // And store it.
+    let lm = Components.classes["@mozilla.org/login-manager;1"]
+                       .getService(Components.interfaces.nsILoginManager);
+    lm.addLogin(l);
+  },
+};