// Copyright 2020 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 "cryptohome/fingerprint_manager.h"

#include <utility>
#include <vector>

#include <base/test/bind_test_util.h>
#include <chromeos/dbus/service_constants.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>

#include "biod/biod_proxy/mock_biometrics_manager_proxy_base.h"

namespace cryptohome {

// Peer class for testing FingerprintManager.
class FingerprintManagerPeer {
 public:
  explicit FingerprintManagerPeer(FingerprintManager* fingerprint_manager) {
    fingerprint_manager_ = fingerprint_manager;
  }

  // FingerprintManager won't allow any operation unless
  // |connected_to_auth_scan_done_signal_| is true, so set that for testing.
  void SetConnectedToAuthScanDoneSignal(bool success) {
    fingerprint_manager_->connected_to_auth_scan_done_signal_ = success;
  }

  void SignalAuthScanDone(dbus::Signal* signal) {
    fingerprint_manager_->OnAuthScanDone(signal);
  }

  bool NoAuthSession() {
    return fingerprint_manager_->state_ ==
           FingerprintManager::State::NO_AUTH_SESSION;
  }

  bool AuthSessionIsOpen() {
    return fingerprint_manager_->state_ ==
           FingerprintManager::State::AUTH_SESSION_OPEN;
  }

  bool AuthSessionIsLocked() {
    return fingerprint_manager_->state_ ==
           FingerprintManager::State::AUTH_SESSION_LOCKED;
  }

 private:
  FingerprintManager* fingerprint_manager_;
};

namespace {
using testing::_;
using testing::NiceMock;
using testing::Return;

constexpr char kUser[] = "user";

class FingerprintManagerTest : public testing::Test {
 public:
  FingerprintManagerTest() {
    fingerprint_manager_ = std::make_unique<FingerprintManager>();
    fingerprint_manager_->SetProxy(&mock_biod_proxy_);

    fingerprint_manager_peer_ =
        std::make_unique<FingerprintManagerPeer>(fingerprint_manager_.get());
    // Mark |connected_to_auth_scan_done_signal_| to true to allow operations.
    fingerprint_manager_peer_->SetConnectedToAuthScanDoneSignal(true);
  }

  void AddMatchToScanResult(dbus::MessageWriter* matches_writer,
                            const std::string& user) {
    dbus::MessageWriter entry_writer(nullptr);
    matches_writer->OpenDictEntry(&entry_writer);
    entry_writer.AppendString(user);
    // A dumb fingerprint record path is sufficient.
    entry_writer.AppendArrayOfObjectPaths(std::vector<dbus::ObjectPath>());
    matches_writer->CloseContainer(&entry_writer);
  }

  std::unique_ptr<FingerprintManager> fingerprint_manager_;
  std::unique_ptr<FingerprintManagerPeer> fingerprint_manager_peer_;
  NiceMock<biod::MockBiometricsManagerProxyBase> mock_biod_proxy_;
  bool status_;
  FingerprintScanStatus scan_status_;
};

TEST_F(FingerprintManagerTest, StartAuthSessionFail) {
  EXPECT_CALL(mock_biod_proxy_, StartAuthSessionAsync(_))
      .WillOnce([](base::Callback<void(bool success)> callback) {
        std::move(callback).Run(false);
      });
  status_ = true;
  fingerprint_manager_->StartAuthSessionAsyncForUser(
      kUser,
      base::BindLambdaForTesting([this](bool success) { status_ = success; }));
  EXPECT_FALSE(status_);
  EXPECT_TRUE(fingerprint_manager_->GetCurrentUser().empty());
  EXPECT_TRUE(fingerprint_manager_peer_->NoAuthSession());
}

TEST_F(FingerprintManagerTest, StartAuthSessionSuccess) {
  EXPECT_CALL(mock_biod_proxy_, StartAuthSessionAsync(_))
      .WillOnce([](base::Callback<void(bool success)> callback) {
        std::move(callback).Run(true);
      });
  status_ = false;
  fingerprint_manager_->StartAuthSessionAsyncForUser(
      kUser,
      base::BindLambdaForTesting([this](bool success) { status_ = success; }));
  EXPECT_TRUE(status_);
  EXPECT_EQ(fingerprint_manager_->GetCurrentUser(), kUser);
  EXPECT_TRUE(fingerprint_manager_peer_->AuthSessionIsOpen());

  // Test that we can close the auth session.
  EXPECT_CALL(mock_biod_proxy_, EndAuthSession());
  fingerprint_manager_->EndAuthSession();
  EXPECT_TRUE(fingerprint_manager_peer_->NoAuthSession());
}

TEST_F(FingerprintManagerTest, StartAuthSessionTwice) {
  // First auth session still exists.
  EXPECT_CALL(mock_biod_proxy_, StartAuthSessionAsync(_))
      .WillOnce([](base::Callback<void(bool success)> callback) {
        std::move(callback).Run(true);
      });
  status_ = false;
  fingerprint_manager_->StartAuthSessionAsyncForUser(
      kUser,
      base::BindLambdaForTesting([this](bool success) { status_ = success; }));
  EXPECT_TRUE(status_);
  EXPECT_EQ(fingerprint_manager_->GetCurrentUser(), kUser);

  // Second time should fail.
  status_ = true;
  fingerprint_manager_->StartAuthSessionAsyncForUser(
      kUser,
      base::BindLambdaForTesting([this](bool success) { status_ = success; }));
  EXPECT_FALSE(status_);
  // The existing session is unaffected.
  EXPECT_TRUE(fingerprint_manager_peer_->AuthSessionIsOpen());
}

TEST_F(FingerprintManagerTest, AuthScanDoneNoScanResult) {
  EXPECT_CALL(mock_biod_proxy_, StartAuthSessionAsync(_))
      .WillOnce([](base::Callback<void(bool success)> callback) {
        std::move(callback).Run(true);
      });
  fingerprint_manager_->StartAuthSessionAsyncForUser(
      kUser,
      base::BindLambdaForTesting([this](bool success) { status_ = success; }));
  EXPECT_TRUE(fingerprint_manager_peer_->AuthSessionIsOpen());

  // This signal does not include a ScanResult, so it's invalid.
  dbus::Signal signal(biod::kBiometricsManagerInterface,
                      biod::kBiometricsManagerAuthScanDoneSignal);

  fingerprint_manager_->SetAuthScanDoneCallback(base::BindLambdaForTesting(
      [this](FingerprintScanStatus status) { scan_status_ = status; }));
  scan_status_ = FingerprintScanStatus::SUCCESS;
  fingerprint_manager_peer_->SignalAuthScanDone(&signal);
  EXPECT_EQ(scan_status_, FingerprintScanStatus::FAILED_RETRY_NOT_ALLOWED);
  // Unrecoverable error should lock the auth session.
  EXPECT_TRUE(fingerprint_manager_peer_->AuthSessionIsLocked());
}

TEST_F(FingerprintManagerTest, AuthScanDoneScanResultFailed) {
  EXPECT_CALL(mock_biod_proxy_, StartAuthSessionAsync(_))
      .WillOnce([](base::Callback<void(bool success)> callback) {
        std::move(callback).Run(true);
      });
  fingerprint_manager_->StartAuthSessionAsyncForUser(
      kUser,
      base::BindLambdaForTesting([this](bool success) { status_ = success; }));
  EXPECT_TRUE(fingerprint_manager_peer_->AuthSessionIsOpen());

  dbus::Signal signal(biod::kBiometricsManagerInterface,
                      biod::kBiometricsManagerAuthScanDoneSignal);
  dbus::MessageWriter writer(&signal);
  writer.AppendUint32(
      static_cast<uint32_t>(biod::ScanResult::SCAN_RESULT_PARTIAL));

  fingerprint_manager_->SetAuthScanDoneCallback(base::BindLambdaForTesting(
      [this](FingerprintScanStatus status) { scan_status_ = status; }));
  scan_status_ = FingerprintScanStatus::SUCCESS;
  fingerprint_manager_peer_->SignalAuthScanDone(&signal);
  EXPECT_EQ(scan_status_, FingerprintScanStatus::FAILED_RETRY_ALLOWED);
  // Auth session should still be open since retry is allowed.
  EXPECT_TRUE(fingerprint_manager_peer_->AuthSessionIsOpen());
}

TEST_F(FingerprintManagerTest, AuthScanDoneNoMatch) {
  EXPECT_CALL(mock_biod_proxy_, StartAuthSessionAsync(_))
      .WillOnce([](base::Callback<void(bool success)> callback) {
        std::move(callback).Run(true);
      });
  fingerprint_manager_->StartAuthSessionAsyncForUser(
      kUser,
      base::BindLambdaForTesting([this](bool success) { status_ = success; }));
  EXPECT_TRUE(fingerprint_manager_peer_->AuthSessionIsOpen());

  dbus::Signal signal(biod::kBiometricsManagerInterface,
                      biod::kBiometricsManagerAuthScanDoneSignal);
  dbus::MessageWriter writer(&signal);
  writer.AppendUint32(
      static_cast<uint32_t>(biod::ScanResult::SCAN_RESULT_SUCCESS));
  dbus::MessageWriter matches_writer(nullptr);
  writer.OpenArray("{sao}", &matches_writer);
  // No matches.
  writer.CloseContainer(&matches_writer);

  fingerprint_manager_->SetAuthScanDoneCallback(base::BindLambdaForTesting(
      [this](FingerprintScanStatus status) { scan_status_ = status; }));
  scan_status_ = FingerprintScanStatus::SUCCESS;
  fingerprint_manager_peer_->SignalAuthScanDone(&signal);
  EXPECT_EQ(scan_status_, FingerprintScanStatus::FAILED_RETRY_ALLOWED);
  // Auth session should still be open since retry is allowed.
  EXPECT_TRUE(fingerprint_manager_peer_->AuthSessionIsOpen());
}

TEST_F(FingerprintManagerTest, AuthScanDoneSuccess) {
  EXPECT_CALL(mock_biod_proxy_, StartAuthSessionAsync(_))
      .WillOnce([](base::Callback<void(bool success)> callback) {
        std::move(callback).Run(true);
      });
  fingerprint_manager_->StartAuthSessionAsyncForUser(
      kUser,
      base::BindLambdaForTesting([this](bool success) { status_ = success; }));
  EXPECT_TRUE(fingerprint_manager_peer_->AuthSessionIsOpen());

  dbus::Signal signal(biod::kBiometricsManagerInterface,
                      biod::kBiometricsManagerAuthScanDoneSignal);
  dbus::MessageWriter writer(&signal);
  writer.AppendUint32(
      static_cast<uint32_t>(biod::ScanResult::SCAN_RESULT_SUCCESS));
  dbus::MessageWriter matches_writer(nullptr);
  writer.OpenArray("{sao}", &matches_writer);
  AddMatchToScanResult(&matches_writer, kUser);
  writer.CloseContainer(&matches_writer);

  fingerprint_manager_->SetAuthScanDoneCallback(base::BindLambdaForTesting(
      [this](FingerprintScanStatus status) { scan_status_ = status; }));
  scan_status_ = FingerprintScanStatus::FAILED_RETRY_NOT_ALLOWED;
  fingerprint_manager_peer_->SignalAuthScanDone(&signal);
  EXPECT_EQ(scan_status_, FingerprintScanStatus::SUCCESS);
  // A successful scan should cause further scans in the same session to be
  // ignored.
  EXPECT_TRUE(fingerprint_manager_peer_->AuthSessionIsLocked());
}

TEST_F(FingerprintManagerTest, AuthScanDoneTooManyRetries) {
  EXPECT_CALL(mock_biod_proxy_, StartAuthSessionAsync(_))
      .WillOnce([](base::Callback<void(bool success)> callback) {
        std::move(callback).Run(true);
      });
  fingerprint_manager_->StartAuthSessionAsyncForUser(
      kUser,
      base::BindLambdaForTesting([this](bool success) { status_ = success; }));
  EXPECT_TRUE(fingerprint_manager_peer_->AuthSessionIsOpen());

  dbus::Signal signal(biod::kBiometricsManagerInterface,
                      biod::kBiometricsManagerAuthScanDoneSignal);
  dbus::MessageWriter writer(&signal);
  writer.AppendUint32(
      static_cast<uint32_t>(biod::ScanResult::SCAN_RESULT_SUCCESS));
  dbus::MessageWriter matches_writer(nullptr);
  writer.OpenArray("{sao}", &matches_writer);
  // No matches.
  writer.CloseContainer(&matches_writer);

  for (int i = 0; i < kMaxFingerprintRetries - 1; i++) {
    fingerprint_manager_->SetAuthScanDoneCallback(base::BindLambdaForTesting(
        [this](FingerprintScanStatus status) { scan_status_ = status; }));
    scan_status_ = FingerprintScanStatus::SUCCESS;
    fingerprint_manager_peer_->SignalAuthScanDone(&signal);
    EXPECT_EQ(scan_status_, FingerprintScanStatus::FAILED_RETRY_ALLOWED);
  }
  // The last invalid retry should lock the auth session.
  fingerprint_manager_->SetAuthScanDoneCallback(base::BindLambdaForTesting(
      [this](FingerprintScanStatus status) { scan_status_ = status; }));
  scan_status_ = FingerprintScanStatus::SUCCESS;
  fingerprint_manager_peer_->SignalAuthScanDone(&signal);
  EXPECT_EQ(scan_status_, FingerprintScanStatus::FAILED_RETRY_NOT_ALLOWED);
  EXPECT_TRUE(fingerprint_manager_peer_->AuthSessionIsLocked());

  // Any further operation is denied in the auth session, regardless of the
  // scan result.
  scan_status_ = FingerprintScanStatus::SUCCESS;
  fingerprint_manager_->SetAuthScanDoneCallback(base::BindLambdaForTesting(
      [this](FingerprintScanStatus status) { scan_status_ = status; }));
  EXPECT_EQ(scan_status_, FingerprintScanStatus::FAILED_RETRY_NOT_ALLOWED);
}

}  // namespace
}  // namespace cryptohome
