// Copyright 2016 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 "remoting/host/security_key/security_key_auth_handler.h"

#include <cstdint>
#include <memory>
#include <string>

#include "base/bind.h"
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "ipc/ipc_channel.h"
#include "ipc/ipc_listener.h"
#include "ipc/ipc_message.h"
#include "ipc/ipc_message_macros.h"
#include "remoting/host/host_mock_objects.h"
#include "remoting/host/security_key/fake_security_key_ipc_client.h"
#include "remoting/host/security_key/fake_security_key_ipc_server.h"
#include "remoting/host/security_key/security_key_ipc_constants.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace {
const int kConnectionId1 = 1;
const int kConnectionId2 = 2;
}  // namespace

namespace remoting {

class SecurityKeyAuthHandlerWinTest : public testing::Test {
 public:
  SecurityKeyAuthHandlerWinTest();
  ~SecurityKeyAuthHandlerWinTest() override;

  // Passed to the object used for testing to be called back to signal
  // completion of an IPC channel state change or reception of an IPC message.
  void OperationComplete();

 protected:
  // Waits until the current |run_loop_| instance is signaled, then resets it.
  void WaitForOperationComplete();

  // Used as a callback given to the object under test, expected to be called
  // back when a security key request is received by it.
  void SendMessageToClient(int connection_id, const std::string& data);

  // Creates a new security key connection on the object under test.
  void CreateSecurityKeyConnection(
      const mojo::NamedPlatformChannel::ServerName& server_name);

  // Uses |fake_ipc_client| to connect to the IPC server channel, it then
  // validates internal state of the object under test and closes the connection
  // based on |close_connection|.
  void EstablishIpcConnection(
      FakeSecurityKeyIpcClient* fake_ipc_client,
      int expected_connection_id,
      const mojo::NamedPlatformChannel::ServerName& server_name,
      bool close_connection);

  // Sends a security key response message using |fake_ipc_server| and
  // validates the state of the object under test.
  void SendRequestToSecurityKeyAuthHandler(
      const base::WeakPtr<FakeSecurityKeyIpcServer>& fake_ipc_server,
      int connection_id,
      const std::string& request_payload);

  // Sends a security key response message to |fake_ipc_server| and validates
  // the state of the object under test.
  void SendResponseViaSecurityKeyAuthHandler(
      const base::WeakPtr<FakeSecurityKeyIpcServer>& fake_ipc_server,
      int connection_id,
      const std::string& response_payload);

  // Closes a security key session IPC channel and validates state.
  void CloseSecurityKeySessionIpcChannel(
      const base::WeakPtr<FakeSecurityKeyIpcServer>& fake_ipc_server,
      int connection_id);

  // Returns a unique IPC channel handle which prevents conflicts when running
  // tests concurrently.
  mojo::NamedPlatformChannel::ServerName GetUniqueTestChannelHandle();

  // IPC tests require a valid MessageLoop to run.
  base::MessageLoopForIO message_loop_;

  // Used to allow |message_loop_| to run during tests.  The instance is reset
  // after each stage of the tests has been completed.
  std::unique_ptr<base::RunLoop> run_loop_;

  // The object under test.
  std::unique_ptr<SecurityKeyAuthHandler> auth_handler_;

  // Set as the default factory to create SecurityKeyIpcServerFactory
  // instances, this class will track each objects creation and allow the tests
  // to access it and use it for driving tests and validating state.
  FakeSecurityKeyIpcServerFactory ipc_server_factory_;

  // Used to validate the object under test uses the correct ID when
  // communicating over the IPC channel.
  int last_connection_id_received_ = -1;

  // Stores the contents of the last IPC message received for validation.
  std::string last_message_received_;

 private:
  testing::NiceMock<MockClientSessionDetails> mock_client_session_details_;

  DISALLOW_COPY_AND_ASSIGN(SecurityKeyAuthHandlerWinTest);
};

SecurityKeyAuthHandlerWinTest::SecurityKeyAuthHandlerWinTest()
    : run_loop_(new base::RunLoop()) {
  auth_handler_ = remoting::SecurityKeyAuthHandler::Create(
      &mock_client_session_details_,
      base::Bind(&SecurityKeyAuthHandlerWinTest::SendMessageToClient,
                 base::Unretained(this)),
      /*file_task_runner=*/nullptr);
}

SecurityKeyAuthHandlerWinTest::~SecurityKeyAuthHandlerWinTest() {}

void SecurityKeyAuthHandlerWinTest::OperationComplete() {
  run_loop_->Quit();
}

void SecurityKeyAuthHandlerWinTest::WaitForOperationComplete() {
  run_loop_->Run();
  run_loop_.reset(new base::RunLoop());
}

void SecurityKeyAuthHandlerWinTest::SendMessageToClient(
    int connection_id,
    const std::string& data) {
  last_connection_id_received_ = connection_id;
  last_message_received_ = data;
  OperationComplete();
}

void SecurityKeyAuthHandlerWinTest::CreateSecurityKeyConnection(
    const mojo::NamedPlatformChannel::ServerName& server_name) {
  ASSERT_EQ(0u, auth_handler_->GetActiveConnectionCountForTest());

  remoting::SetSecurityKeyIpcChannelForTest(server_name);

  // Create a new SecurityKey IPC Server connection.
  auth_handler_->CreateSecurityKeyConnection();
}

void SecurityKeyAuthHandlerWinTest::EstablishIpcConnection(
    FakeSecurityKeyIpcClient* fake_ipc_client,
    int expected_connection_id,
    const mojo::NamedPlatformChannel::ServerName& server_name,
    bool close_connection) {
  size_t expected_connection_count =
      auth_handler_->GetActiveConnectionCountForTest() + 1;

  ASSERT_FALSE(auth_handler_->IsValidConnectionId(expected_connection_id));
  fake_ipc_client->set_on_channel_connected_callback(
      base::Bind(&SecurityKeyAuthHandlerWinTest::OperationComplete,
                 base::Unretained(this)));
  ASSERT_TRUE(fake_ipc_client->ConnectViaIpc(server_name));
  WaitForOperationComplete();

  // Retrieve the IPC server instance created when the client connected.
  base::WeakPtr<FakeSecurityKeyIpcServer> fake_ipc_server =
      ipc_server_factory_.GetIpcServerObject(expected_connection_id);
  ASSERT_TRUE(fake_ipc_server.get());
  fake_ipc_server->SendConnectionReadyMessage();
  WaitForOperationComplete();

  // Verify the internal state of the SecurityKeyAuthHandler is correct.
  ASSERT_TRUE(auth_handler_->IsValidConnectionId(expected_connection_id));
  ASSERT_EQ(expected_connection_count,
            auth_handler_->GetActiveConnectionCountForTest());

  if (close_connection) {
    fake_ipc_client->CloseIpcConnection();
    WaitForOperationComplete();
  }
}

void SecurityKeyAuthHandlerWinTest::SendRequestToSecurityKeyAuthHandler(
    const base::WeakPtr<FakeSecurityKeyIpcServer>& fake_ipc_server,
    int connection_id,
    const std::string& request_payload) {
  size_t expected_connection_count =
      auth_handler_->GetActiveConnectionCountForTest();
  // Send a security key request using the fake IPC server.
  fake_ipc_server->SendRequest(request_payload);
  WaitForOperationComplete();

  // Verify the FakeSecurityKeyIpcServer instance was not destroyed.
  ASSERT_TRUE(fake_ipc_server.get());

  // Verify the request was received.
  ASSERT_EQ(connection_id, last_connection_id_received_);
  ASSERT_EQ(request_payload, last_message_received_);

  // Verify the internal state of the SecurityKeyAuthHandler is still correct.
  ASSERT_TRUE(auth_handler_->IsValidConnectionId(connection_id));
  ASSERT_EQ(expected_connection_count,
            auth_handler_->GetActiveConnectionCountForTest());
}

void SecurityKeyAuthHandlerWinTest::SendResponseViaSecurityKeyAuthHandler(
    const base::WeakPtr<FakeSecurityKeyIpcServer>& fake_ipc_server,
    int connection_id,
    const std::string& response_payload) {
  size_t expected_connection_count =
      auth_handler_->GetActiveConnectionCountForTest();

  // Send a security key response using the new IPC channel.
  auth_handler_->SendClientResponse(connection_id, response_payload);
  WaitForOperationComplete();

  // Verify the security key response was received.
  ASSERT_EQ(response_payload, fake_ipc_server->last_message_received());

  // Verify the internal state of the SecurityKeyAuthHandler is still correct.
  ASSERT_TRUE(auth_handler_->IsValidConnectionId(connection_id));
  ASSERT_EQ(expected_connection_count,
            auth_handler_->GetActiveConnectionCountForTest());
}

void SecurityKeyAuthHandlerWinTest::CloseSecurityKeySessionIpcChannel(
    const base::WeakPtr<FakeSecurityKeyIpcServer>& fake_ipc_server,
    int connection_id) {
  size_t expected_connection_count =
      auth_handler_->GetActiveConnectionCountForTest() - 1;

  fake_ipc_server->CloseChannel();

  // Verify the internal state has been updated.
  ASSERT_FALSE(auth_handler_->IsValidConnectionId(connection_id));
  ASSERT_EQ(expected_connection_count,
            auth_handler_->GetActiveConnectionCountForTest());

  // Verify the FakeSecurityKeyIpcServer instance was destroyed.
  ASSERT_FALSE(fake_ipc_server.get());
}

mojo::NamedPlatformChannel::ServerName
SecurityKeyAuthHandlerWinTest::GetUniqueTestChannelHandle() {
  std::string channel_name("Uber_Awesome_Super_Mega_Test_Channel.");
  channel_name.append(IPC::Channel::GenerateUniqueRandomChannelID());
  return mojo::NamedPlatformChannel::ServerNameFromUTF8(channel_name);
}

TEST_F(SecurityKeyAuthHandlerWinTest, HandleSingleSecurityKeyRequest) {
  mojo::NamedPlatformChannel::ServerName server_name =
      GetUniqueTestChannelHandle();
  CreateSecurityKeyConnection(server_name);
  ASSERT_FALSE(auth_handler_->IsValidConnectionId(kConnectionId1));

  // Create a fake client and connect to the IPC server channel.
  FakeSecurityKeyIpcClient fake_ipc_client(
      base::Bind(&SecurityKeyAuthHandlerWinTest::OperationComplete,
                 base::Unretained(this)));
  EstablishIpcConnection(&fake_ipc_client, kConnectionId1, server_name,
                         /*close_connection=*/true);

  // Retrieve the IPC server instance created when the client connected.
  base::WeakPtr<FakeSecurityKeyIpcServer> fake_ipc_server =
      ipc_server_factory_.GetIpcServerObject(kConnectionId1);
  ASSERT_TRUE(fake_ipc_server.get());

  fake_ipc_server->set_send_response_callback(
      base::Bind(&SecurityKeyAuthHandlerWinTest::OperationComplete,
                 base::Unretained(this)));

  // Send a security key request using the fake IPC server.
  SendRequestToSecurityKeyAuthHandler(fake_ipc_server, kConnectionId1,
                                      "0123456789");

  // Send a security key response using the new IPC channel.
  SendResponseViaSecurityKeyAuthHandler(fake_ipc_server, kConnectionId1,
                                        "9876543210");

  CloseSecurityKeySessionIpcChannel(fake_ipc_server, kConnectionId1);
}

TEST_F(SecurityKeyAuthHandlerWinTest, HandleConcurrentSecurityKeyRequests) {
  mojo::NamedPlatformChannel::ServerName server_name =
      GetUniqueTestChannelHandle();
  CreateSecurityKeyConnection(server_name);

  // Create fake clients and connect each to the IPC server channel.
  FakeSecurityKeyIpcClient fake_ipc_client_1(
      base::Bind(&SecurityKeyAuthHandlerWinTest::OperationComplete,
                 base::Unretained(this)));
  FakeSecurityKeyIpcClient fake_ipc_client_2(
      base::Bind(&SecurityKeyAuthHandlerWinTest::OperationComplete,
                 base::Unretained(this)));

  EstablishIpcConnection(&fake_ipc_client_1, kConnectionId1, server_name,
                         /*close_connection=*/true);
  EstablishIpcConnection(&fake_ipc_client_2, kConnectionId2, server_name,
                         /*close_connection=*/true);

  base::WeakPtr<FakeSecurityKeyIpcServer> fake_ipc_server_1 =
      ipc_server_factory_.GetIpcServerObject(kConnectionId1);
  ASSERT_TRUE(fake_ipc_server_1.get());

  base::WeakPtr<FakeSecurityKeyIpcServer> fake_ipc_server_2 =
      ipc_server_factory_.GetIpcServerObject(kConnectionId2);
  ASSERT_TRUE(fake_ipc_server_2.get());

  fake_ipc_server_1->set_send_response_callback(
      base::Bind(&SecurityKeyAuthHandlerWinTest::OperationComplete,
                 base::Unretained(this)));
  fake_ipc_server_2->set_send_response_callback(
      base::Bind(&SecurityKeyAuthHandlerWinTest::OperationComplete,
                 base::Unretained(this)));

  // Connect and send a security key request using the first IPC channel.
  SendRequestToSecurityKeyAuthHandler(fake_ipc_server_1, kConnectionId1,
                                      "aaaaaaaaaa");

  // Send a security key request using the second IPC channel.
  SendRequestToSecurityKeyAuthHandler(fake_ipc_server_1, kConnectionId1,
                                      "bbbbbbbbbb");

  // Send a security key response using the first IPC channel.
  SendResponseViaSecurityKeyAuthHandler(fake_ipc_server_2, kConnectionId2,
                                        "cccccccccc");

  // Send a security key response using the second IPC channel.
  SendResponseViaSecurityKeyAuthHandler(fake_ipc_server_2, kConnectionId2,
                                        "dddddddddd");

  // Close the IPC channels.
  CloseSecurityKeySessionIpcChannel(fake_ipc_server_1, kConnectionId1);
  CloseSecurityKeySessionIpcChannel(fake_ipc_server_2, kConnectionId2);
}

TEST_F(SecurityKeyAuthHandlerWinTest, HandleSequentialSecurityKeyRequests) {
  mojo::NamedPlatformChannel::ServerName server_name =
      GetUniqueTestChannelHandle();
  CreateSecurityKeyConnection(server_name);

  // Create fake clients to connect to the IPC server channel.
  FakeSecurityKeyIpcClient fake_ipc_client_1(
      base::Bind(&SecurityKeyAuthHandlerWinTest::OperationComplete,
                 base::Unretained(this)));

  EstablishIpcConnection(&fake_ipc_client_1, kConnectionId1, server_name,
                         /*close_connection=*/true);

  base::WeakPtr<FakeSecurityKeyIpcServer> fake_ipc_server_1 =
      ipc_server_factory_.GetIpcServerObject(kConnectionId1);
  ASSERT_TRUE(fake_ipc_server_1.get());

  fake_ipc_server_1->set_send_response_callback(
      base::Bind(&SecurityKeyAuthHandlerWinTest::OperationComplete,
                 base::Unretained(this)));

  // Send a security key request using the first IPC channel.
  SendRequestToSecurityKeyAuthHandler(fake_ipc_server_1, kConnectionId1,
                                      "aaaaaaaaaa");

  // Send a security key response using the first IPC channel.
  SendResponseViaSecurityKeyAuthHandler(fake_ipc_server_1, kConnectionId1,
                                        "cccccccccc");

  // Close the IPC channel.
  CloseSecurityKeySessionIpcChannel(fake_ipc_server_1, kConnectionId1);

  // Now connect with a second client.
  FakeSecurityKeyIpcClient fake_ipc_client_2(
      base::Bind(&SecurityKeyAuthHandlerWinTest::OperationComplete,
                 base::Unretained(this)));
  EstablishIpcConnection(&fake_ipc_client_2, kConnectionId2, server_name,
                         /*close_connection=*/true);

  base::WeakPtr<FakeSecurityKeyIpcServer> fake_ipc_server_2 =
      ipc_server_factory_.GetIpcServerObject(kConnectionId2);
  ASSERT_TRUE(fake_ipc_server_2.get());

  fake_ipc_server_2->set_send_response_callback(
      base::Bind(&SecurityKeyAuthHandlerWinTest::OperationComplete,
                 base::Unretained(this)));

  // Send a security key request using the second IPC channel.
  SendRequestToSecurityKeyAuthHandler(fake_ipc_server_2, kConnectionId2,
                                      "bbbbbbbbbb");

  // Send a security key response using the second IPC channel.
  SendResponseViaSecurityKeyAuthHandler(fake_ipc_server_2, kConnectionId2,
                                        "dddddddddd");

  // Close the IPC channel.
  CloseSecurityKeySessionIpcChannel(fake_ipc_server_2, kConnectionId2);
}

TEST_F(SecurityKeyAuthHandlerWinTest, HandleSecurityKeyErrorResponse) {
  mojo::NamedPlatformChannel::ServerName server_name =
      GetUniqueTestChannelHandle();
  CreateSecurityKeyConnection(server_name);
  ASSERT_EQ(0u, auth_handler_->GetActiveConnectionCountForTest());

  // Create a fake client and connect to the IPC server channel.
  FakeSecurityKeyIpcClient fake_ipc_client(
      base::Bind(&SecurityKeyAuthHandlerWinTest::OperationComplete,
                 base::Unretained(this)));
  EstablishIpcConnection(&fake_ipc_client, kConnectionId1, server_name,
                         /*close_connection=*/true);

  // Retrieve the IPC server instance created when the client connected.
  base::WeakPtr<FakeSecurityKeyIpcServer> fake_ipc_server =
      ipc_server_factory_.GetIpcServerObject(kConnectionId1);
  ASSERT_TRUE(fake_ipc_server.get());

  fake_ipc_server->set_send_response_callback(
      base::Bind(&SecurityKeyAuthHandlerWinTest::OperationComplete,
                 base::Unretained(this)));

  // Send a security key request using the fake IPC server.
  SendRequestToSecurityKeyAuthHandler(fake_ipc_server, kConnectionId1,
                                      "0123456789");

  // Simulate a security key error from the client.
  auth_handler_->SendErrorAndCloseConnection(kConnectionId1);
  // Wait for the ipc server channel to be torn down.
  WaitForOperationComplete();

  // Verify the connection was cleaned up.
  ASSERT_FALSE(fake_ipc_server.get());
  ASSERT_FALSE(auth_handler_->IsValidConnectionId(kConnectionId1));
  ASSERT_EQ(0u, auth_handler_->GetActiveConnectionCountForTest());

  // Attempt to connect again after the error.
  EstablishIpcConnection(&fake_ipc_client, kConnectionId2, server_name,
                         /*close_connection=*/true);
}

}  // namespace remoting
