test_password_prompt.js (2896B)
1 // -*- indent-tabs-mode: nil; js-indent-level: 2 -*- 2 // Any copyright is dedicated to the Public Domain. 3 // http://creativecommons.org/publicdomain/zero/1.0/ 4 "use strict"; 5 6 // Tests that PSM can successfully ask for a password from the user and relay it 7 // back to NSS. Does so by mocking out the actual dialog and "filling in" the 8 // password. Also tests that providing an incorrect password will fail (well, 9 // technically the user will just get prompted again, but if they then cancel 10 // the dialog the overall operation will fail). 11 12 var gMockPrompter = { 13 passwordToTry: null, 14 numPrompts: 0, 15 16 // This intentionally does not use arrow function syntax to avoid an issue 17 // where in the context of the arrow function, |this != gMockPrompter| due to 18 // how objects get wrapped when going across xpcom boundaries. 19 promptPassword(dialogTitle, text, password, checkMsg) { 20 this.numPrompts++; 21 if (this.numPrompts > 1) { 22 // don't keep retrying a bad password 23 return false; 24 } 25 equal( 26 text, 27 "Please enter your Primary Password.", 28 "password prompt text should be as expected" 29 ); 30 equal(checkMsg, null, "checkMsg should be null"); 31 ok(this.passwordToTry, "passwordToTry should be non-null"); 32 password.value = this.passwordToTry; 33 return true; 34 }, 35 36 QueryInterface: ChromeUtils.generateQI(["nsIPrompt"]), 37 }; 38 39 // Mock nsIWindowWatcher. PSM calls getNewPrompter on this to get an nsIPrompt 40 // to call promptPassword. We return the mock one, above. 41 var gWindowWatcher = { 42 getNewPrompter: () => gMockPrompter, 43 QueryInterface: ChromeUtils.generateQI(["nsIWindowWatcher"]), 44 }; 45 46 function run_test() { 47 do_get_profile(); 48 49 let windowWatcherCID = MockRegistrar.register( 50 "@mozilla.org/embedcomp/window-watcher;1", 51 gWindowWatcher 52 ); 53 registerCleanupFunction(() => { 54 MockRegistrar.unregister(windowWatcherCID); 55 }); 56 57 // Set an initial password. 58 let tokenDB = Cc["@mozilla.org/security/pk11tokendb;1"].getService( 59 Ci.nsIPK11TokenDB 60 ); 61 let token = tokenDB.getInternalKeyToken(); 62 token.initPassword("hunter2"); 63 token.logoutSimple(); 64 65 // Try with the correct password. 66 gMockPrompter.passwordToTry = "hunter2"; 67 // Using nsISecretDecoderRing will cause the password prompt to come up if the 68 // token has a password and is logged out. 69 let sdr = Cc["@mozilla.org/security/sdr;1"].getService( 70 Ci.nsISecretDecoderRing 71 ); 72 sdr.encryptString("poke"); 73 equal(gMockPrompter.numPrompts, 1, "should have prompted for password once"); 74 75 // Reset state. 76 gMockPrompter.numPrompts = 0; 77 token.logoutSimple(); 78 79 // Try with an incorrect password. 80 gMockPrompter.passwordToTry = "*******"; 81 throws( 82 () => sdr.encryptString("poke2"), 83 /NS_ERROR_FAILURE/, 84 "logging in with the wrong password should fail" 85 ); 86 equal(gMockPrompter.numPrompts, 2, "should have prompted for password twice"); 87 }