aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--docs/passwords.md51
-rw-r--r--lib/libbugzilla.js135
-rw-r--r--lib/passwords.js58
-rw-r--r--tests/test-password.js18
4 files changed, 79 insertions, 183 deletions
diff --git a/docs/passwords.md b/docs/passwords.md
deleted file mode 100644
index 283c54b..0000000
--- a/docs/passwords.md
+++ /dev/null
@@ -1,51 +0,0 @@
-The `passwords` module provides access to the Firefox Password Manager.
-
-<api name="setPassword">
-@method
-The `setPassword` method sets new authentication pair to the encrypted
-Firefox's nsILoginManager.
-
-It is most useful for storing sensitive data with private information
-to the store. It is most useful in situation where script would need
-some personal information, but it is our responsibility to store it
-securely.
-
-@param username {string} login name
-@param pass {string} password
-@param domain {string} hostname of the server we are connecting to as URL.
-As for example "http://bugzilla.mozilla.org"
-@param realm {string} String distinguishing this login to other ones for
-the same hostname.
-
-@returns {string}
-</api>
-
-<api name="getPassword">
-@method
-The `getPassword` method returns the password specified by the
-parameters of this function.
-
-@param username {string} login name
-@param domain {string} the same as in `setPassword` method.
-@param realm {string} the same as in `setPassword` method.
-
-@returns {string}
-</api>
-
-<api name="removePassword">
-@method
-The `removePassword` method remove the login information from the storage.
-Note that the serach parameters of this function must much **EXACTLY**
-parameters of the corresponding call to `setPassword`.
-
-@param username {string} login name
-@param domain {string} the same as in `setPassword` method.
-@param realm {string} the same as in `setPassword` method.
-
-@returns {string}
-</api>
-
-Examples
---------
-
-For examples see `tests/test-password.js` \ No newline at end of file
diff --git a/lib/libbugzilla.js b/lib/libbugzilla.js
index 28e2be1..aeccead 100644
--- a/lib/libbugzilla.js
+++ b/lib/libbugzilla.js
@@ -73,36 +73,53 @@ function getRealBugNoSlow(bugNo, location, callback) {
}).get();
}
-function getPassword(login, domain) {
+function getPassword(login, domain, callback) {
var passPrompt = "Enter your Bugzilla password for fixing MIME attachment types";
var switchPrompt = "Do you want to switch off features requiring password completely";
var prefName = BTSPrefNS+"withoutPassowrd";
-
- var pass = passUtils.getPassword(login,
- domain, BTSPassRealm);
var retObject = {
password: null, // password string or null if no password provided
withoutPass: false // whether user doesn't want to use password at all
};
- // pass === null means no appropriate password in the storage
- if (!preferences.get(prefName,false) && (pass === null)) {
- var passwordText = prompts.promptPassword(passPrompt);
- if (passwordText && passwordText.length > 0) {
- passUtils.setLogin(login, passwordText, domain,
- BTSPassRealm);
- retObject.password = passwordText;
- } else {
- var switchOff = prompts.promptYesNoCancel(switchPrompt);
- if (switchOff) {
- preferences.set(prefName,true);
+ passUtils.search({
+ username: login,
+ url: domain,
+ realm: BTSPassRealm,
+ onComplete: function onComplete([credential]) {
+ if (credential) {
+ // We found the password, just go ahead and use it
+ retObject.password = credential.password;
+ callback(retObject);
+ } else {
+ // We don't have a stored password, ask for one
+ var passwordText = prompts.promptPassword(passPrompt);
+ if (passwordText && passwordText.length > 0) {
+ // Right, we've got it … store it and then use it.
+ retObject.password = passwordText;
+ passUtils.store({
+ username: login,
+ password: passwordText,
+ url: domain,
+ realm: BTSPassRealm,
+ onComplete: function onComplete() {
+ callback(retObject);
+ }
+ });
+ } else {
+ // We don't have password, and user haven't entered one?
+ // Does he want to live passwordless?
+ // FIXME should we call the callback at all?
+ var switchOff = prompts.promptYesNoCancel(switchPrompt);
+ if (switchOff) {
+ preferences.set(prefName,true);
+ }
+ retObject.withoutPass = switchOff;
+ callback(retObject);
+ }
}
- retObject.withoutPass = switchOff;
}
- } else {
- retObject.password = pass;
- }
- return retObject;
+ });
}
exports.changeJSONURL = function changeJSONURL() {
@@ -184,20 +201,21 @@ exports.getInstalledPackages = function getInstalledPackages(locationLoginObj, c
var locURL = new urlMod.URL(locationLoginObj.location);
var passDomain = locURL.scheme + "://" + locURL.host;
- var passwObj = getPassword(locationLoginObj.login, passDomain);
- // In order to avoid sending whole password to the content script,
- // we are sending just these two Booleans.
- config.constantData.passwordState = {
- passAvailable: (passwObj.password !== null),
- withoutPass: passwObj.withoutPass
- };
-
- callback(new Message("CreateButtons", {
- instPkgs: installedPackages,
- constData: config.constantData,
- config: config.configData,
- kNodes: config.gJSONData.configData.killNodes
- }));
+ getPassword(locationLoginObj.login, passDomain, function (passwObj) {
+ // In order to avoid sending whole password to the content script,
+ // we are sending just these two Booleans.
+ config.constantData.passwordState = {
+ passAvailable: (passwObj.password !== null),
+ withoutPass: passwObj.withoutPass
+ };
+
+ callback(new Message("CreateButtons", {
+ instPkgs: installedPackages,
+ constData: config.constantData,
+ config: config.configData,
+ kNodes: config.gJSONData.configData.killNodes
+ }));
+ });
};
exports.getClipboard = function getClipboard(cb) {
@@ -261,29 +279,34 @@ exports.createUpstreamBug = function createUpstreamBug(urlStr, subject, comment)
// Make a XML-RPC call ... most of the business logic should stay in the content script
exports.makeXMLRPCCall = function makeXMLRPCCall(url, login, method, params, callback) {
var urlObj = urlMod.URL(url);
- var passwObj = getPassword(login, urlObj.schema + "://" + urlObj.host);
- if (!passwObj.password) {
- return null; // TODO this should happen, only when user presses Escape in password prompt
- }
-
- var msg = new xrpc.XMLRPCMessage(method);
- params.forEach(function (par) {
- msg.addParameter(par);
- });
- msg.addParameter(login);
- msg.addParameter(passwObj.password);
-
- Request({
- url: url,
- onComplete: function(response) {
- if (response.status == 200) {
- var resp = parseXMLfromString(response.text);
- callback(resp.toXMLString());
+ getPassword(login,
+ urlObj.schema + "://" + urlObj.host,
+ function (passwObj) {
+ if (!passwObj.password) {
+ // TODO this should happen, only when user presses Escape in password prompt
+ return null;
}
- },
- content: msg.xml(),
- contentType: "text/xml"
- }).post();
+
+ var msg = new xrpc.XMLRPCMessage(method);
+ params.forEach(function (par) {
+ msg.addParameter(par);
+ });
+ msg.addParameter(login);
+ msg.addParameter(passwObj.password);
+
+ Request({
+ url: url,
+ onComplete: function(response) {
+ if (response.status == 200) {
+ var resp = parseXMLfromString(response.text);
+ callback(resp.toXMLString());
+ }
+ },
+ content: msg.xml(),
+ contentType: "text/xml"
+ }).post();
+ }
+ );
};
exports.initialize = function initialize(config, callback) {
diff --git a/lib/passwords.js b/lib/passwords.js
deleted file mode 100644
index af76f47..0000000
--- a/lib/passwords.js
+++ /dev/null
@@ -1,58 +0,0 @@
-// Released under the MIT/X11 license
-// http://www.opensource.org/licenses/mit-license.php
-"use strict";
-var Cc = require("chrome").Cc;
-var Ci = require("chrome").Ci;
-var components = require("chrome").components;
-
-function getLoginInfo(username, pass,
- domain, realm) {
- var nsLoginInfo = new components.
- Constructor("@mozilla.org/login-manager/loginInfo;1",
- Ci.nsILoginInfo, "init");
- return new nsLoginInfo(domain,
- null, realm, username, pass, "", "");
-}
-
-function getPasswordManager() {
- return Cc["@mozilla.org/login-manager;1"].
- getService(Ci.nsILoginManager);
-}
-
-exports.setLogin = function setLogin (username, pass,
- domain, realm) {
- var lInfo = getLoginInfo(username, pass, domain, realm);
- getPasswordManager().addLogin(lInfo);
-};
-
-var getPassword = exports.getPassword = function getPassword(username,
- domain, realm) {
-
- var pwMgr = getPasswordManager();
- var logins = pwMgr.findLogins({}, domain, "", realm);
- var ourLogins = Array.filter(logins, function (x) {
- return (x.username = username);
- }, this);
- // What to do when we have more than one password?
- if (ourLogins.length > 0) {
- return ourLogins[0].password;
- } else {
- return null;
- }
-};
-
-exports.removeLogin = function removeLogin(username,
- domain, realm) {
- var pass = getPassword(username, domain, realm);
- var pwMgr = getPasswordManager();
- var logins = pwMgr.findLogins({}, domain, "", realm);
-
- // Don't do Array.forEach here ... emulating break there
- // is an abomination
- for (var i = 0, ii = logins.length; i < ii; i++) {
- if (logins[i].username === username) {
- pwMgr.removeLogin(logins[i]);
- break;
- }
- }
-};
diff --git a/tests/test-password.js b/tests/test-password.js
deleted file mode 100644
index e46ed9c..0000000
--- a/tests/test-password.js
+++ /dev/null
@@ -1,18 +0,0 @@
-/*jslint forin: true, rhino: true, onevar: false, browser: true, evil: true, laxbreak: true, undef: true, nomen: true, eqeqeq: true, bitwise: true, maxerr: 1000, immed: false, white: false, plusplus: false, regexp: false, undef: false */
-// Released under the MIT/X11 license
-// http://www.opensource.org/licenses/mit-license.php
-"use strict";
-var passMod = require("passwords");
-var BTSRealm = "BTSTest";
-var testLogin = "testUser";
-var testPass = "verySecret";
-var testDomain = "http://www.example.com";
-
-exports.ensurePasswordMachinery = function (test) {
- passMod.setLogin(testLogin, testPass,
- testDomain, BTSRealm);
- test.assertEqual(passMod.getPassword(testLogin,
- testDomain, BTSRealm), testPass, "");
- passMod.removeLogin(testLogin, testPass,
- testDomain, BTSRealm);
-};