// 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 <string>
#include <utility>
#include <vector>

#include "base/lazy_instance.h"
#include "base/logging.h"
#include "base/test/metrics/histogram_tester.h"
#include "chrome/browser/content_settings/host_content_settings_map_factory.h"
#include "chrome/browser/content_settings/tab_specific_content_settings.h"
#include "chrome/browser/safe_browsing/test_safe_browsing_database_helper.h"
#include "chrome/browser/subresource_filter/chrome_subresource_filter_client.h"
#include "chrome/browser/subresource_filter/subresource_filter_browser_test_harness.h"
#include "chrome/browser/ui/blocked_content/safe_browsing_triggered_popup_blocker.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "chrome/test/base/ui_test_utils.h"
#include "components/content_settings/core/browser/host_content_settings_map.h"
#include "components/content_settings/core/common/content_settings_types.h"
#include "components/safe_browsing/db/util.h"
#include "components/subresource_filter/core/browser/subresource_filter_constants.h"
#include "components/subresource_filter/core/browser/subresource_filter_features.h"
#include "components/url_pattern_index/proto/rules.pb.h"
#include "content/public/browser/web_contents.h"
#include "content/public/test/browser_test.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/test_navigation_observer.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"

using safe_browsing::SubresourceFilterType;
using safe_browsing::SubresourceFilterLevel;

namespace subresource_filter {

namespace {

base::LazyInstance<std::vector<std::string>>::DestructorAtExit error_messages_ =
    LAZY_INSTANCE_INITIALIZER;

class ScopedLoggingObserver {
 public:
  ScopedLoggingObserver() {
    logging::SetLogMessageHandler(&ScopedLoggingObserver::LogHandler);
  }

  void RoundTripAndVerifyLogMessages(
      content::WebContents* web_contents,
      std::vector<std::string> messages_expected,
      std::vector<std::string> messages_not_expected) {
    // Round trip to the renderer to ensure the message would have gotten sent.
    EXPECT_TRUE(content::ExecuteScript(web_contents, "var a = 1;"));
    std::deque<bool> verify_messages_expected(messages_expected.size(), false);
    for (size_t i = 0; i < messages_expected.size(); i++)
      verify_messages_expected[i] = false;

    for (const auto& message : error_messages_.Get()) {
      for (size_t i = 0; i < messages_expected.size(); i++) {
        verify_messages_expected[i] |=
            (message.find(messages_expected[i]) != std::string::npos);
      }
      for (const auto& message_not_expected : messages_not_expected)
        EXPECT_EQ(std::string::npos, message.find(message_not_expected))
            << message_not_expected;
    }
    for (size_t i = 0; i < messages_expected.size(); i++)
      EXPECT_TRUE(verify_messages_expected[i]) << messages_expected[i];
  }

 private:
  // Intercepts all console messages. Only used when the ConsoleObserverDelegate
  // cannot be (e.g. when we need the standard delegate).
  static bool LogHandler(int severity,
                         const char* file,
                         int line,
                         size_t message_start,
                         const std::string& str) {
    if (file && std::string("CONSOLE") == file)
      error_messages_.Get().push_back(str);
    return false;
  }
};

}  // namespace

const char kSubresourceFilterActionsHistogram[] = "SubresourceFilter.Actions2";

// Tests that subresource_filter interacts well with the abusive enforcement in
// chrome/browser/ui/blocked_content/safe_browsing_triggered_popup_blocker.
class SubresourceFilterPopupBrowserTest
    : public SubresourceFilterListInsertingBrowserTest,
      public ::testing::WithParamInterface<
          bool /* enable_adblock_on_abusive_sites */> {
 public:
  void SetUpOnMainThread() override {
    SubresourceFilterBrowserTest::SetUpOnMainThread();
    Configuration config(subresource_filter::mojom::ActivationLevel::kEnabled,
                         subresource_filter::ActivationScope::ACTIVATION_LIST,
                         subresource_filter::ActivationList::BETTER_ADS);
    ResetConfiguration(std::move(config));
    ASSERT_NO_FATAL_FAILURE(
        SetRulesetToDisallowURLsWithPathSuffix("included_script.js"));
  }
  void ConfigureAsAbusiveAndBetterAds(const GURL& url,
                                      SubresourceFilterLevel abusive_level,
                                      SubresourceFilterLevel bas_level) {
    safe_browsing::ThreatMetadata metadata;
    metadata.subresource_filter_match[SubresourceFilterType::ABUSIVE] =
        abusive_level;
    metadata.subresource_filter_match[SubresourceFilterType::BETTER_ADS] =
        bas_level;

    database_helper()->AddFullHashToDbAndFullHashCache(
        url, safe_browsing::GetUrlSubresourceFilterId(), metadata);
  }

  bool AreDisallowedRequestsBlocked() {
    std::string script = base::StringPrintf(
        R"(
      var script = document.createElement('script');
      script.src = '%s';
      script.type = 'text/javascript';
      script.onload = () => { window.domAutomationController.send(true); }
      script.onerror = () => { window.domAutomationController.send(false); }
      document.head.appendChild(script);
    )",
        embedded_test_server()
            ->GetURL("/subresource_filter/included_script.js")
            .spec()
            .c_str());
    bool loaded;
    EXPECT_TRUE(
        content::ExecuteScriptAndExtractBool(web_contents(), script, &loaded));
    return !loaded;
  }
};

IN_PROC_BROWSER_TEST_F(SubresourceFilterPopupBrowserTest,
                       NoConfiguration_AllowCreatingNewWindows) {
  ResetConfiguration(Configuration::MakePresetForLiveRunOnPhishingSites());
  base::HistogramTester tester;
  const char kWindowOpenPath[] = "/subresource_filter/window_open.html";
  GURL a_url(embedded_test_server()->GetURL("a.com", kWindowOpenPath));
  // Only configure |a_url| as a phishing URL.
  ConfigureAsPhishingURL(a_url);

  // Navigate to a_url, should not trigger the popup blocker.
  ui_test_utils::NavigateToURL(browser(), a_url);
  bool opened_window = false;
  content::WebContents* web_contents =
      browser()->tab_strip_model()->GetActiveWebContents();
  EXPECT_TRUE(content::ExecuteScriptAndExtractBool(web_contents, "openWindow()",
                                                   &opened_window));
  EXPECT_TRUE(opened_window);
  EXPECT_FALSE(TabSpecificContentSettings::FromWebContents(web_contents)
                   ->IsContentBlocked(CONTENT_SETTINGS_TYPE_POPUPS));

  // Navigate again to trigger histogram logging. Make sure the navigation
  // happens in the original WebContents.
  browser()->tab_strip_model()->ToggleSelectionAt(
      browser()->tab_strip_model()->GetIndexOfWebContents(web_contents));
  ui_test_utils::NavigateToURL(browser(),
                               embedded_test_server()->GetURL("/title1.html"));
}

IN_PROC_BROWSER_TEST_P(SubresourceFilterPopupBrowserTest,
                       BlockCreatingNewWindows) {
  bool enable_adblock_on_abusive_sites = GetParam();
  base::test::ScopedFeatureList scoped_feature_list;
  scoped_feature_list.InitWithFeatureState(
      subresource_filter::kFilterAdsOnAbusiveSites,
      enable_adblock_on_abusive_sites);
  base::HistogramTester tester;
  const char kWindowOpenPath[] = "/subresource_filter/window_open.html";
  GURL a_url(embedded_test_server()->GetURL("a.com", kWindowOpenPath));
  GURL b_url(embedded_test_server()->GetURL("b.com", kWindowOpenPath));
  // Configure as abusive and BAS warn.
  ConfigureAsAbusiveAndBetterAds(
      a_url, SubresourceFilterLevel::ENFORCE /* abusive_level */,
      SubresourceFilterLevel::WARN /* bas_level */);

  // Navigate to a_url, should trigger the popup blocker.
  ui_test_utils::NavigateToURL(browser(), a_url);
  bool opened_window = false;
  content::WebContents* web_contents =
      browser()->tab_strip_model()->GetActiveWebContents();
  EXPECT_TRUE(content::ExecuteScriptAndExtractBool(web_contents, "openWindow()",
                                                   &opened_window));
  EXPECT_FALSE(opened_window);
  tester.ExpectTotalCount(kSubresourceFilterActionsHistogram, 0);
  // Make sure the popup UI was shown.
  EXPECT_TRUE(TabSpecificContentSettings::FromWebContents(web_contents)
                  ->IsContentBlocked(CONTENT_SETTINGS_TYPE_POPUPS));

  // Block again.
  EXPECT_TRUE(content::ExecuteScriptAndExtractBool(web_contents, "openWindow()",
                                                   &opened_window));
  EXPECT_FALSE(opened_window);

  EXPECT_EQ(enable_adblock_on_abusive_sites, AreDisallowedRequestsBlocked());

  // Navigate to |b_url|, which should successfully open the popup.
  ui_test_utils::NavigateToURL(browser(), b_url);
  opened_window = false;
  EXPECT_TRUE(content::ExecuteScriptAndExtractBool(web_contents, "openWindow()",
                                                   &opened_window));
  EXPECT_TRUE(opened_window);
  // Popup UI should not be shown.
  EXPECT_FALSE(TabSpecificContentSettings::FromWebContents(web_contents)
                   ->IsContentBlocked(CONTENT_SETTINGS_TYPE_POPUPS));
}

IN_PROC_BROWSER_TEST_F(SubresourceFilterPopupBrowserTest,
                       BlockCreatingNewWindows_LogsToConsole) {
  content::ConsoleObserverDelegate console_observer(web_contents(),
                                                    kAbusiveEnforceMessage);
  web_contents()->SetDelegate(&console_observer);
  const char kWindowOpenPath[] = "/subresource_filter/window_open.html";
  GURL a_url(embedded_test_server()->GetURL("a.com", kWindowOpenPath));
  ConfigureAsAbusiveAndBetterAds(
      a_url, SubresourceFilterLevel::ENFORCE /* abusive_level */,
      SubresourceFilterLevel::ENFORCE /* bas_level */);

  // Navigate to a_url, should trigger the popup blocker.
  ui_test_utils::NavigateToURL(browser(), a_url);
  bool opened_window = false;
  EXPECT_TRUE(content::ExecuteScriptAndExtractBool(
      web_contents(), "openWindow()", &opened_window));
  EXPECT_FALSE(opened_window);
  console_observer.Wait();
  EXPECT_EQ(kAbusiveEnforceMessage, console_observer.message());

  EXPECT_TRUE(AreDisallowedRequestsBlocked());
}

IN_PROC_BROWSER_TEST_F(SubresourceFilterPopupBrowserTest,
                       WarningDoNotBlockCreatingNewWindows_LogsToConsole) {
  const char kWindowOpenPath[] = "/subresource_filter/window_open.html";
  GURL a_url(embedded_test_server()->GetURL("a.com", kWindowOpenPath));

  ConfigureAsAbusiveAndBetterAds(
      a_url, SubresourceFilterLevel::WARN /* abusive_level */,
      SubresourceFilterLevel::WARN /* bas_level */);

  // Navigate to a_url, should log a warning and not trigger the popup blocker.
  ScopedLoggingObserver log_observer;

  ui_test_utils::NavigateToURL(browser(), a_url);
  content::WebContents* web_contents =
      browser()->tab_strip_model()->GetActiveWebContents();

  log_observer.RoundTripAndVerifyLogMessages(
      web_contents, {kActivationWarningConsoleMessage, kAbusiveWarnMessage},
      {});

  bool opened_window = false;
  EXPECT_TRUE(content::ExecuteScriptAndExtractBool(web_contents, "openWindow()",
                                                   &opened_window));
  EXPECT_TRUE(opened_window);
  EXPECT_FALSE(AreDisallowedRequestsBlocked());
}

IN_PROC_BROWSER_TEST_F(SubresourceFilterPopupBrowserTest,
                       WarnAbusiveAndBetterAds_LogsToConsole) {
  const char kWindowOpenPath[] = "/subresource_filter/window_open.html";
  GURL a_url(embedded_test_server()->GetURL("a.com", kWindowOpenPath));
  ConfigureAsAbusiveAndBetterAds(
      a_url, SubresourceFilterLevel::WARN /* abusive_level */,
      SubresourceFilterLevel::WARN /* bas_level */);

  // Allow popups on |a_url|.
  HostContentSettingsMap* settings_map =
      HostContentSettingsMapFactory::GetForProfile(browser()->profile());
  settings_map->SetContentSettingDefaultScope(
      a_url, a_url, ContentSettingsType::CONTENT_SETTINGS_TYPE_POPUPS,
      std::string(), CONTENT_SETTING_ALLOW);

  // Navigate to a_url, should not trigger the popup blocker.
  ScopedLoggingObserver log_observer;

  ui_test_utils::NavigateToURL(browser(), a_url);
  bool opened_window = false;
  EXPECT_TRUE(content::ExecuteScriptAndExtractBool(
      web_contents(), "openWindow()", &opened_window));
  EXPECT_TRUE(opened_window);

  EXPECT_FALSE(AreDisallowedRequestsBlocked());

  log_observer.RoundTripAndVerifyLogMessages(
      web_contents(), {kAbusiveWarnMessage, kActivationWarningConsoleMessage},
      {});
}

// Whitelisted sites should not have console logging.
IN_PROC_BROWSER_TEST_F(SubresourceFilterPopupBrowserTest,
                       AllowCreatingNewWindows_NoLogToConsole) {
  const char kWindowOpenPath[] = "/subresource_filter/window_open.html";
  GURL a_url(embedded_test_server()->GetURL("a.com", kWindowOpenPath));
  // Enforce BAS, warn abusive.
  ConfigureAsAbusiveAndBetterAds(
      a_url, SubresourceFilterLevel::WARN /* abusive_level */,
      SubresourceFilterLevel::ENFORCE /* bas_level */);

  // Allow popups on |a_url|.
  HostContentSettingsMap* settings_map =
      HostContentSettingsMapFactory::GetForProfile(browser()->profile());
  settings_map->SetContentSettingDefaultScope(
      a_url, a_url, ContentSettingsType::CONTENT_SETTINGS_TYPE_POPUPS,
      std::string(), CONTENT_SETTING_ALLOW);

  // Navigate to a_url, should not trigger the popup blocker.
  ScopedLoggingObserver log_observer;
  ui_test_utils::NavigateToURL(browser(), a_url);
  EXPECT_TRUE(AreDisallowedRequestsBlocked());

  bool opened_window = false;
  EXPECT_TRUE(content::ExecuteScriptAndExtractBool(
      web_contents(), "openWindow()", &opened_window));
  EXPECT_TRUE(opened_window);

  // On the new window, requests should be allowed.
  EXPECT_FALSE(AreDisallowedRequestsBlocked());

  log_observer.RoundTripAndVerifyLogMessages(
      web_contents(), {kActivationConsoleMessage}, {kAbusiveEnforceMessage});
}

IN_PROC_BROWSER_TEST_P(SubresourceFilterPopupBrowserTest, BlockOpenURLFromTab) {
  bool enable_adblock_on_abusive_sites = GetParam();
  base::test::ScopedFeatureList scoped_feature_list;
  scoped_feature_list.InitWithFeatureState(
      subresource_filter::kFilterAdsOnAbusiveSites,
      enable_adblock_on_abusive_sites);
  base::HistogramTester tester;
  const char kWindowOpenPath[] =
      "/subresource_filter/window_open_spoof_click.html";
  GURL a_url(embedded_test_server()->GetURL("a.com", kWindowOpenPath));
  GURL b_url(embedded_test_server()->GetURL("b.com", kWindowOpenPath));
  ConfigureAsAbusiveAndBetterAds(
      a_url, SubresourceFilterLevel::ENFORCE /* abusive_level */,
      SubresourceFilterLevel::WARN /* bas_level */);

  // Navigate to a_url, should trigger the popup blocker.
  ui_test_utils::NavigateToURL(browser(), a_url);

  content::WebContents* web_contents =
      browser()->tab_strip_model()->GetActiveWebContents();
  EXPECT_TRUE(content::ExecuteScript(web_contents, "openWindow()"));
  tester.ExpectTotalCount(kSubresourceFilterActionsHistogram, 0);

  EXPECT_TRUE(TabSpecificContentSettings::FromWebContents(web_contents)
                  ->IsContentBlocked(CONTENT_SETTINGS_TYPE_POPUPS));
  EXPECT_EQ(enable_adblock_on_abusive_sites, AreDisallowedRequestsBlocked());

  // Navigate to |b_url|, which should successfully open the popup.

  ui_test_utils::NavigateToURL(browser(), b_url);

  content::TestNavigationObserver navigation_observer(nullptr, 1);
  navigation_observer.StartWatchingNewWebContents();
  EXPECT_TRUE(content::ExecuteScript(web_contents, "openWindow()"));
  navigation_observer.Wait();

  // Popup UI should not be shown.
  EXPECT_FALSE(TabSpecificContentSettings::FromWebContents(web_contents)
                   ->IsContentBlocked(CONTENT_SETTINGS_TYPE_POPUPS));
  EXPECT_FALSE(AreDisallowedRequestsBlocked());
}

IN_PROC_BROWSER_TEST_P(SubresourceFilterPopupBrowserTest,
                       BlockOpenURLFromTabInIframe) {
  bool enable_adblock_on_abusive_sites = GetParam();
  base::test::ScopedFeatureList scoped_feature_list;
  scoped_feature_list.InitWithFeatureState(
      subresource_filter::kFilterAdsOnAbusiveSites,
      enable_adblock_on_abusive_sites);
  const char popup_path[] = "/subresource_filter/iframe_spoof_click_popup.html";
  GURL a_url(embedded_test_server()->GetURL("a.com", popup_path));
  ConfigureAsAbusiveAndBetterAds(
      a_url, SubresourceFilterLevel::ENFORCE /* abusive_level */,
      SubresourceFilterLevel::WARN /* bas_level */);

  // Navigate to a_url, should not trigger the popup blocker.
  ui_test_utils::NavigateToURL(browser(), a_url);
  bool sent_open = false;
  content::WebContents* web_contents =
      browser()->tab_strip_model()->GetActiveWebContents();
  EXPECT_TRUE(content::ExecuteScriptAndExtractBool(web_contents, "openWindow()",
                                                   &sent_open));
  EXPECT_TRUE(sent_open);
  EXPECT_TRUE(TabSpecificContentSettings::FromWebContents(web_contents)
                  ->IsContentBlocked(CONTENT_SETTINGS_TYPE_POPUPS));
  EXPECT_EQ(enable_adblock_on_abusive_sites, AreDisallowedRequestsBlocked());
}

IN_PROC_BROWSER_TEST_P(SubresourceFilterPopupBrowserTest,
                       TraditionalWindowOpen_NotBlocked) {
  bool enable_adblock_on_abusive_sites = GetParam();
  base::test::ScopedFeatureList scoped_feature_list;
  scoped_feature_list.InitWithFeatureState(
      subresource_filter::kFilterAdsOnAbusiveSites,
      enable_adblock_on_abusive_sites);
  GURL url(GetTestUrl("/title2.html"));
  ConfigureAsAbusiveAndBetterAds(
      url, SubresourceFilterLevel::ENFORCE /* abusive_level */,
      SubresourceFilterLevel::WARN /* bas_level */);
  ui_test_utils::NavigateToURL(browser(), GetTestUrl("/title1.html"));

  // Should not trigger the popup blocker because internally opens the tab with
  // a user gesture.
  ui_test_utils::NavigateToURLWithDisposition(
      browser(), url, WindowOpenDisposition::NEW_FOREGROUND_TAB,
      ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);

  content::WebContents* web_contents =
      browser()->tab_strip_model()->GetActiveWebContents();
  EXPECT_FALSE(TabSpecificContentSettings::FromWebContents(web_contents)
                   ->IsContentBlocked(CONTENT_SETTINGS_TYPE_POPUPS));
  EXPECT_EQ(enable_adblock_on_abusive_sites, AreDisallowedRequestsBlocked());
}

INSTANTIATE_TEST_CASE_P(/* no prefix */,
                        SubresourceFilterPopupBrowserTest,
                        ::testing::Values(false, true));

}  // namespace subresource_filter
