summaryrefslogtreecommitdiffstats
path: root/security/manager/ssl/tests/unit/test_password_prompt.js
diff options
context:
space:
mode:
Diffstat (limited to 'security/manager/ssl/tests/unit/test_password_prompt.js')
-rw-r--r--security/manager/ssl/tests/unit/test_password_prompt.js87
1 files changed, 87 insertions, 0 deletions
diff --git a/security/manager/ssl/tests/unit/test_password_prompt.js b/security/manager/ssl/tests/unit/test_password_prompt.js
new file mode 100644
index 0000000000..cf4c6db7bf
--- /dev/null
+++ b/security/manager/ssl/tests/unit/test_password_prompt.js
@@ -0,0 +1,87 @@
+// -*- indent-tabs-mode: nil; js-indent-level: 2 -*-
+// Any copyright is dedicated to the Public Domain.
+// http://creativecommons.org/publicdomain/zero/1.0/
+"use strict";
+
+// Tests that PSM can successfully ask for a password from the user and relay it
+// back to NSS. Does so by mocking out the actual dialog and "filling in" the
+// password. Also tests that providing an incorrect password will fail (well,
+// technically the user will just get prompted again, but if they then cancel
+// the dialog the overall operation will fail).
+
+var gMockPrompter = {
+ passwordToTry: null,
+ numPrompts: 0,
+
+ // This intentionally does not use arrow function syntax to avoid an issue
+ // where in the context of the arrow function, |this != gMockPrompter| due to
+ // how objects get wrapped when going across xpcom boundaries.
+ promptPassword(dialogTitle, text, password, checkMsg, checkValue) {
+ this.numPrompts++;
+ if (this.numPrompts > 1) {
+ // don't keep retrying a bad password
+ return false;
+ }
+ equal(
+ text,
+ "Please enter your Primary Password.",
+ "password prompt text should be as expected"
+ );
+ equal(checkMsg, null, "checkMsg should be null");
+ ok(this.passwordToTry, "passwordToTry should be non-null");
+ password.value = this.passwordToTry;
+ return true;
+ },
+
+ QueryInterface: ChromeUtils.generateQI(["nsIPrompt"]),
+};
+
+// Mock nsIWindowWatcher. PSM calls getNewPrompter on this to get an nsIPrompt
+// to call promptPassword. We return the mock one, above.
+var gWindowWatcher = {
+ getNewPrompter: () => gMockPrompter,
+ QueryInterface: ChromeUtils.generateQI(["nsIWindowWatcher"]),
+};
+
+function run_test() {
+ do_get_profile();
+
+ let windowWatcherCID = MockRegistrar.register(
+ "@mozilla.org/embedcomp/window-watcher;1",
+ gWindowWatcher
+ );
+ registerCleanupFunction(() => {
+ MockRegistrar.unregister(windowWatcherCID);
+ });
+
+ // Set an initial password.
+ let tokenDB = Cc["@mozilla.org/security/pk11tokendb;1"].getService(
+ Ci.nsIPK11TokenDB
+ );
+ let token = tokenDB.getInternalKeyToken();
+ token.initPassword("hunter2");
+ token.logoutSimple();
+
+ // Try with the correct password.
+ gMockPrompter.passwordToTry = "hunter2";
+ // Using nsISecretDecoderRing will cause the password prompt to come up if the
+ // token has a password and is logged out.
+ let sdr = Cc["@mozilla.org/security/sdr;1"].getService(
+ Ci.nsISecretDecoderRing
+ );
+ sdr.encryptString("poke");
+ equal(gMockPrompter.numPrompts, 1, "should have prompted for password once");
+
+ // Reset state.
+ gMockPrompter.numPrompts = 0;
+ token.logoutSimple();
+
+ // Try with an incorrect password.
+ gMockPrompter.passwordToTry = "*******";
+ throws(
+ () => sdr.encryptString("poke2"),
+ /NS_ERROR_FAILURE/,
+ "logging in with the wrong password should fail"
+ );
+ equal(gMockPrompter.numPrompts, 2, "should have prompted for password twice");
+}