// Copyright 2019 The Chromium OS 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 "kerberos/account_manager.h"

#include <map>
#include <memory>
#include <utility>

#include <base/bind.h>
#include <base/files/file_path.h>
#include <base/files/file_util.h>
#include <base/files/scoped_temp_dir.h>
#include <base/memory/ref_counted.h>
#include <base/test/test_mock_time_task_runner.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <libpasswordprovider/fake_password_provider.h>
#include <libpasswordprovider/password_provider_test_utils.h>

#include "kerberos/fake_krb5_interface.h"
#include "kerberos/kerberos_metrics.h"
#include "kerberos/krb5_jail_wrapper.h"

using testing::_;
using testing::Mock;
using testing::NiceMock;
using testing::Return;

namespace kerberos {
namespace {

constexpr char kUser[] = "user@REALM.COM";
constexpr char kUser2[] = "user2@REALM2.COM";
constexpr char kUser3[] = "user3@REALM3.COM";
constexpr char kPassword[] = "i<3k3R8e5Oz";
constexpr char kPassword2[] = "ih4zf00d";
constexpr char kKrb5Conf[] = R"(
  [libdefaults]
    default_realm = REALM.COM)";

constexpr Krb5Interface::TgtStatus kValidTgt(3600, 3600);
constexpr Krb5Interface::TgtStatus kExpiredTgt(0, 0);

// Convenience defines to make code more readable
constexpr bool kManaged = true;
constexpr bool kUnmanaged = false;

constexpr bool kRememberPassword = true;
constexpr bool kDontRememberPassword = false;

constexpr bool kUseLoginPassword = true;
constexpr bool kDontUseLoginPassword = false;

constexpr char kEmptyPassword[] = "";

class MockMetrics : public KerberosMetrics {
 public:
  explicit MockMetrics(const base::FilePath& storage_dir)
      : KerberosMetrics(storage_dir) {}
  ~MockMetrics() override = default;

  MOCK_METHOD(bool, ShouldReportDailyUsageStats, (), (override));
  MOCK_METHOD(void,
              ReportDailyUsageStats,
              (int, int, int, int, int),
              (override));

 private:
  DISALLOW_COPY_AND_ASSIGN(MockMetrics);
};

}  // namespace

class AccountManagerTest : public ::testing::Test {
 public:
  AccountManagerTest()
      : kerberos_files_changed_(
            base::BindRepeating(&AccountManagerTest::OnKerberosFilesChanged,
                                base::Unretained(this))),
        kerberos_ticket_expiring_(
            base::BindRepeating(&AccountManagerTest::OnKerberosTicketExpiring,
                                base::Unretained(this))) {}
  ~AccountManagerTest() override = default;

  void SetUp() override {
    ::testing::Test::SetUp();

    // Create temp directory for files written during tests.
    CHECK(storage_dir_.CreateUniqueTempDir());
    accounts_path_ = storage_dir_.GetPath().Append("accounts");
    account_dir_ = storage_dir_.GetPath().Append(
        AccountManager::GetSafeFilenameForTesting(kUser));
    krb5cc_path_ = account_dir_.Append("krb5cc");
    krb5conf_path_ = account_dir_.Append("krb5.conf");
    password_path_ = account_dir_.Append("password");

    // Create the manager with a fake krb5 interface.
    auto krb5 = std::make_unique<FakeKrb5Interface>();
    auto password_provider =
        std::make_unique<password_provider::FakePasswordProvider>();
    metrics_ = std::make_unique<NiceMock<MockMetrics>>(storage_dir_.GetPath());
    krb5_ = krb5.get();
    password_provider_ = password_provider.get();
    manager_ = std::make_unique<AccountManager>(
        storage_dir_.GetPath(), kerberos_files_changed_,
        kerberos_ticket_expiring_, std::move(krb5),
        std::move(password_provider), metrics_.get());
  }

  void TearDown() override {
    // Make sure the file stored on disk contains the same accounts as the
    // manager instance. This catches cases where AccountManager forgets to save
    // accounts on some change.
    if (base::PathExists(accounts_path_)) {
      std::vector<Account> accounts;
      EXPECT_EQ(ERROR_NONE, manager_->ListAccounts(&accounts));

      AccountManager other_manager(
          storage_dir_.GetPath(), kerberos_files_changed_,
          kerberos_ticket_expiring_, std::make_unique<FakeKrb5Interface>(),
          std::make_unique<password_provider::FakePasswordProvider>(),
          metrics_.get());
      other_manager.LoadAccounts();
      std::vector<Account> other_accounts;
      EXPECT_EQ(ERROR_NONE, other_manager.ListAccounts(&other_accounts));

      ASSERT_NO_FATAL_FAILURE(ExpectAccountsEqual(accounts, other_accounts));
    }

    ::testing::Test::TearDown();
  }

  // Add account with default settings.
  ErrorType AddAccount() { return manager_->AddAccount(kUser, kUnmanaged); }

  // Sets some default Kerberos configuration.
  ErrorType SetConfig() { return manager_->SetConfig(kUser, kKrb5Conf); }

  // Acquire Kerberos ticket with default credentials and settings.
  ErrorType AcquireTgt() {
    return manager_->AcquireTgt(kUser, kPassword, kDontRememberPassword,
                                kDontUseLoginPassword);
  }

  void SaveLoginPassword(const char* password) {
    auto password_ptr = password_provider::test::CreatePassword(password);
    password_provider_->SavePassword(*password_ptr);
  }

  // Fast forwards to the next scheduled task (assumed to be the renewal task)
  // and verifies expectation that |krb5_->RenewTgt() was called|.
  void RunScheduledRenewalTask() {
    int initial_count = krb5_->renew_tgt_call_count();
    EXPECT_EQ(1, task_runner_->GetPendingTaskCount());
    task_runner_->FastForwardBy(task_runner_->NextPendingTaskDelay());
    EXPECT_EQ(initial_count + 1, krb5_->renew_tgt_call_count());
  }

 protected:
  void OnKerberosFilesChanged(const std::string& principal_name) {
    kerberos_files_changed_count_[principal_name]++;
  }

  void OnKerberosTicketExpiring(const std::string& principal_name) {
    kerberos_ticket_expiring_count_[principal_name]++;
  }

  void ExpectAccountsEqual(const std::vector<Account>& account_list_1,
                           const std::vector<Account>& account_list_2) {
    ASSERT_EQ(account_list_1.size(), account_list_2.size());
    for (size_t n = 0; n < account_list_1.size(); ++n) {
      const Account& account1 = account_list_1[n];
      const Account& account2 = account_list_2[n];

      EXPECT_EQ(account1.principal_name(), account2.principal_name());
      EXPECT_EQ(account1.is_managed(), account2.is_managed());
      EXPECT_EQ(account1.use_login_password(), account2.use_login_password());
      // TODO(https://crbug.com/952239): Check additional properties.
    }
  }

  std::unique_ptr<AccountManager> manager_;

  // Fake Kerberos interface used by |manager_|. Not owned.
  FakeKrb5Interface* krb5_;

  // Fake password provider to get the login password. Not owned.
  password_provider::FakePasswordProvider* password_provider_;

  // Mock metrics for testing UMA stat recording.
  std::unique_ptr<NiceMock<MockMetrics>> metrics_;

  // Paths of files stored by |manager_|.
  base::ScopedTempDir storage_dir_;
  base::FilePath accounts_path_;
  base::FilePath account_dir_;
  base::FilePath krb5conf_path_;
  base::FilePath krb5cc_path_;
  base::FilePath password_path_;

  AccountManager::KerberosFilesChangedCallback kerberos_files_changed_;
  AccountManager::KerberosTicketExpiringCallback kerberos_ticket_expiring_;

  std::map<std::string, int> kerberos_files_changed_count_;
  std::map<std::string, int> kerberos_ticket_expiring_count_;

  scoped_refptr<base::TestMockTimeTaskRunner> task_runner_{
      new base::TestMockTimeTaskRunner()};
  base::TestMockTimeTaskRunner::ScopedContext scoped_context_{task_runner_};

 private:
  DISALLOW_COPY_AND_ASSIGN(AccountManagerTest);
};

// Adding an account succeeds and serializes the file on disk.
TEST_F(AccountManagerTest, AddAccountSuccess) {
  EXPECT_FALSE(base::PathExists(accounts_path_));
  EXPECT_EQ(ERROR_NONE, AddAccount());
  EXPECT_TRUE(base::PathExists(accounts_path_));
}

// AddAccount() fails if the same account is added twice.
TEST_F(AccountManagerTest, AddDuplicateAccountFail) {
  ignore_result(AddAccount());

  EXPECT_TRUE(base::DeleteFile(accounts_path_, false /* recursive */));
  EXPECT_EQ(ERROR_DUPLICATE_PRINCIPAL_NAME, AddAccount());
  EXPECT_FALSE(base::PathExists(accounts_path_));
}

// Adding a managed account overwrites an existing unmanaged account.
TEST_F(AccountManagerTest, ManagedOverridesUnmanaged) {
  ignore_result(manager_->AddAccount(kUser, kUnmanaged));

  EXPECT_EQ(ERROR_NONE, AcquireTgt());
  EXPECT_TRUE(base::PathExists(krb5cc_path_));

  // Overwriting with a managed account should wipe existing files and make the
  // account managed.
  EXPECT_EQ(ERROR_DUPLICATE_PRINCIPAL_NAME,
            manager_->AddAccount(kUser, kManaged));
  EXPECT_FALSE(base::PathExists(krb5cc_path_));

  std::vector<Account> accounts;
  EXPECT_EQ(ERROR_NONE, manager_->ListAccounts(&accounts));
  ASSERT_EQ(1u, accounts.size());
  EXPECT_TRUE(accounts[0].is_managed());
}

// Adding an unmanaged account does not overwrite an existing managed account.
TEST_F(AccountManagerTest, UnmanagedDoesNotOverrideManaged) {
  ignore_result(manager_->AddAccount(kUser, kManaged));

  EXPECT_EQ(ERROR_DUPLICATE_PRINCIPAL_NAME,
            manager_->AddAccount(kUser, kUnmanaged));
  std::vector<Account> accounts;
  EXPECT_EQ(ERROR_NONE, manager_->ListAccounts(&accounts));
  ASSERT_EQ(1u, accounts.size());
  EXPECT_TRUE(accounts[0].is_managed());
}

// RemoveAccount() succeeds if the account exists and serializes the file on
// disk.
TEST_F(AccountManagerTest, RemoveAccountSuccess) {
  ignore_result(AddAccount());

  EXPECT_TRUE(base::DeleteFile(accounts_path_, false /* recursive */));
  EXPECT_EQ(ERROR_NONE, manager_->RemoveAccount(kUser));
  EXPECT_TRUE(base::PathExists(accounts_path_));
}

// RemoveAccount() fails if the account does not exist.
TEST_F(AccountManagerTest, RemoveUnknownAccountFail) {
  EXPECT_EQ(ERROR_UNKNOWN_PRINCIPAL_NAME, manager_->RemoveAccount(kUser));
  EXPECT_FALSE(base::PathExists(accounts_path_));
}

// RemoveAccount() does not trigger KerberosFilesChanged if the credential cache
// does not exists.
TEST_F(AccountManagerTest, RemoveAccountTriggersKFCIfCCExists) {
  ignore_result(AddAccount());

  EXPECT_EQ(ERROR_NONE, manager_->RemoveAccount(kUser));
  EXPECT_EQ(0, kerberos_files_changed_count_[kUser]);
}

// RemoveAccount() triggers KerberosFilesChanged if the credential cache exists.
TEST_F(AccountManagerTest, RemoveAccountDoesNotTriggerKFCIfCCDoesNotExist) {
  ignore_result(AddAccount());

  EXPECT_EQ(ERROR_NONE, AcquireTgt());
  EXPECT_EQ(1, kerberos_files_changed_count_[kUser]);
  EXPECT_EQ(ERROR_NONE, manager_->RemoveAccount(kUser));
  EXPECT_EQ(2, kerberos_files_changed_count_[kUser]);
}

// Repeatedly calling AddAccount() and RemoveAccount() succeeds.
TEST_F(AccountManagerTest, RepeatedAddRemoveSuccess) {
  ignore_result(AddAccount());
  ignore_result(manager_->RemoveAccount(kUser));

  EXPECT_EQ(ERROR_NONE, AddAccount());
  EXPECT_EQ(ERROR_NONE, manager_->RemoveAccount(kUser));
}

// ClearAccounts(CLEAR_ALL) clears all accounts.
TEST_F(AccountManagerTest, ClearAccountsSuccess) {
  ignore_result(manager_->AddAccount(kUser, kUnmanaged));
  ignore_result(manager_->AddAccount(kUser2, kManaged));

  EXPECT_EQ(ERROR_NONE, manager_->ClearAccounts(CLEAR_ALL, {}));
  std::vector<Account> accounts;
  EXPECT_EQ(ERROR_NONE, manager_->ListAccounts(&accounts));
  EXPECT_EQ(0u, accounts.size());
}

// ClearAccounts(CLEAR_ALL) wipes Kerberos configuration and credential cache.
TEST_F(AccountManagerTest, ClearAccountsRemovesKerberosFiles) {
  ignore_result(AddAccount());

  EXPECT_EQ(ERROR_NONE, SetConfig());
  EXPECT_EQ(ERROR_NONE, AcquireTgt());
  EXPECT_TRUE(base::PathExists(krb5conf_path_));
  EXPECT_TRUE(base::PathExists(krb5cc_path_));
  EXPECT_EQ(ERROR_NONE, manager_->ClearAccounts(CLEAR_ALL, {}));
  EXPECT_FALSE(base::PathExists(krb5conf_path_));
  EXPECT_FALSE(base::PathExists(krb5cc_path_));
}

// ClearAccounts(CLEAR_ALL) triggers KerberosFilesChanged if the credential
// cache exists.
TEST_F(AccountManagerTest, ClearAccountsTriggersKFCIfCCExists) {
  ignore_result(AddAccount());

  EXPECT_EQ(ERROR_NONE, AcquireTgt());
  EXPECT_EQ(1, kerberos_files_changed_count_[kUser]);
  EXPECT_EQ(ERROR_NONE, manager_->ClearAccounts(CLEAR_ALL, {}));
  EXPECT_EQ(2, kerberos_files_changed_count_[kUser]);
}

// ClearAccounts(CLEAR_ALL) does not trigger KerberosFilesChanged if the
// credential cache does not exist.
TEST_F(AccountManagerTest, ClearAccountsDoesNotTriggerKFCIfDoesNotCCExist) {
  ignore_result(AddAccount());

  EXPECT_EQ(ERROR_NONE, manager_->ClearAccounts(CLEAR_ALL, {}));
  EXPECT_EQ(0, kerberos_files_changed_count_[kUser]);
}

// ClearAccounts(CLEAR_ONLY_UNMANAGED_ACCOUNTS) clears only unmanaged accounts.
TEST_F(AccountManagerTest, ClearUnmanagedAccountsSuccess) {
  ignore_result(manager_->AddAccount(kUser, kUnmanaged));
  ignore_result(manager_->AddAccount(kUser2, kManaged));

  EXPECT_EQ(ERROR_NONE,
            manager_->ClearAccounts(CLEAR_ONLY_UNMANAGED_ACCOUNTS, {}));
  std::vector<Account> accounts;
  EXPECT_EQ(ERROR_NONE, manager_->ListAccounts(&accounts));
  ASSERT_EQ(1u, accounts.size());
  EXPECT_EQ(kUser2, accounts[0].principal_name());
}

// ClearAccounts(CLEAR_ONLY_UNMANAGED_REMEMBERED_PASSWORDS) clears only
// passwords of unmanaged accounts.
TEST_F(AccountManagerTest, ClearUnmanagedPasswordsSuccess) {
  // kUser is unmanaged, kUser2 is managed.
  ignore_result(manager_->AddAccount(kUser, kUnmanaged));
  ignore_result(manager_->AddAccount(kUser2, kManaged));
  ignore_result(manager_->AcquireTgt(kUser, kPassword, kRememberPassword,
                                     kDontUseLoginPassword));
  ignore_result(manager_->AcquireTgt(kUser2, kPassword, kRememberPassword,
                                     kDontUseLoginPassword));

  base::FilePath password_path_2 =
      storage_dir_.GetPath()
          .Append(AccountManager::GetSafeFilenameForTesting(kUser2))
          .Append("password");
  EXPECT_TRUE(base::PathExists(password_path_));
  EXPECT_TRUE(base::PathExists(password_path_2));

  EXPECT_EQ(ERROR_NONE, manager_->ClearAccounts(
                            CLEAR_ONLY_UNMANAGED_REMEMBERED_PASSWORDS, {}));
  std::vector<Account> accounts;
  EXPECT_EQ(ERROR_NONE, manager_->ListAccounts(&accounts));
  ASSERT_EQ(2u, accounts.size());
  EXPECT_FALSE(base::PathExists(password_path_));
  EXPECT_TRUE(base::PathExists(password_path_2));
}

// ClearAccounts(CLEAR_ONLY_MANAGED_ACCOUNTS) clears only managed accounts that
// are not on the keep list.
TEST_F(AccountManagerTest, ClearManagedPasswordsWithKeepListSuccess) {
  ignore_result(manager_->AddAccount(kUser, kManaged));
  ignore_result(manager_->AddAccount(kUser2, kManaged));
  ignore_result(manager_->AddAccount(kUser3, kUnmanaged));

  // Keep the managed kUser-account.
  EXPECT_EQ(ERROR_NONE,
            manager_->ClearAccounts(CLEAR_ONLY_MANAGED_ACCOUNTS, {kUser}));
  std::vector<Account> accounts;
  EXPECT_EQ(ERROR_NONE, manager_->ListAccounts(&accounts));
  ASSERT_EQ(2u, accounts.size());
  EXPECT_EQ(kUser, accounts[0].principal_name());
  EXPECT_EQ(kUser3, accounts[1].principal_name());
}

// SetConfig() succeeds and writes the config to |krb5conf_path_|.
TEST_F(AccountManagerTest, SetConfigSuccess) {
  ignore_result(AddAccount());

  EXPECT_EQ(ERROR_NONE, SetConfig());
  std::string krb5_conf;
  EXPECT_TRUE(base::ReadFileToString(krb5conf_path_, &krb5_conf));
  EXPECT_EQ(krb5_conf, kKrb5Conf);
}

// SetConfig() calls ValidateConfig on the Kerberos interface.
TEST_F(AccountManagerTest, SetConfigValidatesConfig) {
  ignore_result(AddAccount());

  krb5_->set_validate_config_error(ERROR_BAD_CONFIG);
  EXPECT_EQ(ERROR_BAD_CONFIG, SetConfig());
}

// SetConfig() triggers KerberosFilesChanged if the credential cache exists.
TEST_F(AccountManagerTest, SetConfigTriggersKFCIfCCExists) {
  ignore_result(AddAccount());

  EXPECT_EQ(ERROR_NONE, AcquireTgt());
  EXPECT_EQ(1, kerberos_files_changed_count_[kUser]);
  EXPECT_EQ(ERROR_NONE, SetConfig());
  EXPECT_EQ(2, kerberos_files_changed_count_[kUser]);
}

// SetConfig() does not trigger KerberosFilesChanged if the credential cache
// does not exist.
TEST_F(AccountManagerTest, SetConfigDoesNotTriggerKFCIfDoesNotCCExist) {
  ignore_result(AddAccount());

  EXPECT_EQ(ERROR_NONE, SetConfig());
  EXPECT_EQ(0, kerberos_files_changed_count_[kUser]);
}

// RemoveAccount() removes the config file.
TEST_F(AccountManagerTest, RemoveAccountRemovesConfig) {
  ignore_result(AddAccount());
  ignore_result(SetConfig());

  EXPECT_TRUE(base::PathExists(krb5conf_path_));
  EXPECT_EQ(ERROR_NONE, manager_->RemoveAccount(kUser));
  EXPECT_FALSE(base::PathExists(krb5conf_path_));
}

// ValidateConfig() validates a good config successfully.
TEST_F(AccountManagerTest, ValidateConfigSuccess) {
  constexpr char kValidKrb5Conf[] = "";
  ConfigErrorInfo error_info;
  EXPECT_EQ(ERROR_NONE, manager_->ValidateConfig(kValidKrb5Conf, &error_info));
  EXPECT_EQ(CONFIG_ERROR_NONE, error_info.code());
}

// ValidateConfig() returns the correct error for a bad config.
TEST_F(AccountManagerTest, ValidateConfigFailure) {
  ConfigErrorInfo expected_error_info;
  expected_error_info.set_code(CONFIG_ERROR_SECTION_SYNTAX);
  krb5_->set_config_error_info(expected_error_info);
  krb5_->set_validate_config_error(ERROR_BAD_CONFIG);

  constexpr char kBadKrb5Conf[] =
      "[libdefaults]'); DROP TABLE KerberosTickets;--";
  ConfigErrorInfo error_info;
  EXPECT_EQ(ERROR_BAD_CONFIG,
            manager_->ValidateConfig(kBadKrb5Conf, &error_info));
  EXPECT_EQ(expected_error_info.SerializeAsString(),
            error_info.SerializeAsString());
}

// AcquireTgt() succeeds and writes a credential cache file.
TEST_F(AccountManagerTest, AcquireTgtSuccess) {
  ignore_result(AddAccount());

  EXPECT_EQ(ERROR_NONE, AcquireTgt());
  EXPECT_TRUE(base::PathExists(krb5cc_path_));
}

// AcquireTgt() triggers KerberosFilesChanged on success.
TEST_F(AccountManagerTest, AcquireTgtTriggersKFCOnSuccess) {
  ignore_result(AddAccount());

  EXPECT_EQ(0, kerberos_files_changed_count_[kUser]);
  EXPECT_EQ(ERROR_NONE, AcquireTgt());
  EXPECT_EQ(1, kerberos_files_changed_count_[kUser]);
}

// AcquireTgt() does not trigger KerberosFilesChanged on failure.
TEST_F(AccountManagerTest, AcquireTgtDoesNotTriggerKFCOnFailure) {
  ignore_result(AddAccount());

  krb5_->set_acquire_tgt_error(ERROR_UNKNOWN);
  EXPECT_EQ(ERROR_UNKNOWN, AcquireTgt());
  EXPECT_EQ(0, kerberos_files_changed_count_[kUser]);
}

// AcquireTgt() saves password to disk if |remember_password| is true and
// removes the file again if |remember_password| is false.
TEST_F(AccountManagerTest, AcquireTgtRemembersPasswordsIfWanted) {
  ignore_result(AddAccount());

  EXPECT_FALSE(base::PathExists(password_path_));
  EXPECT_EQ(ERROR_NONE,
            manager_->AcquireTgt(kUser, kPassword, kRememberPassword,
                                 kDontUseLoginPassword));
  EXPECT_TRUE(base::PathExists(password_path_));

  EXPECT_EQ(ERROR_NONE,
            manager_->AcquireTgt(kUser, kPassword, kDontRememberPassword,
                                 kDontUseLoginPassword));
  EXPECT_FALSE(base::PathExists(password_path_));
}

// AcquireTgt() uses saved password if none is given, no matter if it should be
// remembered again or not.
TEST_F(AccountManagerTest, AcquireTgtLoadsRememberedPassword) {
  ignore_result(AddAccount());
  ignore_result(manager_->AcquireTgt(kUser, kPassword, kRememberPassword,
                                     kDontUseLoginPassword));

  // This should load stored password and keep it.
  EXPECT_EQ(ERROR_NONE,
            manager_->AcquireTgt(kUser, kEmptyPassword, kRememberPassword,
                                 kDontUseLoginPassword));
  EXPECT_TRUE(base::PathExists(password_path_));

  // This should load stored password, but erase it afterwards.
  EXPECT_EQ(ERROR_NONE,
            manager_->AcquireTgt(kUser, kEmptyPassword, kDontRememberPassword,
                                 kDontUseLoginPassword));
  EXPECT_FALSE(base::PathExists(password_path_));

  // Check that the fake krb5 interface returns an error for a missing password.
  // This verifies that the above AcquireTgt() call actually loaded the
  // password from disk.
  EXPECT_EQ(ERROR_BAD_PASSWORD,
            manager_->AcquireTgt(kUser, kEmptyPassword, kDontRememberPassword,
                                 kDontUseLoginPassword));
}

// AcquireTgt() uses the login password if saved.
TEST_F(AccountManagerTest, AcquireTgtUsesLoginPassword) {
  ignore_result(AddAccount());

  // Shouldn't explode if the login password not set yet.
  EXPECT_EQ(ERROR_BAD_PASSWORD,
            manager_->AcquireTgt(kUser, kEmptyPassword, kDontRememberPassword,
                                 kUseLoginPassword));

  SaveLoginPassword(kPassword);
  krb5_->set_expected_password(kPassword);

  // Uses the login password.
  EXPECT_EQ(ERROR_NONE,
            manager_->AcquireTgt(kUser, kEmptyPassword, kDontRememberPassword,
                                 kUseLoginPassword));

  // Check if auth fails without kUseLoginPassword.
  EXPECT_EQ(ERROR_BAD_PASSWORD,
            manager_->AcquireTgt(kUser, kEmptyPassword, kDontRememberPassword,
                                 kDontUseLoginPassword));
}

// AcquireTgt() wipes a saved password if the login password is used.
TEST_F(AccountManagerTest, AcquireTgtWipesStoredPasswordOnUsesLoginPassword) {
  ignore_result(AddAccount());
  ignore_result(manager_->AcquireTgt(kUser, kPassword, kRememberPassword,
                                     kDontUseLoginPassword));
  EXPECT_TRUE(base::PathExists(password_path_));

  SaveLoginPassword(kPassword);

  // Note: kRememberPassword gets ignored if kUseLoginPassword is passed.
  EXPECT_EQ(ERROR_NONE,
            manager_->AcquireTgt(kUser, kEmptyPassword, kRememberPassword,
                                 kUseLoginPassword));
  EXPECT_FALSE(base::PathExists(password_path_));
}

// AcquireTgt() ignores the passed password if the login password is used.
TEST_F(AccountManagerTest, AcquireTgtIgnoresPassedPasswordOnUsesLoginPassword) {
  ignore_result(AddAccount());

  SaveLoginPassword(kPassword);
  krb5_->set_expected_password(kPassword);

  // Auth works despite passed kPassword2 != expected kPassword because the
  // login kPassword is used.
  EXPECT_EQ(ERROR_NONE,
            manager_->AcquireTgt(kUser, kPassword2, kDontRememberPassword,
                                 kUseLoginPassword));
}

// RemoveAccount() removes the credential cache file.
TEST_F(AccountManagerTest, RemoveAccountRemovesCC) {
  ignore_result(AddAccount());
  ignore_result(AcquireTgt());

  EXPECT_TRUE(base::PathExists(krb5cc_path_));
  EXPECT_EQ(ERROR_NONE, manager_->RemoveAccount(kUser));
  EXPECT_FALSE(base::PathExists(krb5cc_path_));
}

// RemoveAccount() removes saved passwords.
TEST_F(AccountManagerTest, RemoveAccountRemovesPassword) {
  ignore_result(AddAccount());
  ignore_result(manager_->AcquireTgt(kUser, kPassword, kRememberPassword,
                                     kDontUseLoginPassword));

  EXPECT_TRUE(base::PathExists(password_path_));
  EXPECT_EQ(ERROR_NONE, manager_->RemoveAccount(kUser));
  EXPECT_FALSE(base::PathExists(password_path_));
}

// ListAccounts() succeeds and contains the expected data.
TEST_F(AccountManagerTest, ListAccountsSuccess) {
  ignore_result(manager_->AddAccount(kUser, kManaged));
  ignore_result(SetConfig());
  ignore_result(manager_->AcquireTgt(kUser, kPassword, kRememberPassword,
                                     kDontUseLoginPassword));
  SaveLoginPassword(kPassword);
  ignore_result(manager_->AddAccount(kUser2, kUnmanaged));
  // Note: kRememberPassword should be ignored here, see below.
  ignore_result(manager_->AcquireTgt(kUser2, kPassword, kRememberPassword,
                                     kUseLoginPassword));
  EXPECT_TRUE(base::PathExists(krb5cc_path_));

  // Set a fake tgt status.
  constexpr int kRenewalSeconds = 10;
  constexpr int kValiditySeconds = 90;
  krb5_->set_tgt_status(
      Krb5Interface::TgtStatus(kValiditySeconds, kRenewalSeconds));

  // Verify that ListAccounts returns the expected account.
  std::vector<Account> accounts;
  EXPECT_EQ(ERROR_NONE, manager_->ListAccounts(&accounts));
  ASSERT_EQ(2u, accounts.size());

  EXPECT_EQ(kUser, accounts[0].principal_name());
  EXPECT_EQ(kKrb5Conf, accounts[0].krb5conf());
  EXPECT_EQ(kRenewalSeconds, accounts[0].tgt_renewal_seconds());
  EXPECT_EQ(kValiditySeconds, accounts[0].tgt_validity_seconds());
  EXPECT_TRUE(accounts[0].is_managed());
  EXPECT_TRUE(accounts[0].password_was_remembered());

  EXPECT_EQ(kUser2, accounts[1].principal_name());
  EXPECT_FALSE(accounts[1].password_was_remembered());
  EXPECT_TRUE(accounts[1].use_login_password());
}

// ListAccounts() ignores failures in GetTgtStatus() and loading the config.
TEST_F(AccountManagerTest, ListAccountsIgnoresFailures) {
  ignore_result(AddAccount());
  ignore_result(SetConfig());
  ignore_result(AcquireTgt());
  EXPECT_TRUE(base::PathExists(krb5cc_path_));

  // Make reading the config fail.
  EXPECT_TRUE(base::SetPosixFilePermissions(krb5conf_path_, 0));

  // Make GetTgtStatus() fail.
  krb5_->set_get_tgt_status_error(ERROR_UNKNOWN);

  // ListAccounts() should still work, despite the errors.
  std::vector<Account> accounts;
  EXPECT_EQ(ERROR_NONE, manager_->ListAccounts(&accounts));
  ASSERT_EQ(1u, accounts.size());
  EXPECT_EQ(kUser, accounts[0].principal_name());

  // The config should not be set since we made reading the file fail.
  EXPECT_FALSE(accounts[0].has_krb5conf());

  // tgt_*_seconds should not be set since we made GetTgtStatus() fail.
  EXPECT_FALSE(accounts[0].has_tgt_renewal_seconds());
  EXPECT_FALSE(accounts[0].has_tgt_validity_seconds());
}

// GetKerberosFiles returns empty KerberosFiles if there is no credential cache,
// even if there is a config.
TEST_F(AccountManagerTest, GetKerberosFilesSucceesWithoutCC) {
  ignore_result(AddAccount());
  ignore_result(SetConfig());

  KerberosFiles files;
  EXPECT_EQ(ERROR_NONE, manager_->GetKerberosFiles(kUser, &files));
  EXPECT_FALSE(files.has_krb5cc());
  EXPECT_FALSE(files.has_krb5conf());
}

// GetKerberosFiles returns the expected KerberosFiles if there is a credential
// cache.
TEST_F(AccountManagerTest, GetKerberosFilesSucceesWithCC) {
  ignore_result(AddAccount());
  ignore_result(SetConfig());
  ignore_result(AcquireTgt());

  KerberosFiles files;
  EXPECT_EQ(ERROR_NONE, manager_->GetKerberosFiles(kUser, &files));
  EXPECT_FALSE(files.krb5cc().empty());
  EXPECT_EQ(kKrb5Conf, files.krb5conf());
}

// Most methods return ERROR_UNKNOWN_PRINCIPAL if called with such a principal.
TEST_F(AccountManagerTest, MethodsReturnUnknownPrincipal) {
  KerberosFiles files;
  EXPECT_EQ(ERROR_UNKNOWN_PRINCIPAL_NAME, manager_->RemoveAccount(kUser));
  EXPECT_EQ(ERROR_UNKNOWN_PRINCIPAL_NAME, SetConfig());
  EXPECT_EQ(ERROR_UNKNOWN_PRINCIPAL_NAME, AcquireTgt());
  EXPECT_EQ(ERROR_UNKNOWN_PRINCIPAL_NAME,
            manager_->GetKerberosFiles(kUser, &files));
}

// Accounts can be saved to disk and loaded from disk.
TEST_F(AccountManagerTest, SerializationSuccess) {
  ignore_result(manager_->AddAccount(kUser, kManaged));
  ignore_result(manager_->AcquireTgt(kUser, kPassword, kDontRememberPassword,
                                     kUseLoginPassword));

  ignore_result(manager_->AddAccount(kUser2, kUnmanaged));
  ignore_result(manager_->AcquireTgt(kUser2, kPassword, kDontRememberPassword,
                                     kDontUseLoginPassword));

  EXPECT_EQ(ERROR_NONE, manager_->SaveAccounts());
  AccountManager other_manager(
      storage_dir_.GetPath(), kerberos_files_changed_,
      kerberos_ticket_expiring_, std::make_unique<FakeKrb5Interface>(),
      std::make_unique<password_provider::FakePasswordProvider>(),
      metrics_.get());
  other_manager.LoadAccounts();
  std::vector<Account> accounts;
  EXPECT_EQ(ERROR_NONE, other_manager.ListAccounts(&accounts));
  ASSERT_EQ(2u, accounts.size());

  EXPECT_EQ(kUser, accounts[0].principal_name());
  EXPECT_EQ(kUser2, accounts[1].principal_name());

  EXPECT_TRUE(accounts[0].is_managed());
  EXPECT_FALSE(accounts[1].is_managed());

  EXPECT_TRUE(accounts[0].use_login_password());
  EXPECT_FALSE(accounts[1].use_login_password());

  // TODO(https://crbug.com/952239): Check additional Account properties.
}

// The StartObservingTickets() method triggers KerberosTicketExpiring for
// expired signals and starts observing valid tickets.
TEST_F(AccountManagerTest, StartObservingTickets) {
  krb5_->set_tgt_status(kValidTgt);
  ignore_result(AddAccount());
  ignore_result(SetConfig());
  ignore_result(AcquireTgt());
  EXPECT_EQ(0, kerberos_ticket_expiring_count_[kUser]);
  task_runner_->ClearPendingTasks();

  // Fake an expired ticket. Check that KerberosTicketExpiring is triggered, but
  // no renewal task is scheduled.
  krb5_->set_tgt_status(kExpiredTgt);
  manager_->StartObservingTickets();
  EXPECT_EQ(1, kerberos_ticket_expiring_count_[kUser]);
  EXPECT_EQ(0, task_runner_->GetPendingTaskCount());

  // Fake a valid ticket. Check that KerberosTicketExpiring is NOT triggered,
  // but a renewal task is scheduled.
  krb5_->set_tgt_status(kValidTgt);
  EXPECT_EQ(0, task_runner_->GetPendingTaskCount());
  manager_->StartObservingTickets();
  EXPECT_EQ(1, task_runner_->GetPendingTaskCount());
  EXPECT_EQ(1, kerberos_ticket_expiring_count_[kUser]);
  EXPECT_EQ(0, krb5_->renew_tgt_call_count());
  task_runner_->FastForwardBy(task_runner_->NextPendingTaskDelay());
  EXPECT_EQ(1, krb5_->renew_tgt_call_count());
}

// When a TGT is acquired successfully, automatic renewal is scheduled.
TEST_F(AccountManagerTest, AcquireTgtSchedulesRenewalOnSuccess) {
  ignore_result(AddAccount());

  krb5_->set_tgt_status(kValidTgt);
  EXPECT_EQ(0, task_runner_->GetPendingTaskCount());
  EXPECT_EQ(ERROR_NONE, AcquireTgt());
  EXPECT_EQ(1, task_runner_->GetPendingTaskCount());
}

// When a TGT fails to be acquired, no automatic renewal is scheduled.
TEST_F(AccountManagerTest, AcquireTgtDoesNotScheduleRenewalOnFailure) {
  ignore_result(AddAccount());

  krb5_->set_tgt_status(kValidTgt);
  krb5_->set_acquire_tgt_error(ERROR_UNKNOWN);
  EXPECT_EQ(0, task_runner_->GetPendingTaskCount());
  EXPECT_EQ(ERROR_UNKNOWN, AcquireTgt());
  EXPECT_EQ(0, task_runner_->GetPendingTaskCount());
}

// A scheduled TGT renewal task calls |krb5_->RenewTgt()|.
TEST_F(AccountManagerTest, AutoRenewalCallsRenewTgt) {
  krb5_->set_tgt_status(kValidTgt);
  ignore_result(AddAccount());
  ignore_result(AcquireTgt());
  int initial_acquire_tgt_call_count = krb5_->acquire_tgt_call_count();

  // Set some return value for the RenewTgt() call and fast forward to scheduled
  // renewal task.
  const ErrorType expected_error = ERROR_UNKNOWN;
  krb5_->set_renew_tgt_error(expected_error);
  RunScheduledRenewalTask();

  EXPECT_EQ(initial_acquire_tgt_call_count, krb5_->acquire_tgt_call_count());
  EXPECT_EQ(expected_error, manager_->last_renew_tgt_error_for_testing());
}

// A scheduled TGT renewal task calls |krb5_->AcquireTgt()| using the login
// password if the call to |krb5_->RenewTgt()| fails and the login password was
// used for the initial AcquireTgt() call.
TEST_F(AccountManagerTest, AutoRenewalUsesLoginPasswordIfRenewalFails) {
  krb5_->set_tgt_status(kValidTgt);
  ignore_result(AddAccount());

  // Acquire TGT with login password.
  SaveLoginPassword(kPassword);
  krb5_->set_expected_password(kPassword);
  EXPECT_EQ(ERROR_NONE,
            manager_->AcquireTgt(kUser, std::string(), kDontRememberPassword,
                                 kUseLoginPassword));
  int initial_acquire_tgt_call_count = krb5_->acquire_tgt_call_count();

  krb5_->set_renew_tgt_error(ERROR_UNKNOWN);
  RunScheduledRenewalTask();

  // The scheduled renewal task should have called AcquireTgt() with the login
  // password and succeeded.
  EXPECT_EQ(initial_acquire_tgt_call_count + 1,
            krb5_->acquire_tgt_call_count());
  EXPECT_EQ(ERROR_NONE, manager_->last_renew_tgt_error_for_testing());
}

// A scheduled TGT renewal task calls |krb5_->AcquireTgt()| using the remembered
// password if the call to |krb5_->RenewTgt()| fails and the password was
// remembered for the initial AcquireTgt() call.
TEST_F(AccountManagerTest, AutoRenewalUsesRememberedPasswordIfRenewalFails) {
  krb5_->set_tgt_status(kValidTgt);
  ignore_result(AddAccount());

  // Acquire TGT and remember password.
  krb5_->set_expected_password(kPassword);
  EXPECT_EQ(ERROR_NONE,
            manager_->AcquireTgt(kUser, kPassword, kRememberPassword,
                                 kDontUseLoginPassword));
  int initial_acquire_tgt_call_count = krb5_->acquire_tgt_call_count();

  krb5_->set_renew_tgt_error(ERROR_UNKNOWN);
  RunScheduledRenewalTask();

  // The scheduled renewal task should have called AcquireTgt() with the
  // remembered password and succeeded.
  EXPECT_EQ(initial_acquire_tgt_call_count + 1,
            krb5_->acquire_tgt_call_count());
  EXPECT_EQ(ERROR_NONE, manager_->last_renew_tgt_error_for_testing());
}

// A scheduled TGT renewal task does not call |krb5_->AcquireTgt()| using the
// remembered password if the call to |krb5_->RenewTgt()| succeeds and the
// password was remembered for the initial AcquireTgt() call (similar for login
// password, but we don't test that).
TEST_F(AccountManagerTest, AutoRenewalDoesNotCallAcquireTgtIfRenewalSucceeds) {
  krb5_->set_tgt_status(kValidTgt);
  ignore_result(AddAccount());

  // Acquire TGT and remember password.
  krb5_->set_expected_password(kPassword);
  EXPECT_EQ(ERROR_NONE,
            manager_->AcquireTgt(kUser, kPassword, kRememberPassword,
                                 kDontUseLoginPassword));
  int initial_acquire_tgt_call_count = krb5_->acquire_tgt_call_count();

  krb5_->set_renew_tgt_error(ERROR_NONE);
  RunScheduledRenewalTask();

  // The scheduled renewal task should NOT have called AcquireTgt() again since
  // |krb5_->RenewTgt()|.
  EXPECT_EQ(initial_acquire_tgt_call_count, krb5_->acquire_tgt_call_count());
  EXPECT_EQ(ERROR_NONE, manager_->last_renew_tgt_error_for_testing());
}

// Verifies that all files written have the expected access permissions.
// Unfortunately, file ownership can't be tested as the test won't run as
// kerberosd user nor can it switch to it.
TEST_F(AccountManagerTest, FilePermissions) {
  constexpr int kFileMode_rw =
      base::FILE_PERMISSION_READ_BY_USER | base::FILE_PERMISSION_WRITE_BY_USER;
  constexpr int kFileMode_rw_r =
      kFileMode_rw | base::FILE_PERMISSION_READ_BY_GROUP;
  constexpr int kFileMode_rw_r__r =
      kFileMode_rw_r | base::FILE_PERMISSION_READ_BY_OTHERS;
  constexpr int kFileMode_rwxrwx =
      base::FILE_PERMISSION_USER_MASK | base::FILE_PERMISSION_GROUP_MASK;

  // Wrap the fake krb5 in a jail wrapper to get the file permissions of krb5cc
  // right. Note that we can't use a Krb5JailWrapper for the whole test since
  // that would break the counters in FakeKrb5Interface (they would be inc'ed in
  // another process!).
  manager_->WrapKrb5ForTesting();

  // Can't set user in this test.
  Krb5JailWrapper::DisableChangeUserForTesting(true);

  EXPECT_EQ(ERROR_NONE, AddAccount());
  EXPECT_EQ(ERROR_NONE, SetConfig());
  EXPECT_EQ(ERROR_NONE,
            manager_->AcquireTgt(kUser, kPassword, kRememberPassword,
                                 kDontUseLoginPassword));

  int mode;

  EXPECT_TRUE(GetPosixFilePermissions(accounts_path_, &mode));
  EXPECT_EQ(kFileMode_rw, mode);

  EXPECT_TRUE(GetPosixFilePermissions(account_dir_, &mode));
  EXPECT_EQ(kFileMode_rwxrwx, mode);

  EXPECT_TRUE(GetPosixFilePermissions(krb5cc_path_, &mode));
  EXPECT_EQ(kFileMode_rw_r, mode);

  EXPECT_TRUE(GetPosixFilePermissions(krb5conf_path_, &mode));
  EXPECT_EQ(kFileMode_rw_r__r, mode);

  EXPECT_TRUE(GetPosixFilePermissions(password_path_, &mode));
  EXPECT_EQ(kFileMode_rw, mode);
}

// Tests that [Should]ReportDailyUsageStats is called as advertised.
TEST_F(AccountManagerTest, ReportDailyUsageStats) {
  // ShouldReportDailyUsageStats() should be called by GetKerberosFiles() even
  // if there is no account, and if that returns true, ReportDailyUsageStats()
  // should be called as well.
  EXPECT_CALL(*metrics_, ShouldReportDailyUsageStats()).WillOnce(Return(true));
  EXPECT_CALL(*metrics_, ReportDailyUsageStats(0, 0, 0, 0, 0));
  KerberosFiles files;
  EXPECT_EQ(ERROR_UNKNOWN_PRINCIPAL_NAME,
            manager_->GetKerberosFiles(kUser, &files));
  Mock::VerifyAndClearExpectations(metrics_.get());

  AddAccount();

  // ShouldReportDailyUsageStats() should be called by AcquireTgt(), but if that
  // returns false, ReportDailyUsageStats() should NOT be called.
  EXPECT_CALL(*metrics_, ShouldReportDailyUsageStats()).WillOnce(Return(false));
  EXPECT_CALL(*metrics_, ReportDailyUsageStats(_, _, _, _, _)).Times(0);
  AcquireTgt();
  Mock::VerifyAndClearExpectations(metrics_.get());

  // ShouldReportDailyUsageStats() should be called by AcquireTgt(), and if that
  // returns true, ReportDailyUsageStats() should be called as well.
  EXPECT_CALL(*metrics_, ShouldReportDailyUsageStats()).WillOnce(Return(true));
  EXPECT_CALL(*metrics_, ReportDailyUsageStats(_, _, _, _, _));
  AcquireTgt();
  Mock::VerifyAndClearExpectations(metrics_.get());
}

TEST_F(AccountManagerTest, AccountStats) {
  SaveLoginPassword(kPassword);

  EXPECT_EQ(ERROR_NONE, manager_->AddAccount(kUser, kManaged));
  EXPECT_EQ(ERROR_NONE, manager_->AddAccount(kUser2, kManaged));
  EXPECT_EQ(ERROR_NONE, manager_->AddAccount(kUser3, kUnmanaged));

  // Set metrics up so that the stats are reported on the last call.
  EXPECT_CALL(*metrics_, ShouldReportDailyUsageStats())
      .WillOnce(Return(false))
      .WillOnce(Return(false))
      .WillOnce(Return(true));

  // 3 accounts total, 2 managed, 1 unmanaged, 1 remembering the password, 1
  // using the login password.
  EXPECT_CALL(*metrics_, ReportDailyUsageStats(3, 2, 1, 1, 1));

  EXPECT_EQ(ERROR_NONE,
            manager_->AcquireTgt(kUser, kPassword, kDontRememberPassword,
                                 kDontUseLoginPassword));
  EXPECT_EQ(ERROR_NONE,
            manager_->AcquireTgt(kUser2, kPassword, kRememberPassword,
                                 kDontUseLoginPassword));
  EXPECT_EQ(ERROR_NONE,
            manager_->AcquireTgt(kUser3, kEmptyPassword, kDontRememberPassword,
                                 kUseLoginPassword));
}

}  // namespace kerberos
