Commit bb1dbfa4 authored by Johannes J. Schmidt's avatar Johannes J. Schmidt
Browse files

Bug 1832490 - make LoginManagerAuthPrompter promts async...

Bug 1832490 - make LoginManagerAuthPrompter promts async r=credential-management-reviewers,necko-reviewers,jesup,dimi

to use `addLoginAsync` instead of `addLogin`.

Differential Revision: https://phabricator.services.mozilla.com/D178285
parent ed04a950
Loading
Loading
Loading
Loading
+42 −1
Original line number Diff line number Diff line
@@ -37,7 +37,6 @@ interface nsIAuthPrompt : nsISupports

    /**
     * Puts up a username/password dialog with OK and Cancel buttons.
     * Puts up a password dialog with OK and Cancel buttons.
     * @param  dialogText    The title for the dialog.
     * @param  text          The text to display in the dialog.
     * @param  passwordRealm The "realm" the password belongs to: e.g.
@@ -55,6 +54,25 @@ interface nsIAuthPrompt : nsISupports
                                      inout wstring user,
                                      inout wstring pwd);

    /**
     * Puts up an async username/password dialog with OK and Cancel buttons.
     * @param  dialogText    The title for the dialog.
     * @param  text          The text to display in the dialog.
     * @param  passwordRealm The "realm" the password belongs to: e.g.
     *                       ldap://localhost/dc=test
     * @param  savePassword  One of the SAVE_PASSWORD_* options above.
     * @param  user          The username entered in the dialog.
     * @param  pwd           The password entered by the user if OK was
     *                       selected.
     * @return promise resolving to true for OK, false for Cancel
     */
    Promise asyncPromptUsernameAndPassword(in wstring dialogTitle,
                                      in wstring text,
                                      in wstring passwordRealm,
                                      in uint32_t savePassword,
                                      inout wstring user,
                                      inout wstring pwd);

    /**
     * Puts up a password dialog with OK and Cancel buttons.
     * @param  dialogText    The title for the dialog.
@@ -77,4 +95,27 @@ interface nsIAuthPrompt : nsISupports
                           in wstring passwordRealm,
                           in uint32_t savePassword,
                           inout wstring pwd);

    /**
     * Puts up an async password dialog with OK and Cancel buttons.
     * @param  dialogText    The title for the dialog.
     * @param  text          The text to display in the dialog.
     * @param  passwordRealm The "realm" the password belongs to: e.g.
     *                       ldap://localhost/dc=test. If a username is
     *                       specified (http://user@site.com) it will be used
     *                       when matching existing logins or saving new ones.
     *                       If no username is specified, only password-only
     *                       logins will be matched or saved.
     *                       Note: if a username is specified, the username
     *                       should be escaped.
     * @param  savePassword  One of the SAVE_PASSWORD_* options above.
     * @param  pwd           The password entered by the user if OK was
     *                       selected.
     * @return promise resolving to true for OK, false for Cancel
     */
    Promise asyncPromptPassword(in wstring dialogTitle,
                           in wstring text,
                           in wstring passwordRealm,
                           in uint32_t savePassword,
                           inout wstring pwd);
};
+5 −5
Original line number Diff line number Diff line
@@ -383,7 +383,7 @@ LoginManagerAuthPrompter.prototype = {
   * Looks up a username and password in the database. Will prompt the user
   * with a dialog, even if a username and password are found.
   */
  promptUsernameAndPassword(
  async asyncPromptUsernameAndPassword(
    aDialogTitle,
    aText,
    aPasswordRealm,
@@ -393,7 +393,7 @@ LoginManagerAuthPrompter.prototype = {
  ) {
    if (aSavePassword == Ci.nsIAuthPrompt.SAVE_PASSWORD_FOR_SESSION) {
      throw new Components.Exception(
        "promptUsernameAndPassword doesn't support SAVE_PASSWORD_FOR_SESSION",
        "asyncPromptUsernameAndPassword doesn't support SAVE_PASSWORD_FOR_SESSION",
        Cr.NS_ERROR_NOT_IMPLEMENTED
      );
    }
@@ -474,7 +474,7 @@ LoginManagerAuthPrompter.prototype = {
    if (!selectedLogin) {
      // add as new
      this.log(`New login seen for: ${realm}.`);
      Services.logins.addLogin(newLogin);
      await Services.logins.addLoginAsync(newLogin);
    } else if (aPassword.value != selectedLogin.password) {
      // update password
      this.log(`Updating password for ${realm}.`);
@@ -500,7 +500,7 @@ LoginManagerAuthPrompter.prototype = {
   * with a dialog with a text field and ok/cancel buttons. If the user
   * allows it, then the password will be saved in the database.
   */
  promptPassword(
  async asyncPromptPassword(
    aDialogTitle,
    aText,
    aPasswordRealm,
@@ -560,7 +560,7 @@ LoginManagerAuthPrompter.prototype = {

      this.log(`New login seen for ${realm}.`);

      Services.logins.addLogin(newLogin);
      await Services.logins.addLoginAsync(newLogin);
    }

    return ok;
+25 −25
Original line number Diff line number Diff line
@@ -2,7 +2,7 @@
<html>
<head>
  <meta charset="utf-8">
  <title>Test prompter.{prompt,promptPassword,promptUsernameAndPassword}</title>
  <title>Test prompter.{prompt,asyncPromptPassword,asyncPromptUsernameAndPassword}</title>
  <script src="/tests/SimpleTest/SimpleTest.js"></script>
  <script type="text/javascript" src="pwmgr_common.js"></script>
  <script type="text/javascript" src="../../../prompts/test/prompt_common.js"></script>
@@ -32,8 +32,8 @@ let prompterParent = runInParent(() => {
  let chromeWin = Services.wm.getMostRecentWindow("navigator:browser");
  let prompter1 = promptFac.getPrompt(chromeWin, Ci.nsIAuthPrompt);

  addMessageListener("proxyPrompter", function onMessage(msg) {
    let rv = prompter1[msg.methodName](...msg.args);
  addMessageListener("proxyPrompter", async function onMessage(msg) {
    let rv = await prompter1[msg.methodName](...msg.args);
    return {
      rv,
      // Send the args back to content so out/inout args can be checked.
@@ -136,7 +136,7 @@ add_task(async function test_promptPassword_defaultAccept() {
  };
  pword.value = "inputpw";
  promptDone = handlePrompt(state, action);
  isOk = prompter1.promptPassword(defaultTitle, defaultMsg, "http://example.com",
  isOk = await prompter1.asyncPromptPassword(defaultTitle, defaultMsg, "http://example.com",
                                  Ci.nsIAuthPrompt.SAVE_PASSWORD_NEVER, pword);
  await promptDone;
  ok(isOk, "Checking dialog return value (accept)");
@@ -165,7 +165,7 @@ add_task(async function test_promptPassword_defaultCancel() {
  };
  pword.value = "inputpw";
  promptDone = handlePrompt(state, action);
  isOk = prompter1.promptPassword(defaultTitle, defaultMsg, "http://example.com",
  isOk = await prompter1.asyncPromptPassword(defaultTitle, defaultMsg, "http://example.com",
                                  Ci.nsIAuthPrompt.SAVE_PASSWORD_NEVER, pword);
  await promptDone;
  ok(!isOk, "Checking dialog return value (cancel)");
@@ -194,7 +194,7 @@ add_task(async function test_promptPassword_emptyAccept() {
  };
  pword.value = null;
  promptDone = handlePrompt(state, action);
  isOk = prompter1.promptPassword(defaultTitle, defaultMsg, "http://nonexample.com",
  isOk = await prompter1.asyncPromptPassword(defaultTitle, defaultMsg, "http://nonexample.com",
                                  Ci.nsIAuthPrompt.SAVE_PASSWORD_NEVER, pword);
  await promptDone;
  ok(isOk, "Checking dialog return value (accept)");
@@ -204,7 +204,7 @@ add_task(async function test_promptPassword_emptyAccept() {
add_task(async function test_promptPassword_saved() {
  // No default password provided, matching login is returned w/o prompting.
  pword.value = null;
  isOk = prompter1.promptPassword(defaultTitle, defaultMsg, "http://example.com",
  isOk = await prompter1.asyncPromptPassword(defaultTitle, defaultMsg, "http://example.com",
                                  Ci.nsIAuthPrompt.SAVE_PASSWORD_NEVER, pword);
  ok(isOk, "Checking dialog return value (accept)");
  is(pword.value, "examplepass", "Checking returned password");
@@ -234,7 +234,7 @@ add_task(async function test_promptPassword_noMatchingPasswordForEmptyUN() {
  };
  pword.value = null;
  promptDone = handlePrompt(state, action);
  isOk = prompter1.promptPassword(defaultTitle, defaultMsg, "http://example2.com",
  isOk = await prompter1.asyncPromptPassword(defaultTitle, defaultMsg, "http://example2.com",
                                  Ci.nsIAuthPrompt.SAVE_PASSWORD_NEVER, pword);
  await promptDone;
  ok(isOk, "Checking dialog return value (accept)");
@@ -244,7 +244,7 @@ add_task(async function test_promptPassword_noMatchingPasswordForEmptyUN() {
add_task(async function test_promptPassword_matchingPWForUN() {
  // No default password provided, matching login is returned w/o prompting.
  pword.value = null;
  isOk = prompter1.promptPassword(defaultTitle, defaultMsg, "http://user1name@example2.com",
  isOk = await prompter1.asyncPromptPassword(defaultTitle, defaultMsg, "http://user1name@example2.com",
                                  Ci.nsIAuthPrompt.SAVE_PASSWORD_NEVER, pword);
  ok(isOk, "Checking dialog return value (accept)");
  is(pword.value, "user1pass", "Checking returned password");
@@ -253,7 +253,7 @@ add_task(async function test_promptPassword_matchingPWForUN() {
add_task(async function test_promptPassword_matchingPWForUN2() {
  // No default password provided, matching login is returned w/o prompting.
  pword.value = null;
  isOk = prompter1.promptPassword(defaultTitle, defaultMsg, "http://user2name@example2.com",
  isOk = await prompter1.asyncPromptPassword(defaultTitle, defaultMsg, "http://user2name@example2.com",
                                  Ci.nsIAuthPrompt.SAVE_PASSWORD_NEVER, pword);
  ok(isOk, "Checking dialog return value (accept)");
  is(pword.value, "user2pass", "Checking returned password");
@@ -262,7 +262,7 @@ add_task(async function test_promptPassword_matchingPWForUN2() {
add_task(async function test_promptPassword_matchingPWForUN3() {
  // No default password provided, matching login is returned w/o prompting.
  pword.value = null;
  isOk = prompter1.promptPassword(defaultTitle, defaultMsg, "http://user3%2Ename%40host@example2.com",
  isOk = await prompter1.asyncPromptPassword(defaultTitle, defaultMsg, "http://user3%2Ename%40host@example2.com",
                                  Ci.nsIAuthPrompt.SAVE_PASSWORD_NEVER, pword);
  ok(isOk, "Checking dialog return value (accept)");
  is(pword.value, "user3pass", "Checking returned password");
@@ -271,7 +271,7 @@ add_task(async function test_promptPassword_matchingPWForUN3() {
add_task(async function test_promptPassword_extraAt() {
  // No default password provided, matching login is returned w/o prompting.
  pword.value = null;
  isOk = prompter1.promptPassword(defaultTitle, defaultMsg, "http://100@beef@example2.com",
  isOk = await prompter1.asyncPromptPassword(defaultTitle, defaultMsg, "http://100@beef@example2.com",
                                  Ci.nsIAuthPrompt.SAVE_PASSWORD_NEVER, pword);
  ok(isOk, "Checking dialog return value (accept)");
  is(pword.value, "user3pass", "Checking returned password");
@@ -280,7 +280,7 @@ add_task(async function test_promptPassword_extraAt() {
add_task(async function test_promptPassword_usernameEncoding() {
  // No default password provided, matching login is returned w/o prompting.
  pword.value = null;
  isOk = prompter1.promptPassword(defaultTitle, defaultMsg, "http://100%25beef@example2.com",
  isOk = await prompter1.asyncPromptPassword(defaultTitle, defaultMsg, "http://100%25beef@example2.com",
                                  Ci.nsIAuthPrompt.SAVE_PASSWORD_NEVER, pword);
  ok(isOk, "Checking dialog return value (accept)");
  is(pword.value, "user3pass", "Checking returned password");
@@ -311,7 +311,7 @@ add_task(async function test_promptPassword_realm() {
  };
  pword.value = null;
  promptDone = handlePrompt(state, action);
  isOk = prompter1.promptPassword(defaultTitle, defaultMsg, "example2.com:80 (somerealm)",
  isOk = await prompter1.asyncPromptPassword(defaultTitle, defaultMsg, "example2.com:80 (somerealm)",
                                  Ci.nsIAuthPrompt.SAVE_PASSWORD_NEVER, pword);
  await promptDone;
  ok(isOk, "Checking dialog return value (accept)");
@@ -341,7 +341,7 @@ add_task(async function test_promptPassword_realm2() {
  };
  pword.value = null;
  promptDone = handlePrompt(state, action);
  isOk = prompter1.promptPassword(defaultTitle, defaultMsg, "example2.com:80 (somerealm)",
  isOk = await prompter1.asyncPromptPassword(defaultTitle, defaultMsg, "example2.com:80 (somerealm)",
                                  Ci.nsIAuthPrompt.SAVE_PASSWORD_PERMANENTLY, pword);
  await promptDone;
  ok(isOk, "Checking dialog return value (accept)");
@@ -372,7 +372,7 @@ add_task(async function test_promptUsernameAndPassword_accept() {
  uname.value = "inuser";
  pword.value = "inpass";
  promptDone = handlePrompt(state, action);
  isOk = prompter1.promptUsernameAndPassword(defaultTitle, defaultMsg, "http://nonexample.com",
  isOk = await prompter1.asyncPromptUsernameAndPassword(defaultTitle, defaultMsg, "http://nonexample.com",
                                             Ci.nsIAuthPrompt.SAVE_PASSWORD_NEVER, uname, pword);
  await promptDone;
  ok(isOk, "Checking dialog return value (accept)");
@@ -402,7 +402,7 @@ add_task(async function test_promptUsernameAndPassword_cancel() {
  uname.value = "inuser";
  pword.value = "inpass";
  promptDone = handlePrompt(state, action);
  isOk = prompter1.promptUsernameAndPassword(defaultTitle, defaultMsg, "http://nonexample.com",
  isOk = await prompter1.asyncPromptUsernameAndPassword(defaultTitle, defaultMsg, "http://nonexample.com",
                                             Ci.nsIAuthPrompt.SAVE_PASSWORD_NEVER, uname, pword);
  await promptDone;
  ok(!isOk, "Checking dialog return value (cancel)");
@@ -431,7 +431,7 @@ add_task(async function test_promptUsernameAndPassword_autofill() {
  uname.value = null;
  pword.value = null;
  promptDone = handlePrompt(state, action);
  isOk = prompter1.promptUsernameAndPassword(defaultTitle, defaultMsg, "http://example.com",
  isOk = await prompter1.asyncPromptUsernameAndPassword(defaultTitle, defaultMsg, "http://example.com",
                                             Ci.nsIAuthPrompt.SAVE_PASSWORD_PERMANENTLY, uname, pword);
  await promptDone;
  ok(isOk, "Checking dialog return value (accept)");
@@ -463,7 +463,7 @@ add_task(async function test_promptUsernameAndPassword_multipleExisting() {
  uname.value = null;
  pword.value = null;
  promptDone = handlePrompt(state, action);
  isOk = prompter1.promptUsernameAndPassword(defaultTitle, defaultMsg, "http://example2.com",
  isOk = await prompter1.asyncPromptUsernameAndPassword(defaultTitle, defaultMsg, "http://example2.com",
                                             Ci.nsIAuthPrompt.SAVE_PASSWORD_PERMANENTLY, uname, pword);
  await promptDone;
  ok(isOk, "Checking dialog return value (accept)");
@@ -494,7 +494,7 @@ add_task(async function test_promptUsernameAndPassword_multipleExisting1() {
  uname.value = "user1name";
  pword.value = null;
  promptDone = handlePrompt(state, action);
  isOk = prompter1.promptUsernameAndPassword(defaultTitle, defaultMsg, "http://example2.com",
  isOk = await prompter1.asyncPromptUsernameAndPassword(defaultTitle, defaultMsg, "http://example2.com",
                                             Ci.nsIAuthPrompt.SAVE_PASSWORD_PERMANENTLY, uname, pword);
  await promptDone;
  ok(isOk, "Checking dialog return value (accept)");
@@ -525,7 +525,7 @@ add_task(async function test_promptUsernameAndPassword_multipleExisting2() {
  uname.value = "user2name";
  pword.value = null;
  promptDone = handlePrompt(state, action);
  isOk = prompter1.promptUsernameAndPassword(defaultTitle, defaultMsg, "http://example2.com",
  isOk = await prompter1.asyncPromptUsernameAndPassword(defaultTitle, defaultMsg, "http://example2.com",
                                             Ci.nsIAuthPrompt.SAVE_PASSWORD_PERMANENTLY, uname, pword);
  await promptDone;
  ok(isOk, "Checking dialog return value (accept)");
@@ -557,7 +557,7 @@ add_task(async function test_promptUsernameAndPassword_passwordChange() {
  uname.value = "user2name";
  pword.value = null;
  promptDone = handlePrompt(state, action);
  isOk = prompter1.promptUsernameAndPassword(defaultTitle, defaultMsg, "http://example2.com",
  isOk = await prompter1.asyncPromptUsernameAndPassword(defaultTitle, defaultMsg, "http://example2.com",
                                             Ci.nsIAuthPrompt.SAVE_PASSWORD_PERMANENTLY, uname, pword);
  await promptDone;
  ok(isOk, "Checking dialog return value (accept)");
@@ -589,7 +589,7 @@ add_task(async function test_promptUsernameAndPassword_changePasswordBack() {
  uname.value = "user2name";
  pword.value = null;
  promptDone = handlePrompt(state, action);
  isOk = prompter1.promptUsernameAndPassword(defaultTitle, defaultMsg, "http://example2.com",
  isOk = await prompter1.asyncPromptUsernameAndPassword(defaultTitle, defaultMsg, "http://example2.com",
                                             Ci.nsIAuthPrompt.SAVE_PASSWORD_PERMANENTLY, uname, pword);
  await promptDone;
  ok(isOk, "Checking dialog return value (accept)");
@@ -622,7 +622,7 @@ add_task(async function test_promptUsernameAndPassword_realm() {
  uname.value = null;
  pword.value = null;
  promptDone = handlePrompt(state, action);
  isOk = prompter1.promptUsernameAndPassword(defaultTitle, defaultMsg, "example2.com:80 (somerealm)",
  isOk = await prompter1.asyncPromptUsernameAndPassword(defaultTitle, defaultMsg, "example2.com:80 (somerealm)",
                                             Ci.nsIAuthPrompt.SAVE_PASSWORD_NEVER, uname, pword);
  await promptDone;
  ok(isOk, "Checking dialog return value (accept)");
@@ -655,7 +655,7 @@ add_task(async function test_promptUsernameAndPassword_realm2() {
  uname.value = null;
  pword.value = null;
  promptDone = handlePrompt(state, action);
  isOk = prompter1.promptUsernameAndPassword(defaultTitle, defaultMsg, "example2.com:80 (somerealm)",
  isOk = await prompter1.asyncPromptUsernameAndPassword(defaultTitle, defaultMsg, "example2.com:80 (somerealm)",
                                             Ci.nsIAuthPrompt.SAVE_PASSWORD_PERMANENTLY, uname, pword);
  await promptDone;
  ok(isOk, "Checking dialog return value (accept)");
+4 −2
Original line number Diff line number Diff line
@@ -397,11 +397,13 @@ function PrompterProxy(chromeScript) {
              outParams = [];
              break;
            }
            case "promptPassword": {
            case "promptPassword":
            case "asyncPromptPassword": {
              outParams = [/* pwd */ 4];
              break;
            }
            case "promptUsernameAndPassword": {
            case "promptUsernameAndPassword":
            case "asyncPromptUsernameAndPassword": {
              outParams = [/* user */ 4, /* pwd */ 5];
              break;
            }