// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/command_line.h"
#include "base/macros.h"
#include "base/stl_util.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "base/test/scoped_feature_list.h"
#include "chrome/browser/password_manager/chrome_password_manager_client.h"
#include "chrome/browser/password_manager/password_manager_test_base.h"
#include "chrome/browser/password_manager/password_store_factory.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/profiles/profile_io_data.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/passwords/passwords_model_delegate.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/test/base/ui_test_utils.h"
#include "components/password_manager/core/browser/password_bubble_experiment.h"
#include "components/password_manager/core/browser/test_password_store.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_contents_observer.h"
#include "content/public/common/content_features.h"
#include "content/public/common/content_switches.h"
#include "content/public/test/browser_test.h"
#include "content/public/test/browser_test_utils.h"
#include "net/dns/mock_host_resolver.h"

namespace {

class CredentialManagerBrowserTest : public PasswordManagerBrowserTestBase {
 public:
  CredentialManagerBrowserTest() {
    scoped_feature_list_.InitAndEnableFeature(features::kWebAuth);
  }

  void SetUpOnMainThread() override {
    PasswordManagerBrowserTestBase::SetUpOnMainThread();
    // Redirect all requests to localhost.
    host_resolver()->AddRule("*", "127.0.0.1");
  }

  bool IsShowingAccountChooser() {
    return PasswordsModelDelegateFromWebContents(WebContents())->GetState() ==
           password_manager::ui::CREDENTIAL_REQUEST_STATE;
  }

  void SetUpCommandLine(base::CommandLine* command_line) override {
    // To permit using webauthentication features.
    command_line->AppendSwitch(
        switches::kEnableExperimentalWebPlatformFeatures);
  }

  // Similarly to PasswordManagerBrowserTestBase::NavigateToFile this is a
  // wrapper around ui_test_utils::NavigateURL that waits until DidFinishLoad()
  // fires. Different to NavigateToFile this method allows passing a test_server
  // and modifications to the hostname.
  void NavigateToURL(const net::EmbeddedTestServer& test_server,
                     const std::string& hostname,
                     const std::string& relative_url) {
    NavigationObserver observer(WebContents());
    GURL url = test_server.GetURL(hostname, relative_url);
    ui_test_utils::NavigateToURL(browser(), url);
    observer.Wait();
  }

  // Triggers a call to `navigator.credentials.get` to retrieve passwords, waits
  // for success, and ASSERTs that |expect_has_results| is satisfied.
  void TriggerNavigatorGetPasswordCredentialsAndExpectHasResult(
      content::WebContents* web_contents,
      bool expect_has_results) {
    bool result = false;
    ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
        web_contents,
        "navigator.credentials.get({password: true}).then(c => {"
        "  window.domAutomationController.send(!!c);"
        "});",
        &result));
    ASSERT_EQ(expect_has_results, result);
  }

  // Attempt to create a publicKeyCredential with an unsupported algorithm type.
  void CreatePublicKeyCredentialWithUnsupportedAlgorithmAndExpectNotSupported(
      content::WebContents* web_contents) {
    std::string result;
    std::string script =
        "navigator.credentials.create({ publicKey: {"
        "  challenge: new TextEncoder().encode('climb a mountain'),"
        "  rp: { id: '1098237235409872', name: 'Acme' },"
        "  user: { "
        "    id: new TextEncoder().encode('1098237235409872'),"
        "    name: 'avery.a.jones@example.com',"
        "    displayName: 'Avery A. Jones', "
        "    icon: 'https://pics.acme.com/00/p/aBjjjpqPb.png'},"
        "  pubKeyCredParams: [{ type: 'public-key', alg: '123'}],"
        "  timeout: 60000,"
        "  excludeList: [] }"
        "}).catch(c => window.domAutomationController.send(c.toString()));";
    ASSERT_TRUE(
        content::ExecuteScriptAndExtractString(web_contents, script, &result));
    ASSERT_EQ(
        "NotSupportedError: Parameters for this operation are not supported.",
        result);
  }

  // Schedules a call to be made to navigator.credentials.store() in the
  // `unload` handler to save a credential with |username| and |password|.
  void ScheduleNavigatorStoreCredentialAtUnload(
      content::WebContents* web_contents,
      const char* username,
      const char* password) {
    ASSERT_TRUE(content::ExecuteScript(
        web_contents,
        base::StringPrintf(
            "window.addEventListener(\"unload\", () => {"
            "  var c = new PasswordCredential({ id: '%s', password: '%s' });"
            "  navigator.credentials.store(c);"
            "});",
            username, password)));
  }

  // Tests that when navigator.credentials.store() is called in an `unload`
  // handler before a same-RenderFrame navigation, the request is either dropped
  // or serviced in the context of the old document.
  //
  // If |preestablish_mojo_pipe| is set, then the CredentialManagerClient will
  // establish the Mojo connection to the ContentCredentialManager ahead of
  // time, instead of letting the Mojo connection be established on-demand when
  // the call to store() triggered from the unload handler.
  void TestStoreInUnloadHandlerForSameSiteNavigation(
      bool preestablish_mojo_pipe) {
    // Use URLs that differ on subdomains so we can tell which one was used for
    // saving, but they still belong to the same SiteInstance, so they will be
    // renderered in the same RenderFrame (in the same process).
    const GURL a_url1 = https_test_server().GetURL("foo.a.com", "/title1.html");
    const GURL a_url2 = https_test_server().GetURL("bar.a.com", "/title2.html");

    // Navigate to a mostly empty page.
    ui_test_utils::NavigateToURL(browser(), a_url1);

    ChromePasswordManagerClient* client =
        ChromePasswordManagerClient::FromWebContents(WebContents());

    EXPECT_FALSE(client->has_binding_for_credential_manager());
    if (preestablish_mojo_pipe) {
      ASSERT_NO_FATAL_FAILURE(
          TriggerNavigatorGetPasswordCredentialsAndExpectHasResult(
              WebContents(), false));
      EXPECT_TRUE(client->has_binding_for_credential_manager());
    }

    // Schedule storing a credential on the `unload` event.
    ASSERT_NO_FATAL_FAILURE(ScheduleNavigatorStoreCredentialAtUnload(
        WebContents(), "user", "hunter2"));

    // Trigger a same-site navigation carried out in the same RenderFrame.
    content::RenderFrameHost* old_rfh = WebContents()->GetMainFrame();
    ui_test_utils::NavigateToURL(browser(), a_url2);
    ASSERT_EQ(old_rfh, WebContents()->GetMainFrame());

    // Ensure that the old document no longer has a mojom::CredentialManager
    // interface connection to the ContentCredentialManager, nor can it get one
    // later.
    //
    // The sequence of events for same-RFH navigations is as follows:
    //  1.) FrameHostMsg_DidStartProvisionalLoad
    //  ... waiting for first response byte ...
    //  2.) FrameLoader::PrepareForCommit
    //  2.1) Document::Shutdown (old Document)
    //  3.) mojom::FrameHost::DidCommitProvisionalLoad (new load)
    //  ... loading ...
    //  4.) FrameHostMsg_DidStopLoading
    //  5.) content::WaitForLoadStop inside NavigateToURL returns
    //  6.) NavigateToURL returns
    //
    // After Step 2.1, the old Document no longer executes any author JS, so
    // there can be no more calls to the Credential Management API, hence no
    // more InterfaceRequests for mojom::CredentialManager.
    //
    // Because the InterfaceRegistry, through which the client end of the
    // mojom::CredentialManager interface to the ContentCredentialManager is
    // retrieved, is re-bound by the RenderFrameHostImpl to a new pipe on
    // DidCommitProvisionalLoad, any InterfaceRequest messages issued before or
    // during Step 2.1 will either have already been dispatched on the browser
    // side and serviced before DidCommitProvisionalLoad in Step 3, or will be
    // ignored altogether.
    //
    // Hence it is sufficient to check that the Mojo connection is closed now
    // after NavigateToURL above has returned.
    EXPECT_FALSE(client->has_binding_for_credential_manager());

    // Ensure that the navigator.credentials.store() call issued on the previous
    // mojom::CredentialManager connection was either serviced in the context of
    // the old URL, |a_url|, or dropped altogether.
    //
    // The behavior is non-deterministic because the mojom::CredentialManager
    // interface is not Channel-associated, so message ordering with legacy IPC
    // messages is not preserved.
    //
    // If the store() method invoked from the `unload` handler (in Step 2.1)
    // happens to be speedily dispatched before DidCommitProvisionalLoad, it
    // will have been serviced in the context of the old document. Otherwise the
    // ContentCredentialManager should have closed the underlying interface
    // connection in response to DidCommitProvisionalLoad in Step 3, and the
    // method call should be ignored.
    if (!client->was_store_ever_called())
      return;

    BubbleObserver prompt_observer(WebContents());
    prompt_observer.WaitForAutomaticSavePrompt();
    ASSERT_TRUE(prompt_observer.IsSavePromptShownAutomatically());
    prompt_observer.AcceptSavePrompt();

    WaitForPasswordStore();

    password_manager::TestPasswordStore* test_password_store =
        static_cast<password_manager::TestPasswordStore*>(
            PasswordStoreFactory::GetForProfile(
                browser()->profile(), ServiceAccessType::IMPLICIT_ACCESS)
                .get());

    ASSERT_EQ(1u, test_password_store->stored_passwords().size());
    autofill::PasswordForm signin_form =
        test_password_store->stored_passwords().begin()->second[0];
    EXPECT_EQ(base::ASCIIToUTF16("user"), signin_form.username_value);
    EXPECT_EQ(base::ASCIIToUTF16("hunter2"), signin_form.password_value);
    EXPECT_EQ(a_url1.GetOrigin(), signin_form.origin);
  }

  // Tests the when navigator.credentials.store() is called in an `unload`
  // handler before a cross-site transfer navigation, the request is ignored.
  //
  // If |preestablish_mojo_pipe| is set, then the CredentialManagerClient will
  // establish the Mojo connection to the ContentCredentialManager ahead of
  // time, instead of letting the Mojo connection be established on-demand when
  // the call to store() triggered from the unload handler.
  void TestStoreInUnloadHandlerForCrossSiteNavigation(
      bool preestablish_mojo_pipe) {
    const GURL a_url = https_test_server().GetURL("a.com", "/title1.html");
    const GURL b_url = https_test_server().GetURL("b.com", "/title2.html");

    // Navigate to a mostly empty page.
    ui_test_utils::NavigateToURL(browser(), a_url);

    ChromePasswordManagerClient* client =
        ChromePasswordManagerClient::FromWebContents(WebContents());

    if (preestablish_mojo_pipe) {
      EXPECT_FALSE(client->has_binding_for_credential_manager());
      ASSERT_NO_FATAL_FAILURE(
          TriggerNavigatorGetPasswordCredentialsAndExpectHasResult(
              WebContents(), false));
      EXPECT_TRUE(client->has_binding_for_credential_manager());
    }

    // Schedule storing a credential on the `unload` event.
    ASSERT_NO_FATAL_FAILURE(ScheduleNavigatorStoreCredentialAtUnload(
        WebContents(), "user", "hunter2"));

    // Trigger a cross-site navigation that is carried out in a new renderer,
    // and which will swap out the old RenderFrameHost.
    content::RenderFrameDeletedObserver rfh_destruction_observer(
        WebContents()->GetMainFrame());
    ui_test_utils::NavigateToURL(browser(), b_url);

    // Ensure that the navigator.credentials.store() call is never serviced.
    // The sufficient conditions for this are:
    //  -- The swapped out RFH is destroyed, so the RenderFrame cannot
    //     establish a new Mojo connection to ContentCredentialManager anymore.
    //  -- There is no pre-existing Mojo connection to ContentCredentialManager
    //     either, which could be used to call store() in the future.
    //  -- There have not been any calls to store() in the past.
    rfh_destruction_observer.WaitUntilDeleted();
    EXPECT_FALSE(client->has_binding_for_credential_manager());
    EXPECT_FALSE(client->was_store_ever_called());
  }

 private:
  base::test::ScopedFeatureList scoped_feature_list_;

  DISALLOW_COPY_AND_ASSIGN(CredentialManagerBrowserTest);
};

// Tests.

IN_PROC_BROWSER_TEST_F(CredentialManagerBrowserTest,
                       AccountChooserWithOldCredentialAndNavigation) {
  // Save credentials with 'skip_zero_click'.
  scoped_refptr<password_manager::TestPasswordStore> password_store =
      static_cast<password_manager::TestPasswordStore*>(
          PasswordStoreFactory::GetForProfile(
              browser()->profile(), ServiceAccessType::IMPLICIT_ACCESS)
              .get());
  autofill::PasswordForm signin_form;
  signin_form.signon_realm = embedded_test_server()->base_url().spec();
  signin_form.password_value = base::ASCIIToUTF16("password");
  signin_form.username_value = base::ASCIIToUTF16("user");
  signin_form.origin = embedded_test_server()->base_url();
  signin_form.skip_zero_click = true;
  password_store->AddLogin(signin_form);

  NavigateToFile("/password/password_form.html");
  std::string fill_password =
      "document.getElementById('username_field').value = 'user';"
      "document.getElementById('password_field').value = 'password';";
  ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), fill_password));

  // Call the API to trigger the notification to the client.
  ASSERT_TRUE(content::ExecuteScript(
      RenderViewHost(),
      "navigator.credentials.get({password: true})"
      ".then(cred => window.location = '/password/done.html')"));
  // Mojo calls from the renderer are asynchronous.
  BubbleObserver(WebContents()).WaitForAccountChooser();
  PasswordsModelDelegateFromWebContents(WebContents())
      ->ChooseCredential(
          signin_form,
          password_manager::CredentialType::CREDENTIAL_TYPE_PASSWORD);

  NavigationObserver observer(WebContents());
  observer.SetPathToWaitFor("/password/done.html");
  observer.Wait();

  // Verify that the form's 'skip_zero_click' is updated and not overwritten
  // by the autofill password manager on successful login.
  WaitForPasswordStore();
  password_manager::TestPasswordStore::PasswordMap passwords_map =
      password_store->stored_passwords();
  ASSERT_EQ(1u, passwords_map.size());
  const std::vector<autofill::PasswordForm>& passwords_vector =
      passwords_map.begin()->second;
  ASSERT_EQ(1u, passwords_vector.size());
  const autofill::PasswordForm& form = passwords_vector[0];
  EXPECT_EQ(base::ASCIIToUTF16("user"), form.username_value);
  EXPECT_EQ(base::ASCIIToUTF16("password"), form.password_value);
  EXPECT_FALSE(form.skip_zero_click);
}

IN_PROC_BROWSER_TEST_F(CredentialManagerBrowserTest,
                       StoreExistingCredentialIsNoOp) {
  scoped_refptr<password_manager::TestPasswordStore> password_store =
      static_cast<password_manager::TestPasswordStore*>(
          PasswordStoreFactory::GetForProfile(
              browser()->profile(), ServiceAccessType::IMPLICIT_ACCESS)
              .get());

  GURL origin = embedded_test_server()->base_url();

  autofill::PasswordForm form_1;
  form_1.signon_realm = origin.spec();
  form_1.username_value = base::ASCIIToUTF16("user1");
  form_1.password_value = base::ASCIIToUTF16("abcdef");
  form_1.preferred = true;

  autofill::PasswordForm form_2;
  form_2.signon_realm = origin.spec();
  form_2.username_value = base::ASCIIToUTF16("user2");
  form_2.password_value = base::ASCIIToUTF16("123456");

  password_store->AddLogin(form_1);
  password_store->AddLogin(form_2);
  WaitForPasswordStore();

  // Check that the password store contains the values we expect.
  {
    auto found = password_store->stored_passwords().find(origin.spec());
    ASSERT_NE(password_store->stored_passwords().end(), found);
    const std::vector<autofill::PasswordForm>& passwords = found->second;

    ASSERT_EQ(2U, passwords.size());
    EXPECT_EQ(base::ASCIIToUTF16("user1"), passwords[0].username_value);
    EXPECT_EQ(base::ASCIIToUTF16("abcdef"), passwords[0].password_value);
    EXPECT_EQ(base::ASCIIToUTF16("user2"), passwords[1].username_value);
    EXPECT_EQ(base::ASCIIToUTF16("123456"), passwords[1].password_value);
  }

  {
    NavigateToFile("/password/simple_password.html");

    // Call the API to store 'user1' with the old password.
    ASSERT_TRUE(content::ExecuteScript(
        RenderViewHost(),
        "navigator.credentials.store("
        "  new PasswordCredential({ id: 'user1', password: 'abcdef' }))"
        ".then(cred => window.location = '/password/done.html');"));

    NavigationObserver observer(WebContents());
    observer.SetPathToWaitFor("/password/done.html");
    observer.Wait();
  }

  {
    NavigateToFile("/password/simple_password.html");

    // Call the API to store 'user2' with the old password.
    ASSERT_TRUE(content::ExecuteScript(
        RenderViewHost(),
        "navigator.credentials.store("
        "  new PasswordCredential({ id: 'user2', password: '123456' }))"
        ".then(cred => window.location = '/password/done.html');"));

    NavigationObserver observer(WebContents());
    observer.SetPathToWaitFor("/password/done.html");
    observer.Wait();
  }
  // Wait for the password store to process the store request.
  WaitForPasswordStore();

  // Check that the password still store contains the values we expect.
  {
    auto found = password_store->stored_passwords().find(origin.spec());
    ASSERT_NE(password_store->stored_passwords().end(), found);
    const std::vector<autofill::PasswordForm>& passwords = found->second;

    ASSERT_EQ(2U, passwords.size());
    EXPECT_EQ(base::ASCIIToUTF16("user1"), passwords[0].username_value);
    EXPECT_EQ(base::ASCIIToUTF16("abcdef"), passwords[0].password_value);
    EXPECT_EQ(base::ASCIIToUTF16("user2"), passwords[1].username_value);
    EXPECT_EQ(base::ASCIIToUTF16("123456"), passwords[1].password_value);
  }
}

IN_PROC_BROWSER_TEST_F(CredentialManagerBrowserTest,
                       StoreUpdatesPasswordOfExistingCredential) {
  scoped_refptr<password_manager::TestPasswordStore> password_store =
      static_cast<password_manager::TestPasswordStore*>(
          PasswordStoreFactory::GetForProfile(
              browser()->profile(), ServiceAccessType::IMPLICIT_ACCESS)
              .get());

  GURL origin = embedded_test_server()->base_url();

  autofill::PasswordForm form_1;
  form_1.signon_realm = origin.spec();
  form_1.username_value = base::ASCIIToUTF16("user1");
  form_1.password_value = base::ASCIIToUTF16("abcdef");
  form_1.preferred = true;

  autofill::PasswordForm form_2;
  form_2.signon_realm = origin.spec();
  form_2.username_value = base::ASCIIToUTF16("user2");
  form_2.password_value = base::ASCIIToUTF16("123456");

  password_store->AddLogin(form_1);
  password_store->AddLogin(form_2);
  WaitForPasswordStore();

  // Check that the password store contains the values we expect.
  {
    auto found = password_store->stored_passwords().find(origin.spec());
    ASSERT_NE(password_store->stored_passwords().end(), found);
    const std::vector<autofill::PasswordForm>& passwords = found->second;

    ASSERT_EQ(2U, passwords.size());
    EXPECT_EQ(base::ASCIIToUTF16("user1"), passwords[0].username_value);
    EXPECT_EQ(base::ASCIIToUTF16("abcdef"), passwords[0].password_value);
    EXPECT_EQ(base::ASCIIToUTF16("user2"), passwords[1].username_value);
    EXPECT_EQ(base::ASCIIToUTF16("123456"), passwords[1].password_value);
  }

  {
    NavigateToFile("/password/simple_password.html");

    // Call the API to store 'user1' with a new password.
    ASSERT_TRUE(content::ExecuteScript(
        RenderViewHost(),
        "navigator.credentials.store("
        "  new PasswordCredential({ id: 'user1', password: 'ABCDEF' }))"
        ".then(cred => window.location = '/password/done.html');"));

    NavigationObserver observer(WebContents());
    observer.SetPathToWaitFor("/password/done.html");
    observer.Wait();
  }

  {
    NavigateToFile("/password/simple_password.html");

    // Call the API to store 'user2' with a new password.
    ASSERT_TRUE(content::ExecuteScript(
        RenderViewHost(),
        "navigator.credentials.store("
        "  new PasswordCredential({ id: 'user2', password: 'UVWXYZ' }))"
        ".then(cred => window.location = '/password/done.html');"));

    NavigationObserver observer(WebContents());
    observer.SetPathToWaitFor("/password/done.html");
    observer.Wait();
  }

  // Wait for the password store to process the store request.
  WaitForPasswordStore();

  // Check that the password store contains the values we expect.
  {
    auto found = password_store->stored_passwords().find(origin.spec());
    ASSERT_NE(password_store->stored_passwords().end(), found);
    const std::vector<autofill::PasswordForm>& passwords = found->second;

    ASSERT_EQ(2U, passwords.size());
    EXPECT_EQ(base::ASCIIToUTF16("user1"), passwords[0].username_value);
    EXPECT_EQ(base::ASCIIToUTF16("ABCDEF"), passwords[0].password_value);
    EXPECT_EQ(base::ASCIIToUTF16("user2"), passwords[1].username_value);
    EXPECT_EQ(base::ASCIIToUTF16("UVWXYZ"), passwords[1].password_value);
  }
}

IN_PROC_BROWSER_TEST_F(CredentialManagerBrowserTest,
                       StoreUpdatesPasswordOfExistingCredentialWithAttributes) {
  // This test is the same as the previous one, except that the already existing
  // credentials contain metadata.
  scoped_refptr<password_manager::TestPasswordStore> password_store =
      static_cast<password_manager::TestPasswordStore*>(
          PasswordStoreFactory::GetForProfile(
              browser()->profile(), ServiceAccessType::IMPLICIT_ACCESS)
              .get());

  GURL origin = embedded_test_server()->base_url();

  autofill::PasswordForm form_1;
  form_1.signon_realm = origin.spec();
  form_1.username_value = base::ASCIIToUTF16("user1");
  form_1.password_value = base::ASCIIToUTF16("abcdef");
  form_1.username_element = base::ASCIIToUTF16("user");
  form_1.password_element = base::ASCIIToUTF16("pass");
  form_1.origin = GURL(origin.spec() + "/my/custom/path/");
  form_1.preferred = true;

  autofill::PasswordForm form_2;
  form_2.signon_realm = origin.spec();
  form_2.username_value = base::ASCIIToUTF16("user2");
  form_2.password_value = base::ASCIIToUTF16("123456");
  form_2.username_element = base::ASCIIToUTF16("username");
  form_2.password_element = base::ASCIIToUTF16("password");
  form_2.origin = GURL(origin.spec() + "/my/other/path/");

  password_store->AddLogin(form_1);
  password_store->AddLogin(form_2);
  WaitForPasswordStore();

  // Check that the password store contains the values we expect.
  {
    auto found = password_store->stored_passwords().find(origin.spec());
    ASSERT_NE(password_store->stored_passwords().end(), found);
    const std::vector<autofill::PasswordForm>& passwords = found->second;

    ASSERT_EQ(2U, passwords.size());
    EXPECT_EQ(base::ASCIIToUTF16("user1"), passwords[0].username_value);
    EXPECT_EQ(base::ASCIIToUTF16("abcdef"), passwords[0].password_value);
    EXPECT_EQ(base::ASCIIToUTF16("user"), passwords[0].username_element);
    EXPECT_EQ(base::ASCIIToUTF16("pass"), passwords[0].password_element);
    EXPECT_EQ(base::ASCIIToUTF16("user2"), passwords[1].username_value);
    EXPECT_EQ(base::ASCIIToUTF16("123456"), passwords[1].password_value);
    EXPECT_EQ(base::ASCIIToUTF16("username"), passwords[1].username_element);
    EXPECT_EQ(base::ASCIIToUTF16("password"), passwords[1].password_element);
  }

  {
    NavigateToFile("/password/simple_password.html");

    // Call the API to store 'user1' with a new password.
    ASSERT_TRUE(content::ExecuteScript(
        RenderViewHost(),
        "navigator.credentials.store("
        "  new PasswordCredential({ id: 'user1', password: 'ABCDEF' }))"
        ".then(cred => window.location = '/password/done.html');"));

    NavigationObserver observer(WebContents());
    observer.SetPathToWaitFor("/password/done.html");
    observer.Wait();
  }

  {
    NavigateToFile("/password/simple_password.html");

    // Call the API to store 'user2' with a new password.
    ASSERT_TRUE(content::ExecuteScript(
        RenderViewHost(),
        "navigator.credentials.store("
        "  new PasswordCredential({ id: 'user2', password: 'UVWXYZ' }))"
        ".then(cred => window.location = '/password/done.html');"));

    NavigationObserver observer(WebContents());
    observer.SetPathToWaitFor("/password/done.html");
    observer.Wait();
  }

  // Wait for the password store to process the store request.
  WaitForPasswordStore();

  // Check that the password store contains the values we expect.
  // Note that we don't check for username and password elements, as they don't
  // exist for credentials saved by the API.
  {
    auto found = password_store->stored_passwords().find(origin.spec());
    ASSERT_NE(password_store->stored_passwords().end(), found);
    const std::vector<autofill::PasswordForm>& passwords = found->second;

    ASSERT_EQ(2U, passwords.size());
    EXPECT_EQ(base::ASCIIToUTF16("user1"), passwords[0].username_value);
    EXPECT_EQ(base::ASCIIToUTF16("ABCDEF"), passwords[0].password_value);
    EXPECT_EQ(base::ASCIIToUTF16("user2"), passwords[1].username_value);
    EXPECT_EQ(base::ASCIIToUTF16("UVWXYZ"), passwords[1].password_value);
  }
}

IN_PROC_BROWSER_TEST_F(CredentialManagerBrowserTest,
                       StoreSavesPSLMatchedCredential) {
  scoped_refptr<password_manager::TestPasswordStore> password_store =
      static_cast<password_manager::TestPasswordStore*>(
          PasswordStoreFactory::GetForProfile(
              browser()->profile(), ServiceAccessType::IMPLICIT_ACCESS)
              .get());

  // The call to |GetURL| is needed to get the correct port.
  GURL psl_url = https_test_server().GetURL("psl.example.com", "/");

  autofill::PasswordForm signin_form;
  signin_form.signon_realm = psl_url.spec();
  signin_form.password_value = base::ASCIIToUTF16("password");
  signin_form.username_value = base::ASCIIToUTF16("user");
  signin_form.origin = psl_url;
  password_store->AddLogin(signin_form);

  NavigateToURL(https_test_server(), "www.example.com",
                "/password/password_form.html");

  // Call the API to trigger |get| and |store| and redirect.
  ASSERT_TRUE(
      content::ExecuteScript(RenderViewHost(),
                             "navigator.credentials.get({password: true})"
                             ".then(cred => "
                             "navigator.credentials.store(cred)"
                             ".then(cred => "
                             "window.location = '/password/done.html'))"));

  // Mojo calls from the renderer are asynchronous.
  BubbleObserver(WebContents()).WaitForAccountChooser();
  PasswordsModelDelegateFromWebContents(WebContents())
      ->ChooseCredential(
          signin_form,
          password_manager::CredentialType::CREDENTIAL_TYPE_PASSWORD);

  NavigationObserver observer(WebContents());
  observer.SetPathToWaitFor("/password/done.html");
  observer.Wait();

  // Wait for the password store before checking the prompt because it pops up
  // after the store replies.
  WaitForPasswordStore();
  BubbleObserver prompt_observer(WebContents());
  EXPECT_FALSE(prompt_observer.IsSavePromptShownAutomatically());
  EXPECT_FALSE(prompt_observer.IsUpdatePromptShownAutomatically());

  // There should be an entry for both psl.example.com and www.example.com.
  password_manager::TestPasswordStore::PasswordMap passwords =
      password_store->stored_passwords();
  GURL www_url = https_test_server().GetURL("www.example.com", "/");
  EXPECT_EQ(2U, passwords.size());
  EXPECT_TRUE(base::ContainsKey(passwords, psl_url.spec()));
  EXPECT_TRUE(base::ContainsKey(passwords, www_url.spec()));
}

IN_PROC_BROWSER_TEST_F(CredentialManagerBrowserTest,
                       UpdatingPSLMatchedCredentialCreatesSecondEntry) {
  scoped_refptr<password_manager::TestPasswordStore> password_store =
      static_cast<password_manager::TestPasswordStore*>(
          PasswordStoreFactory::GetForProfile(
              browser()->profile(), ServiceAccessType::IMPLICIT_ACCESS)
              .get());

  // The call to |GetURL| is needed to get the correct port.
  GURL psl_url = https_test_server().GetURL("psl.example.com", "/");

  autofill::PasswordForm signin_form;
  signin_form.signon_realm = psl_url.spec();
  signin_form.password_value = base::ASCIIToUTF16("password");
  signin_form.username_value = base::ASCIIToUTF16("user");
  signin_form.origin = psl_url;
  password_store->AddLogin(signin_form);

  NavigateToURL(https_test_server(), "www.example.com",
                "/password/password_form.html");

  // Call the API to trigger |get| and |store| and redirect.
  ASSERT_TRUE(content::ExecuteScript(
      RenderViewHost(),
      "navigator.credentials.store("
      "  new PasswordCredential({ id: 'user', password: 'P4SSW0RD' }))"
      ".then(cred => window.location = '/password/done.html');"));

  NavigationObserver observer(WebContents());
  observer.SetPathToWaitFor("/password/done.html");
  observer.Wait();

  BubbleObserver prompt_observer(WebContents());
  prompt_observer.WaitForAutomaticSavePrompt();
  ASSERT_TRUE(prompt_observer.IsSavePromptShownAutomatically());
  prompt_observer.AcceptSavePrompt();
  WaitForPasswordStore();

  // There should be an entry for both psl.example.com and www.example.com.
  password_manager::TestPasswordStore::PasswordMap passwords =
      password_store->stored_passwords();
  GURL www_url = https_test_server().GetURL("www.example.com", "/");
  EXPECT_EQ(2U, passwords.size());
  EXPECT_TRUE(base::ContainsKey(passwords, psl_url.spec()));
  EXPECT_TRUE(base::ContainsKey(passwords, www_url.spec()));
  EXPECT_EQ(base::ASCIIToUTF16("user"),
            passwords[psl_url.spec()].front().username_value);
  EXPECT_EQ(base::ASCIIToUTF16("password"),
            passwords[psl_url.spec()].front().password_value);
  EXPECT_EQ(base::ASCIIToUTF16("user"),
            passwords[www_url.spec()].front().username_value);
  EXPECT_EQ(base::ASCIIToUTF16("P4SSW0RD"),
            passwords[www_url.spec()].front().password_value);
}

IN_PROC_BROWSER_TEST_F(CredentialManagerBrowserTest,
                       ObsoleteHttpCredentialMovedOnMigrationToHstsSite) {
  // Add an http credential to the password store.
  GURL https_origin = https_test_server().base_url();
  ASSERT_TRUE(https_origin.SchemeIs(url::kHttpsScheme));
  GURL::Replacements rep;
  rep.SetSchemeStr(url::kHttpScheme);
  GURL http_origin = https_origin.ReplaceComponents(rep);
  autofill::PasswordForm http_form;
  http_form.signon_realm = http_origin.spec();
  http_form.origin = http_origin;
  http_form.username_value = base::ASCIIToUTF16("user");
  http_form.password_value = base::ASCIIToUTF16("12345");
  scoped_refptr<password_manager::TestPasswordStore> password_store =
      static_cast<password_manager::TestPasswordStore*>(
          PasswordStoreFactory::GetForProfile(
              browser()->profile(), ServiceAccessType::IMPLICIT_ACCESS)
              .get());
  password_store->AddLogin(http_form);
  WaitForPasswordStore();

  // Treat the host of the HTTPS test server as HSTS.
  AddHSTSHost(https_test_server().host_port_pair().host());

  // Navigate to HTTPS page and trigger the migration.
  ui_test_utils::NavigateToURL(
      browser(), https_test_server().GetURL("/password/done.html"));

  // Call the API to trigger the account chooser.
  ASSERT_TRUE(content::ExecuteScript(
      RenderViewHost(), "navigator.credentials.get({password: true})"));
  BubbleObserver(WebContents()).WaitForAccountChooser();

  // Wait for the migration logic to actually touch the password store.
  WaitForPasswordStore();
  // Only HTTPS passwords should be present.
  EXPECT_TRUE(
      password_store->stored_passwords().at(http_origin.spec()).empty());
  EXPECT_FALSE(
      password_store->stored_passwords().at(https_origin.spec()).empty());
}

IN_PROC_BROWSER_TEST_F(CredentialManagerBrowserTest,
                       AutoSigninOldCredentialAndNavigation) {
  // Save credentials with 'skip_zero_click' false.
  scoped_refptr<password_manager::TestPasswordStore> password_store =
      static_cast<password_manager::TestPasswordStore*>(
          PasswordStoreFactory::GetForProfile(
              browser()->profile(), ServiceAccessType::IMPLICIT_ACCESS).get());
  autofill::PasswordForm signin_form;
  signin_form.signon_realm = embedded_test_server()->base_url().spec();
  signin_form.password_value = base::ASCIIToUTF16("password");
  signin_form.username_value = base::ASCIIToUTF16("user");
  signin_form.origin = embedded_test_server()->base_url();
  signin_form.skip_zero_click = false;
  password_store->AddLogin(signin_form);

  // Enable 'auto signin' for the profile.
  password_bubble_experiment::RecordAutoSignInPromptFirstRunExperienceWasShown(
      browser()->profile()->GetPrefs());

  NavigateToFile("/password/password_form.html");
  std::string fill_password =
  "document.getElementById('username_field').value = 'trash';"
  "document.getElementById('password_field').value = 'trash';";
  ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), fill_password));

  // Call the API to trigger the notification to the client.
  ASSERT_TRUE(content::ExecuteScript(
      RenderViewHost(),
      "navigator.credentials.get({password: true})"
      ".then(cred => window.location = '/password/done.html');"));

  NavigationObserver observer(WebContents());
  observer.SetPathToWaitFor("/password/done.html");
  observer.Wait();

  BubbleObserver prompt_observer(WebContents());
  // The autofill password manager shouldn't react to the successful login
  // because it was suppressed when the site got the credential back.
  EXPECT_FALSE(prompt_observer.IsSavePromptShownAutomatically());
}

// Regression test for https://crbug.com/736357.
IN_PROC_BROWSER_TEST_F(CredentialManagerBrowserTest,
                       StoreInUnloadHandler_SameSite_OnDemandMojoPipe) {
  TestStoreInUnloadHandlerForSameSiteNavigation(
      false /* preestablish_mojo_pipe */);
}

// Regression test for https://crbug.com/736357.
IN_PROC_BROWSER_TEST_F(CredentialManagerBrowserTest,
                       StoreInUnloadHandler_SameSite_PreestablishedPipe) {
  TestStoreInUnloadHandlerForSameSiteNavigation(
      true /* preestablish_mojo_pipe */);
}
// Regression test for https://crbug.com/736357.
IN_PROC_BROWSER_TEST_F(CredentialManagerBrowserTest,
                       StoreInUnloadHandler_CrossSite_OnDemandMojoPipe) {
  TestStoreInUnloadHandlerForCrossSiteNavigation(
      false /* preestablish_mojo_pipe */);
}

// Regression test for https://crbug.com/736357.
IN_PROC_BROWSER_TEST_F(CredentialManagerBrowserTest,
                       StoreInUnloadHandler_CrossSite_PreestablishedPipe) {
  TestStoreInUnloadHandlerForCrossSiteNavigation(
      true /* preestablish_mojo_pipe */);
}

// Regression test for https://crbug.com/736357.
IN_PROC_BROWSER_TEST_F(CredentialManagerBrowserTest,
                       MojoConnectionRecreatedAfterNavigation) {
  const GURL a_url1 = https_test_server().GetURL("a.com", "/title1.html");
  const GURL a_url2 = https_test_server().GetURL("a.com", "/title2.html");
  const GURL a_url2_ref = https_test_server().GetURL("a.com", "/title2.html#r");
  const GURL b_url = https_test_server().GetURL("b.com", "/title2.html#ref");

  // Enable 'auto signin' for the profile.
  password_bubble_experiment::RecordAutoSignInPromptFirstRunExperienceWasShown(
      browser()->profile()->GetPrefs());

  // Navigate to a mostly empty page.
  ui_test_utils::NavigateToURL(browser(), a_url1);

  ChromePasswordManagerClient* client =
      ChromePasswordManagerClient::FromWebContents(WebContents());

  // Store a credential, and expect it to establish the Mojo connection.
  EXPECT_FALSE(client->has_binding_for_credential_manager());
  EXPECT_FALSE(client->was_store_ever_called());

  ASSERT_TRUE(content::ExecuteScript(
      WebContents(),
      "var c = new PasswordCredential({ id: 'user', password: 'hunter2' });"
      "navigator.credentials.store(c);"));

  BubbleObserver prompt_observer(WebContents());
  prompt_observer.WaitForAutomaticSavePrompt();
  ASSERT_TRUE(prompt_observer.IsSavePromptShownAutomatically());
  prompt_observer.AcceptSavePrompt();
  WaitForPasswordStore();

  EXPECT_TRUE(client->has_binding_for_credential_manager());
  EXPECT_TRUE(client->was_store_ever_called());

  // Trigger a same-site navigation.
  content::RenderFrameHost* old_rfh = WebContents()->GetMainFrame();
  ui_test_utils::NavigateToURL(browser(), a_url2);
  ASSERT_EQ(old_rfh, WebContents()->GetMainFrame());

  // Expect the Mojo connection closed.
  EXPECT_FALSE(client->has_binding_for_credential_manager());

  // Calling navigator.credentials.get() again should re-establish the Mojo
  // connection and succeed.
  ASSERT_NO_FATAL_FAILURE(
      TriggerNavigatorGetPasswordCredentialsAndExpectHasResult(WebContents(),
                                                               true));
  EXPECT_TRUE(client->has_binding_for_credential_manager());

  // Same-document navigation. Call to get() succeeds.
  ui_test_utils::NavigateToURL(browser(), a_url2_ref);
  ASSERT_EQ(old_rfh, WebContents()->GetMainFrame());
  EXPECT_TRUE(client->has_binding_for_credential_manager());
  ASSERT_NO_FATAL_FAILURE(
      TriggerNavigatorGetPasswordCredentialsAndExpectHasResult(WebContents(),
                                                               true));

  // Cross-site navigation. Call to get() succeeds without results.
  ui_test_utils::NavigateToURL(browser(), b_url);
  ASSERT_NO_FATAL_FAILURE(
      TriggerNavigatorGetPasswordCredentialsAndExpectHasResult(WebContents(),
                                                               false));

  // Trigger a cross-site navigation back. Call to get() should still succeed,
  // and once again with results.
  ui_test_utils::NavigateToURL(browser(), a_url1);
  ASSERT_NO_FATAL_FAILURE(
      TriggerNavigatorGetPasswordCredentialsAndExpectHasResult(WebContents(),
                                                               true));
}

IN_PROC_BROWSER_TEST_F(CredentialManagerBrowserTest, SaveViaAPIAndAutofill) {
  NavigateToFile("/password/password_form.html");

  ASSERT_TRUE(content::ExecuteScript(
      RenderViewHost(),
      "document.getElementById('input_submit_button').addEventListener('click',"
      "function(event) {"
        "var c = new PasswordCredential({ id: 'user', password: 'API' });"
        "navigator.credentials.store(c);"
      "});"));
  // Fill the password and click the button to submit the page. The API should
  // suppress the autofill password manager.
  NavigationObserver form_submit_observer(WebContents());
  ASSERT_TRUE(content::ExecuteScript(
      RenderViewHost(),
      "document.getElementById('username_field').value = 'user';"
      "document.getElementById('password_field').value = 'autofill';"
      "document.getElementById('input_submit_button').click();"));
  form_submit_observer.Wait();

  WaitForPasswordStore();
  BubbleObserver prompt_observer(WebContents());
  ASSERT_TRUE(prompt_observer.IsSavePromptShownAutomatically());
  prompt_observer.AcceptSavePrompt();

  WaitForPasswordStore();
  password_manager::TestPasswordStore::PasswordMap stored =
      static_cast<password_manager::TestPasswordStore*>(
          PasswordStoreFactory::GetForProfile(
              browser()->profile(), ServiceAccessType::IMPLICIT_ACCESS)
              .get())->stored_passwords();
  ASSERT_EQ(1u, stored.size());
  autofill::PasswordForm signin_form = stored.begin()->second[0];
  EXPECT_EQ(base::ASCIIToUTF16("user"), signin_form.username_value);
  EXPECT_EQ(base::ASCIIToUTF16("API"), signin_form.password_value);
  EXPECT_EQ(embedded_test_server()->base_url().spec(),
            signin_form.signon_realm);
  EXPECT_EQ(embedded_test_server()->base_url(), signin_form.origin);
}

IN_PROC_BROWSER_TEST_F(CredentialManagerBrowserTest, UpdateViaAPIAndAutofill) {
  // Save credentials with 'skip_zero_click' false.
  scoped_refptr<password_manager::TestPasswordStore> password_store =
      static_cast<password_manager::TestPasswordStore*>(
          PasswordStoreFactory::GetForProfile(
              browser()->profile(), ServiceAccessType::IMPLICIT_ACCESS)
              .get());
  autofill::PasswordForm signin_form;
  signin_form.signon_realm = embedded_test_server()->base_url().spec();
  signin_form.password_value = base::ASCIIToUTF16("old_pass");
  signin_form.username_value = base::ASCIIToUTF16("user");
  signin_form.origin = embedded_test_server()->base_url();
  signin_form.skip_zero_click = true;
  signin_form.preferred = true;
  password_store->AddLogin(signin_form);

  NavigateToFile("/password/password_form.html");

  ASSERT_TRUE(content::ExecuteScript(
      RenderViewHost(),
      "document.getElementById('input_submit_button').addEventListener('click',"
      "function(event) {"
        "var c = new PasswordCredential({ id: 'user', password: 'API' });"
        "navigator.credentials.store(c);"
      "});"));
  // Fill the new password and click the button to submit the page later. The
  // API should suppress the autofill password manager and overwrite the
  // password.
  NavigationObserver form_submit_observer(WebContents());
  ASSERT_TRUE(content::ExecuteScript(
      RenderViewHost(),
      "document.getElementById('username_field').value = 'user';"
      "document.getElementById('password_field').value = 'autofill';"
      "document.getElementById('input_submit_button').click();"));
  form_submit_observer.Wait();

  // Wait for the password store before checking the prompt because it pops up
  // after the store replies.
  WaitForPasswordStore();
  BubbleObserver prompt_observer(WebContents());
  EXPECT_FALSE(prompt_observer.IsSavePromptShownAutomatically());
  EXPECT_FALSE(prompt_observer.IsUpdatePromptShownAutomatically());
  signin_form.skip_zero_click = false;
  signin_form.times_used = 1;
  signin_form.password_value = base::ASCIIToUTF16("API");
  password_manager::TestPasswordStore::PasswordMap stored =
      password_store->stored_passwords();
  ASSERT_EQ(1u, stored.size());
  EXPECT_EQ(signin_form, stored[signin_form.signon_realm][0]);
}

IN_PROC_BROWSER_TEST_F(CredentialManagerBrowserTest, CredentialsAutofilled) {
  NavigateToFile("/password/password_form.html");

  ASSERT_TRUE(content::ExecuteScript(
      RenderFrameHost(),
      "var c = new PasswordCredential({ id: 'user', password: '12345' });"
      "navigator.credentials.store(c);"));
  BubbleObserver bubble_observer(WebContents());
  bubble_observer.WaitForAutomaticSavePrompt();
  bubble_observer.AcceptSavePrompt();

  // Reload the page and make sure it's autofilled.
  NavigateToFile("/password/password_form.html");
  WaitForElementValue("username_field", "user");
  content::SimulateMouseClickAt(
      WebContents(), 0, blink::WebMouseEvent::Button::kLeft, gfx::Point(1, 1));
  WaitForElementValue("password_field", "12345");
}

// Tests that when navigator.credentials.create() is called with an unsupported
// algorithm, we get a NotSupportedError.
IN_PROC_BROWSER_TEST_F(CredentialManagerBrowserTest,
                       CreatePublicKeyCredentialAlgorithmNotSupported) {
  const GURL a_url1 = https_test_server().GetURL("a.com", "/title1.html");

  // Navigate to a mostly empty page.
  ui_test_utils::NavigateToURL(browser(), a_url1);

  ASSERT_NO_FATAL_FAILURE(
      CreatePublicKeyCredentialWithUnsupportedAlgorithmAndExpectNotSupported(
          WebContents()));
}

}  // namespace
