// Copyright 2015 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 "chrome/browser/password_manager/password_store_proxy_mac.h"

#include <utility>

#include "base/files/scoped_temp_dir.h"
#include "base/macros.h"
#include "base/scoped_observer.h"
#include "base/strings/utf_string_conversions.h"
#include "base/test/histogram_tester.h"
#include "chrome/browser/password_manager/password_store_mac.h"
#include "chrome/browser/password_manager/password_store_mac_internal.h"
#include "chrome/browser/prefs/browser_prefs.h"
#include "components/os_crypt/os_crypt.h"
#include "components/password_manager/core/browser/login_database.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/common/password_manager_pref_names.h"
#include "components/syncable_prefs/testing_pref_service_syncable.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "crypto/mock_apple_keychain.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/origin.h"

namespace {

using autofill::PasswordForm;
using content::BrowserThread;
using password_manager::MigrationStatus;
using password_manager::PasswordStoreChange;
using password_manager::PasswordStoreChangeList;
using testing::_;
using testing::ElementsAre;
using testing::IsEmpty;
using testing::Pointee;

ACTION(QuitUIMessageLoop) {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);
  base::MessageLoop::current()->QuitWhenIdle();
}

// Returns a change list corresponding to |form| being added.
PasswordStoreChangeList AddChangeForForm(const PasswordForm& form) {
  return PasswordStoreChangeList(
      1, PasswordStoreChange(PasswordStoreChange::ADD, form));
}

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

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

class MockPasswordStoreObserver
    : public password_manager::PasswordStore::Observer {
 public:
  explicit MockPasswordStoreObserver(PasswordStoreProxyMac* password_store)
      : guard_(this) {
    guard_.Add(password_store);
  }
  MOCK_METHOD1(OnLoginsChanged,
               void(const password_manager::PasswordStoreChangeList& changes));

 private:
  ScopedObserver<PasswordStoreProxyMac, MockPasswordStoreObserver> guard_;
};

// A mock LoginDatabase that simulates a failing Init() method.
class BadLoginDatabase : public password_manager::LoginDatabase {
 public:
  BadLoginDatabase() : password_manager::LoginDatabase(base::FilePath()) {}
  ~BadLoginDatabase() override {}

  // LoginDatabase:
  bool Init() override { return false; }

 private:
  DISALLOW_COPY_AND_ASSIGN(BadLoginDatabase);
};

class PasswordStoreProxyMacTest
    : public testing::TestWithParam<MigrationStatus> {
 public:
  PasswordStoreProxyMacTest();
  ~PasswordStoreProxyMacTest() override;

  void SetUp() override;
  void TearDown() override;

  void CreateAndInitPasswordStore(
      scoped_ptr<password_manager::LoginDatabase> login_db);

  void ClosePasswordStore();

  // Do a store-level query to wait for all the previously enqueued operations
  // to finish.
  void FinishAsyncProcessing();

  // Add/Update/Remove |form| and verify the operation succeeded.
  void AddForm(const PasswordForm& form);
  void UpdateForm(const PasswordForm& form);
  void RemoveForm(const PasswordForm& form);

  // Tests RemoveLoginsCreatedBetween or RemoveLoginsSyncedBetween depending on
  // |check_created|.
  void CheckRemoveLoginsBetween(bool check_created);

  base::FilePath test_login_db_file_path() const;

  password_manager::LoginDatabase* login_db() const {
    return store_->login_metadata_db();
  }

  PasswordStoreProxyMac* store() { return store_.get(); }

 protected:
  content::TestBrowserThreadBundle ui_thread_;

  base::ScopedTempDir db_dir_;
  scoped_refptr<PasswordStoreProxyMac> store_;
  syncable_prefs::TestingPrefServiceSyncable testing_prefs_;
};

PasswordStoreProxyMacTest::PasswordStoreProxyMacTest() {
  EXPECT_TRUE(db_dir_.CreateUniqueTempDir());
  chrome::RegisterUserProfilePrefs(testing_prefs_.registry());
  testing_prefs_.SetInteger(password_manager::prefs::kKeychainMigrationStatus,
                            static_cast<int>(GetParam()));
  // Ensure that LoginDatabase will use the mock keychain if it needs to
  // encrypt/decrypt a password.
  OSCrypt::UseMockKeychain(true);
}

PasswordStoreProxyMacTest::~PasswordStoreProxyMacTest() {
}

void PasswordStoreProxyMacTest::SetUp() {
  scoped_ptr<password_manager::LoginDatabase> login_db(
      new password_manager::LoginDatabase(test_login_db_file_path()));
  CreateAndInitPasswordStore(std::move(login_db));
}

void PasswordStoreProxyMacTest::TearDown() {
  ClosePasswordStore();
}

void PasswordStoreProxyMacTest::CreateAndInitPasswordStore(
    scoped_ptr<password_manager::LoginDatabase> login_db) {
  store_ = new PasswordStoreProxyMac(
      BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI),
      make_scoped_ptr(new crypto::MockAppleKeychain), std::move(login_db),
      &testing_prefs_);
  ASSERT_TRUE(store_->Init(syncer::SyncableService::StartSyncFlare()));
}

void PasswordStoreProxyMacTest::ClosePasswordStore() {
  if (!store_)
    return;
  store_->ShutdownOnUIThread();
  EXPECT_FALSE(store_->GetBackgroundTaskRunner());
  store_ = nullptr;
}

void PasswordStoreProxyMacTest::FinishAsyncProcessing() {
  // Do a store-level query to wait for all the previously enqueued operations
  // to finish.
  MockPasswordStoreConsumer consumer;
  store_->GetLogins(PasswordForm(), &consumer);
  EXPECT_CALL(consumer, OnGetPasswordStoreResultsConstRef(_))
      .WillOnce(QuitUIMessageLoop());
  base::MessageLoop::current()->Run();
}

base::FilePath PasswordStoreProxyMacTest::test_login_db_file_path() const {
  return db_dir_.path().Append(FILE_PATH_LITERAL("login.db"));
}

void PasswordStoreProxyMacTest::AddForm(const PasswordForm& form) {
  MockPasswordStoreObserver mock_observer(store());

  password_manager::PasswordStoreChangeList list;
  list.push_back(password_manager::PasswordStoreChange(
      password_manager::PasswordStoreChange::ADD, form));
  EXPECT_CALL(mock_observer, OnLoginsChanged(list));
  store()->AddLogin(form);
  FinishAsyncProcessing();
}

void PasswordStoreProxyMacTest::UpdateForm(const PasswordForm& form) {
  MockPasswordStoreObserver mock_observer(store());

  password_manager::PasswordStoreChangeList list;
  list.push_back(password_manager::PasswordStoreChange(
      password_manager::PasswordStoreChange::UPDATE, form));
  EXPECT_CALL(mock_observer, OnLoginsChanged(list));
  store()->UpdateLogin(form);
  FinishAsyncProcessing();
}

void PasswordStoreProxyMacTest::RemoveForm(const PasswordForm& form) {
  MockPasswordStoreObserver mock_observer(store());

  password_manager::PasswordStoreChangeList list;
  list.push_back(password_manager::PasswordStoreChange(
      password_manager::PasswordStoreChange::REMOVE, form));
  EXPECT_CALL(mock_observer, OnLoginsChanged(list));
  store()->RemoveLogin(form);
  FinishAsyncProcessing();
}

void PasswordStoreProxyMacTest::CheckRemoveLoginsBetween(bool check_created) {
  PasswordForm old_form;
  old_form.origin = GURL("http://accounts.google.com/LoginAuth");
  old_form.signon_realm = "http://accounts.google.com/";
  old_form.username_value = base::ASCIIToUTF16("my_username");
  old_form.federation_origin =
      url::Origin(GURL("http://accounts.google.com/federation"));

  PasswordForm new_form = old_form;
  new_form.origin = GURL("http://accounts.google2.com/LoginAuth");
  new_form.signon_realm = "http://accounts.google2.com/";

  base::Time now = base::Time::Now();
  base::Time next_day = now + base::TimeDelta::FromDays(1);
  if (check_created) {
    old_form.date_created = now;
    new_form.date_created = next_day;
  } else {
    old_form.date_synced = now;
    new_form.date_synced = next_day;
  }

  AddForm(old_form);
  AddForm(new_form);

  MockPasswordStoreObserver mock_observer(store());
  password_manager::PasswordStoreChangeList list;
  list.push_back(password_manager::PasswordStoreChange(
      password_manager::PasswordStoreChange::REMOVE, old_form));
  EXPECT_CALL(mock_observer, OnLoginsChanged(list));
  if (check_created) {
    store()->RemoveLoginsCreatedBetween(base::Time(), next_day,
                                        base::Closure());
  } else {
    store()->RemoveLoginsSyncedBetween(base::Time(), next_day);
  }
  FinishAsyncProcessing();
}

// ----------- Tests -------------

TEST_P(PasswordStoreProxyMacTest, StartAndStop) {
  // PasswordStore::ShutdownOnUIThread() immediately follows
  // PasswordStore::Init(). The message loop isn't running in between. Anyway,
  // PasswordStore should end up in the right state.
  ClosePasswordStore();

  int status = testing_prefs_.GetInteger(
      password_manager::prefs::kKeychainMigrationStatus);
  if (GetParam() == MigrationStatus::NOT_STARTED ||
      GetParam() == MigrationStatus::FAILED_ONCE) {
    EXPECT_EQ(static_cast<int>(MigrationStatus::MIGRATED), status);
  } else {
    EXPECT_EQ(static_cast<int>(GetParam()), status);
  }
}

TEST_P(PasswordStoreProxyMacTest, FormLifeCycle) {
  PasswordForm password_form;
  password_form.origin = GURL("http://example.com");
  password_form.username_value = base::ASCIIToUTF16("test1@gmail.com");
  password_form.password_value = base::ASCIIToUTF16("12345");
  password_form.signon_realm = "http://example.com/";

  AddForm(password_form);
  password_form.password_value = base::ASCIIToUTF16("password");
  UpdateForm(password_form);
  RemoveForm(password_form);
}

TEST_P(PasswordStoreProxyMacTest, TestRemoveLoginsCreatedBetween) {
  CheckRemoveLoginsBetween(true);
}

TEST_P(PasswordStoreProxyMacTest, TestRemoveLoginsSyncedBetween) {
  CheckRemoveLoginsBetween(false);
}

TEST_P(PasswordStoreProxyMacTest, FillLogins) {
  PasswordForm password_form;
  password_form.origin = GURL("http://example.com");
  password_form.signon_realm = "http://example.com/";
  password_form.username_value = base::ASCIIToUTF16("test1@gmail.com");
  password_form.password_value = base::ASCIIToUTF16("12345");
  AddForm(password_form);

  PasswordForm blacklisted_form;
  blacklisted_form.origin = GURL("http://example2.com");
  blacklisted_form.signon_realm = "http://example2.com/";
  blacklisted_form.blacklisted_by_user = true;
  AddForm(blacklisted_form);

  MockPasswordStoreConsumer mock_consumer;
  store()->GetLogins(password_form, &mock_consumer);
  EXPECT_CALL(mock_consumer, OnGetPasswordStoreResultsConstRef(
                                 ElementsAre(Pointee(password_form))))
      .WillOnce(QuitUIMessageLoop());
  base::MessageLoop::current()->Run();

  store()->GetBlacklistLogins(&mock_consumer);
  EXPECT_CALL(mock_consumer, OnGetPasswordStoreResultsConstRef(
                                 ElementsAre(Pointee(blacklisted_form))))
      .WillOnce(QuitUIMessageLoop());
  base::MessageLoop::current()->Run();

  store()->GetAutofillableLogins(&mock_consumer);
  EXPECT_CALL(mock_consumer, OnGetPasswordStoreResultsConstRef(
                                 ElementsAre(Pointee(password_form))))
      .WillOnce(QuitUIMessageLoop());
  base::MessageLoop::current()->Run();
}

TEST_P(PasswordStoreProxyMacTest, OperationsOnABadDatabaseSilentlyFail) {
  // Verify that operations on a PasswordStore with a bad database cause no
  // explosions, but fail without side effect, return no data and trigger no
  // notifications.
  ClosePasswordStore();
  CreateAndInitPasswordStore(make_scoped_ptr(new BadLoginDatabase));
  FinishAsyncProcessing();
  EXPECT_FALSE(login_db());

  // The store should outlive the observer.
  scoped_refptr<PasswordStoreProxyMac> store_refptr = store();
  MockPasswordStoreObserver mock_observer(store());
  EXPECT_CALL(mock_observer, OnLoginsChanged(_)).Times(0);

  // Add a new autofillable login + a blacklisted login.
  password_manager::PasswordFormData www_form_data = {
      PasswordForm::SCHEME_HTML, "http://www.facebook.com/",
      "http://www.facebook.com/index.html", "login", L"username", L"password",
      L"submit", L"not_joe_user", L"12345", true, false, 1};
  scoped_ptr<PasswordForm> form =
      CreatePasswordFormFromDataForTesting(www_form_data);
  scoped_ptr<PasswordForm> blacklisted_form(new PasswordForm(*form));
  blacklisted_form->signon_realm = "http://foo.example.com";
  blacklisted_form->origin = GURL("http://foo.example.com/origin");
  blacklisted_form->action = GURL("http://foo.example.com/action");
  blacklisted_form->blacklisted_by_user = true;
  store()->AddLogin(*form);
  store()->AddLogin(*blacklisted_form);
  FinishAsyncProcessing();

  // Get all logins; autofillable logins; blacklisted logins.
  MockPasswordStoreConsumer mock_consumer;
  store()->GetLogins(*form, &mock_consumer);
  ON_CALL(mock_consumer, OnGetPasswordStoreResultsConstRef(_))
      .WillByDefault(QuitUIMessageLoop());
  EXPECT_CALL(mock_consumer, OnGetPasswordStoreResultsConstRef(IsEmpty()));
  base::MessageLoop::current()->Run();

  store()->GetAutofillableLogins(&mock_consumer);
  EXPECT_CALL(mock_consumer, OnGetPasswordStoreResultsConstRef(IsEmpty()));
  base::MessageLoop::current()->Run();

  store()->GetBlacklistLogins(&mock_consumer);
  EXPECT_CALL(mock_consumer, OnGetPasswordStoreResultsConstRef(IsEmpty()));
  base::MessageLoop::current()->Run();

  // Report metrics.
  store()->ReportMetrics("Test Username", true);
  FinishAsyncProcessing();

  // Change the login.
  form->password_value = base::ASCIIToUTF16("a different password");
  store()->UpdateLogin(*form);
  FinishAsyncProcessing();

  // Delete one login; a range of logins.
  store()->RemoveLogin(*form);
  store()->RemoveLoginsCreatedBetween(base::Time(), base::Time::Max(),
                                      base::Closure());
  store()->RemoveLoginsSyncedBetween(base::Time(), base::Time::Max());
  FinishAsyncProcessing();

  // Verify no notifications are fired during shutdown either.
  ClosePasswordStore();
}

INSTANTIATE_TEST_CASE_P(,
                        PasswordStoreProxyMacTest,
                        testing::Values(MigrationStatus::NOT_STARTED,
                                        MigrationStatus::MIGRATED,
                                        MigrationStatus::FAILED_ONCE,
                                        MigrationStatus::FAILED_TWICE));

// Test the migration process.
class PasswordStoreProxyMacMigrationTest : public PasswordStoreProxyMacTest {
 public:
  void SetUp() override;

  void TestMigration(bool lock_keychain);

 protected:
  scoped_ptr<password_manager::LoginDatabase> login_db_;
  scoped_ptr<crypto::MockAppleKeychain> keychain_;
  base::HistogramTester histogram_tester_;
};

void PasswordStoreProxyMacMigrationTest::SetUp() {
  login_db_.reset(
      new password_manager::LoginDatabase(test_login_db_file_path()));
  keychain_.reset(new crypto::MockAppleKeychain);
}

void PasswordStoreProxyMacMigrationTest::TestMigration(bool lock_keychain) {
  PasswordForm form;
  form.origin = GURL("http://accounts.google.com/LoginAuth");
  form.signon_realm = "http://accounts.google.com/";
  form.username_value = base::ASCIIToUTF16("my_username");
  form.password_value = base::ASCIIToUTF16("12345");

  if (GetParam() != MigrationStatus::MIGRATED)
    login_db_->set_clear_password_values(true);
  EXPECT_TRUE(login_db_->Init());
  EXPECT_EQ(AddChangeForForm(form), login_db_->AddLogin(form));
  // Prepare another database instance with the same content which is to be
  // initialized by PasswordStoreProxyMac.
  login_db_.reset(
      new password_manager::LoginDatabase(test_login_db_file_path()));
  MacKeychainPasswordFormAdapter adapter(keychain_.get());
  EXPECT_TRUE(adapter.AddPassword(form));

  // Init the store. It may trigger the migration.
  if (lock_keychain)
    keychain_->set_locked(true);
  store_ = new PasswordStoreProxyMac(
      BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI),
      std::move(keychain_), std::move(login_db_), &testing_prefs_);
  ASSERT_TRUE(store_->Init(syncer::SyncableService::StartSyncFlare()));
  FinishAsyncProcessing();

  // Check the password is still there.
  if (lock_keychain && store_->password_store_mac()) {
    static_cast<crypto::MockAppleKeychain*>(
        store_->password_store_mac()->keychain())->set_locked(false);
  }
  MockPasswordStoreConsumer mock_consumer;
  store()->GetLogins(form, &mock_consumer);
  EXPECT_CALL(mock_consumer,
              OnGetPasswordStoreResultsConstRef(ElementsAre(Pointee(form))))
      .WillOnce(QuitUIMessageLoop());
  base::MessageLoop::current()->Run();

  int status = testing_prefs_.GetInteger(
      password_manager::prefs::kKeychainMigrationStatus);
  if (GetParam() == MigrationStatus::MIGRATED ||
      GetParam() == MigrationStatus::FAILED_TWICE) {
    EXPECT_EQ(static_cast<int>(GetParam()), status);
  } else if (lock_keychain) {
    EXPECT_EQ(static_cast<int>(GetParam() == MigrationStatus::NOT_STARTED
                                   ? MigrationStatus::FAILED_ONCE
                                   : MigrationStatus::FAILED_TWICE),
              status);
  } else {
    EXPECT_EQ(static_cast<int>(MigrationStatus::MIGRATED), status);
  }
  histogram_tester_.ExpectUniqueSample(
      "PasswordManager.KeychainMigration.Status",
      status, 1);
}

TEST_P(PasswordStoreProxyMacMigrationTest, TestSuccessfullMigration) {
  TestMigration(false);
}

TEST_P(PasswordStoreProxyMacMigrationTest, TestFailedMigration) {
  TestMigration(true);
}

INSTANTIATE_TEST_CASE_P(,
                        PasswordStoreProxyMacMigrationTest,
                        testing::Values(MigrationStatus::NOT_STARTED,
                                        MigrationStatus::MIGRATED,
                                        MigrationStatus::FAILED_ONCE,
                                        MigrationStatus::FAILED_TWICE));

}  // namespace
