// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/files/file_util.h"
#include "base/path_service.h"
#include "base/test/scoped_feature_list.h"
#include "base/threading/thread_restrictions.h"
#include "build/android_buildflags.h"
#include "build/build_config.h"
#include "build/chromeos_buildflags.h"
#include "chrome/browser/extensions/api/permissions/permissions_api.h"
#include "chrome/browser/extensions/extension_apitest.h"
#include "chrome/browser/extensions/extension_management_test_util.h"
#include "chrome/browser/extensions/extension_with_management_policy_apitest.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/common/chrome_paths.h"
#include "components/policy/core/browser/browser_policy_connector.h"
#include "components/policy/core/common/mock_configuration_policy_provider.h"
#include "content/public/test/browser_test.h"
#include "extensions/browser/extension_prefs.h"
#include "extensions/common/extension_features.h"
#include "extensions/common/permissions/permission_set.h"
#include "extensions/common/switches.h"
#include "net/dns/mock_host_resolver.h"

#if BUILDFLAG(IS_ANDROID)
#include "chrome/browser/net/chrome_network_delegate.h"
#endif

namespace extensions {

namespace {

static void AddPattern(URLPatternSet* extent, const std::string& pattern) {
  int schemes = URLPattern::SCHEME_ALL;
  extent->AddPattern(URLPattern(schemes, pattern));
}

}  // namespace

using ContextType = extensions::browser_test_util::ContextType;

class ExperimentalApiTest : public ExtensionApiTest {
 public:
  ExperimentalApiTest() = default;
  ~ExperimentalApiTest() override = default;
  ExperimentalApiTest(const ExperimentalApiTest&) = delete;
  ExperimentalApiTest& operator=(const ExperimentalApiTest&) = delete;

  void SetUpCommandLine(base::CommandLine* command_line) override {
    ExtensionApiTest::SetUpCommandLine(command_line);
    command_line->AppendSwitch(switches::kEnableExperimentalExtensionApis);
  }
};

class PermissionsApiTest : public ExtensionApiTest {
 public:
 public:
  explicit PermissionsApiTest(ContextType context_type = ContextType::kNone)
      : ExtensionApiTest(context_type) {}
  ~PermissionsApiTest() override = default;
  PermissionsApiTest(const PermissionsApiTest&) = delete;
  PermissionsApiTest& operator=(const PermissionsApiTest&) = delete;

  void SetUpOnMainThread() override {
    ExtensionApiTest::SetUpOnMainThread();
    host_resolver()->AddRule("*", "127.0.0.1");
  }
};

class PermissionsApiTestWithContextType
    : public PermissionsApiTest,
      public testing::WithParamInterface<ContextType> {
 public:
  PermissionsApiTestWithContextType() : PermissionsApiTest(GetParam()) {}
  ~PermissionsApiTestWithContextType() override = default;
  PermissionsApiTestWithContextType(const PermissionsApiTestWithContextType&) =
      delete;
  PermissionsApiTestWithContextType& operator=(
      const PermissionsApiTestWithContextType&) = delete;
};

IN_PROC_BROWSER_TEST_P(PermissionsApiTestWithContextType, PermissionsFail) {
  ASSERT_TRUE(RunExtensionTest("permissions/disabled")) << message_;

  // Since the experimental APIs require a flag, this will fail even though
  // it's enabled.
  // TODO(erikkay) This test is currently broken because LoadExtension in
  // ExtensionBrowserTest doesn't actually fail, it just times out.  To fix this
  // I'll need to add an EXTENSION_LOAD_ERROR notification, which is probably
  // too much for the branch.  I'll enable this on trunk later.
  // ASSERT_FALSE(RunExtensionTest("permissions/enabled"))) << message_;
}

IN_PROC_BROWSER_TEST_F(ExperimentalApiTest, PermissionsSucceed) {
  ASSERT_TRUE(RunExtensionTest("permissions/enabled")) << message_;
}

IN_PROC_BROWSER_TEST_P(PermissionsApiTestWithContextType,
                       ExperimentalPermissionsFail) {
  // At the time this test is being created, there is no experimental
  // function that will not be graduating soon, and does not require a
  // tab id as an argument.  So, we need the tab permission to get
  // a tab id.
  ASSERT_TRUE(RunExtensionTest("permissions/experimental_disabled"))
      << message_;
}

// TODO(crbug.com/40124130): Flaky on ChromeOS, Linux, and Mac non-dbg builds.
#if (BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_MAC)) && \
    defined(NDEBUG)
#define MAYBE_FaviconPermission DISABLED_FaviconPermission
#else
#define MAYBE_FaviconPermission FaviconPermission
#endif
IN_PROC_BROWSER_TEST_F(PermissionsApiTest, MAYBE_FaviconPermission) {
  ASSERT_TRUE(RunExtensionTest("permissions/favicon")) << message_;
}

#if BUILDFLAG(ENABLE_EXTENSIONS)
// Test functions and APIs that are always allowed (even if you ask for no
// permissions).
// TODO(crbug.com/371432155): Port to desktop Android when chrome.tabs API
// is available.
IN_PROC_BROWSER_TEST_F(PermissionsApiTest, AlwaysAllowed) {
  ASSERT_TRUE(RunExtensionTest("permissions/always_allowed")) << message_;
}
#endif  // BUILDFLAG(ENABLE_EXTENSIONS)

// Tests that the optional permissions API works correctly.
IN_PROC_BROWSER_TEST_P(PermissionsApiTestWithContextType,
                       OptionalPermissionsGranted) {
  // Mark all the tested APIs as granted to bypass the confirmation UI.
  APIPermissionSet apis;
  apis.insert(extensions::mojom::APIPermissionID::kBookmark);
  URLPatternSet explicit_hosts;
  AddPattern(&explicit_hosts, "http://*.c.com/*");

  ExtensionPrefs* prefs = ExtensionPrefs::Get(profile());
  prefs->AddRuntimeGrantedPermissions(
      "kjmkgkdkpedkejedfhmfcenooemhbpbo",
      PermissionSet(std::move(apis), ManifestPermissionSet(),
                    std::move(explicit_hosts), URLPatternSet()));

  PermissionsRequestFunction::SetIgnoreUserGestureForTests(true);
  ASSERT_TRUE(StartEmbeddedTestServer());
  EXPECT_TRUE(RunExtensionTest("permissions/optional")) << message_;
}

// Tests that the optional permissions API works correctly.
IN_PROC_BROWSER_TEST_P(PermissionsApiTestWithContextType,
                       OptionalPermissionsAutoConfirm) {
  // Rather than setting the granted permissions, set the UI autoconfirm flag
  // and run the same tests.
  auto dialog_action_reset =
      PermissionsRequestFunction::SetDialogActionForTests(
          PermissionsRequestFunction::DialogAction::kAutoConfirm);
  PermissionsRequestFunction::SetIgnoreUserGestureForTests(true);
  ASSERT_TRUE(StartEmbeddedTestServer());
  EXPECT_TRUE(RunExtensionTest("permissions/optional")) << message_;
}

// Test that denying the optional permissions confirmation dialog works.
IN_PROC_BROWSER_TEST_F(PermissionsApiTest, OptionalPermissionsDeny) {
  // Mark the management permission as already granted since we auto reject
  // user prompts.
  APIPermissionSet apis;
  apis.insert(mojom::APIPermissionID::kManagement);

  ExtensionPrefs* prefs = ExtensionPrefs::Get(profile());
  prefs->AddRuntimeGrantedPermissions(
      "kjmkgkdkpedkejedfhmfcenooemhbpbo",
      PermissionSet(std::move(apis), ManifestPermissionSet(), URLPatternSet(),
                    URLPatternSet()));

  auto dialog_action_reset =
      PermissionsRequestFunction::SetDialogActionForTests(
          PermissionsRequestFunction::DialogAction::kAutoReject);
  PermissionsRequestFunction::SetIgnoreUserGestureForTests(true);
  ASSERT_TRUE(StartEmbeddedTestServer());
  EXPECT_TRUE(RunExtensionTest("permissions/optional_deny")) << message_;
}

// Tests that the permissions.request function must be called from within a
// user gesture.
IN_PROC_BROWSER_TEST_P(PermissionsApiTestWithContextType,
                       OptionalPermissionsGesture) {
  PermissionsRequestFunction::SetIgnoreUserGestureForTests(false);
  ASSERT_TRUE(StartEmbeddedTestServer());
  EXPECT_TRUE(RunExtensionTest("permissions/optional_gesture")) << message_;
}

// Tests that the user gesture is retained in the permissions.request function
// callback.
IN_PROC_BROWSER_TEST_F(PermissionsApiTest, OptionalPermissionsRetainGesture) {
  auto dialog_action_reset =
      PermissionsRequestFunction::SetDialogActionForTests(
          PermissionsRequestFunction::DialogAction::kAutoConfirm);
  PermissionsRequestFunction::SetIgnoreUserGestureForTests(false);
  ASSERT_TRUE(StartEmbeddedTestServer());
  EXPECT_TRUE(RunExtensionTest("permissions/optional_retain_gesture"))
      << message_;
}

// Test that optional permissions blocked by enterprise policy will be denied
// automatically.
IN_PROC_BROWSER_TEST_F(ExtensionApiTestWithManagementPolicy,
                       OptionalPermissionsPolicyBlocked) {
  // Set enterprise policy to block some API permissions.
  {
    ExtensionManagementPolicyUpdater pref(&policy_provider_);
    pref.AddBlockedPermission("*", "management");
  }
  // Set auto confirm UI flag.
  auto dialog_action_reset =
      PermissionsRequestFunction::SetDialogActionForTests(
          PermissionsRequestFunction::DialogAction::kAutoConfirm);
  PermissionsRequestFunction::SetIgnoreUserGestureForTests(true);
  EXPECT_TRUE(RunExtensionTest("permissions/optional_policy_blocked"))
      << message_;
}

// Tests that an extension can't gain access to file: URLs without the checkbox
// entry in prefs. There shouldn't be a warning either.
IN_PROC_BROWSER_TEST_F(PermissionsApiTest, OptionalPermissionsFileAccess) {
  // There shouldn't be a warning, so we shouldn't need to autoconfirm.
  auto dialog_action_reset =
      PermissionsRequestFunction::SetDialogActionForTests(
          PermissionsRequestFunction::DialogAction::kAutoReject);
  PermissionsRequestFunction::SetIgnoreUserGestureForTests(true);

  ExtensionPrefs* prefs = ExtensionPrefs::Get(profile());

  EXPECT_TRUE(RunExtensionTest("permissions/file_access_no")) << message_;
  EXPECT_FALSE(prefs->AllowFileAccess(last_loaded_extension_id()));
  EXPECT_TRUE(RunExtensionTest("permissions/file_access_yes", {},
                               {.allow_file_access = true}))
      << message_;
  EXPECT_TRUE(prefs->AllowFileAccess(last_loaded_extension_id()));
}

// Tests loading of files or directory listings when an extension has file
// access.
IN_PROC_BROWSER_TEST_F(PermissionsApiTest, FileLoad) {
#if BUILDFLAG(IS_ANDROID)
  // Enable access to arbitrary files via file: schema. Ordinarily Chrome on
  // Android blocks access to many directories, which affects the built-in
  // web server this test extension accesses.
  ChromeNetworkDelegate::EnableAccessToAllFilesForTesting(true);
#endif
  base::ScopedTempDir temp_dir;
  {
    base::ScopedAllowBlockingForTesting allow_blocking;
    ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
    base::FilePath empty_file = temp_dir.GetPath().AppendASCII("empty.html");
    base::FilePath dir_test_data;
    base::PathService::Get(chrome::DIR_TEST_DATA, &dir_test_data);
    base::FilePath original_empty_file =
        dir_test_data.AppendASCII("empty.html");

    EXPECT_TRUE(base::PathExists(original_empty_file));
    EXPECT_TRUE(base::CopyFile(original_empty_file, empty_file));
  }
  EXPECT_TRUE(RunExtensionTest(
      "permissions/file_load",
      {.custom_arg = temp_dir.GetPath().MaybeAsASCII().c_str()},
      {.allow_file_access = true}))
      << message_;
  {
    base::ScopedAllowBlockingForTesting allow_blocking;
    ASSERT_TRUE(temp_dir.Delete());
  }
}

// Test requesting, querying, and removing host permissions for host
// permissions that are a subset of the optional permissions.
IN_PROC_BROWSER_TEST_P(PermissionsApiTestWithContextType, HostSubsets) {
  auto dialog_action_reset =
      PermissionsRequestFunction::SetDialogActionForTests(
          PermissionsRequestFunction::DialogAction::kAutoConfirm);
  PermissionsRequestFunction::SetIgnoreUserGestureForTests(true);
  EXPECT_TRUE(RunExtensionTest("permissions/host_subsets")) << message_;
}

#if BUILDFLAG(ENABLE_EXTENSIONS)
// Tests that requesting an optional permission from a background page, with
// another window open, grants the permission and updates the bindings
// (chrome.whatever, in this case chrome.alarms). Regression test for
// crbug.com/435141, see details there for trickiness.
// TODO(crbug.com/371432155): Port to desktop Android when chrome.tabs API
// is available.
IN_PROC_BROWSER_TEST_F(PermissionsApiTest, OptionalPermissionsUpdatesBindings) {
  ASSERT_TRUE(RunExtensionTest("permissions/optional_updates_bindings"))
      << message_;
}
#endif  // BUILDFLAG(ENABLE_EXTENSIONS)

// Desktop Android only supports manifest V3 / service worker.
#if !BUILDFLAG(IS_ANDROID)
INSTANTIATE_TEST_SUITE_P(PersistentBackground,
                         PermissionsApiTestWithContextType,
                         testing::Values(ContextType::kPersistentBackground));
#endif
INSTANTIATE_TEST_SUITE_P(ServiceWorker,
                         PermissionsApiTestWithContextType,
                         testing::Values(ContextType::kServiceWorker));

class PermissionsApiHostAccessRequestsTest : public PermissionsApiTest {
 public:
  PermissionsApiHostAccessRequestsTest() {
    scoped_feature_list_.InitAndEnableFeature(
        extensions_features::kApiPermissionsHostAccessRequests);
  }
  ~PermissionsApiHostAccessRequestsTest() override = default;
  PermissionsApiHostAccessRequestsTest(
      const PermissionsApiHostAccessRequestsTest&) = delete;
  PermissionsApiHostAccessRequestsTest& operator=(
      const PermissionsApiHostAccessRequestsTest&) = delete;

 private:
  base::test::ScopedFeatureList scoped_feature_list_;
};

IN_PROC_BROWSER_TEST_F(PermissionsApiHostAccessRequestsTest,
                       InvalidAddHostAccessRequests) {
  ASSERT_TRUE(StartEmbeddedTestServer());

  ASSERT_TRUE(RunExtensionTest("permissions/add_host_access_request"))
      << message_;
}

IN_PROC_BROWSER_TEST_F(PermissionsApiHostAccessRequestsTest,
                       InvalidRemoveHostAccessRequests) {
  ASSERT_TRUE(StartEmbeddedTestServer());

  ASSERT_TRUE(RunExtensionTest("permissions/remove_host_access_request"))
      << message_;
}

}  // namespace extensions
