// Copyright 2014 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/chromeos/login/users/multi_profile_user_controller.h"

#include <stddef.h>

#include <memory>

#include "base/bind.h"
#include "base/memory/ptr_util.h"
#include "base/memory/ref_counted.h"
#include "base/run_loop.h"
#include "base/stl_util.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/chromeos/login/users/fake_chrome_user_manager.h"
#include "chrome/browser/chromeos/login/users/multi_profile_user_controller_delegate.h"
#include "chrome/browser/chromeos/policy/policy_cert_service.h"
#include "chrome/browser/chromeos/policy/policy_cert_service_factory.h"
#include "chrome/browser/chromeos/profiles/profile_helper.h"
#include "chrome/browser/prefs/browser_prefs.h"
#include "chrome/common/pref_names.h"
#include "chrome/test/base/scoped_testing_local_state.h"
#include "chrome/test/base/testing_browser_process.h"
#include "chrome/test/base/testing_profile.h"
#include "chrome/test/base/testing_profile_manager.h"
#include "components/sync_preferences/testing_pref_service_syncable.h"
#include "components/user_manager/scoped_user_manager.h"
#include "components/user_manager/user_manager.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "net/cert/cert_verify_proc.h"
#include "net/cert/x509_certificate.h"
#include "net/test/cert_test_util.h"
#include "net/test/test_data_directory.h"
#include "services/network/cert_verifier_with_trust_anchors.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace chromeos {

namespace {

const char* const kUsers[] = {"a@gmail.com", "b@gmail.com"};

struct BehaviorTestCase {
  const char* primary;
  const char* secondary;
  MultiProfileUserController::UserAllowedInSessionReason
      expected_primary_policy;
  MultiProfileUserController::UserAllowedInSessionReason
      expected_secondary_allowed;
};

const BehaviorTestCase kBehaviorTestCases[] = {
    {
        MultiProfileUserController::kBehaviorUnrestricted,
        MultiProfileUserController::kBehaviorUnrestricted,
        MultiProfileUserController::ALLOWED,
        MultiProfileUserController::ALLOWED,
    },
    {
        MultiProfileUserController::kBehaviorUnrestricted,
        MultiProfileUserController::kBehaviorPrimaryOnly,
        MultiProfileUserController::ALLOWED,
        MultiProfileUserController::NOT_ALLOWED_POLICY_FORBIDS,
    },
    {
        MultiProfileUserController::kBehaviorUnrestricted,
        MultiProfileUserController::kBehaviorNotAllowed,
        MultiProfileUserController::ALLOWED,
        MultiProfileUserController::NOT_ALLOWED_POLICY_FORBIDS,
    },
    {
        MultiProfileUserController::kBehaviorPrimaryOnly,
        MultiProfileUserController::kBehaviorUnrestricted,
        MultiProfileUserController::ALLOWED,
        MultiProfileUserController::ALLOWED,
    },
    {
        MultiProfileUserController::kBehaviorPrimaryOnly,
        MultiProfileUserController::kBehaviorPrimaryOnly,
        MultiProfileUserController::ALLOWED,
        MultiProfileUserController::NOT_ALLOWED_POLICY_FORBIDS,
    },
    {
        MultiProfileUserController::kBehaviorPrimaryOnly,
        MultiProfileUserController::kBehaviorNotAllowed,
        MultiProfileUserController::ALLOWED,
        MultiProfileUserController::NOT_ALLOWED_POLICY_FORBIDS,
    },
    {
        MultiProfileUserController::kBehaviorNotAllowed,
        MultiProfileUserController::kBehaviorUnrestricted,
        MultiProfileUserController::NOT_ALLOWED_PRIMARY_USER_POLICY_FORBIDS,
        MultiProfileUserController::NOT_ALLOWED_PRIMARY_USER_POLICY_FORBIDS,
    },
    {
        MultiProfileUserController::kBehaviorNotAllowed,
        MultiProfileUserController::kBehaviorPrimaryOnly,
        MultiProfileUserController::NOT_ALLOWED_PRIMARY_USER_POLICY_FORBIDS,
        MultiProfileUserController::NOT_ALLOWED_PRIMARY_USER_POLICY_FORBIDS,
    },
    {
        MultiProfileUserController::kBehaviorNotAllowed,
        MultiProfileUserController::kBehaviorNotAllowed,
        MultiProfileUserController::NOT_ALLOWED_PRIMARY_USER_POLICY_FORBIDS,
        MultiProfileUserController::NOT_ALLOWED_PRIMARY_USER_POLICY_FORBIDS,
    },
};

// Weak ptr to network::CertVerifierWithTrustAnchors - object is freed in test
// destructor once we've ensured the profile has been shut down.
network::CertVerifierWithTrustAnchors* g_policy_cert_verifier_for_factory =
    NULL;

std::unique_ptr<KeyedService> TestPolicyCertServiceFactory(
    content::BrowserContext* context) {
  return policy::PolicyCertService::CreateForTesting(
      kUsers[0], g_policy_cert_verifier_for_factory,
      user_manager::UserManager::Get());
}

class MockCertVerifyProc : public net::CertVerifyProc {
 public:
  MockCertVerifyProc() = default;

  // net::CertVerifyProc implementation
  bool SupportsAdditionalTrustAnchors() const override { return true; }

 protected:
  ~MockCertVerifyProc() override = default;

 private:
  int VerifyInternal(net::X509Certificate* cert,
                     const std::string& hostname,
                     const std::string& ocsp_response,
                     int flags,
                     net::CRLSet* crl_set,
                     const net::CertificateList& additional_trust_anchors,
                     net::CertVerifyResult* result) override {
    return net::ERR_FAILED;
  }
};

}  // namespace

class MultiProfileUserControllerTest
    : public testing::Test,
      public MultiProfileUserControllerDelegate {
 public:
  MultiProfileUserControllerTest()
      : fake_user_manager_(new FakeChromeUserManager),
        user_manager_enabler_(base::WrapUnique(fake_user_manager_)),
        user_not_allowed_count_(0) {
    for (size_t i = 0; i < base::size(kUsers); ++i) {
      test_users_.push_back(AccountId::FromUserEmail(kUsers[i]));
    }
  }

  ~MultiProfileUserControllerTest() override {}

  void SetUp() override {
    profile_manager_.reset(
        new TestingProfileManager(TestingBrowserProcess::GetGlobal()));
    ASSERT_TRUE(profile_manager_->SetUp());
    controller_.reset(new MultiProfileUserController(
        this, TestingBrowserProcess::GetGlobal()->local_state()));

    for (size_t i = 0; i < test_users_.size(); ++i) {
      const AccountId account_id(test_users_[i]);
      const user_manager::User* user =
          fake_user_manager_->AddUser(test_users_[i]);

      // Note that user profiles are created after user login in reality.
      TestingProfile* user_profile =
          profile_manager_->CreateTestingProfile(account_id.GetUserEmail());
      user_profile->set_profile_name(account_id.GetUserEmail());
      user_profiles_.push_back(user_profile);

      ProfileHelper::Get()->SetUserToProfileMappingForTesting(user,
                                                              user_profile);
    }
  }

  void TearDown() override {
    // Clear our cached pointer to the network::CertVerifierWithTrustAnchors.
    g_policy_cert_verifier_for_factory = NULL;

    // We must ensure that the network::CertVerifierWithTrustAnchors outlives
    // the PolicyCertService so shutdown the profile here. Additionally, we need
    // to run the message loop between freeing the PolicyCertService and
    // freeing the network::CertVerifierWithTrustAnchors (see
    // PolicyCertService::OnTrustAnchorsChanged() which is called from
    // PolicyCertService::Shutdown()).
    controller_.reset();
    profile_manager_.reset();
    base::RunLoop().RunUntilIdle();
  }

  void LoginUser(size_t user_index) {
    ASSERT_LT(user_index, test_users_.size());
    fake_user_manager_->LoginUser(test_users_[user_index]);
    controller_->StartObserving(user_profiles_[user_index]);
  }

  void SetOwner(size_t user_index) {
    fake_user_manager_->set_owner_id(test_users_[user_index]);
  }

  PrefService* GetUserPrefs(size_t user_index) {
    return user_profiles_[user_index]->GetPrefs();
  }

  void SetPrefBehavior(size_t user_index, const std::string& behavior) {
    GetUserPrefs(user_index)
        ->SetString(prefs::kMultiProfileUserBehavior, behavior);
  }

  std::string GetCachedBehavior(size_t user_index) {
    return controller_->GetCachedValue(test_users_[user_index].GetUserEmail());
  }

  void SetCachedBehavior(size_t user_index, const std::string& behavior) {
    controller_->SetCachedValue(test_users_[user_index].GetUserEmail(),
                                behavior);
  }

  void ResetCounts() { user_not_allowed_count_ = 0; }

  // MultiProfileUserControllerDeleagte overrides:
  void OnUserNotAllowed(const std::string& user_email) override {
    ++user_not_allowed_count_;
  }

  MultiProfileUserController* controller() { return controller_.get(); }
  int user_not_allowed_count() const { return user_not_allowed_count_; }

  TestingProfile* profile(int index) { return user_profiles_[index]; }

  content::TestBrowserThreadBundle threads_;
  std::unique_ptr<network::CertVerifierWithTrustAnchors> cert_verifier_;
  std::unique_ptr<TestingProfileManager> profile_manager_;
  FakeChromeUserManager* fake_user_manager_;  // Not owned
  user_manager::ScopedUserManager user_manager_enabler_;

  std::unique_ptr<MultiProfileUserController> controller_;

  std::vector<TestingProfile*> user_profiles_;

  int user_not_allowed_count_;

  std::vector<AccountId> test_users_;

 private:
  DISALLOW_COPY_AND_ASSIGN(MultiProfileUserControllerTest);
};

// Tests that everyone is allowed before a session starts.
TEST_F(MultiProfileUserControllerTest, AllAllowedBeforeLogin) {
  const char* const kTestCases[] = {
      MultiProfileUserController::kBehaviorUnrestricted,
      MultiProfileUserController::kBehaviorPrimaryOnly,
      MultiProfileUserController::kBehaviorNotAllowed,
  };
  for (size_t i = 0; i < base::size(kTestCases); ++i) {
    SetCachedBehavior(0, kTestCases[i]);
    MultiProfileUserController::UserAllowedInSessionReason reason;
    EXPECT_TRUE(controller()->IsUserAllowedInSession(
        test_users_[0].GetUserEmail(), &reason))
        << "Case " << i;
    EXPECT_EQ(MultiProfileUserController::ALLOWED, reason) << "Case " << i;
    EXPECT_EQ(MultiProfileUserController::ALLOWED,
              MultiProfileUserController::GetPrimaryUserPolicy())
        << "Case " << i;
  }
}

// Tests that invalid cache value would become the default "unrestricted".
TEST_F(MultiProfileUserControllerTest, InvalidCacheBecomesDefault) {
  const char kBad[] = "some invalid value";
  SetCachedBehavior(0, kBad);
  EXPECT_EQ(MultiProfileUserController::kBehaviorUnrestricted,
            GetCachedBehavior(0));
}

// Tests that cached behavior value changes with user pref after login.
TEST_F(MultiProfileUserControllerTest, CachedBehaviorUpdate) {
  LoginUser(0);

  const char* const kTestCases[] = {
      MultiProfileUserController::kBehaviorUnrestricted,
      MultiProfileUserController::kBehaviorPrimaryOnly,
      MultiProfileUserController::kBehaviorNotAllowed,
      MultiProfileUserController::kBehaviorUnrestricted,
  };
  for (size_t i = 0; i < base::size(kTestCases); ++i) {
    SetPrefBehavior(0, kTestCases[i]);
    EXPECT_EQ(kTestCases[i], GetCachedBehavior(0));
  }
}

// Tests that compromised cache value would be fixed and pref value is checked
// upon login.
TEST_F(MultiProfileUserControllerTest, CompromisedCacheFixedOnLogin) {
  SetPrefBehavior(0, MultiProfileUserController::kBehaviorPrimaryOnly);
  SetCachedBehavior(0, MultiProfileUserController::kBehaviorUnrestricted);
  EXPECT_EQ(MultiProfileUserController::kBehaviorUnrestricted,
            GetCachedBehavior(0));
  LoginUser(0);
  EXPECT_EQ(MultiProfileUserController::kBehaviorPrimaryOnly,
            GetCachedBehavior(0));

  EXPECT_EQ(0, user_not_allowed_count());
  SetPrefBehavior(1, MultiProfileUserController::kBehaviorPrimaryOnly);
  SetCachedBehavior(1, MultiProfileUserController::kBehaviorUnrestricted);
  EXPECT_EQ(MultiProfileUserController::kBehaviorUnrestricted,
            GetCachedBehavior(1));
  LoginUser(1);
  EXPECT_EQ(MultiProfileUserController::kBehaviorPrimaryOnly,
            GetCachedBehavior(1));
  EXPECT_EQ(1, user_not_allowed_count());
}

// Tests cases before the second user login.
TEST_F(MultiProfileUserControllerTest, IsSecondaryAllowed) {
  LoginUser(0);

  for (size_t i = 0; i < base::size(kBehaviorTestCases); ++i) {
    SetPrefBehavior(0, kBehaviorTestCases[i].primary);
    SetCachedBehavior(1, kBehaviorTestCases[i].secondary);
    EXPECT_EQ(kBehaviorTestCases[i].expected_primary_policy,
              MultiProfileUserController::GetPrimaryUserPolicy())
        << "Case " << i;
    MultiProfileUserController::UserAllowedInSessionReason reason;
    controller()->IsUserAllowedInSession(test_users_[1].GetUserEmail(),
                                         &reason);
    EXPECT_EQ(kBehaviorTestCases[i].expected_secondary_allowed, reason)
        << "Case " << i;
  }
}

// Tests user behavior changes within a two-user session.
TEST_F(MultiProfileUserControllerTest, PrimaryBehaviorChange) {
  LoginUser(0);
  LoginUser(1);

  for (size_t i = 0; i < base::size(kBehaviorTestCases); ++i) {
    SetPrefBehavior(0, MultiProfileUserController::kBehaviorUnrestricted);
    SetPrefBehavior(1, MultiProfileUserController::kBehaviorUnrestricted);
    ResetCounts();

    SetPrefBehavior(0, kBehaviorTestCases[i].primary);
    SetPrefBehavior(1, kBehaviorTestCases[i].secondary);
    if (user_not_allowed_count() == 0) {
      EXPECT_EQ(kBehaviorTestCases[i].expected_secondary_allowed,
                MultiProfileUserController::ALLOWED)
          << "Case " << i;
    } else {
      EXPECT_NE(kBehaviorTestCases[i].expected_secondary_allowed,
                MultiProfileUserController::ALLOWED)
          << "Case " << i;
    }
  }
}

TEST_F(MultiProfileUserControllerTest,
       UsedPolicyCertificatesAllowedForPrimary) {
  // Verifies that any user can sign-in as the primary user, regardless of the
  // tainted state.
  policy::PolicyCertServiceFactory::SetUsedPolicyCertificates(
      test_users_[0].GetUserEmail());
  MultiProfileUserController::UserAllowedInSessionReason reason;
  EXPECT_TRUE(controller()->IsUserAllowedInSession(
      test_users_[0].GetUserEmail(), &reason));
  EXPECT_EQ(MultiProfileUserController::ALLOWED, reason);
  EXPECT_TRUE(controller()->IsUserAllowedInSession(
      test_users_[1].GetUserEmail(), &reason));
  EXPECT_EQ(MultiProfileUserController::ALLOWED, reason);
  EXPECT_EQ(MultiProfileUserController::ALLOWED,
            MultiProfileUserController::GetPrimaryUserPolicy());
}

TEST_F(MultiProfileUserControllerTest,
       UsedPolicyCertificatesDisallowedForSecondary) {
  // Verifies that if a regular user is signed-in then other regular users can
  // be added but tainted users can't.
  LoginUser(1);

  // TODO(xiyuan): Remove the following SetPrefBehavor when default is
  // changed back to enabled.
  SetPrefBehavior(1, MultiProfileUserController::kBehaviorUnrestricted);

  MultiProfileUserController::UserAllowedInSessionReason reason;
  EXPECT_TRUE(controller()->IsUserAllowedInSession(
      test_users_[0].GetUserEmail(), &reason));
  EXPECT_EQ(MultiProfileUserController::ALLOWED, reason);

  policy::PolicyCertServiceFactory::SetUsedPolicyCertificates(
      test_users_[0].GetUserEmail());
  EXPECT_FALSE(controller()->IsUserAllowedInSession(
      test_users_[0].GetUserEmail(), &reason));
  EXPECT_EQ(MultiProfileUserController::NOT_ALLOWED_POLICY_CERT_TAINTED,
            reason);
}

TEST_F(MultiProfileUserControllerTest,
       UsedPolicyCertificatesDisallowsSecondaries) {
  // Verifies that if a tainted user is signed-in then no other users can
  // be added.
  policy::PolicyCertServiceFactory::SetUsedPolicyCertificates(
      test_users_[0].GetUserEmail());
  LoginUser(0);

  cert_verifier_.reset(
      new network::CertVerifierWithTrustAnchors(base::Closure()));
  cert_verifier_->InitializeOnIOThread(
      base::MakeRefCounted<MockCertVerifyProc>());
  g_policy_cert_verifier_for_factory = cert_verifier_.get();
  ASSERT_TRUE(
      policy::PolicyCertServiceFactory::GetInstance()->SetTestingFactoryAndUse(
          profile(0), base::BindRepeating(&TestPolicyCertServiceFactory)));

  MultiProfileUserController::UserAllowedInSessionReason reason;
  EXPECT_FALSE(controller()->IsUserAllowedInSession(
      test_users_[1].GetUserEmail(), &reason));
  EXPECT_EQ(MultiProfileUserController::NOT_ALLOWED_PRIMARY_POLICY_CERT_TAINTED,
            reason);
  EXPECT_EQ(MultiProfileUserController::NOT_ALLOWED_PRIMARY_POLICY_CERT_TAINTED,
            MultiProfileUserController::GetPrimaryUserPolicy());
  policy::PolicyCertServiceFactory::SetUsedPolicyCertificates(
      test_users_[1].GetUserEmail());
  EXPECT_FALSE(controller()->IsUserAllowedInSession(
      test_users_[1].GetUserEmail(), &reason));
  EXPECT_EQ(MultiProfileUserController::NOT_ALLOWED_POLICY_CERT_TAINTED,
            reason);
  EXPECT_EQ(MultiProfileUserController::NOT_ALLOWED_PRIMARY_POLICY_CERT_TAINTED,
            MultiProfileUserController::GetPrimaryUserPolicy());

  // Flush tasks posted to IO.
  base::RunLoop().RunUntilIdle();
}

TEST_F(MultiProfileUserControllerTest,
       PolicyCertificatesInMemoryDisallowsSecondaries) {
  // Verifies that if a user is signed-in and has policy certificates installed
  // then no other users can be added.
  LoginUser(0);

  // TODO(xiyuan): Remove the following SetPrefBehavor when default is
  // changed back to enabled.
  SetPrefBehavior(0, MultiProfileUserController::kBehaviorUnrestricted);

  cert_verifier_.reset(
      new network::CertVerifierWithTrustAnchors(base::Closure()));
  cert_verifier_->InitializeOnIOThread(
      base::MakeRefCounted<MockCertVerifyProc>());
  g_policy_cert_verifier_for_factory = cert_verifier_.get();
  ASSERT_TRUE(
      policy::PolicyCertServiceFactory::GetInstance()->SetTestingFactoryAndUse(
          profile(0), base::BindRepeating(&TestPolicyCertServiceFactory)));
  policy::PolicyCertService* service =
      policy::PolicyCertServiceFactory::GetForProfile(profile(0));
  ASSERT_TRUE(service);

  EXPECT_FALSE(service->has_policy_certificates());
  MultiProfileUserController::UserAllowedInSessionReason reason;
  EXPECT_TRUE(controller()->IsUserAllowedInSession(
      test_users_[1].GetUserEmail(), &reason));
  EXPECT_EQ(MultiProfileUserController::ALLOWED, reason);
  EXPECT_EQ(MultiProfileUserController::ALLOWED,
            MultiProfileUserController::GetPrimaryUserPolicy());

  net::CertificateList certificates;
  certificates.push_back(
      net::ImportCertFromFile(net::GetTestCertsDirectory(), "ok_cert.pem"));
  service->OnPolicyProvidedCertsChanged(
      certificates /* all_server_and_authority_certs */,
      certificates /* trust_anchors */);
  EXPECT_TRUE(service->has_policy_certificates());
  EXPECT_FALSE(controller()->IsUserAllowedInSession(
      test_users_[1].GetUserEmail(), &reason));
  EXPECT_EQ(MultiProfileUserController::NOT_ALLOWED_PRIMARY_POLICY_CERT_TAINTED,
            reason);
  EXPECT_EQ(MultiProfileUserController::NOT_ALLOWED_PRIMARY_POLICY_CERT_TAINTED,
            MultiProfileUserController::GetPrimaryUserPolicy());

  // Flush tasks posted to IO.
  base::RunLoop().RunUntilIdle();
}

}  // namespace chromeos
