// 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 "extensions/renderer/runtime_hooks_delegate.h"

#include <memory>

#include "components/crx_file/id_util.h"
#include "content/public/common/child_process_host.h"
#include "extensions/common/extension.h"
#include "extensions/common/extension_builder.h"
#include "extensions/common/extension_messages.h"
#include "extensions/common/value_builder.h"
#include "extensions/renderer/bindings/api_binding_test_util.h"
#include "extensions/renderer/message_target.h"
#include "extensions/renderer/native_extension_bindings_system.h"
#include "extensions/renderer/native_extension_bindings_system_test_base.h"
#include "extensions/renderer/native_renderer_messaging_service.h"
#include "extensions/renderer/script_context.h"
#include "extensions/renderer/script_context_set.h"
#include "extensions/renderer/send_message_tester.h"

namespace extensions {
namespace {

void CallAPIAndExpectError(v8::Local<v8::Context> context,
                           base::StringPiece method_name,
                           base::StringPiece args) {
  SCOPED_TRACE(base::StringPrintf("Args: `%s`", args.data()));
  constexpr char kTemplate[] = "(function() { chrome.runtime.%s(%s); })";

  v8::Isolate* isolate = context->GetIsolate();

  // Just verify some error was thrown. Expecting the exact error message
  // tends to rely too much on our argument spec code, which is tested
  // separately.
  v8::Local<v8::Function> function = FunctionFromString(
      context, base::StringPrintf(kTemplate, method_name.data(), args.data()));
  v8::TryCatch try_catch(isolate);
  v8::MaybeLocal<v8::Value> result =
      function->Call(context, v8::Undefined(isolate), 0, nullptr);
  EXPECT_TRUE(result.IsEmpty());
  EXPECT_TRUE(try_catch.HasCaught());
}

}  // namespace

class RuntimeHooksDelegateTest : public NativeExtensionBindingsSystemUnittest {
 public:
  RuntimeHooksDelegateTest() {}
  ~RuntimeHooksDelegateTest() override {}

  // NativeExtensionBindingsSystemUnittest:
  void SetUp() override {
    NativeExtensionBindingsSystemUnittest::SetUp();
    messaging_service_ =
        std::make_unique<NativeRendererMessagingService>(bindings_system());

    bindings_system()->api_system()->GetHooksForAPI("runtime")->SetDelegate(
        std::make_unique<RuntimeHooksDelegate>(messaging_service_.get()));

    scoped_refptr<Extension> mutable_extension = BuildExtension();
    RegisterExtension(mutable_extension);
    extension_ = mutable_extension;

    v8::HandleScope handle_scope(isolate());
    v8::Local<v8::Context> context = MainContext();

    script_context_ = CreateScriptContext(context, mutable_extension.get(),
                                          Feature::BLESSED_EXTENSION_CONTEXT);
    script_context_->set_url(extension_->url());
    bindings_system()->UpdateBindingsForContext(script_context_);
  }
  void TearDown() override {
    script_context_ = nullptr;
    extension_ = nullptr;
    messaging_service_.reset();
    NativeExtensionBindingsSystemUnittest::TearDown();
  }
  bool UseStrictIPCMessageSender() override { return true; }

  virtual scoped_refptr<Extension> BuildExtension() {
    return ExtensionBuilder("foo").Build();
  }

  NativeRendererMessagingService* messaging_service() {
    return messaging_service_.get();
  }
  ScriptContext* script_context() { return script_context_; }
  const Extension* extension() { return extension_.get(); }

 private:
  std::unique_ptr<NativeRendererMessagingService> messaging_service_;

  ScriptContext* script_context_ = nullptr;
  scoped_refptr<const Extension> extension_;

  DISALLOW_COPY_AND_ASSIGN(RuntimeHooksDelegateTest);
};

TEST_F(RuntimeHooksDelegateTest, RuntimeId) {
  v8::HandleScope handle_scope(isolate());
  v8::Local<v8::Context> context = MainContext();

  {
    DictionaryBuilder connectable;
    connectable.Set("matches",
                    ListBuilder().Append("*://example.com/*").Build());
    scoped_refptr<Extension> connectable_extension =
        ExtensionBuilder("connectable")
            .MergeManifest(
                DictionaryBuilder()
                    .Set("externally_connectable", connectable.Build())
                    .Build())
            .Build();
    RegisterExtension(connectable_extension);
  }

  auto get_id = [](v8::Local<v8::Context> context) {
    v8::Local<v8::Function> get_id = FunctionFromString(
        context, "(function() { return chrome.runtime.id; })");
    return RunFunction(get_id, context, 0, nullptr);
  };

  {
    v8::Local<v8::Value> id = get_id(context);
    EXPECT_EQ(extension()->id(), gin::V8ToString(id));
  }

  {
    // In order for chrome.runtime to be available to web pages, we need to have
    // an associated connectable extension, so pretend to be example.com.
    v8::Local<v8::Context> web_context = AddContext();
    ScriptContext* script_context =
        CreateScriptContext(web_context, nullptr, Feature::WEB_PAGE_CONTEXT);
    script_context->set_url(GURL("http://example.com"));
    bindings_system()->UpdateBindingsForContext(script_context);
    v8::Local<v8::Value> id = get_id(web_context);
    EXPECT_TRUE(id->IsUndefined());
  }
}

TEST_F(RuntimeHooksDelegateTest, GetManifest) {
  v8::HandleScope handle_scope(isolate());
  v8::Local<v8::Context> context = MainContext();

  v8::Local<v8::Function> get_manifest = FunctionFromString(
      context, "(function() { return chrome.runtime.getManifest(); })");
  v8::Local<v8::Value> manifest =
      RunFunction(get_manifest, context, 0, nullptr);
  ASSERT_FALSE(manifest.IsEmpty());
  ASSERT_TRUE(manifest->IsObject());
  EXPECT_EQ(ValueToString(*extension()->manifest()->value()),
            V8ToString(manifest, context));
}

TEST_F(RuntimeHooksDelegateTest, GetURL) {
  v8::HandleScope handle_scope(isolate());
  v8::Local<v8::Context> context = MainContext();

  auto get_url = [this, context](const char* args, const GURL& expected_url) {
    SCOPED_TRACE(base::StringPrintf("Args: `%s`", args));
    constexpr char kGetUrlTemplate[] =
        "(function() { return chrome.runtime.getURL(%s); })";
    v8::Local<v8::Function> get_url =
        FunctionFromString(context, base::StringPrintf(kGetUrlTemplate, args));
    v8::Local<v8::Value> url = RunFunction(get_url, context, 0, nullptr);
    ASSERT_FALSE(url.IsEmpty());
    ASSERT_TRUE(url->IsString());
    EXPECT_EQ(expected_url.spec(), gin::V8ToString(url));
  };

  get_url("''", extension()->url());
  get_url("'foo'", extension()->GetResourceURL("foo"));
  get_url("'/foo'", extension()->GetResourceURL("foo"));
}

TEST_F(RuntimeHooksDelegateTest, Connect) {
  v8::HandleScope handle_scope(isolate());
  v8::Local<v8::Context> context = MainContext();

  {
    // Sanity check: connectNative is unavailable (missing permission).
    v8::Local<v8::Value> connect_native =
        V8ValueFromScriptSource(context, "chrome.runtime.connectNative");
    ASSERT_FALSE(connect_native.IsEmpty());
    EXPECT_TRUE(connect_native->IsUndefined());
  }

  SendMessageTester tester(ipc_message_sender(), script_context(), 0,
                           "runtime");
  MessageTarget self_target = MessageTarget::ForExtension(extension()->id());
  tester.TestConnect("", "", self_target, false);
  tester.TestConnect("{name: 'channel'}", "channel", self_target, false);
  tester.TestConnect("{includeTlsChannelId: true}", "", self_target, true);
  tester.TestConnect("{includeTlsChannelId: true, name: 'channel'}", "channel",
                     self_target, true);

  std::string other_id = crx_file::id_util::GenerateId("other");
  MessageTarget other_target = MessageTarget::ForExtension(other_id);
  tester.TestConnect(base::StringPrintf("'%s'", other_id.c_str()), "",
                     other_target, false);
  tester.TestConnect(
      base::StringPrintf("'%s', {name: 'channel'}", other_id.c_str()),
      "channel", other_target, false);
}

// Tests the end-to-end (renderer) flow for a call to runtime.sendMessage
// from the call in JS to the expected IPCs. The intricacies of sendMessage
// are also tested more in the renderer messaging service unittests.
TEST_F(RuntimeHooksDelegateTest, SendMessage) {
  v8::HandleScope handle_scope(isolate());
  v8::Local<v8::Context> context = MainContext();

  {
    // Sanity check: sendNativeMessage is unavailable (missing permission).
    v8::Local<v8::Value> send_native_message =
        V8ValueFromScriptSource(context, "chrome.runtime.sendNativeMessage");
    ASSERT_FALSE(send_native_message.IsEmpty());
    EXPECT_TRUE(send_native_message->IsUndefined());
  }

  SendMessageTester tester(ipc_message_sender(), script_context(), 0,
                           "runtime");

  MessageTarget self_target = MessageTarget::ForExtension(extension()->id());
  tester.TestSendMessage("''", R"("")", self_target, false,
                         SendMessageTester::CLOSED);

  constexpr char kStandardMessage[] = R"({"data":"hello"})";
  tester.TestSendMessage("{data: 'hello'}", kStandardMessage, self_target,
                         false, SendMessageTester::CLOSED);
  tester.TestSendMessage("{data: 'hello'}, function() {}", kStandardMessage,
                         self_target, false, SendMessageTester::OPEN);
  tester.TestSendMessage("{data: 'hello'}, {includeTlsChannelId: true}",
                         kStandardMessage, self_target, true,
                         SendMessageTester::CLOSED);
  tester.TestSendMessage(
      "{data: 'hello'}, {includeTlsChannelId: true}, function() {}",
      kStandardMessage, self_target, true, SendMessageTester::OPEN);

  std::string other_id_str = crx_file::id_util::GenerateId("other");
  const char* other_id = other_id_str.c_str();  // For easy StringPrintf()ing.
  MessageTarget other_target = MessageTarget::ForExtension(other_id_str);

  tester.TestSendMessage(base::StringPrintf("'%s', {data: 'hello'}", other_id),
                         kStandardMessage, other_target, false,
                         SendMessageTester::CLOSED);
  tester.TestSendMessage(
      base::StringPrintf("'%s', {data: 'hello'}, function() {}", other_id),
      kStandardMessage, other_target, false, SendMessageTester::OPEN);
  tester.TestSendMessage(base::StringPrintf("'%s', 'string message'", other_id),
                         R"("string message")", other_target, false,
                         SendMessageTester::CLOSED);

  // Funny case. The only required argument is `message`, which can be any type.
  // This means that if an extension provides a <string, object> pair for the
  // first three arguments, it could apply to either the target id and the
  // message or to the message and the connect options.
  // In this case, we *always* pick the arguments as target id and message,
  // because they were the first options (connectOptions was added later), and
  // because connectOptions is pretty rarely used.
  // TODO(devlin): This is the determination JS has always made, but we could be
  // a bit more intelligent about it. We could examine the string to see if it's
  // a valid extension id as well as looking at the properties on the object.
  // But probably not worth it at this time.
  tester.TestSendMessage(
      base::StringPrintf("'%s', {includeTlsChannelId: true}", other_id),
      R"({"includeTlsChannelId":true})", other_target, false,
      SendMessageTester::CLOSED);
  tester.TestSendMessage(
      base::StringPrintf("'%s', {includeTlsChannelId: true}, function() {}",
                         other_id),
      R"({"includeTlsChannelId":true})", other_target, false,
      SendMessageTester::OPEN);
}

// Test that some incorrect invocations of sendMessage() throw errors.
TEST_F(RuntimeHooksDelegateTest, SendMessageErrors) {
  v8::HandleScope handle_scope(isolate());
  v8::Local<v8::Context> context = MainContext();

  auto send_message = [context](base::StringPiece args) {
    CallAPIAndExpectError(context, "sendMessage", args);
  };

  send_message("{data: 'hi'}, {unknownProp: true}");
  send_message("'some id', 'some message', 'some other string'");
  send_message("'some id', 'some message', {}, {}");
}

TEST_F(RuntimeHooksDelegateTest, SendMessageWithTrickyOptions) {
  v8::HandleScope handle_scope(isolate());
  v8::Local<v8::Context> context = MainContext();

  SendMessageTester tester(ipc_message_sender(), script_context(), 0,
                           "runtime");

  MessageTarget self_target = MessageTarget::ForExtension(extension()->id());
  constexpr char kStandardMessage[] = R"({"data":"hello"})";
  {
    // Even though we parse the message options separately, we do a conversion
    // of the object passed into the API. This means that something subtle like
    // this, which throws on the second access of a property, shouldn't trip us
    // up.
    constexpr char kTrickyConnectOptions[] =
        R"({data: 'hello'},
           {
             get includeTlsChannelId() {
               if (this.checkedOnce)
                 throw new Error('tricked!');
               this.checkedOnce = true;
               return true;
             }
           })";
    tester.TestSendMessage(kTrickyConnectOptions, kStandardMessage, self_target,
                           true, SendMessageTester::CLOSED);
  }
  {
    // A different form of trickiness: the options object doesn't have the
    // includeTlsChannelId key (which is acceptable, since its optional), but
    // any attempt to access the key on an object without a value for it results
    // in an error. Our argument parsing code should protect us from this.
    constexpr const char kMessWithObjectPrototype[] =
        R"((function() {
             Object.defineProperty(
                 Object.prototype, 'includeTlsChannelId',
                 { get() { throw new Error('tricked!'); } });
           }))";
    v8::Local<v8::Function> mess_with_proto =
        FunctionFromString(context, kMessWithObjectPrototype);
    RunFunction(mess_with_proto, context, 0, nullptr);
    tester.TestSendMessage("{data: 'hello'}, {}", kStandardMessage, self_target,
                           false, SendMessageTester::CLOSED);
  }
}

class RuntimeHooksDelegateNativeMessagingTest
    : public RuntimeHooksDelegateTest {
 public:
  RuntimeHooksDelegateNativeMessagingTest() {}
  ~RuntimeHooksDelegateNativeMessagingTest() override {}

  scoped_refptr<Extension> BuildExtension() override {
    return ExtensionBuilder("foo").AddPermission("nativeMessaging").Build();
  }
};

TEST_F(RuntimeHooksDelegateNativeMessagingTest, ConnectNative) {
  v8::HandleScope handle_scope(isolate());
  v8::Local<v8::Context> context = MainContext();

  int next_context_port_id = 0;
  auto run_connect_native = [this, context, &next_context_port_id](
                                const std::string& args,
                                const std::string& expected_app_name) {
    // connectNative() doesn't name channels or ever include the TLS channel ID.
    const std::string kEmptyExpectedChannel;
    const bool kExpectedIncludeTlsChannelId = false;

    SCOPED_TRACE(base::StringPrintf("Args: '%s'", args.c_str()));
    constexpr char kAddPortTemplate[] =
        "(function() { return chrome.runtime.connectNative(%s); })";
    PortId expected_port_id(script_context()->context_id(),
                            next_context_port_id++, true);
    MessageTarget expected_target(
        MessageTarget::ForNativeApp(expected_app_name));
    EXPECT_CALL(*ipc_message_sender(),
                SendOpenMessageChannel(script_context(), expected_port_id,
                                       expected_target, kEmptyExpectedChannel,
                                       kExpectedIncludeTlsChannelId));

    v8::Local<v8::Function> add_port = FunctionFromString(
        context, base::StringPrintf(kAddPortTemplate, args.c_str()));
    v8::Local<v8::Value> port = RunFunction(add_port, context, 0, nullptr);
    ::testing::Mock::VerifyAndClearExpectations(ipc_message_sender());
    ASSERT_FALSE(port.IsEmpty());
    ASSERT_TRUE(port->IsObject());
  };

  run_connect_native("'native_app'", "native_app");
  run_connect_native("'some_other_native_app'", "some_other_native_app");

  auto connect_native_error = [context](base::StringPiece args) {
    CallAPIAndExpectError(context, "connectNative", args);
  };
  connect_native_error("'native_app', {name: 'name'}");
}

TEST_F(RuntimeHooksDelegateNativeMessagingTest, SendNativeMessage) {
  v8::HandleScope handle_scope(isolate());
  v8::Local<v8::Context> context = MainContext();

  // Whether we expect the port to be open or closed at the end of the call.
  enum PortStatus {
    CLOSED,
    OPEN,
  };

  int next_context_port_id = 0;
  auto send_native_message = [this, context, &next_context_port_id](
                                 const char* args,
                                 const std::string& expected_message,
                                 const std::string& expected_application_name,
                                 PortStatus expected_port_status) {
    // sendNativeMessage() doesn't name channels or ever include the TLS channel
    // ID.
    const std::string kEmptyExpectedChannel;
    const bool kExpectedIncludeTlsChannelId = false;

    SCOPED_TRACE(base::StringPrintf("Args: '%s'", args));
    constexpr char kSendMessageTemplate[] =
        "(function() { chrome.runtime.sendNativeMessage(%s); })";

    PortId expected_port_id(script_context()->context_id(),
                            next_context_port_id++, true);
    MessageTarget expected_target(
        MessageTarget::ForNativeApp(expected_application_name));
    EXPECT_CALL(*ipc_message_sender(),
                SendOpenMessageChannel(script_context(), expected_port_id,
                                       expected_target, kEmptyExpectedChannel,
                                       kExpectedIncludeTlsChannelId));
    Message message(expected_message, false);
    EXPECT_CALL(
        *ipc_message_sender(),
        SendPostMessageToPort(MSG_ROUTING_NONE, expected_port_id, message));
    if (expected_port_status == CLOSED) {
      EXPECT_CALL(
          *ipc_message_sender(),
          SendCloseMessagePort(MSG_ROUTING_NONE, expected_port_id, true));
    }
    v8::Local<v8::Function> send_message = FunctionFromString(
        context, base::StringPrintf(kSendMessageTemplate, args));
    RunFunction(send_message, context, 0, nullptr);
    ::testing::Mock::VerifyAndClearExpectations(ipc_message_sender());
  };

  send_native_message("'native_app', {hi:'bye'}", R"({"hi":"bye"})",
                      "native_app", CLOSED);
  send_native_message("'another_native_app', {alpha: 2}, function() {}",
                      R"({"alpha":2})", "another_native_app", OPEN);

  auto send_native_message_error = [context](base::StringPiece args) {
    CallAPIAndExpectError(context, "sendNativeMessage", args);
  };

  send_native_message_error("{data: 'hi'}, function() {}");
  send_native_message_error(
      "'native_app', 'some message', {includeTlsChannelId: true}");
}

}  // namespace extensions
