// Copyright 2017 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 "chromeos/dbus/auth_policy/fake_auth_policy_client.h"

#include "base/bind.h"
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "chromeos/dbus/session_manager/session_manager_client.h"
#include "chromeos/tpm/stub_install_attributes.h"
#include "components/account_id/account_id.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace em = enterprise_management;

namespace chromeos {
namespace {

constexpr char kCorrectMachineName[] = "machine_name";
constexpr char kCorrectUserName[] = "user@domain.com";
constexpr char kCorrectUserDomain[] = "domain.com";
constexpr char kAccountId[] = "user-account-id";
constexpr char kMachineDomain[] = "machine.domain";

}  // namespace

class FakeAuthPolicyClientTest : public ::testing::Test {
 public:
  FakeAuthPolicyClientTest() = default;

 protected:
  FakeAuthPolicyClient* authpolicy_client() {
    return FakeAuthPolicyClient::Get();
  }

  void SetUp() override {
    ::testing::Test::SetUp();
    SessionManagerClient::InitializeFakeInMemory();
    AuthPolicyClient::InitializeFake();
    authpolicy_client()->DisableOperationDelayForTesting();
  }

  void TearDown() override {
    AuthPolicyClient::Shutdown();
    SessionManagerClient::Shutdown();
  }

  void JoinAdDomain(const std::string& machine_name,
                    const std::string& username,
                    AuthPolicyClient::JoinCallback callback) {
    authpolicy::JoinDomainRequest request;
    request.set_machine_name(machine_name);
    request.set_user_principal_name(username);
    authpolicy_client()->JoinAdDomain(request, /* password_fd */ -1,
                                      std::move(callback));
  }

  void JoinAdDomainWithMachineDomain(const std::string& machine_name,
                                     const std::string& machine_domain,
                                     const std::string& username,
                                     AuthPolicyClient::JoinCallback callback) {
    authpolicy::JoinDomainRequest request;
    request.set_machine_name(machine_name);
    request.set_user_principal_name(username);
    request.set_machine_domain(machine_domain);
    authpolicy_client()->JoinAdDomain(request, /* password_fd */ -1,
                                      std::move(callback));
  }

  void AuthenticateUser(const std::string& username,
                        const std::string& account_id,
                        AuthPolicyClient::AuthCallback callback) {
    authpolicy::AuthenticateUserRequest request;
    request.set_user_principal_name(username);
    request.set_account_id(account_id);
    authpolicy_client()->AuthenticateUser(request, /* password_fd */ -1,
                                          std::move(callback));
  }

  void WaitForServiceToBeAvailable() {
    authpolicy_client()->WaitForServiceToBeAvailable(base::BindOnce(
        &FakeAuthPolicyClientTest::OnWaitForServiceToBeAvailableCalled,
        base::Unretained(this)));
  }

  void OnWaitForServiceToBeAvailableCalled(bool is_service_available) {
    EXPECT_TRUE(is_service_available);
    service_is_available_called_num_++;
  }

  void LockDevice() {
    install_attributes_.Get()->SetActiveDirectoryManaged("example.com",
                                                         "device_id");
  }

  int service_is_available_called_num_ = 0;

 private:
  ScopedStubInstallAttributes install_attributes_;
  base::MessageLoop loop_;

  DISALLOW_COPY_AND_ASSIGN(FakeAuthPolicyClientTest);
};

// Tests parsing machine name.
TEST_F(FakeAuthPolicyClientTest, JoinAdDomain_ParseMachineName) {
  authpolicy_client()->SetStarted(true);
  JoinAdDomain("correct_length1", kCorrectUserName,
               base::BindOnce(
                   [](authpolicy::ErrorType error, const std::string& domain) {
                     EXPECT_EQ(authpolicy::ERROR_NONE, error);
                     EXPECT_EQ(kCorrectUserDomain, domain);
                   }));
  JoinAdDomain("", kCorrectUserName,
               base::BindOnce(
                   [](authpolicy::ErrorType error, const std::string& domain) {
                     EXPECT_EQ(authpolicy::ERROR_INVALID_MACHINE_NAME, error);
                     EXPECT_TRUE(domain.empty());
                   }));
  JoinAdDomain("too_long_machine_name", kCorrectUserName,
               base::BindOnce(
                   [](authpolicy::ErrorType error, const std::string& domain) {
                     EXPECT_EQ(authpolicy::ERROR_MACHINE_NAME_TOO_LONG, error);
                     EXPECT_TRUE(domain.empty());
                   }));
  JoinAdDomain("invalid:name", kCorrectUserName,
               base::BindOnce(
                   [](authpolicy::ErrorType error, const std::string& domain) {
                     EXPECT_EQ(authpolicy::ERROR_INVALID_MACHINE_NAME, error);
                     EXPECT_TRUE(domain.empty());
                   }));
  base::RunLoop loop;
  JoinAdDomain(">nvalidname", kCorrectUserName,
               base::BindOnce(
                   [](base::OnceClosure closure, authpolicy::ErrorType error,
                      const std::string& domain) {
                     EXPECT_EQ(authpolicy::ERROR_INVALID_MACHINE_NAME, error);
                     EXPECT_TRUE(domain.empty());
                     std::move(closure).Run();
                   },
                   loop.QuitClosure()));
  loop.Run();
}

// Tests join to a different machine domain.
TEST_F(FakeAuthPolicyClientTest, JoinAdDomain_MachineDomain) {
  authpolicy_client()->SetStarted(true);
  JoinAdDomainWithMachineDomain(kCorrectMachineName, kMachineDomain,
                                kCorrectUserName,
                                base::BindOnce([](authpolicy::ErrorType error,
                                                  const std::string& domain) {
                                  EXPECT_EQ(authpolicy::ERROR_NONE, error);
                                  EXPECT_EQ(kMachineDomain, domain);
                                }));
  base::RunLoop loop;
  JoinAdDomainWithMachineDomain(
      kCorrectMachineName, "", kCorrectUserName,
      base::BindOnce(
          [](base::OnceClosure closure, authpolicy::ErrorType error,
             const std::string& domain) {
            EXPECT_EQ(authpolicy::ERROR_NONE, error);
            EXPECT_EQ(kCorrectUserDomain, domain);
            std::move(closure).Run();
          },
          loop.QuitClosure()));
  loop.Run();
}

// Tests parsing user name.
TEST_F(FakeAuthPolicyClientTest, JoinAdDomain_ParseUPN) {
  authpolicy_client()->SetStarted(true);
  JoinAdDomain(kCorrectMachineName, kCorrectUserName,
               base::BindOnce(
                   [](authpolicy::ErrorType error, const std::string& domain) {
                     EXPECT_EQ(authpolicy::ERROR_NONE, error);
                     EXPECT_EQ(kCorrectUserDomain, domain);
                   }));
  JoinAdDomain(kCorrectMachineName, "user",
               base::BindOnce(
                   [](authpolicy::ErrorType error, const std::string& domain) {
                     EXPECT_EQ(authpolicy::ERROR_PARSE_UPN_FAILED, error);
                     EXPECT_TRUE(domain.empty());
                   }));
  JoinAdDomain(kCorrectMachineName, "",
               base::BindOnce(
                   [](authpolicy::ErrorType error, const std::string& domain) {
                     EXPECT_EQ(authpolicy::ERROR_PARSE_UPN_FAILED, error);
                     EXPECT_TRUE(domain.empty());
                   }));
  JoinAdDomain(kCorrectMachineName, "user@",
               base::BindOnce(
                   [](authpolicy::ErrorType error, const std::string& domain) {
                     EXPECT_EQ(authpolicy::ERROR_PARSE_UPN_FAILED, error);
                     EXPECT_TRUE(domain.empty());
                   }));
  JoinAdDomain(kCorrectMachineName, "@realm",
               base::BindOnce(
                   [](authpolicy::ErrorType error, const std::string& domain) {
                     EXPECT_EQ(authpolicy::ERROR_PARSE_UPN_FAILED, error);
                     EXPECT_TRUE(domain.empty());
                   }));
  base::RunLoop loop;
  JoinAdDomain(kCorrectMachineName, "user@realm@com",
               base::BindOnce(
                   [](base::OnceClosure closure, authpolicy::ErrorType error,
                      const std::string& domain) {
                     EXPECT_EQ(authpolicy::ERROR_PARSE_UPN_FAILED, error);
                     EXPECT_TRUE(domain.empty());
                     std::move(closure).Run();
                   },
                   loop.QuitClosure()));
  loop.Run();
}

// Tests that fake server does not support legacy encryption types.
TEST_F(FakeAuthPolicyClientTest, JoinAdDomain_NotSupportedEncType) {
  authpolicy_client()->SetStarted(true);
  base::RunLoop loop;
  authpolicy::JoinDomainRequest request;
  request.set_machine_name(kCorrectMachineName);
  request.set_user_principal_name(kCorrectUserName);
  request.set_kerberos_encryption_types(
      authpolicy::KerberosEncryptionTypes::ENC_TYPES_LEGACY);
  authpolicy_client()->JoinAdDomain(
      request, /* password_fd */ -1,
      base::BindOnce(
          [](base::OnceClosure closure, authpolicy::ErrorType error,
             const std::string& domain) {
            EXPECT_EQ(authpolicy::ERROR_KDC_DOES_NOT_SUPPORT_ENCRYPTION_TYPE,
                      error);
            EXPECT_TRUE(domain.empty());
            std::move(closure).Run();
          },
          loop.QuitClosure()));
  loop.Run();
}

// Test AuthenticateUser.
TEST_F(FakeAuthPolicyClientTest, AuthenticateUser_ByAccountId) {
  authpolicy_client()->SetStarted(true);
  LockDevice();
  // Check that account_id do not change.
  AuthenticateUser(
      kCorrectUserName, kAccountId,
      base::BindOnce(
          [](authpolicy::ErrorType error,
             const authpolicy::ActiveDirectoryAccountInfo& account_info) {
            EXPECT_EQ(authpolicy::ERROR_NONE, error);
            EXPECT_EQ(kAccountId, account_info.account_id());
          }));
}

// Tests calls to not started authpolicyd fails.
TEST_F(FakeAuthPolicyClientTest, NotStartedAuthPolicyService) {
  JoinAdDomain(kCorrectMachineName, kCorrectUserName,
               base::BindOnce(
                   [](authpolicy::ErrorType error, const std::string& domain) {
                     EXPECT_EQ(authpolicy::ERROR_DBUS_FAILURE, error);
                     EXPECT_TRUE(domain.empty());
                   }));
  LockDevice();
  AuthenticateUser(
      kCorrectUserName, std::string() /* account_id */,
      base::BindOnce([](authpolicy::ErrorType error,
                        const authpolicy::ActiveDirectoryAccountInfo&) {
        EXPECT_EQ(authpolicy::ERROR_DBUS_FAILURE, error);
      }));
  authpolicy_client()->RefreshDevicePolicy(
      base::BindOnce([](authpolicy::ErrorType error) {
        EXPECT_EQ(authpolicy::ERROR_DBUS_FAILURE, error);
      }));
  base::RunLoop loop;
  authpolicy_client()->RefreshUserPolicy(
      AccountId::FromUserEmail(kCorrectUserName),
      base::BindOnce(
          [](base::OnceClosure closure, authpolicy::ErrorType error) {
            EXPECT_EQ(authpolicy::ERROR_DBUS_FAILURE, error);
            std::move(closure).Run();
          },
          loop.QuitClosure()));
  loop.Run();
}

// Tests RefreshDevicePolicy. On a not locked device it should cache policy. On
// a locked device it should send policy to session_manager.
TEST_F(FakeAuthPolicyClientTest, NotLockedDeviceCachesPolicy) {
  authpolicy_client()->SetStarted(true);
  authpolicy_client()->RefreshDevicePolicy(
      base::BindOnce([](authpolicy::ErrorType error) {
        EXPECT_EQ(authpolicy::ERROR_DEVICE_POLICY_CACHED_BUT_NOT_SENT, error);
      }));
  LockDevice();
  base::RunLoop loop;
  authpolicy_client()->RefreshDevicePolicy(base::BindOnce(
      [](base::OnceClosure closure, authpolicy::ErrorType error) {
        EXPECT_EQ(authpolicy::ERROR_NONE, error);
        std::move(closure).Run();
      },
      loop.QuitClosure()));
  loop.Run();
}

// Tests that RefreshDevicePolicy stores device policy in the session manager.
TEST_F(FakeAuthPolicyClientTest, RefreshDevicePolicyStoresPolicy) {
  authpolicy_client()->SetStarted(true);
  LockDevice();

  {
    // Call RefreshDevicePolicy.
    base::RunLoop loop;
    em::ChromeDeviceSettingsProto policy;
    policy.mutable_allow_new_users()->set_allow_new_users(true);
    authpolicy_client()->set_device_policy(policy);
    authpolicy_client()->RefreshDevicePolicy(base::BindOnce(
        [](base::OnceClosure closure, authpolicy::ErrorType error) {
          EXPECT_EQ(authpolicy::ERROR_NONE, error);
          std::move(closure).Run();
        },
        loop.QuitClosure()));
    loop.Run();
  }

  {
    // Retrieve device policy from the session manager.
    std::string response_blob;
    EXPECT_EQ(SessionManagerClient::RetrievePolicyResponseType::SUCCESS,
              SessionManagerClient::Get()->BlockingRetrieveDevicePolicy(
                  &response_blob));
    em::PolicyFetchResponse response;
    EXPECT_TRUE(response.ParseFromString(response_blob));
    EXPECT_TRUE(response.has_policy_data());

    em::PolicyData policy_data;
    EXPECT_TRUE(policy_data.ParseFromString(response.policy_data()));

    em::ChromeDeviceSettingsProto policy;
    EXPECT_TRUE(policy.ParseFromString(policy_data.policy_value()));
    EXPECT_TRUE(policy.has_allow_new_users());
    EXPECT_TRUE(policy.allow_new_users().allow_new_users());
  }
}

TEST_F(FakeAuthPolicyClientTest, WaitForServiceToBeAvailableCalled) {
  WaitForServiceToBeAvailable();
  WaitForServiceToBeAvailable();
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(0, service_is_available_called_num_);
  authpolicy_client()->SetStarted(true);
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(2, service_is_available_called_num_);
  WaitForServiceToBeAvailable();
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(3, service_is_available_called_num_);
}

}  // namespace chromeos
