diff options
author | Matěj Cepl <mcepl@redhat.com> | 2011-03-23 13:13:09 +0100 |
---|---|---|
committer | Matěj Cepl <mcepl@redhat.com> | 2011-03-23 13:13:09 +0100 |
commit | 47e405b5b74839a53aeea2887a7cee87787d3f28 (patch) | |
tree | 81bad14cf271e119e441fc9a01e98e7f34639f41 | |
parent | fae26306deee2d4dd95c2f4704f320b2b6747e29 (diff) | |
download | bugzilla-triage-47e405b5b74839a53aeea2887a7cee87787d3f28.tar.gz |
Convert to using passwords.js from Add-on SDK, not out own.
Exccessive callbacks are considered harmful!
-rw-r--r-- | docs/passwords.md | 51 | ||||
-rw-r--r-- | lib/libbugzilla.js | 135 | ||||
-rw-r--r-- | lib/passwords.js | 58 | ||||
-rw-r--r-- | tests/test-password.js | 18 |
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); -}; |