// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/internal_auth.h"

#include <stddef.h>

#include <algorithm>

#include "base/lazy_instance.h"
#include "base/test/task_environment.h"
#include "base/time/time.h"
#include "testing/gtest/include/gtest/gtest.h"

class InternalAuthTest : public ::testing::Test {
 public:
  InternalAuthTest() {
    long_string_ = "seed";
    for (int i = 20; i--;)
      long_string_ += long_string_;
  }
  ~InternalAuthTest() override {}

  void SetUp() override {}

  void TearDown() override {}

  base::test::SingleThreadTaskEnvironment task_environment_;
  std::string long_string_;
};

TEST_F(InternalAuthTest, BasicGeneration) {
  std::map<std::string, std::string> map;
  map["key"] = "value";
  std::string token = InternalAuthGeneration::GeneratePassport(
      "zapata", map);
  ASSERT_GT(token.size(), 10u);  // short token is insecure.

  map["key2"] = "value2";
  token = InternalAuthGeneration::GeneratePassport("zapata", map);
  ASSERT_GT(token.size(), 10u);
}

TEST_F(InternalAuthTest, DoubleGeneration) {
  std::map<std::string, std::string> map;
  map["key"] = "value";
  std::string token1 = InternalAuthGeneration::GeneratePassport(
      "zapata", map);
  ASSERT_GT(token1.size(), 10u);

  std::string token2 = InternalAuthGeneration::GeneratePassport(
      "zapata", map);
  ASSERT_GT(token2.size(), 10u);
  // tokens are different even if credentials coincide.
  ASSERT_NE(token1, token2);
}

TEST_F(InternalAuthTest, BadGeneration) {
  std::map<std::string, std::string> map;
  map["key"] = "value";
  // Trying huge domain.
  std::string token = InternalAuthGeneration::GeneratePassport(
      long_string_, map);
  ASSERT_TRUE(token.empty());
  ASSERT_FALSE(InternalAuthVerification::VerifyPassport(
      token, long_string_, map));

  // Trying empty domain.
  token = InternalAuthGeneration::GeneratePassport(std::string(), map);
  ASSERT_TRUE(token.empty());
  ASSERT_FALSE(
      InternalAuthVerification::VerifyPassport(token, std::string(), map));

  std::string dummy("abcdefghij");
  for (size_t i = 1000; i--;) {
    std::string key = dummy;
    std::next_permutation(dummy.begin(), dummy.end());
    std::string value = dummy;
    std::next_permutation(dummy.begin(), dummy.end());
    map[key] = value;
  }
  // Trying huge var=value map.
  token = InternalAuthGeneration::GeneratePassport("zapata", map);
  ASSERT_TRUE(token.empty());
  ASSERT_FALSE(InternalAuthVerification::VerifyPassport(token, "zapata", map));

  map.clear();
  map[std::string()] = "value";
  // Trying empty key.
  token = InternalAuthGeneration::GeneratePassport("zapata", map);
  ASSERT_TRUE(token.empty());
  ASSERT_FALSE(InternalAuthVerification::VerifyPassport(token, "zapata", map));
}

TEST_F(InternalAuthTest, BasicVerification) {
  std::map<std::string, std::string> map;
  map["key"] = "value";
  std::string token = InternalAuthGeneration::GeneratePassport("zapata", map);
  ASSERT_GT(token.size(), 10u);
  ASSERT_TRUE(InternalAuthVerification::VerifyPassport(token, "zapata", map));
  // Passport can not be reused.
  for (int i = 1000; i--;) {
    ASSERT_FALSE(InternalAuthVerification::VerifyPassport(
        token, "zapata", map));
  }
}

TEST_F(InternalAuthTest, BruteForce) {
  std::map<std::string, std::string> map;
  map["key"] = "value";
  std::string token = InternalAuthGeneration::GeneratePassport("zapata", map);
  ASSERT_GT(token.size(), 10u);

  // Trying bruteforce.
  std::string dummy = token;
  for (size_t i = 100; i--;) {
    std::next_permutation(dummy.begin(), dummy.end());
    ASSERT_FALSE(InternalAuthVerification::VerifyPassport(
        dummy, "zapata", map));
  }
  dummy = token;
  for (size_t i = 100; i--;) {
    std::next_permutation(dummy.begin(), dummy.begin() + dummy.size() / 2);
    ASSERT_FALSE(InternalAuthVerification::VerifyPassport(
        dummy, "zapata", map));
  }
  // We brute forced just too little, so original token must not expire yet.
  ASSERT_TRUE(InternalAuthVerification::VerifyPassport(token, "zapata", map));
}

TEST_F(InternalAuthTest, ExpirationAndBruteForce) {
  int kCustomVerificationWindow = 2;
  InternalAuthVerification::set_verification_window_seconds(
      kCustomVerificationWindow);

  std::map<std::string, std::string> map;
  map["key"] = "value";
  std::string token = InternalAuthGeneration::GeneratePassport("zapata", map);
  ASSERT_GT(token.size(), 10u);

  // We want to test token expiration, so we need to wait some amount of time,
  // so we are brute-forcing during this time.
  base::Time timestamp = base::Time::Now();
  std::string dummy1 = token;
  std::string dummy2 = token;
  for (;;) {
    for (size_t i = 100; i--;) {
      std::next_permutation(dummy1.begin(), dummy1.end());
      ASSERT_FALSE(InternalAuthVerification::VerifyPassport(
          dummy1, "zapata", map));
    }
    for (size_t i = 100; i--;) {
      std::next_permutation(dummy2.begin(), dummy2.begin() + dummy2.size() / 2);
      ASSERT_FALSE(InternalAuthVerification::VerifyPassport(
          dummy2, "zapata", map));
    }
    if (base::Time::Now() - timestamp >
        base::Seconds(kCustomVerificationWindow + 1)) {
      break;
    }
  }
  ASSERT_FALSE(InternalAuthVerification::VerifyPassport(token, "zapata", map));
  // Reset verification window to default.
  InternalAuthVerification::set_verification_window_seconds(0);
}

TEST_F(InternalAuthTest, ChangeKey) {
  std::map<std::string, std::string> map;
  map["key"] = "value";
  std::string token = InternalAuthGeneration::GeneratePassport("zapata", map);
  ASSERT_GT(token.size(), 10u);

  InternalAuthGeneration::GenerateNewKey();
  // Passport should survive key change.
  ASSERT_TRUE(InternalAuthVerification::VerifyPassport(token, "zapata", map));

  token = InternalAuthGeneration::GeneratePassport("zapata", map);
  ASSERT_GT(token.size(), 10u);
  for (int i = 20; i--;)
    InternalAuthGeneration::GenerateNewKey();
  // Passport should not survive series of key changes.
  ASSERT_FALSE(InternalAuthVerification::VerifyPassport(token, "zapata", map));
}
