// Copyright (c) 2012 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.

// The passwords in the tests below are all empty because PasswordStoreDefault
// does not store the actual passwords on OS X (they are stored in the Keychain
// instead). We could special-case it, but it is easier to just have empty
// passwords. This will not be needed anymore if crbug.com/466638 is fixed.

#include <stddef.h>

#include <utility>

#include "base/bind.h"
#include "base/files/scoped_temp_dir.h"
#include "base/macros.h"
#include "base/memory/ptr_util.h"
#include "base/run_loop.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/synchronization/waitable_event.h"
#include "base/test/scoped_task_environment.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/time/time.h"
#include "build/build_config.h"
#include "components/password_manager/core/browser/affiliated_match_helper.h"
#include "components/password_manager/core/browser/affiliation_service.h"
#include "components/password_manager/core/browser/mock_affiliated_match_helper.h"
#include "components/password_manager/core/browser/password_manager_test_utils.h"
#include "components/password_manager/core/browser/password_store_consumer.h"
#include "components/password_manager/core/browser/password_store_default.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

#if defined(OS_MACOSX)
#include "components/os_crypt/os_crypt_mocker.h"
#endif

using autofill::PasswordForm;
using base::WaitableEvent;
using testing::_;
using testing::DoAll;
using testing::WithArg;

namespace password_manager {

namespace {

const char kTestWebRealm1[] = "https://one.example.com/";
const char kTestWebOrigin1[] = "https://one.example.com/origin";
const char kTestWebRealm2[] = "https://two.example.com/";
const char kTestWebOrigin2[] = "https://two.example.com/origin";
const char kTestWebRealm3[] = "https://three.example.com/";
const char kTestWebOrigin3[] = "https://three.example.com/origin";
const char kTestWebRealm5[] = "https://five.example.com/";
const char kTestWebOrigin5[] = "https://five.example.com/origin";
const char kTestPSLMatchingWebRealm[] = "https://psl.example.com/";
const char kTestPSLMatchingWebOrigin[] = "https://psl.example.com/origin";
const char kTestUnrelatedWebRealm[] = "https://notexample.com/";
const char kTestUnrelatedWebOrigin[] = "https:/notexample.com/origin";
const char kTestInsecureWebRealm[] = "http://one.example.com/";
const char kTestInsecureWebOrigin[] = "http://one.example.com/origin";
const char kTestAndroidRealm1[] = "android://hash@com.example.android/";
const char kTestAndroidRealm2[] = "android://hash@com.example.two.android/";
const char kTestAndroidRealm3[] = "android://hash@com.example.three.android/";
const char kTestUnrelatedAndroidRealm[] =
    "android://hash@com.notexample.android/";

class MockPasswordStoreConsumer : public PasswordStoreConsumer {
 public:
  MOCK_METHOD1(OnGetPasswordStoreResultsConstRef,
               void(const std::vector<std::unique_ptr<PasswordForm>>&));

  // GMock cannot mock methods with move-only args.
  void OnGetPasswordStoreResults(
      std::vector<std::unique_ptr<PasswordForm>> results) override {
    OnGetPasswordStoreResultsConstRef(results);
  }
};

class StartSyncFlareMock {
 public:
  StartSyncFlareMock() {}
  ~StartSyncFlareMock() {}

  MOCK_METHOD1(StartSyncFlare, void(syncer::ModelType));
};

}  // namespace

class PasswordStoreTest : public testing::Test {
 protected:
  PasswordStoreTest()
      : scoped_task_environment_(
            base::test::ScopedTaskEnvironment::MainThreadType::UI) {}

  void SetUp() override { ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); }

  void TearDown() override { ASSERT_TRUE(temp_dir_.Delete()); }

  base::FilePath test_login_db_file_path() const {
    return temp_dir_.GetPath().Append(FILE_PATH_LITERAL("login_test"));
  }

  base::test::ScopedTaskEnvironment scoped_task_environment_;
  base::ScopedTempDir temp_dir_;
};

TEST_F(PasswordStoreTest, IgnoreOldWwwGoogleLogins) {
  scoped_refptr<PasswordStoreDefault> store(new PasswordStoreDefault(
      base::ThreadTaskRunnerHandle::Get(), base::ThreadTaskRunnerHandle::Get(),
      base::MakeUnique<LoginDatabase>(test_login_db_file_path())));
  store->Init(syncer::SyncableService::StartSyncFlare());

  const time_t cutoff = 1325376000;  // 00:00 Jan 1 2012 UTC
  static const PasswordFormData form_data[] = {
      // A form on https://www.google.com/ older than the cutoff. Will be
      // ignored.
      {PasswordForm::SCHEME_HTML, "https://www.google.com",
       "https://www.google.com/origin", "https://www.google.com/action",
       L"submit_element", L"username_element", L"password_element",
       L"username_value_1", L"", true, cutoff - 1},
      // A form on https://www.google.com/ older than the cutoff. Will be
      // ignored.
      {PasswordForm::SCHEME_HTML, "https://www.google.com",
       "https://www.google.com/origin", "https://www.google.com/action",
       L"submit_element", L"username_element", L"password_element",
       L"username_value_2", L"", true, cutoff - 1},
      // A form on https://www.google.com/ newer than the cutoff.
      {PasswordForm::SCHEME_HTML, "https://www.google.com",
       "https://www.google.com/origin", "https://www.google.com/action",
       L"submit_element", L"username_element", L"password_element",
       L"username_value_3", L"", true, cutoff + 1},
      // A form on https://accounts.google.com/ older than the cutoff.
      {PasswordForm::SCHEME_HTML, "https://accounts.google.com",
       "https://accounts.google.com/origin",
       "https://accounts.google.com/action", L"submit_element",
       L"username_element", L"password_element", L"username_value", L"", true,
       cutoff - 1},
      // A form on http://bar.example.com/ older than the cutoff.
      {PasswordForm::SCHEME_HTML, "http://bar.example.com",
       "http://bar.example.com/origin", "http://bar.example.com/action",
       L"submit_element", L"username_element", L"password_element",
       L"username_value", L"", true, cutoff - 1},
  };

  // Build the forms vector and add the forms to the store.
  std::vector<std::unique_ptr<PasswordForm>> all_forms;
  for (size_t i = 0; i < arraysize(form_data); ++i) {
    all_forms.push_back(CreatePasswordFormFromDataForTesting(form_data[i]));
    store->AddLogin(*all_forms.back());
  }
  base::RunLoop().RunUntilIdle();

  // We expect to get back only the "recent" www.google.com login.
  // Theoretically these should never actually exist since there are no longer
  // any login forms on www.google.com to save, but we technically allow them.
  // We should not get back the older saved password though.
  const PasswordStore::FormDigest www_google = {
      PasswordForm::SCHEME_HTML, "https://www.google.com", GURL()};
  std::vector<std::unique_ptr<PasswordForm>> www_google_expected;
  www_google_expected.push_back(base::MakeUnique<PasswordForm>(*all_forms[2]));

  // We should still get the accounts.google.com login even though it's older
  // than our cutoff - this is the new location of all Google login forms.
  const PasswordStore::FormDigest accounts_google = {
      PasswordForm::SCHEME_HTML, "https://accounts.google.com", GURL()};
  std::vector<std::unique_ptr<PasswordForm>> accounts_google_expected;
  accounts_google_expected.push_back(
      base::MakeUnique<PasswordForm>(*all_forms[3]));

  // Same thing for a generic saved login.
  const PasswordStore::FormDigest bar_example = {
      PasswordForm::SCHEME_HTML, "http://bar.example.com", GURL()};
  std::vector<std::unique_ptr<PasswordForm>> bar_example_expected;
  bar_example_expected.push_back(base::MakeUnique<PasswordForm>(*all_forms[4]));

  MockPasswordStoreConsumer consumer;
  testing::InSequence s;
  EXPECT_CALL(consumer,
              OnGetPasswordStoreResultsConstRef(
                  UnorderedPasswordFormElementsAre(&www_google_expected)))
      .RetiresOnSaturation();
  EXPECT_CALL(consumer,
              OnGetPasswordStoreResultsConstRef(
                  UnorderedPasswordFormElementsAre(&accounts_google_expected)))
      .RetiresOnSaturation();
  EXPECT_CALL(consumer,
              OnGetPasswordStoreResultsConstRef(
                  UnorderedPasswordFormElementsAre(&bar_example_expected)))
      .RetiresOnSaturation();

  store->GetLogins(www_google, &consumer);
  store->GetLogins(accounts_google, &consumer);
  store->GetLogins(bar_example, &consumer);

  base::RunLoop().RunUntilIdle();

  store->ShutdownOnUIThread();
  base::RunLoop().RunUntilIdle();
}

TEST_F(PasswordStoreTest, StartSyncFlare) {
  scoped_refptr<PasswordStoreDefault> store(new PasswordStoreDefault(
      base::ThreadTaskRunnerHandle::Get(), base::ThreadTaskRunnerHandle::Get(),
      base::MakeUnique<LoginDatabase>(test_login_db_file_path())));
  StartSyncFlareMock mock;
  store->Init(
      base::Bind(&StartSyncFlareMock::StartSyncFlare, base::Unretained(&mock)));
  {
    PasswordForm form;
    form.origin = GURL("http://accounts.google.com/LoginAuth");
    form.signon_realm = "http://accounts.google.com/";
    EXPECT_CALL(mock, StartSyncFlare(syncer::PASSWORDS));
    store->AddLogin(form);
    base::RunLoop().RunUntilIdle();
  }
  store->ShutdownOnUIThread();
  base::RunLoop().RunUntilIdle();
}

TEST_F(PasswordStoreTest, GetLoginImpl) {
  /* clang-format off */
  static const PasswordFormData kTestCredential = {
      PasswordForm::SCHEME_HTML,
      kTestWebRealm1,
      kTestWebOrigin1,
      "", L"", L"username_element",  L"password_element",
      L"username_value",
      L"", true, 1};
  /* clang-format on */

  scoped_refptr<PasswordStoreDefault> store(new PasswordStoreDefault(
      base::ThreadTaskRunnerHandle::Get(), base::ThreadTaskRunnerHandle::Get(),
      base::MakeUnique<LoginDatabase>(test_login_db_file_path())));
  store->Init(syncer::SyncableService::StartSyncFlare());

  // For each attribute in the primary key, create one form that mismatches on
  // that attribute.
  std::unique_ptr<PasswordForm> test_form(
      CreatePasswordFormFromDataForTesting(kTestCredential));
  std::unique_ptr<PasswordForm> mismatching_form_1(
      new PasswordForm(*test_form));
  mismatching_form_1->signon_realm = kTestPSLMatchingWebRealm;
  std::unique_ptr<PasswordForm> mismatching_form_2(
      new PasswordForm(*test_form));
  mismatching_form_2->origin = GURL(kTestPSLMatchingWebOrigin);
  std::unique_ptr<PasswordForm> mismatching_form_3(
      new PasswordForm(*test_form));
  mismatching_form_3->username_element = base::ASCIIToUTF16("other_element");
  std::unique_ptr<PasswordForm> mismatching_form_4(
      new PasswordForm(*test_form));
  mismatching_form_4->password_element = base::ASCIIToUTF16("other_element");
  std::unique_ptr<PasswordForm> mismatching_form_5(
      new PasswordForm(*test_form));
  mismatching_form_5->username_value =
      base::ASCIIToUTF16("other_username_value");

  store->AddLogin(*mismatching_form_1);
  store->AddLogin(*mismatching_form_2);
  store->AddLogin(*mismatching_form_3);
  store->AddLogin(*mismatching_form_4);
  store->AddLogin(*mismatching_form_5);
  base::RunLoop().RunUntilIdle();
  EXPECT_FALSE(store->GetLoginImpl(*test_form));

  store->AddLogin(*test_form);
  base::RunLoop().RunUntilIdle();
  std::unique_ptr<PasswordForm> returned_form = store->GetLoginImpl(*test_form);
  ASSERT_TRUE(returned_form);
  EXPECT_EQ(*test_form, *returned_form);

  store->ShutdownOnUIThread();
  base::RunLoop().RunUntilIdle();
}

TEST_F(PasswordStoreTest, UpdateLoginPrimaryKeyFields) {
  /* clang-format off */
  static const PasswordFormData kTestCredentials[] = {
      // The old credential.
      {PasswordForm::SCHEME_HTML,
       kTestWebRealm1,
       kTestWebOrigin1,
       "", L"", L"username_element_1",  L"password_element_1",
       L"username_value_1",
       L"", true, 1},
      // The new credential with different values for all primary key fields.
      {PasswordForm::SCHEME_HTML,
       kTestWebRealm2,
       kTestWebOrigin2,
       "", L"", L"username_element_2",  L"password_element_2",
       L"username_value_2",
       L"", true, 1}};
  /* clang-format on */

  scoped_refptr<PasswordStoreDefault> store(new PasswordStoreDefault(
      base::ThreadTaskRunnerHandle::Get(), base::ThreadTaskRunnerHandle::Get(),
      base::MakeUnique<LoginDatabase>(test_login_db_file_path())));
  store->Init(syncer::SyncableService::StartSyncFlare());

  std::unique_ptr<PasswordForm> old_form(
      CreatePasswordFormFromDataForTesting(kTestCredentials[0]));
  store->AddLogin(*old_form);
  base::RunLoop().RunUntilIdle();

  MockPasswordStoreObserver mock_observer;
  store->AddObserver(&mock_observer);

  std::unique_ptr<PasswordForm> new_form(
      CreatePasswordFormFromDataForTesting(kTestCredentials[1]));
  EXPECT_CALL(mock_observer, OnLoginsChanged(testing::SizeIs(2u)));
  PasswordForm old_primary_key;
  old_primary_key.signon_realm = old_form->signon_realm;
  old_primary_key.origin = old_form->origin;
  old_primary_key.username_element = old_form->username_element;
  old_primary_key.username_value = old_form->username_value;
  old_primary_key.password_element = old_form->password_element;
  store->UpdateLoginWithPrimaryKey(*new_form, old_primary_key);
  base::RunLoop().RunUntilIdle();

  MockPasswordStoreConsumer mock_consumer;
  std::vector<std::unique_ptr<PasswordForm>> expected_forms;
  expected_forms.push_back(std::move(new_form));
  EXPECT_CALL(mock_consumer,
              OnGetPasswordStoreResultsConstRef(
                  UnorderedPasswordFormElementsAre(&expected_forms)));
  store->GetAutofillableLogins(&mock_consumer);
  base::RunLoop().RunUntilIdle();

  store->RemoveObserver(&mock_observer);
  store->ShutdownOnUIThread();
  base::RunLoop().RunUntilIdle();
}

// Verify that RemoveLoginsCreatedBetween() fires the completion callback after
// deletions have been performed and notifications have been sent out. Whether
// the correct logins are removed or not is verified in detail in other tests.
TEST_F(PasswordStoreTest, RemoveLoginsCreatedBetweenCallbackIsCalled) {
  /* clang-format off */
  static const PasswordFormData kTestCredential =
      {PasswordForm::SCHEME_HTML,
       kTestWebRealm1,
       kTestWebOrigin1,
       "", L"", L"username_element_1",  L"password_element_1",
       L"username_value_1",
       L"", true, 1};
  /* clang-format on */

  scoped_refptr<PasswordStoreDefault> store(new PasswordStoreDefault(
      base::ThreadTaskRunnerHandle::Get(), base::ThreadTaskRunnerHandle::Get(),
      base::WrapUnique(new LoginDatabase(test_login_db_file_path()))));
  store->Init(syncer::SyncableService::StartSyncFlare());

  std::unique_ptr<PasswordForm> test_form(
      CreatePasswordFormFromDataForTesting(kTestCredential));
  store->AddLogin(*test_form);
  base::RunLoop().RunUntilIdle();

  MockPasswordStoreObserver mock_observer;
  store->AddObserver(&mock_observer);

  EXPECT_CALL(mock_observer, OnLoginsChanged(testing::SizeIs(1u)));
  store->RemoveLoginsCreatedBetween(
      base::Time::FromDoubleT(0), base::Time::FromDoubleT(2),
      base::MessageLoop::current()->QuitWhenIdleClosure());
  base::RunLoop().Run();
  testing::Mock::VerifyAndClearExpectations(&mock_observer);

  store->RemoveObserver(&mock_observer);
  store->ShutdownOnUIThread();
  base::RunLoop().RunUntilIdle();
}

// When no Android applications are actually affiliated with the realm of the
// observed form, GetLoginsWithAffiliations() should still return the exact and
// PSL matching results, but not any stored Android credentials.
TEST_F(PasswordStoreTest, GetLoginsWithoutAffiliations) {
  /* clang-format off */
  static const PasswordFormData kTestCredentials[] = {
      // Credential that is an exact match of the observed form.
      {PasswordForm::SCHEME_HTML,
       kTestWebRealm1,
       kTestWebOrigin1,
       "", L"", L"",  L"",
       L"username_value_1",
       L"", true, 1},
      // Credential that is a PSL match of the observed form.
      {PasswordForm::SCHEME_HTML,
       kTestPSLMatchingWebRealm,
       kTestPSLMatchingWebOrigin,
       "", L"", L"",  L"",
       L"username_value_2",
       L"", true, 1},
      // Credential for an unrelated Android application.
      {PasswordForm::SCHEME_HTML,
       kTestUnrelatedAndroidRealm,
       "", "", L"", L"", L"",
       L"username_value_3",
       L"", true, 1}};
  /* clang-format on */

  scoped_refptr<PasswordStoreDefault> store(new PasswordStoreDefault(
      base::ThreadTaskRunnerHandle::Get(), base::ThreadTaskRunnerHandle::Get(),
      base::WrapUnique(new LoginDatabase(test_login_db_file_path()))));
  store->Init(syncer::SyncableService::StartSyncFlare());

  MockAffiliatedMatchHelper* mock_helper = new MockAffiliatedMatchHelper;
  store->SetAffiliatedMatchHelper(base::WrapUnique(mock_helper));

  std::vector<std::unique_ptr<PasswordForm>> all_credentials;
  for (size_t i = 0; i < arraysize(kTestCredentials); ++i) {
    all_credentials.push_back(
        CreatePasswordFormFromDataForTesting(kTestCredentials[i]));
    store->AddLogin(*all_credentials.back());
    base::RunLoop().RunUntilIdle();
  }

  PasswordStore::FormDigest observed_form = {
      PasswordForm::SCHEME_HTML, kTestWebRealm1, GURL(kTestWebOrigin1)};

  MockPasswordStoreConsumer mock_consumer;
  std::vector<std::unique_ptr<PasswordForm>> expected_results;
  expected_results.push_back(
      base::MakeUnique<PasswordForm>(*all_credentials[0]));
  expected_results.push_back(
      base::MakeUnique<PasswordForm>(*all_credentials[1]));
  for (const auto& result : expected_results) {
    if (result->signon_realm != observed_form.signon_realm)
      result->is_public_suffix_match = true;
  }

  std::vector<std::string> no_affiliated_android_realms;
  mock_helper->ExpectCallToGetAffiliatedAndroidRealms(
      observed_form, no_affiliated_android_realms);

  EXPECT_CALL(mock_consumer,
              OnGetPasswordStoreResultsConstRef(
                  UnorderedPasswordFormElementsAre(&expected_results)));
  store->GetLogins(observed_form, &mock_consumer);
  store->ShutdownOnUIThread();
  base::RunLoop().RunUntilIdle();
}

// There are 3 Android applications affiliated with the realm of the observed
// form, with the PasswordStore having credentials for two of these (even two
// credentials for one). GetLoginsWithAffiliations() should return the exact,
// and PSL matching credentials, and the credentials for these two Android
// applications, but not for the unaffiliated Android application.
TEST_F(PasswordStoreTest, GetLoginsWithAffiliations) {
  /* clang-format off */
  static const PasswordFormData kTestCredentials[] = {
      // Credential that is an exact match of the observed form.
      {PasswordForm::SCHEME_HTML,
       kTestWebRealm1,
       kTestWebOrigin1,
       "", L"", L"",  L"",
       L"username_value_1",
       L"", true, 1},
      // Credential that is a PSL match of the observed form.
      {PasswordForm::SCHEME_HTML,
       kTestPSLMatchingWebRealm,
       kTestPSLMatchingWebOrigin,
       "", L"", L"",  L"",
       L"username_value_2",
       L"", true, 1},
      // Credential for an Android application affiliated with the realm of the
      // observed from.
      {PasswordForm::SCHEME_HTML,
       kTestAndroidRealm1,
       "", "", L"", L"", L"",
       L"username_value_3",
       L"", true, 1},
      // Second credential for the same Android application.
      {PasswordForm::SCHEME_HTML,
       kTestAndroidRealm1,
       "", "", L"", L"", L"",
       L"username_value_3b",
       L"", true, 1},
      // Third credential for the same application which is username-only.
      {PasswordForm::SCHEME_USERNAME_ONLY,
       kTestAndroidRealm1,
       "", "", L"", L"", L"",
       L"username_value_3c",
       L"", true, 1},
      // Credential for another Android application affiliated with the realm
      // of the observed from.
      {PasswordForm::SCHEME_HTML,
       kTestAndroidRealm2,
       "", "", L"", L"", L"",
       L"username_value_4",
       L"", true, 1},
      // Federated credential for this second Android application.
      {PasswordForm::SCHEME_HTML,
       kTestAndroidRealm2,
       "", "", L"", L"", L"",
       L"username_value_4b",
       kTestingFederatedLoginMarker, true, 1},
      // Credential for an unrelated Android application.
      {PasswordForm::SCHEME_HTML,
       kTestUnrelatedAndroidRealm,
       "", "", L"", L"", L"",
       L"username_value_5",
       L"", true, 1}
       };
  /* clang-format on */

  scoped_refptr<PasswordStoreDefault> store(new PasswordStoreDefault(
      base::ThreadTaskRunnerHandle::Get(), base::ThreadTaskRunnerHandle::Get(),
      base::WrapUnique(new LoginDatabase(test_login_db_file_path()))));
  store->Init(syncer::SyncableService::StartSyncFlare());

  MockAffiliatedMatchHelper* mock_helper = new MockAffiliatedMatchHelper;
  store->SetAffiliatedMatchHelper(base::WrapUnique(mock_helper));

  std::vector<std::unique_ptr<PasswordForm>> all_credentials;
  for (size_t i = 0; i < arraysize(kTestCredentials); ++i) {
    all_credentials.push_back(
        CreatePasswordFormFromDataForTesting(kTestCredentials[i]));
    store->AddLogin(*all_credentials.back());
    base::RunLoop().RunUntilIdle();
  }

  PasswordStore::FormDigest observed_form = {
      PasswordForm::SCHEME_HTML, kTestWebRealm1, GURL(kTestWebOrigin1)};

  MockPasswordStoreConsumer mock_consumer;
  std::vector<std::unique_ptr<PasswordForm>> expected_results;
  expected_results.push_back(
      base::MakeUnique<PasswordForm>(*all_credentials[0]));
  expected_results.push_back(
      base::MakeUnique<PasswordForm>(*all_credentials[1]));
  expected_results.push_back(
      base::MakeUnique<PasswordForm>(*all_credentials[2]));
  expected_results.push_back(
      base::MakeUnique<PasswordForm>(*all_credentials[3]));
  expected_results.push_back(
      base::MakeUnique<PasswordForm>(*all_credentials[5]));
  expected_results.push_back(
      base::MakeUnique<PasswordForm>(*all_credentials[6]));

  for (const auto& result : expected_results) {
    if (result->signon_realm != observed_form.signon_realm &&
        !IsValidAndroidFacetURI(result->signon_realm))
      result->is_public_suffix_match = true;
    if (IsValidAndroidFacetURI(result->signon_realm))
      result->is_affiliation_based_match = true;
  }

  std::vector<std::string> affiliated_android_realms;
  affiliated_android_realms.push_back(kTestAndroidRealm1);
  affiliated_android_realms.push_back(kTestAndroidRealm2);
  affiliated_android_realms.push_back(kTestAndroidRealm3);
  mock_helper->ExpectCallToGetAffiliatedAndroidRealms(
      observed_form, affiliated_android_realms);

  EXPECT_CALL(mock_consumer,
              OnGetPasswordStoreResultsConstRef(
                  UnorderedPasswordFormElementsAre(&expected_results)));

  store->GetLogins(observed_form, &mock_consumer);
  store->ShutdownOnUIThread();
  base::RunLoop().RunUntilIdle();
}

// This test must use passwords, which are not stored on Mac, therefore the test
// is disabled on Mac. This should not be a huge issue as functionality in the
// platform-independent base class is tested. See also the file-level comment.
#if defined(OS_MACOSX)
#define MAYBE_UpdatePasswordsStoredForAffiliatedWebsites \
  DISABLED_UpdatePasswordsStoredForAffiliatedWebsites
#else
#define MAYBE_UpdatePasswordsStoredForAffiliatedWebsites \
  UpdatePasswordsStoredForAffiliatedWebsites
#endif

// When the password stored for an Android application is updated, credentials
// with the same username stored for affiliated web sites should also be updated
// automatically.
TEST_F(PasswordStoreTest, MAYBE_UpdatePasswordsStoredForAffiliatedWebsites) {
  const wchar_t kTestUsername[] = L"username_value_1";
  const wchar_t kTestOtherUsername[] = L"username_value_2";
  const wchar_t kTestOldPassword[] = L"old_password_value";
  const wchar_t kTestNewPassword[] = L"new_password_value";
  const wchar_t kTestOtherPassword[] = L"other_password_value";

  /* clang-format off */
  static const PasswordFormData kTestCredentials[] = {
      // The credential for the Android application that will be updated
      // explicitly so it can be tested if the changes are correctly propagated
      // to affiliated Web credentials.
      {PasswordForm::SCHEME_HTML,
       kTestAndroidRealm1,
       "", "", L"", L"", L"",
       kTestUsername,
       kTestOldPassword, true, 2},

      // --- Positive samples --- Credentials that the password update should be
      // automatically propagated to.

      // Credential for an affiliated web site with the same username.
      {PasswordForm::SCHEME_HTML,
       kTestWebRealm1,
       kTestWebOrigin1,
       "", L"", L"",  L"",
       kTestUsername,
       kTestOldPassword, true, 1},
      // Credential for another affiliated web site with the same username.
      // Although the password is different than the current/old password for
      // the Android application, it should be updated regardless.
      {PasswordForm::SCHEME_HTML,
       kTestWebRealm2,
       kTestWebOrigin2,
       "", L"", L"",  L"",
       kTestUsername,
       kTestOtherPassword, true, 1},

      // --- Negative samples --- Credentials that the password update should
      // not be propagated to.

      // Credential for another affiliated web site, but one that already has
      // the new password.
      {PasswordForm::SCHEME_HTML,
       kTestWebRealm3,
       kTestWebOrigin3,
       "", L"", L"",  L"",
       kTestUsername,
       kTestNewPassword, true, 1},
      // Credential for the HTTP version of an affiliated web site.
      {PasswordForm::SCHEME_HTML,
       kTestInsecureWebRealm,
       kTestInsecureWebOrigin,
       "", L"", L"",  L"",
       kTestUsername,
       kTestOldPassword, true, 1},
      // Credential for an affiliated web site, but with a different username.
      {PasswordForm::SCHEME_HTML,
       kTestWebRealm1,
       kTestWebOrigin1,
       "", L"", L"",  L"",
       kTestOtherUsername,
       kTestOldPassword, true, 1},
      // Credential for a web site that is a PSL match to a web sites affiliated
      // with the Android application.
      {PasswordForm::SCHEME_HTML,
       kTestPSLMatchingWebRealm,
       kTestPSLMatchingWebOrigin,
       "poisoned", L"poisoned", L"",  L"",
       kTestUsername,
       kTestOldPassword, true, 1},
      // Credential for an unrelated web site.
      {PasswordForm::SCHEME_HTML,
       kTestUnrelatedWebRealm,
       kTestUnrelatedWebOrigin,
       "", L"", L"",  L"",
       kTestUsername,
       kTestOldPassword, true, 1},
      // Credential for an affiliated Android application.
      {PasswordForm::SCHEME_HTML,
       kTestAndroidRealm2,
       "", "", L"", L"", L"",
       kTestUsername,
       kTestOldPassword, true, 1},
      // Credential for an unrelated Android application.
      {PasswordForm::SCHEME_HTML,
       kTestUnrelatedAndroidRealm,
       "", "", L"", L"", L"",
       kTestUsername,
       kTestOldPassword, true, 1},
      // Credential for an affiliated web site with the same username, but one
      // that was updated at the same time via Sync as the Android credential.
      {PasswordForm::SCHEME_HTML,
       kTestWebRealm5,
       kTestWebOrigin5,
       "", L"", L"",  L"",
       kTestUsername,
       kTestOtherPassword, true, 2}};
  /* clang-format on */

  // The number of positive samples in |kTestCredentials|.
  const size_t kExpectedNumberOfPropagatedUpdates = 2u;

  const bool kFalseTrue[] = {false, true};
  for (bool propagation_enabled : kFalseTrue) {
    for (bool test_remove_and_add_login : kFalseTrue) {
      SCOPED_TRACE(testing::Message("propagation_enabled: ")
                   << propagation_enabled);
      SCOPED_TRACE(testing::Message("test_remove_and_add_login: ")
                   << test_remove_and_add_login);

      scoped_refptr<PasswordStoreDefault> store(new PasswordStoreDefault(
          base::ThreadTaskRunnerHandle::Get(),
          base::ThreadTaskRunnerHandle::Get(),
          base::WrapUnique(new LoginDatabase(test_login_db_file_path()))));
      store->Init(syncer::SyncableService::StartSyncFlare());
      store->RemoveLoginsCreatedBetween(base::Time(), base::Time::Max(),
                                        base::Closure());

      // Set up the initial test data set.
      std::vector<std::unique_ptr<PasswordForm>> all_credentials;
      for (size_t i = 0; i < arraysize(kTestCredentials); ++i) {
        all_credentials.push_back(
            CreatePasswordFormFromDataForTesting(kTestCredentials[i]));
        all_credentials.back()->date_synced =
            all_credentials.back()->date_created;
        store->AddLogin(*all_credentials.back());
        base::RunLoop().RunUntilIdle();
      }

      // The helper must be injected after the initial test data is set up,
      // otherwise it will already start propagating updates as new Android
      // credentials are added.
      MockAffiliatedMatchHelper* mock_helper = new MockAffiliatedMatchHelper;
      store->SetAffiliatedMatchHelper(base::WrapUnique(mock_helper));
      store->enable_propagating_password_changes_to_web_credentials(
          propagation_enabled);

      // Calculate how the correctly updated test data set should look like.
      size_t expected_number_of_propageted_updates =
          propagation_enabled ? kExpectedNumberOfPropagatedUpdates : 0u;
      std::vector<std::unique_ptr<PasswordForm>>
          expected_credentials_after_update;
      for (size_t i = 0; i < all_credentials.size(); ++i) {
        expected_credentials_after_update.push_back(
            base::MakeUnique<PasswordForm>(*all_credentials[i]));
        if (i < 1 + expected_number_of_propageted_updates) {
          expected_credentials_after_update.back()->password_value =
              base::WideToUTF16(kTestNewPassword);
        }
      }

      if (propagation_enabled) {
        std::vector<std::string> affiliated_web_realms;
        affiliated_web_realms.push_back(kTestWebRealm1);
        affiliated_web_realms.push_back(kTestWebRealm2);
        affiliated_web_realms.push_back(kTestWebRealm3);
        affiliated_web_realms.push_back(kTestWebRealm5);
        mock_helper->ExpectCallToGetAffiliatedWebRealms(
            PasswordStore::FormDigest(*expected_credentials_after_update[0]),
            affiliated_web_realms);
      }

      // Explicitly update the Android credential, wait until things calm down,
      // then query all passwords and expect that:
      //   1.) The positive samples in |kTestCredentials| have the new password,
      //       but the negative samples do not.
      //   2.) Change notifications are sent about the updates. Note that as the
      //       test interacts with the (Update|Add)LoginSync methods, only the
      //       derived changes should trigger notifications, the first one would
      //       normally be trigger by Sync.
      MockPasswordStoreObserver mock_observer;
      store->AddObserver(&mock_observer);
      if (propagation_enabled) {
        EXPECT_CALL(mock_observer, OnLoginsChanged(testing::SizeIs(
                                       expected_number_of_propageted_updates)));
      }
      if (test_remove_and_add_login) {
        store->RemoveLoginSync(*all_credentials[0]);
        store->AddLoginSync(*expected_credentials_after_update[0]);
      } else {
        store->UpdateLoginSync(*expected_credentials_after_update[0]);
      }
      base::RunLoop().RunUntilIdle();
      store->RemoveObserver(&mock_observer);

      MockPasswordStoreConsumer mock_consumer;
      EXPECT_CALL(mock_consumer, OnGetPasswordStoreResultsConstRef(
                                     UnorderedPasswordFormElementsAre(
                                         &expected_credentials_after_update)));
      store->GetAutofillableLogins(&mock_consumer);
      store->ShutdownOnUIThread();
      base::RunLoop().RunUntilIdle();
    }
  }
}

TEST_F(PasswordStoreTest, GetLoginsWithAffiliatedRealms) {
  /* clang-format off */
  static const PasswordFormData kTestCredentials[] = {
      {PasswordForm::SCHEME_HTML,
       kTestAndroidRealm1,
       "", "", L"", L"", L"",
       L"username_value_1",
       L"", true, 1},
      {PasswordForm::SCHEME_HTML,
       kTestAndroidRealm2,
       "", "", L"", L"", L"",
       L"username_value_2",
       L"", true, 1},
      {PasswordForm::SCHEME_HTML,
       kTestAndroidRealm3,
       "", "", L"", L"", L"",
       L"username_value_3",
       L"", true, 1}};
  /* clang-format on */

  const bool kFalseTrue[] = {false, true};
  for (bool blacklisted : kFalseTrue) {
    SCOPED_TRACE(testing::Message("use blacklisted logins: ") << blacklisted);
    scoped_refptr<PasswordStoreDefault> store(new PasswordStoreDefault(
        base::ThreadTaskRunnerHandle::Get(),
        base::ThreadTaskRunnerHandle::Get(),
        base::MakeUnique<LoginDatabase>(test_login_db_file_path())));
    store->Init(syncer::SyncableService::StartSyncFlare());
    store->RemoveLoginsCreatedBetween(base::Time(), base::Time::Max(),
                                      base::Closure());

    std::vector<std::unique_ptr<PasswordForm>> all_credentials;
    for (size_t i = 0; i < arraysize(kTestCredentials); ++i) {
      all_credentials.push_back(
          CreatePasswordFormFromDataForTesting(kTestCredentials[i]));
      if (blacklisted)
        all_credentials.back()->blacklisted_by_user = true;
      store->AddLogin(*all_credentials.back());
      base::RunLoop().RunUntilIdle();
    }

    MockPasswordStoreConsumer mock_consumer;
    std::vector<std::unique_ptr<PasswordForm>> expected_results;
    for (size_t i = 0; i < arraysize(kTestCredentials); ++i) {
      expected_results.push_back(
          base::MakeUnique<PasswordForm>(*all_credentials[i]));
    }

    MockAffiliatedMatchHelper* mock_helper = new MockAffiliatedMatchHelper;
    store->SetAffiliatedMatchHelper(base::WrapUnique(mock_helper));

    std::vector<std::string> affiliated_web_realms;
    affiliated_web_realms.push_back(kTestWebRealm1);
    affiliated_web_realms.push_back(kTestWebRealm2);
    affiliated_web_realms.push_back(std::string());
    mock_helper->ExpectCallToInjectAffiliatedWebRealms(affiliated_web_realms);
    for (size_t i = 0; i < expected_results.size(); ++i)
      expected_results[i]->affiliated_web_realm = affiliated_web_realms[i];

    EXPECT_CALL(mock_consumer,
                OnGetPasswordStoreResultsConstRef(
                    UnorderedPasswordFormElementsAre(&expected_results)));
    if (blacklisted)
      store->GetBlacklistLoginsWithAffiliatedRealms(&mock_consumer);
    else
      store->GetAutofillableLoginsWithAffiliatedRealms(&mock_consumer);

    // Since GetAutofillableLoginsWithAffiliatedRealms schedules a request for
    // affiliated realms to UI thread, don't shutdown UI thread until there are
    // no tasks in the UI queue.
    base::RunLoop().RunUntilIdle();
    store->ShutdownOnUIThread();
    base::RunLoop().RunUntilIdle();
  }
}

// TODO(crbug.com/706392): Fix password reuse detection for Android.
#if !defined(OS_ANDROID) && !defined(OS_IOS)
TEST_F(PasswordStoreTest, CheckPasswordReuse) {
  static constexpr PasswordFormData kTestCredentials[] = {
      {PasswordForm::SCHEME_HTML, "https://www.google.com",
       "https://www.google.com", "", L"", L"", L"", L"", L"password", true, 1},
      {PasswordForm::SCHEME_HTML, "https://facebook.com",
       "https://facebook.com", "", L"", L"", L"", L"", L"topsecret", true, 1}};

#if defined(OS_MACOSX)
  // Mock Keychain. There is a call to Keychain on initializling
  // PasswordReuseDetector, so it should be mocked.
  OSCryptMocker::SetUpWithSingleton();
#endif
  scoped_refptr<PasswordStoreDefault> store(new PasswordStoreDefault(
      base::ThreadTaskRunnerHandle::Get(), base::ThreadTaskRunnerHandle::Get(),
      base::MakeUnique<LoginDatabase>(test_login_db_file_path())));
  store->Init(syncer::SyncableService::StartSyncFlare());

  for (const auto& test_credentials : kTestCredentials) {
    auto credentials = CreatePasswordFormFromDataForTesting(test_credentials);
    store->AddLogin(*credentials);
    base::RunLoop().RunUntilIdle();
  }

  static constexpr struct {
    const wchar_t* input;
    const char* domain;
    const wchar_t* reused_password;  // Set to nullptr if no reuse is expected.
    const char* reuse_domain;
  } kReuseTestData[] = {
      {L"12345password", "https://evil.com", L"password", "google.com"},
      {L"1234567890", "https://evil.com", nullptr, nullptr},
      {L"topsecret", "https://m.facebook.com", nullptr, nullptr},
  };

  for (const auto& test_data : kReuseTestData) {
    MockPasswordReuseDetectorConsumer mock_consumer;
    if (test_data.reused_password) {
      EXPECT_CALL(mock_consumer,
                  OnReuseFound(base::WideToUTF16(test_data.reused_password),
                               std::string(test_data.reuse_domain), 2, 1));
    } else {
      EXPECT_CALL(mock_consumer, OnReuseFound(_, _, _, _)).Times(0);
    }

    store->CheckReuse(base::WideToUTF16(test_data.input), test_data.domain,
                      &mock_consumer);
    base::RunLoop().RunUntilIdle();
  }

  store->ShutdownOnUIThread();
  base::RunLoop().RunUntilIdle();
#if defined(OS_MACOSX)
  OSCryptMocker::TearDown();
#endif
}
#endif

}  // namespace password_manager
