// Copyright (c) 2012 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/extensions/api/declarative_webrequest/webrequest_action.h"

#include "base/files/file_path.h"
#include "base/json/json_file_value_serializer.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/message_loop/message_loop.h"
#include "base/path_service.h"
#include "base/test/values_test_util.h"
#include "base/time/time.h"
#include "base/values.h"
#include "chrome/browser/extensions/api/declarative_webrequest/request_stage.h"
#include "chrome/browser/extensions/api/declarative_webrequest/webrequest_condition.h"
#include "chrome/browser/extensions/api/declarative_webrequest/webrequest_constants.h"
#include "chrome/browser/extensions/api/web_request/web_request_api_helpers.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/extensions/extension_constants.h"
#include "chrome/common/extensions/extension_test_util.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "extensions/browser/info_map.h"
#include "extensions/common/extension.h"
#include "net/base/request_priority.h"
#include "net/http/http_response_headers.h"
#include "net/url_request/url_request_test_util.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

using base::DictionaryValue;
using base::ListValue;
using extension_test_util::LoadManifestUnchecked;
using testing::HasSubstr;

namespace extensions {

namespace {

const char kUnknownActionType[] = "unknownType";

scoped_ptr<WebRequestActionSet> CreateSetOfActions(const char* json) {
  scoped_ptr<Value> parsed_value(base::test::ParseJson(json));
  const ListValue* parsed_list;
  CHECK(parsed_value->GetAsList(&parsed_list));

  WebRequestActionSet::AnyVector actions;
  for (ListValue::const_iterator it = parsed_list->begin();
       it != parsed_list->end();
       ++it) {
    const DictionaryValue* dict;
    CHECK((*it)->GetAsDictionary(&dict));
    actions.push_back(linked_ptr<base::Value>(dict->DeepCopy()));
  }

  std::string error;
  bool bad_message = false;

  scoped_ptr<WebRequestActionSet> action_set(
      WebRequestActionSet::Create(NULL, actions, &error, &bad_message));
  EXPECT_EQ("", error);
  EXPECT_FALSE(bad_message);
  CHECK(action_set);
  return action_set.Pass();
}

}  // namespace

namespace keys = declarative_webrequest_constants;

class WebRequestActionWithThreadsTest : public testing::Test {
 public:
  WebRequestActionWithThreadsTest()
      : thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP) {}

 protected:
  virtual void SetUp() OVERRIDE;

  // Creates a URL request for URL |url_string|, and applies the actions from
  // |action_set| as if they were triggered by the extension with
  // |extension_id| during |stage|.
  bool ActionWorksOnRequest(const char* url_string,
                            const std::string& extension_id,
                            const WebRequestActionSet* action_set,
                            RequestStage stage);

  // Expects a JSON description of an |action| requiring <all_urls> host
  // permission, and checks that only an extensions with full host permissions
  // can execute that action at |stage|. Also checks that the action is not
  // executable for http://clients1.google.com.
  void CheckActionNeedsAllUrls(const char* action, RequestStage stage);

  net::TestURLRequestContext context_;

  // An extension with *.com host permissions and the DWR permission.
  scoped_refptr<Extension> extension_;
  // An extension with host permissions for all URLs and the DWR permission.
  scoped_refptr<Extension> extension_all_urls_;
  scoped_refptr<InfoMap> extension_info_map_;

 private:
  content::TestBrowserThreadBundle thread_bundle_;
};

void WebRequestActionWithThreadsTest::SetUp() {
  testing::Test::SetUp();

  std::string error;
  extension_ = LoadManifestUnchecked("permissions",
                                     "web_request_com_host_permissions.json",
                                     Manifest::INVALID_LOCATION,
                                     Extension::NO_FLAGS,
                                     "ext_id_1",
                                     &error);
  ASSERT_TRUE(extension_.get()) << error;
  extension_all_urls_ =
      LoadManifestUnchecked("permissions",
                            "web_request_all_host_permissions.json",
                            Manifest::INVALID_LOCATION,
                            Extension::NO_FLAGS,
                            "ext_id_2",
                            &error);
  ASSERT_TRUE(extension_all_urls_.get()) << error;
  extension_info_map_ = new InfoMap;
  ASSERT_TRUE(extension_info_map_.get());
  extension_info_map_->AddExtension(
      extension_.get(),
      base::Time::Now(),
      false /*incognito_enabled*/,
      false /*notifications_disabled*/);
  extension_info_map_->AddExtension(extension_all_urls_.get(),
                                    base::Time::Now(),
                                    false /*incognito_enabled*/,
                                    false /*notifications_disabled*/);
}

bool WebRequestActionWithThreadsTest::ActionWorksOnRequest(
    const char* url_string,
    const std::string& extension_id,
    const WebRequestActionSet* action_set,
    RequestStage stage) {
  net::TestURLRequest regular_request(
      GURL(url_string), net::DEFAULT_PRIORITY, NULL, &context_);
  std::list<LinkedPtrEventResponseDelta> deltas;
  scoped_refptr<net::HttpResponseHeaders> headers(
      new net::HttpResponseHeaders(""));
  WebRequestData request_data(&regular_request, stage, headers.get());
  std::set<std::string> ignored_tags;
  WebRequestAction::ApplyInfo apply_info = { extension_info_map_.get(),
                                             request_data,
                                             false /*crosses_incognito*/,
                                             &deltas, &ignored_tags };
  action_set->Apply(extension_id, base::Time(), &apply_info);
  return (1u == deltas.size() || 0u < ignored_tags.size());
}

void WebRequestActionWithThreadsTest::CheckActionNeedsAllUrls(
    const char* action,
    RequestStage stage) {
  scoped_ptr<WebRequestActionSet> action_set(CreateSetOfActions(action));

  // Although |extension_| has matching *.com host permission, |action|
  // is intentionally forbidden -- in Declarative WR, host permission
  // for less than all URLs are ignored (except in SendMessageToExtension).
  EXPECT_FALSE(ActionWorksOnRequest(
      "http://test.com", extension_->id(), action_set.get(), stage));
  // With the "<all_urls>" host permission they are allowed.
  EXPECT_TRUE(ActionWorksOnRequest(
      "http://test.com", extension_all_urls_->id(), action_set.get(), stage));

  // The protected URLs should not be touched at all.
  EXPECT_FALSE(ActionWorksOnRequest(
      "http://clients1.google.com", extension_->id(), action_set.get(), stage));
  EXPECT_FALSE(ActionWorksOnRequest("http://clients1.google.com",
                                    extension_all_urls_->id(),
                                    action_set.get(),
                                    stage));
}

TEST(WebRequestActionTest, CreateAction) {
  std::string error;
  bool bad_message = false;
  scoped_refptr<const WebRequestAction> result;

  // Test wrong data type passed.
  error.clear();
  base::ListValue empty_list;
  result = WebRequestAction::Create(NULL, empty_list, &error, &bad_message);
  EXPECT_TRUE(bad_message);
  EXPECT_FALSE(result.get());

  // Test missing instanceType element.
  base::DictionaryValue input;
  error.clear();
  result = WebRequestAction::Create(NULL, input, &error, &bad_message);
  EXPECT_TRUE(bad_message);
  EXPECT_FALSE(result.get());

  // Test wrong instanceType element.
  input.SetString(keys::kInstanceTypeKey, kUnknownActionType);
  error.clear();
  result = WebRequestAction::Create(NULL, input, &error, &bad_message);
  EXPECT_NE("", error);
  EXPECT_FALSE(result.get());

  // Test success
  input.SetString(keys::kInstanceTypeKey, keys::kCancelRequestType);
  error.clear();
  result = WebRequestAction::Create(NULL, input, &error, &bad_message);
  EXPECT_EQ("", error);
  EXPECT_FALSE(bad_message);
  ASSERT_TRUE(result.get());
  EXPECT_EQ(WebRequestAction::ACTION_CANCEL_REQUEST, result->type());
}

TEST(WebRequestActionTest, CreateActionSet) {
  std::string error;
  bool bad_message = false;
  scoped_ptr<WebRequestActionSet> result;

  WebRequestActionSet::AnyVector input;

  // Test empty input.
  error.clear();
  result = WebRequestActionSet::Create(NULL, input, &error, &bad_message);
  EXPECT_TRUE(error.empty()) << error;
  EXPECT_FALSE(bad_message);
  ASSERT_TRUE(result.get());
  EXPECT_TRUE(result->actions().empty());
  EXPECT_EQ(std::numeric_limits<int>::min(), result->GetMinimumPriority());

  DictionaryValue correct_action;
  correct_action.SetString(keys::kInstanceTypeKey, keys::kIgnoreRulesType);
  correct_action.SetInteger(keys::kLowerPriorityThanKey, 10);
  DictionaryValue incorrect_action;
  incorrect_action.SetString(keys::kInstanceTypeKey, kUnknownActionType);

  // Test success.
  input.push_back(linked_ptr<base::Value>(correct_action.DeepCopy()));
  error.clear();
  result = WebRequestActionSet::Create(NULL, input, &error, &bad_message);
  EXPECT_TRUE(error.empty()) << error;
  EXPECT_FALSE(bad_message);
  ASSERT_TRUE(result.get());
  ASSERT_EQ(1u, result->actions().size());
  EXPECT_EQ(WebRequestAction::ACTION_IGNORE_RULES,
            result->actions()[0]->type());
  EXPECT_EQ(10, result->GetMinimumPriority());

  // Test failure.
  input.push_back(linked_ptr<base::Value>(incorrect_action.DeepCopy()));
  error.clear();
  result = WebRequestActionSet::Create(NULL, input, &error, &bad_message);
  EXPECT_NE("", error);
  EXPECT_FALSE(result.get());
}

// Test capture group syntax conversions of WebRequestRedirectByRegExAction
TEST(WebRequestActionTest, PerlToRe2Style) {
#define CallPerlToRe2Style WebRequestRedirectByRegExAction::PerlToRe2Style
  // foo$1bar -> foo\1bar
  EXPECT_EQ("foo\\1bar", CallPerlToRe2Style("foo$1bar"));
  // foo\$1bar -> foo$1bar
  EXPECT_EQ("foo$1bar", CallPerlToRe2Style("foo\\$1bar"));
  // foo\\$1bar -> foo\\\1bar
  EXPECT_EQ("foo\\\\\\1bar", CallPerlToRe2Style("foo\\\\$1bar"));
  // foo\bar -> foobar
  EXPECT_EQ("foobar", CallPerlToRe2Style("foo\\bar"));
  // foo$bar -> foo$bar
  EXPECT_EQ("foo$bar", CallPerlToRe2Style("foo$bar"));
#undef CallPerlToRe2Style
}

TEST_F(WebRequestActionWithThreadsTest, PermissionsToRedirect) {
  const char kAction[] =
      "[{"
      " \"instanceType\": \"declarativeWebRequest.RedirectRequest\","
      " \"redirectUrl\": \"http://www.foobar.com\""
      "}]";
  CheckActionNeedsAllUrls(kAction, ON_BEFORE_REQUEST);
}

TEST_F(WebRequestActionWithThreadsTest, PermissionsToRedirectByRegEx) {
  const char kAction[] =
      "[{"
      " \"instanceType\": \"declarativeWebRequest.RedirectByRegEx\","
      " \"from\": \".*\","
      " \"to\": \"http://www.foobar.com\""
      "}]";
  CheckActionNeedsAllUrls(kAction, ON_BEFORE_REQUEST);
}

TEST_F(WebRequestActionWithThreadsTest, PermissionsToSetRequestHeader) {
  const char kAction[] =
      "[{"
      " \"instanceType\": \"declarativeWebRequest.SetRequestHeader\","
      " \"name\": \"testname\","
      " \"value\": \"testvalue\""
      "}]";
  CheckActionNeedsAllUrls(kAction, ON_BEFORE_SEND_HEADERS);
}

TEST_F(WebRequestActionWithThreadsTest, PermissionsToRemoveRequestHeader) {
  const char kAction[] =
      "[{"
      " \"instanceType\": \"declarativeWebRequest.RemoveRequestHeader\","
      " \"name\": \"testname\""
      "}]";
  CheckActionNeedsAllUrls(kAction, ON_BEFORE_SEND_HEADERS);
}

TEST_F(WebRequestActionWithThreadsTest, PermissionsToAddResponseHeader) {
  const char kAction[] =
      "[{"
      " \"instanceType\": \"declarativeWebRequest.AddResponseHeader\","
      " \"name\": \"testname\","
      " \"value\": \"testvalue\""
      "}]";
  CheckActionNeedsAllUrls(kAction, ON_HEADERS_RECEIVED);
}

TEST_F(WebRequestActionWithThreadsTest, PermissionsToRemoveResponseHeader) {
  const char kAction[] =
      "[{"
      " \"instanceType\": \"declarativeWebRequest.RemoveResponseHeader\","
      " \"name\": \"testname\""
      "}]";
  CheckActionNeedsAllUrls(kAction, ON_HEADERS_RECEIVED);
}

TEST_F(WebRequestActionWithThreadsTest, PermissionsToSendMessageToExtension) {
  const char kAction[] =
      "[{"
      " \"instanceType\": \"declarativeWebRequest.SendMessageToExtension\","
      " \"message\": \"testtext\""
      "}]";
  scoped_ptr<WebRequestActionSet> action_set(CreateSetOfActions(kAction));

  // For sending messages, specific host permissions actually matter.
  EXPECT_TRUE(ActionWorksOnRequest("http://test.com",
                                   extension_->id(),
                                   action_set.get(),
                                   ON_BEFORE_REQUEST));
  // With the "<all_urls>" host permission they are allowed.
  EXPECT_TRUE(ActionWorksOnRequest("http://test.com",
                                   extension_all_urls_->id(),
                                   action_set.get(),
                                   ON_BEFORE_REQUEST));

  // The protected URLs should not be touched at all.
  EXPECT_FALSE(ActionWorksOnRequest("http://clients1.google.com",
                                    extension_->id(),
                                    action_set.get(),
                                    ON_BEFORE_REQUEST));
  EXPECT_FALSE(ActionWorksOnRequest("http://clients1.google.com",
                                    extension_all_urls_->id(),
                                    action_set.get(),
                                    ON_BEFORE_REQUEST));
}

TEST_F(WebRequestActionWithThreadsTest, PermissionsToAddRequestCookie) {
  const char kAction[] =
      "[{"
      " \"instanceType\": \"declarativeWebRequest.AddRequestCookie\","
      " \"cookie\": { \"name\": \"cookiename\", \"value\": \"cookievalue\" }"
      "}]";
  CheckActionNeedsAllUrls(kAction, ON_BEFORE_SEND_HEADERS);
}

TEST_F(WebRequestActionWithThreadsTest, PermissionsToAddResponseCookie) {
  const char kAction[] =
      "[{"
      " \"instanceType\": \"declarativeWebRequest.AddResponseCookie\","
      " \"cookie\": { \"name\": \"cookiename\", \"value\": \"cookievalue\" }"
      "}]";
  CheckActionNeedsAllUrls(kAction, ON_HEADERS_RECEIVED);
}

TEST_F(WebRequestActionWithThreadsTest, PermissionsToEditRequestCookie) {
  const char kAction[] =
      "[{"
      " \"instanceType\": \"declarativeWebRequest.EditRequestCookie\","
      " \"filter\": { \"name\": \"cookiename\", \"value\": \"cookievalue\" },"
      " \"modification\": { \"name\": \"name2\", \"value\": \"value2\" }"
      "}]";
  CheckActionNeedsAllUrls(kAction, ON_BEFORE_SEND_HEADERS);
}

TEST_F(WebRequestActionWithThreadsTest, PermissionsToEditResponseCookie) {
  const char kAction[] =
      "[{"
      " \"instanceType\": \"declarativeWebRequest.EditResponseCookie\","
      " \"filter\": { \"name\": \"cookiename\", \"value\": \"cookievalue\" },"
      " \"modification\": { \"name\": \"name2\", \"value\": \"value2\" }"
      "}]";
  CheckActionNeedsAllUrls(kAction, ON_HEADERS_RECEIVED);
}

TEST_F(WebRequestActionWithThreadsTest, PermissionsToRemoveRequestCookie) {
  const char kAction[] =
      "[{"
      " \"instanceType\": \"declarativeWebRequest.RemoveRequestCookie\","
      " \"filter\": { \"name\": \"cookiename\", \"value\": \"cookievalue\" }"
      "}]";
  CheckActionNeedsAllUrls(kAction, ON_BEFORE_SEND_HEADERS);
}

TEST_F(WebRequestActionWithThreadsTest, PermissionsToRemoveResponseCookie) {
  const char kAction[] =
      "[{"
      " \"instanceType\": \"declarativeWebRequest.RemoveResponseCookie\","
      " \"filter\": { \"name\": \"cookiename\", \"value\": \"cookievalue\" }"
      "}]";
  CheckActionNeedsAllUrls(kAction, ON_HEADERS_RECEIVED);
}

TEST_F(WebRequestActionWithThreadsTest, PermissionsToCancel) {
  const char kAction[] =
      "[{"
      " \"instanceType\": \"declarativeWebRequest.CancelRequest\""
      "}]";
  scoped_ptr<WebRequestActionSet> action_set(CreateSetOfActions(kAction));

  // Cancelling requests works without full host permissions.
  EXPECT_TRUE(ActionWorksOnRequest("http://test.org",
                                   extension_->id(),
                                   action_set.get(),
                                   ON_BEFORE_REQUEST));
}

TEST_F(WebRequestActionWithThreadsTest,
       PermissionsToRedirectToTransparentImage) {
  const char kAction[] =
      "[{"
      " \"instanceType\": \"declarativeWebRequest.RedirectToTransparentImage\""
      "}]";
  scoped_ptr<WebRequestActionSet> action_set(CreateSetOfActions(kAction));

  // Redirecting to transparent images works without full host permissions.
  EXPECT_TRUE(ActionWorksOnRequest("http://test.org",
                                   extension_->id(),
                                   action_set.get(),
                                   ON_BEFORE_REQUEST));
}

TEST_F(WebRequestActionWithThreadsTest, PermissionsToRedirectToEmptyDocument) {
  const char kAction[] =
      "[{"
      " \"instanceType\": \"declarativeWebRequest.RedirectToEmptyDocument\""
      "}]";
  scoped_ptr<WebRequestActionSet> action_set(CreateSetOfActions(kAction));

  // Redirecting to the empty document works without full host permissions.
  EXPECT_TRUE(ActionWorksOnRequest("http://test.org",
                                   extension_->id(),
                                   action_set.get(),
                                   ON_BEFORE_REQUEST));
}

TEST_F(WebRequestActionWithThreadsTest, PermissionsToIgnore) {
  const char kAction[] =
      "[{"
      " \"instanceType\": \"declarativeWebRequest.IgnoreRules\","
      " \"lowerPriorityThan\": 123,"
      " \"hasTag\": \"some_tag\""
      "}]";
  scoped_ptr<WebRequestActionSet> action_set(CreateSetOfActions(kAction));

  // Ignoring rules works without full host permissions.
  EXPECT_TRUE(ActionWorksOnRequest("http://test.org",
                                   extension_->id(),
                                   action_set.get(),
                                   ON_BEFORE_REQUEST));
}

TEST(WebRequestActionTest, GetName) {
  const char kActions[] =
      "[{"
      " \"instanceType\": \"declarativeWebRequest.RedirectRequest\","
      " \"redirectUrl\": \"http://www.foobar.com\""
      "},"
      "{"
      " \"instanceType\": \"declarativeWebRequest.RedirectByRegEx\","
      " \"from\": \".*\","
      " \"to\": \"http://www.foobar.com\""
      "},"
      "{"
      " \"instanceType\": \"declarativeWebRequest.SetRequestHeader\","
      " \"name\": \"testname\","
      " \"value\": \"testvalue\""
      "},"
      "{"
      " \"instanceType\": \"declarativeWebRequest.RemoveRequestHeader\","
      " \"name\": \"testname\""
      "},"
      "{"
      " \"instanceType\": \"declarativeWebRequest.AddResponseHeader\","
      " \"name\": \"testname\","
      " \"value\": \"testvalue\""
      "},"
      "{"
      " \"instanceType\": \"declarativeWebRequest.RemoveResponseHeader\","
      " \"name\": \"testname\""
      "},"
      "{"
      " \"instanceType\": \"declarativeWebRequest.SendMessageToExtension\","
      " \"message\": \"testtext\""
      "},"
      "{"
      " \"instanceType\": \"declarativeWebRequest.AddRequestCookie\","
      " \"cookie\": { \"name\": \"cookiename\", \"value\": \"cookievalue\" }"
      "},"
      "{"
      " \"instanceType\": \"declarativeWebRequest.AddResponseCookie\","
      " \"cookie\": { \"name\": \"cookiename\", \"value\": \"cookievalue\" }"
      "},"
      "{"
      " \"instanceType\": \"declarativeWebRequest.EditRequestCookie\","
      " \"filter\": { \"name\": \"cookiename\", \"value\": \"cookievalue\" },"
      " \"modification\": { \"name\": \"name2\", \"value\": \"value2\" }"
      "},"
      "{"
      " \"instanceType\": \"declarativeWebRequest.EditResponseCookie\","
      " \"filter\": { \"name\": \"cookiename\", \"value\": \"cookievalue\" },"
      " \"modification\": { \"name\": \"name2\", \"value\": \"value2\" }"
      "},"
      "{"
      " \"instanceType\": \"declarativeWebRequest.RemoveRequestCookie\","
      " \"filter\": { \"name\": \"cookiename\", \"value\": \"cookievalue\" }"
      "},"
      "{"
      " \"instanceType\": \"declarativeWebRequest.RemoveResponseCookie\","
      " \"filter\": { \"name\": \"cookiename\", \"value\": \"cookievalue\" }"
      "},"
      "{"
      " \"instanceType\": \"declarativeWebRequest.CancelRequest\""
      "},"
      "{"
      " \"instanceType\": \"declarativeWebRequest.RedirectToTransparentImage\""
      "},"
      "{"
      " \"instanceType\": \"declarativeWebRequest.RedirectToEmptyDocument\""
      "},"
      "{"
      " \"instanceType\": \"declarativeWebRequest.IgnoreRules\","
      " \"lowerPriorityThan\": 123,"
      " \"hasTag\": \"some_tag\""
      "}]";
  const char* kExpectedNames[] = {
    "declarativeWebRequest.RedirectRequest",
    "declarativeWebRequest.RedirectByRegEx",
    "declarativeWebRequest.SetRequestHeader",
    "declarativeWebRequest.RemoveRequestHeader",
    "declarativeWebRequest.AddResponseHeader",
    "declarativeWebRequest.RemoveResponseHeader",
    "declarativeWebRequest.SendMessageToExtension",
    "declarativeWebRequest.AddRequestCookie",
    "declarativeWebRequest.AddResponseCookie",
    "declarativeWebRequest.EditRequestCookie",
    "declarativeWebRequest.EditResponseCookie",
    "declarativeWebRequest.RemoveRequestCookie",
    "declarativeWebRequest.RemoveResponseCookie",
    "declarativeWebRequest.CancelRequest",
    "declarativeWebRequest.RedirectToTransparentImage",
    "declarativeWebRequest.RedirectToEmptyDocument",
    "declarativeWebRequest.IgnoreRules",
  };
  scoped_ptr<WebRequestActionSet> action_set(CreateSetOfActions(kActions));
  ASSERT_EQ(arraysize(kExpectedNames), action_set->actions().size());
  size_t index = 0;
  for (WebRequestActionSet::Actions::const_iterator it =
           action_set->actions().begin();
       it != action_set->actions().end();
       ++it) {
    EXPECT_EQ(kExpectedNames[index], (*it)->GetName());
    ++index;
  }
}

}  // namespace extensions
