// Copyright 2017 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 "biod/biod_storage.h"

#include <sys/resource.h>

#include <algorithm>
#include <memory>
#include <unordered_set>
#include <utility>
#include <vector>

#include <base/bind.h>
#include <base/check.h>
#include <base/files/file_path.h>
#include <base/files/file_util.h>
#include <base/files/scoped_temp_dir.h>
#include <testing/gtest/include/gtest/gtest.h>
#include <base/strings/string_util.h>
#include <base/files/important_file_writer.h>
#include <base/json/json_string_value_serializer.h>

namespace biod {

using Record = BiodStorageInterface::Record;
using RecordMetadata = BiodStorageInterface::RecordMetadata;

namespace {

const char kBiometricsManagerName[] = "BiometricsManager";

const base::FilePath kFilePath("TestFile");

const char kRecordId1[] = "00000000_0000_0000_0000_000000000001";
const char kUserId1[] = "0000000000000000000000000000000000000001";
const char kLabel1[] = "record1";
const std::vector<uint8_t> kValidationVal1 = {0x00, 0x01};
const char kData1[] = "Hello, world1!";

const char kRecordId2[] = "00000000_0000_0000_0000_000000000002";
const char kUserId2[] = "0000000000000000000000000000000000000002";
const char kLabel2[] = "record2";
const std::vector<uint8_t> kValidationVal2 = {0x00, 0x02};
const char kData2[] = "Hello, world2!";

const char kRecordId3[] = "00000000_0000_0000_0000_000000000003";
const char kLabel3[] = "record3";
const std::vector<uint8_t> kValidationVal3 = {0x00, 0x03};
const char kData3[] = "Hello, world3!";

constexpr int kPermissions600 =
    base::FILE_PERMISSION_READ_BY_USER | base::FILE_PERMISSION_WRITE_BY_USER;
constexpr int kPermissions700 = base::FILE_PERMISSION_USER_MASK;

const char kInvalidUTF8[] = "\xed\xa0\x80\xed\xbf\xbf";

constexpr int kFpc1145TemplateSizeBytes = 47616;
constexpr int kFpc1025TemplateSizeBytes = 5156;
constexpr int kElan80TemplateSizeBytes = 41024;
constexpr int kElan515TemplateSizeBytes = 67064;

/**
 * "Max locked memory" value from reading /proc/<PID>/limits on DUT
 *
 * This matches the default value in the kernel:
 * https://chromium.googlesource.com/chromiumos/third_party/kernel/+/a5746cdefaed35de0a85ede48a47e9a340a6f7e6/include/uapi/linux/resource.h#72
 *
 * The default can be overridden in /etc/security/limits.conf:
 * https://access.redhat.com/solutions/61334
 *
 * or in the upstart script http://upstart.ubuntu.com/cookbook/#limit:
 *
 * limit memlock <soft> <hard>
 */
constexpr int kRlimitMemlockBytes = 65536;

struct MemlockTestParams {
  int rlimit_bytes;
  int template_size_bytes;
};

}  // namespace

class BiodStorageBaseTest : public ::testing::Test {
 public:
  BiodStorageBaseTest() {
    CHECK(temp_dir_.CreateUniqueTempDir());
    root_path_ = temp_dir_.GetPath().AppendASCII("biod_storage_unittest_root");
    biod_storage_ = std::make_unique<BiodStorage>(kBiometricsManagerName);
    // Since there is no session manager, allow accesses by default.
    biod_storage_->set_allow_access(true);
    biod_storage_->SetRootPathForTesting(root_path_);
  }
  BiodStorageBaseTest(const BiodStorageBaseTest&) = delete;
  BiodStorageBaseTest& operator=(const BiodStorageBaseTest&) = delete;

  ~BiodStorageBaseTest() override {
    EXPECT_TRUE(base::DeletePathRecursively(temp_dir_.GetPath()));
  }

  base::Value CreateRecordDictionary(
      const std::vector<uint8_t>& validation_val) {
    base::Value record_dictionary(base::Value::Type::DICTIONARY);
    std::string validation_value_str(validation_val.begin(),
                                     validation_val.end());
    base::Base64Encode(validation_value_str, &validation_value_str);
    record_dictionary.SetStringKey("match_validation_value",
                                   validation_value_str);
    return record_dictionary;
  }

 protected:
  base::ScopedTempDir temp_dir_;
  base::FilePath root_path_;
  std::unique_ptr<BiodStorage> biod_storage_;
};

TEST_F(BiodStorageBaseTest, WriteAndReadRecords) {
  const std::vector<uint8_t> kEmpty;
  const std::vector<Record> kRecords(
      {{{kRecordFormatVersion, kRecordId1, kUserId1, kLabel1, kValidationVal1},
        kData1},
       {{kRecordFormatVersion, kRecordId2, kUserId2, kLabel2, kValidationVal2},
        kData2},
       {{kRecordFormatVersion, kRecordId3, kUserId2, kLabel3, kValidationVal3},
        kData3}});

  // Write the record.
  for (auto const& record : kRecords) {
    EXPECT_TRUE(
        biod_storage_->WriteRecord(record.metadata, base::Value(record.data)));
  }

  // Read the record.
  std::unordered_set<std::string> user_ids({kUserId1, kUserId2});
  auto read_result = biod_storage_->ReadRecords(user_ids);

  EXPECT_EQ(read_result.size(), kRecords.size());

  // Check if all records returned by ReadRecords have "valid" flag set.
  EXPECT_TRUE(std::all_of(read_result.begin(), read_result.end(),
                          [](auto const& record) { return record.valid; }));

  EXPECT_TRUE(std::is_permutation(kRecords.begin(), kRecords.end(),
                                  read_result.begin()));
}

TEST_F(BiodStorageBaseTest, WriteAndReadSingleRecord) {
  const std::vector<Record> kRecords(
      {{{kRecordFormatVersion, kRecordId1, kUserId1, kLabel1, kValidationVal1},
        kData1},
       {{kRecordFormatVersion, kRecordId2, kUserId2, kLabel2, kValidationVal2},
        kData2},
       {{kRecordFormatVersion, kRecordId3, kUserId2, kLabel3, kValidationVal3},
        kData3}});

  // Write the record.
  for (auto const& record : kRecords) {
    EXPECT_TRUE(
        biod_storage_->WriteRecord(record.metadata, base::Value(record.data)));
  }

  // Read the records.
  EXPECT_EQ(kRecords[0],
            *biod_storage_->ReadSingleRecord(kUserId1, kRecordId1));
  EXPECT_EQ(kRecords[1],
            *biod_storage_->ReadSingleRecord(kUserId2, kRecordId2));
  EXPECT_EQ(kRecords[2],
            *biod_storage_->ReadSingleRecord(kUserId2, kRecordId3));
}

TEST_F(BiodStorageBaseTest, ReadSingleRecord) {
  const std::vector<Record> kRecords(
      {{{kRecordFormatVersion, kRecordId1, kUserId1, kLabel1, kValidationVal1},
        kData1},
       {{kRecordFormatVersion, kRecordId2, kUserId2, kLabel2, kValidationVal2},
        kData2}});

  // Write the record.
  for (auto const& record : kRecords) {
    EXPECT_TRUE(
        biod_storage_->WriteRecord(record.metadata, base::Value(record.data)));
  }

  // Check if ReadSingleRecord returns empty base::Optional on RecordId,
  // UserId mismatch.
  EXPECT_FALSE(biod_storage_->ReadSingleRecord(kUserId1, kRecordId2));
  EXPECT_FALSE(biod_storage_->ReadSingleRecord(kUserId2, kRecordId1));
}

TEST_F(BiodStorageBaseTest, WriteRecord_InvalidAbsolutePath) {
  Record record = {{kRecordFormatVersion, kRecordId1, "/absolutepath", kLabel1,
                    kValidationVal1},
                   kData1};

  EXPECT_FALSE(
      biod_storage_->WriteRecord(record.metadata, base::Value(record.data)));
}

TEST_F(BiodStorageBaseTest, WriteRecord_RecordIdNotUTF8) {
  EXPECT_FALSE(base::IsStringUTF8(kInvalidUTF8));

  Record record = {
      {kRecordFormatVersion, kInvalidUTF8, kUserId1, kLabel1, kValidationVal1},
      kData1};

  EXPECT_FALSE(record.metadata.IsValidUTF8());
  EXPECT_FALSE(
      biod_storage_->WriteRecord(record.metadata, base::Value(record.data)));
}

TEST_F(BiodStorageBaseTest, WriteRecord_UserIdNotUTF8) {
  EXPECT_FALSE(base::IsStringUTF8(kInvalidUTF8));

  Record record = {{kRecordFormatVersion, kRecordId1, kInvalidUTF8, kLabel1,
                    kValidationVal1},
                   kData1};

  EXPECT_FALSE(record.metadata.IsValidUTF8());
  EXPECT_FALSE(
      biod_storage_->WriteRecord(record.metadata, base::Value(record.data)));
}

TEST_F(BiodStorageBaseTest, WriteRecord_LabelNotUTF8) {
  EXPECT_FALSE(base::IsStringUTF8(kInvalidUTF8));

  Record record = {{kRecordFormatVersion, kRecordId1, kUserId1, kInvalidUTF8,
                    kValidationVal1},
                   kData1};

  EXPECT_FALSE(record.metadata.IsValidUTF8());
  EXPECT_FALSE(
      biod_storage_->WriteRecord(record.metadata, base::Value(record.data)));
}

TEST_F(BiodStorageBaseTest, WriteRecord_CheckUmask) {
  Record record = {
      {kRecordFormatVersion, kRecordId1, kUserId1, kLabel1, kValidationVal1},
      kData1};

  const base::FilePath kRecordStorageFilename =
      root_path_.Append("biod")
          .Append(record.metadata.user_id)
          .Append(kBiometricsManagerName)
          .Append("Record" + record.metadata.record_id);

  ASSERT_FALSE(base::PathExists(kRecordStorageFilename));
  ASSERT_FALSE(base::PathExists(kRecordStorageFilename.DirName()));

  EXPECT_TRUE(
      biod_storage_->WriteRecord(record.metadata, base::Value(record.data)));

  // Check permissions of directory
  int actual_permissions;
  EXPECT_TRUE(base::GetPosixFilePermissions(kRecordStorageFilename.DirName(),
                                            &actual_permissions));
  EXPECT_EQ(kPermissions700, actual_permissions);

  // Check permissions of record
  EXPECT_TRUE(base::GetPosixFilePermissions(kRecordStorageFilename,
                                            &actual_permissions));
  EXPECT_EQ(kPermissions600, actual_permissions);
}

TEST_F(BiodStorageBaseTest, DeleteRecord) {
  const std::vector<uint8_t> kEmpty;
  const Record kRecord = {
      {kRecordFormatVersion, kRecordId1, kUserId1, kLabel1, kValidationVal1},
      kData1};

  // Delete a non-existent record.
  EXPECT_TRUE(biod_storage_->DeleteRecord(kUserId1, kRecordId1));

  EXPECT_TRUE(
      biod_storage_->WriteRecord(kRecord.metadata, base::Value(kRecord.data)));

  // Check this record is properly written.
  std::unordered_set<std::string> user_ids({kUserId1});
  auto read_result = biod_storage_->ReadRecords(user_ids);
  EXPECT_EQ(read_result.size(), 1);
  const auto& record = read_result[0];
  EXPECT_TRUE(record.valid);
  EXPECT_EQ(record, kRecord);

  EXPECT_TRUE(biod_storage_->DeleteRecord(kUserId1, kRecordId1));

  // Check this record is properly deleted.
  read_result = biod_storage_->ReadRecords(user_ids);
  EXPECT_TRUE(read_result.empty());
}

TEST_F(BiodStorageBaseTest, GenerateNewRecordId) {
  // Check the two record ids are different.
  std::string record_id1(BiodStorage::GenerateNewRecordId());
  std::string record_id2(BiodStorage::GenerateNewRecordId());
  EXPECT_NE(record_id1, record_id2);
}

TEST_F(BiodStorageBaseTest, TestEqualOperator) {
  Record record = {
      {kRecordFormatVersion, kRecordId1, kUserId1, kLabel1, kValidationVal1},
      kData1};
  Record record_eq = {
      {kRecordFormatVersion, kRecordId1, kUserId1, kLabel1, kValidationVal1},
      kData1};
  Record record_eq2 = {
      {kRecordFormatVersion, kRecordId1, kUserId1, kLabel1, kValidationVal1},
      kData1,
      /* valid= */ false};
  Record record_ne = {
      {kRecordFormatVersion, kRecordId1, kUserId1, kLabel1, kValidationVal2},
      kData1};

  EXPECT_EQ(record, record_eq);
  EXPECT_EQ(record, record_eq2);
  EXPECT_NE(record, record_ne);
}

TEST_F(BiodStorageBaseTest, TestReadValidationValueFromRecord) {
  auto record_dictionary = CreateRecordDictionary(kValidationVal1);
  auto ret = biod_storage_->ReadValidationValueFromRecord(record_dictionary,
                                                          kFilePath);
  EXPECT_TRUE(ret != nullptr);
  EXPECT_EQ(*ret, kValidationVal1);
}

/**
 * Tests for invalid records. In general records will be correctly formatted
 * since we follow a specific format when writing them, but we should be able
 * to handle invalid records from bugs, disk corruption, etc.
 */
class BiodStorageInvalidRecordTest : public ::testing::Test {
 public:
  BiodStorageInvalidRecordTest() {
    CHECK(temp_dir_.CreateUniqueTempDir());
    root_path_ = temp_dir_.GetPath().AppendASCII(
        "biod_storage_invalid_record_test_root");
    biod_storage_ = std::make_unique<BiodStorage>(kBiometricsManagerName);
    // Since there is no session manager, allow accesses by default.
    biod_storage_->set_allow_access(true);
    biod_storage_->SetRootPathForTesting(root_path_);

    Record record = {
        {kRecordFormatVersion, kRecordId1, kUserId1, kLabel1, kValidationVal1},
        kData1};
    record_name_ = biod_storage_->GetRecordFilename(record.metadata);
    EXPECT_FALSE(record_name_.empty());
    EXPECT_TRUE(base::CreateDirectory(record_name_.DirName()));
  }

 protected:
  base::ScopedTempDir temp_dir_;
  base::FilePath root_path_;
  base::FilePath record_name_;
  std::unique_ptr<BiodStorageInterface> biod_storage_;
};

TEST_F(BiodStorageInvalidRecordTest, InvalidJSON) {
  EXPECT_TRUE(base::ImportantFileWriter::WriteFileAtomically(record_name_,
                                                             "this is not "
                                                             "JSON"));
  auto read_result = biod_storage_->ReadRecordsForSingleUser(kUserId1);
  EXPECT_EQ(read_result.size(), 1);
  EXPECT_FALSE(read_result[0].valid);
}

TEST_F(BiodStorageInvalidRecordTest, MissingFormatVersion) {
  auto record = R"({
    "record_id": "00000000_0000_0000_0000_000000000001",
    "label": "some_label",
    "data": "some_data",
    "match_validation_value": "4567"
  })";

  EXPECT_TRUE(
      base::ImportantFileWriter::WriteFileAtomically(record_name_, record));

  auto read_result = biod_storage_->ReadRecordsForSingleUser(kUserId1);
  EXPECT_EQ(read_result.size(), 1);
  EXPECT_FALSE(read_result[0].valid);
}

TEST_F(BiodStorageInvalidRecordTest, InvalidFormatVersion) {
  auto record = R"({
    "record_id": "00000000_0000_0000_0000_000000000001",
    "label": "some_label",
    "data": "some_data",
    "match_validation_value": "4567",
    "version": -1
  })";

  EXPECT_TRUE(
      base::ImportantFileWriter::WriteFileAtomically(record_name_, record));

  auto read_result = biod_storage_->ReadRecordsForSingleUser(kUserId1);
  EXPECT_EQ(read_result.size(), 1);
  EXPECT_FALSE(read_result[0].valid);
}

TEST_F(BiodStorageInvalidRecordTest, MissingRecordId) {
  auto record = R"({
    "label": "some_label",
    "data": "some_data",
    "match_validation_value": "4567",
    "version": 2
  })";

  EXPECT_TRUE(
      base::ImportantFileWriter::WriteFileAtomically(record_name_, record));

  auto read_result = biod_storage_->ReadRecordsForSingleUser(kUserId1);
  EXPECT_EQ(read_result.size(), 1);
  EXPECT_FALSE(read_result[0].valid);
}

TEST_F(BiodStorageInvalidRecordTest, MissingRecordLabel) {
  auto record = R"({
    "record_id": "00000000_0000_0000_0000_000000000001",
    "data": "some_data",
    "match_validation_value": "4567",
    "version": 2
  })";

  EXPECT_TRUE(
      base::ImportantFileWriter::WriteFileAtomically(record_name_, record));

  auto read_result = biod_storage_->ReadRecordsForSingleUser(kUserId1);
  EXPECT_EQ(read_result.size(), 1);
  EXPECT_FALSE(read_result[0].valid);
}

TEST_F(BiodStorageInvalidRecordTest, MissingRecordData) {
  auto record = R"({
    "record_id": "00000000_0000_0000_0000_000000000001",
    "label": "some_label",
    "match_validation_value": "4567",
    "version": 2
  })";

  EXPECT_TRUE(
      base::ImportantFileWriter::WriteFileAtomically(record_name_, record));

  auto read_result = biod_storage_->ReadRecordsForSingleUser(kUserId1);
  EXPECT_EQ(read_result.size(), 1);
  EXPECT_FALSE(read_result[0].valid);
}

TEST_F(BiodStorageInvalidRecordTest, MissingValidationValue) {
  auto record = R"({
    "record_id": "00000000_0000_0000_0000_000000000001",
    "label": "some_label",
    "data": "some_data",
    "version": 2
  })";

  EXPECT_TRUE(
      base::ImportantFileWriter::WriteFileAtomically(record_name_, record));

  auto read_result = biod_storage_->ReadRecordsForSingleUser(kUserId1);
  EXPECT_EQ(read_result.size(), 1);
  EXPECT_FALSE(read_result[0].valid);
}

TEST_F(BiodStorageInvalidRecordTest, ValidationValueNotBase64) {
  auto record = R"({
    "record_id": "00000000_0000_0000_0000_000000000001",
    "label": "some_label",
    "data": "some_data",
    "match_validation_value": "not valid base64",
    "version": 2
  })";

  EXPECT_TRUE(
      base::ImportantFileWriter::WriteFileAtomically(record_name_, record));

  auto read_result = biod_storage_->ReadRecordsForSingleUser(kUserId1);
  EXPECT_EQ(read_result.size(), 1);
  EXPECT_FALSE(read_result[0].valid);
}

TEST_F(BiodStorageInvalidRecordTest, VersionOneWithoutValidationValueIsValid) {
  auto record = R"({
    "record_id": "00000000_0000_0000_0000_000000000001",
    "label": "some_label",
    "data": "some_data",
    "version": 1
  })";

  EXPECT_TRUE(
      base::ImportantFileWriter::WriteFileAtomically(record_name_, record));

  auto read_result = biod_storage_->ReadRecordsForSingleUser(kUserId1);
  EXPECT_EQ(read_result.size(), 1);
  EXPECT_TRUE(read_result[0].valid);
  EXPECT_TRUE(read_result[0].metadata.validation_val.empty());
  EXPECT_EQ(read_result[0].metadata.record_format_version,
            kRecordFormatVersionNoValidationValue);
}

TEST_F(BiodStorageInvalidRecordTest, RecordIdMismatch) {
  auto record = R"({
    "record_id": "5678",
    "label": "some_label",
    "data": "some_data",
    "match_validation_value": "4567",
    "version": 2
  })";

  EXPECT_TRUE(
      base::ImportantFileWriter::WriteFileAtomically(record_name_, record));

  auto read_result = biod_storage_->ReadRecordsForSingleUser(kUserId1);
  EXPECT_EQ(read_result.size(), 1);
  EXPECT_FALSE(read_result[0].valid);
}

/**
 * Tests to make sure we do not crash due to hitting the RLIMIT_MEMLOCK limit.
 * See http://b/181281782, http://b/175158241, and http://b/173655013.
 */
class BiodStorageMemlockTest
    : public testing::TestWithParam<MemlockTestParams> {
 public:
  BiodStorageMemlockTest() : params_(GetParam()) {
    CHECK(temp_dir_.CreateUniqueTempDir());
    root_path_ =
        temp_dir_.GetPath().AppendASCII("biod_storage_memlock_test_root");
    biod_storage_ = std::make_unique<BiodStorage>(kBiometricsManagerName);
    // Since there is no session manager, allow accesses by default.
    biod_storage_->set_allow_access(true);
    biod_storage_->SetRootPathForTesting(root_path_);

    Record record = {
        {kRecordFormatVersion, kRecordId1, kUserId1, kLabel1, kValidationVal1},
        kData1};
    record_name_ = biod_storage_->GetRecordFilename(record.metadata);
    EXPECT_FALSE(record_name_.empty());
    EXPECT_TRUE(base::CreateDirectory(record_name_.DirName()));

    struct rlimit limit;

    EXPECT_EQ(getrlimit(RLIMIT_MEMLOCK, &limit), 0);
    orig_limit_ = limit;

    limit.rlim_cur = params_.rlimit_bytes;
    EXPECT_LT(limit.rlim_cur, limit.rlim_max);
    EXPECT_EQ(setrlimit(RLIMIT_MEMLOCK, &limit), 0);

    EXPECT_EQ(getrlimit(RLIMIT_MEMLOCK, &limit), 0);
    EXPECT_EQ(limit.rlim_cur, params_.rlimit_bytes);
  }

  ~BiodStorageMemlockTest() override {
    // Restore original limits.
    EXPECT_EQ(setrlimit(RLIMIT_MEMLOCK, &orig_limit_), 0);
  }

 protected:
  const MemlockTestParams params_;
  base::ScopedTempDir temp_dir_;
  base::FilePath root_path_;
  base::FilePath record_name_;
  std::unique_ptr<BiodStorageInterface> biod_storage_;
  struct rlimit orig_limit_;
};

TEST_P(BiodStorageMemlockTest, ReadReadRecords) {
  base::Value record_value(base::Value::Type::DICTIONARY);
  record_value.SetStringKey("record_id", kRecordId1);
  record_value.SetStringKey("label", "some_label");
  record_value.SetStringKey("match_validation_value", "4567");
  record_value.SetIntKey("version", 2);
  std::vector<uint8_t> data(params_.template_size_bytes, 'a');
  record_value.SetStringKey("data", base::Base64Encode(data));

  std::string record;
  JSONStringValueSerializer json_serializer(&record);
  EXPECT_TRUE(json_serializer.Serialize(record_value));

  EXPECT_TRUE(
      base::ImportantFileWriter::WriteFileAtomically(record_name_, record));
  auto read_result = biod_storage_->ReadRecordsForSingleUser(kUserId1);
  EXPECT_EQ(read_result.size(), 1);
  EXPECT_TRUE(read_result[0].valid);
}

INSTANTIATE_TEST_SUITE_P(
    BiodStorageMemlock,
    BiodStorageMemlockTest,
    testing::Values(
        MemlockTestParams{
            .rlimit_bytes = kRlimitMemlockBytes,
            .template_size_bytes = kElan515TemplateSizeBytes,
        },
        MemlockTestParams{
            .rlimit_bytes = kRlimitMemlockBytes,
            .template_size_bytes = kElan80TemplateSizeBytes,
        },
        MemlockTestParams{
            .rlimit_bytes = kRlimitMemlockBytes,
            .template_size_bytes = kFpc1145TemplateSizeBytes,
        },
        MemlockTestParams{
            .rlimit_bytes = kRlimitMemlockBytes,
            .template_size_bytes = kFpc1025TemplateSizeBytes,
        }));

}  // namespace biod
