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

#include "content/browser/permissions/permission_controller_impl.h"

#include <cstdlib>
#include <memory>

#include "base/memory/ptr_util.h"
#include "base/test/mock_callback.h"
#include "content/public/browser/permission_controller_delegate.h"
#include "content/public/test/browser_task_environment.h"
#include "content/public/test/mock_permission_manager.h"
#include "content/public/test/test_browser_context.h"
#include "content/public/test/test_renderer_host.h"
#include "content/public/test/web_contents_tester.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/common/permissions/permission_utils.h"
#include "url/origin.h"

using blink::PermissionType;

namespace content {

namespace {
using ::testing::Unused;
using OverrideStatus = PermissionControllerImpl::OverrideStatus;
using RequestsCallback = base::OnceCallback<void(
    const std::vector<blink::mojom::PermissionStatus>&)>;

constexpr char kTestUrl[] = "https://google.com";

class MockManagerWithRequests : public MockPermissionManager {
 public:
  MockManagerWithRequests() {}

  MockManagerWithRequests(const MockManagerWithRequests&) = delete;
  MockManagerWithRequests& operator=(const MockManagerWithRequests&) = delete;

  ~MockManagerWithRequests() override {}
  MOCK_METHOD(
      void,
      RequestPermissionsFromCurrentDocument,
      (const std::vector<PermissionType>& permission,
       RenderFrameHost* render_frame_host,
       bool user_gesture,
       const base::OnceCallback<
           void(const std::vector<blink::mojom::PermissionStatus>&)> callback),
      (override));
  MOCK_METHOD(
      void,
      RequestPermissions,
      (const std::vector<PermissionType>& permission,
       RenderFrameHost* render_frame_host,
       const GURL& requesting_origin,
       bool user_gesture,
       const base::OnceCallback<
           void(const std::vector<blink::mojom::PermissionStatus>&)> callback),
      (override));
  MOCK_METHOD(void,
              SetPermissionOverridesForDevTools,
              (const absl::optional<url::Origin>& origin,
               const PermissionOverrides& overrides),
              (override));
  MOCK_METHOD(void, ResetPermissionOverridesForDevTools, (), (override));
  MOCK_METHOD(bool,
              IsPermissionOverridableByDevTools,
              (PermissionType, const absl::optional<url::Origin>&),
              (override));
};

// Results are defined based on assumption that same types are queried for
// each test case.
const struct {
  std::map<PermissionType, blink::mojom::PermissionStatus> overrides;

  std::vector<PermissionType> delegated_permissions;
  std::vector<blink::mojom::PermissionStatus> delegated_statuses;

  std::vector<blink::mojom::PermissionStatus> expected_results;
  bool expect_death;
} kTestPermissionRequestCases[] = {
    // No overrides present - all delegated.
    {{},
     {PermissionType::GEOLOCATION, PermissionType::BACKGROUND_SYNC,
      PermissionType::MIDI_SYSEX},
     {blink::mojom::PermissionStatus::DENIED,
      blink::mojom::PermissionStatus::GRANTED,
      blink::mojom::PermissionStatus::GRANTED},
     {blink::mojom::PermissionStatus::DENIED,
      blink::mojom::PermissionStatus::GRANTED,
      blink::mojom::PermissionStatus::GRANTED},
     /*expect_death=*/false},

    // No delegates needed - all overridden.
    {{{PermissionType::GEOLOCATION, blink::mojom::PermissionStatus::GRANTED},
      {PermissionType::BACKGROUND_SYNC,
       blink::mojom::PermissionStatus::GRANTED},
      {PermissionType::MIDI_SYSEX, blink::mojom::PermissionStatus::ASK}},
     {},
     {},
     {blink::mojom::PermissionStatus::GRANTED,
      blink::mojom::PermissionStatus::GRANTED,
      blink::mojom::PermissionStatus::ASK},
     /*expect_death=*/false},

    // Some overridden, some delegated.
    {{{PermissionType::BACKGROUND_SYNC,
       blink::mojom::PermissionStatus::DENIED}},
     {PermissionType::GEOLOCATION, PermissionType::MIDI_SYSEX},
     {blink::mojom::PermissionStatus::GRANTED,
      blink::mojom::PermissionStatus::ASK},
     {blink::mojom::PermissionStatus::GRANTED,
      blink::mojom::PermissionStatus::DENIED,
      blink::mojom::PermissionStatus::ASK},
     /*expect_death=*/false},

    // Some overridden, some delegated.
    {{{PermissionType::GEOLOCATION, blink::mojom::PermissionStatus::GRANTED},
      {PermissionType::BACKGROUND_SYNC,
       blink::mojom::PermissionStatus::DENIED}},
     {PermissionType::MIDI_SYSEX},
     {blink::mojom::PermissionStatus::ASK},
     {blink::mojom::PermissionStatus::GRANTED,
      blink::mojom::PermissionStatus::DENIED,
      blink::mojom::PermissionStatus::ASK},
     /*expect_death=*/false},

    // Too many delegates (causes death).
    {{{PermissionType::GEOLOCATION, blink::mojom::PermissionStatus::GRANTED},
      {PermissionType::MIDI_SYSEX, blink::mojom::PermissionStatus::ASK}},
     {PermissionType::BACKGROUND_SYNC},
     {blink::mojom::PermissionStatus::DENIED,
      blink::mojom::PermissionStatus::GRANTED},
     // Results don't matter because will die.
     {},
     /*expect_death=*/true},

    // Too few delegates (causes death).
    {{},
     {PermissionType::GEOLOCATION, PermissionType::BACKGROUND_SYNC,
      PermissionType::MIDI_SYSEX},
     {blink::mojom::PermissionStatus::GRANTED,
      blink::mojom::PermissionStatus::GRANTED},
     // Results don't matter because will die.
     {},
     /*expect_death=*/true}};

}  // namespace

class PermissionControllerImplTest : public ::testing::Test {
 public:
  PermissionControllerImplTest() {
    browser_context_.SetPermissionControllerDelegate(
        std::make_unique<::testing::NiceMock<MockManagerWithRequests>>());
    permission_controller_ =
        std::make_unique<PermissionControllerImpl>(&browser_context_);
  }

  PermissionControllerImplTest(const PermissionControllerImplTest&) = delete;
  PermissionControllerImplTest& operator=(const PermissionControllerImplTest&) =
      delete;

  ~PermissionControllerImplTest() override {}

  void SetUp() override {
    ON_CALL(*mock_manager(), IsPermissionOverridableByDevTools)
        .WillByDefault(testing::Return(true));
  }

  PermissionControllerImpl* permission_controller() {
    return permission_controller_.get();
  }

  void PermissionControllerRequestPermissionsFromCurrentDocument(
      const std::vector<PermissionType>& permission,
      RenderFrameHost* render_frame_host,
      bool user_gesture,
      base::OnceCallback<
          void(const std::vector<blink::mojom::PermissionStatus>&)> callback) {
    permission_controller()->RequestPermissionsFromCurrentDocument(
        permission, render_frame_host, user_gesture, std::move(callback));
  }

  void PermissionControllerRequestPermissions(
      const std::vector<PermissionType>& permission,
      RenderFrameHost* render_frame_host,
      const url::Origin& requested_origin,
      bool user_gesture,
      base::OnceCallback<
          void(const std::vector<blink::mojom::PermissionStatus>&)> callback) {
    permission_controller()->RequestPermissions(permission, render_frame_host,
                                                requested_origin, user_gesture,
                                                std::move(callback));
  }

  blink::mojom::PermissionStatus GetPermissionStatusForWorker(
      PermissionType permission,
      RenderProcessHost* render_process_host,
      const url::Origin& worker_origin) {
    return permission_controller()->GetPermissionStatusForWorker(
        permission, render_process_host, worker_origin);
  }

  BrowserContext* browser_context() { return &browser_context_; }

  MockManagerWithRequests* mock_manager() {
    return static_cast<MockManagerWithRequests*>(
        browser_context_.GetPermissionControllerDelegate());
  }

 private:
  content::BrowserTaskEnvironment task_environment_;
  TestBrowserContext browser_context_;
  std::unique_ptr<PermissionControllerImpl> permission_controller_;
};

TEST_F(PermissionControllerImplTest, ResettingOverridesForwardsReset) {
  EXPECT_CALL(*mock_manager(), ResetPermissionOverridesForDevTools());
  permission_controller()->ResetOverridesForDevTools();
}

TEST_F(PermissionControllerImplTest, SettingOverridesForwardsUpdates) {
  auto kTestOrigin = absl::make_optional(url::Origin::Create(GURL(kTestUrl)));
  EXPECT_CALL(*mock_manager(),
              SetPermissionOverridesForDevTools(
                  kTestOrigin, testing::ElementsAre(testing::Pair(
                                   PermissionType::GEOLOCATION,
                                   blink::mojom::PermissionStatus::GRANTED))));
  permission_controller()->SetOverrideForDevTools(
      kTestOrigin, PermissionType::GEOLOCATION,
      blink::mojom::PermissionStatus::GRANTED);
}

TEST_F(PermissionControllerImplTest,
       RequestPermissionsFromCurrentDocumentDelegatesIffMissingOverrides) {
  url::Origin kTestOrigin = url::Origin::Create(GURL(kTestUrl));
  RenderViewHostTestEnabler enabler;

  const std::vector<PermissionType> kTypesToQuery = {
      PermissionType::GEOLOCATION, PermissionType::BACKGROUND_SYNC,
      PermissionType::MIDI_SYSEX};

  std::unique_ptr<WebContents> web_contents(
      WebContentsTester::CreateTestWebContents(
          WebContents::CreateParams(browser_context())));

  WebContentsTester* web_contents_tester =
      WebContentsTester::For(web_contents.get());
  web_contents_tester->NavigateAndCommit(GURL(kTestUrl));

  RenderFrameHost* rfh = web_contents->GetPrimaryMainFrame();
  for (const auto& test_case : kTestPermissionRequestCases) {
    // Need to reset overrides for each case to ensure delegation is as
    // expected.
    permission_controller()->ResetOverridesForDevTools();
    for (const auto& permission_status_pair : test_case.overrides) {
      permission_controller()->SetOverrideForDevTools(
          kTestOrigin, permission_status_pair.first,
          permission_status_pair.second);
    }

    // Expect request permission from current document calls if override are
    // missing.
    if (!test_case.delegated_permissions.empty()) {
      auto forward_callbacks = testing::WithArg<3>(
          [&test_case](base::OnceCallback<void(
                           const std::vector<blink::mojom::PermissionStatus>&)>
                           callback) {
            std::move(callback).Run(test_case.delegated_statuses);
            return 0;
          });
      // Regular tests can set expectations.
      if (test_case.expect_death) {
        // Death tests cannot track these expectations but arguments should be
        // forwarded to ensure death occurs.
        ON_CALL(*mock_manager(),
                RequestPermissionsFromCurrentDocument(
                    testing::ElementsAreArray(test_case.delegated_permissions),
                    rfh, true, testing::_))
            .WillByDefault(testing::Invoke(forward_callbacks));
      } else {
        EXPECT_CALL(
            *mock_manager(),
            RequestPermissionsFromCurrentDocument(
                testing::ElementsAreArray(test_case.delegated_permissions), rfh,
                true, testing::_))
            .WillOnce(testing::Invoke(forward_callbacks));
      }
    } else {
      // There should be no call to delegate if all overrides are defined.
      EXPECT_CALL(*mock_manager(), RequestPermissionsFromCurrentDocument)
          .Times(0);
    }

    if (test_case.expect_death) {
      ::testing::FLAGS_gtest_death_test_style = "threadsafe";
      base::MockCallback<RequestsCallback> callback;
      EXPECT_DEATH_IF_SUPPORTED(
          PermissionControllerRequestPermissionsFromCurrentDocument(
              kTypesToQuery, rfh,
              /*user_gesture=*/true, callback.Get()),
          "");
    } else {
      base::MockCallback<RequestsCallback> callback;
      EXPECT_CALL(callback,
                  Run(testing::ElementsAreArray(test_case.expected_results)));
      PermissionControllerRequestPermissionsFromCurrentDocument(
          kTypesToQuery, rfh,
          /*user_gesture=*/true, callback.Get());
    }
  }
}

TEST_F(PermissionControllerImplTest,
       RequestPermissionsDelegatesIffMissingOverrides) {
  url::Origin kTestOrigin = url::Origin::Create(GURL(kTestUrl));
  RenderViewHostTestEnabler enabler;

  const std::vector<PermissionType> kTypesToQuery = {
      PermissionType::GEOLOCATION, PermissionType::BACKGROUND_SYNC,
      PermissionType::MIDI_SYSEX};

  std::unique_ptr<WebContents> web_contents(
      WebContentsTester::CreateTestWebContents(
          WebContents::CreateParams(browser_context())));

  WebContentsTester* web_contents_tester =
      WebContentsTester::For(web_contents.get());
  url::Origin testing_origin = url::Origin::Create(GURL(kTestUrl));
  web_contents_tester->NavigateAndCommit(testing_origin.GetURL());

  RenderFrameHost* rfh = web_contents->GetPrimaryMainFrame();
  for (const auto& test_case : kTestPermissionRequestCases) {
    // Need to reset overrides for each case to ensure delegation is as
    // expected.
    permission_controller()->ResetOverridesForDevTools();
    for (const auto& permission_status_pair : test_case.overrides) {
      permission_controller()->SetOverrideForDevTools(
          kTestOrigin, permission_status_pair.first,
          permission_status_pair.second);
    }

    // Expect request permission call if override are missing.
    if (!test_case.delegated_permissions.empty()) {
      auto forward_callbacks = testing::WithArg<4>(
          [&test_case](base::OnceCallback<void(
                           const std::vector<blink::mojom::PermissionStatus>&)>
                           callback) {
            std::move(callback).Run(test_case.delegated_statuses);
            return 0;
          });
      // Regular tests can set expectations.
      if (test_case.expect_death) {
        // Death tests cannot track these expectations but arguments should be
        // forwarded to ensure death occurs.
        ON_CALL(*mock_manager(),
                RequestPermissions(
                    testing::ElementsAreArray(test_case.delegated_permissions),
                    rfh, testing::_, true, testing::_))
            .WillByDefault(testing::Invoke(forward_callbacks));
      } else {
        EXPECT_CALL(*mock_manager(),
                    RequestPermissions(testing::ElementsAreArray(
                                           test_case.delegated_permissions),
                                       rfh, testing::_, true, testing::_))
            .WillOnce(testing::Invoke(forward_callbacks));
      }
    } else {
      // There should be no call to delegate if all overrides are defined.
      EXPECT_CALL(*mock_manager(), RequestPermissionsFromCurrentDocument)
          .Times(0);
    }

    if (test_case.expect_death) {
      ::testing::FLAGS_gtest_death_test_style = "threadsafe";
      base::MockCallback<RequestsCallback> callback;
      EXPECT_DEATH_IF_SUPPORTED(PermissionControllerRequestPermissions(
                                    kTypesToQuery, rfh, testing_origin,
                                    /*user_gesture=*/true, callback.Get()),
                                "");
    } else {
      base::MockCallback<RequestsCallback> callback;
      EXPECT_CALL(callback,
                  Run(testing::ElementsAreArray(test_case.expected_results)));
      PermissionControllerRequestPermissions(kTypesToQuery, rfh, testing_origin,
                                             /*user_gesture=*/true,
                                             callback.Get());
    }
  }
}

TEST_F(PermissionControllerImplTest,
       NotifyChangedSubscriptionsCallsOnChangeOnly) {
  using PermissionStatusCallback =
      base::RepeatingCallback<void(blink::mojom::PermissionStatus)>;
  GURL kUrl = GURL(kTestUrl);
  url::Origin kTestOrigin = url::Origin::Create(kUrl);

  // Setup.
  blink::mojom::PermissionStatus sync_status = GetPermissionStatusForWorker(
      PermissionType::BACKGROUND_SYNC,
      /*render_process_host=*/nullptr, kTestOrigin);
  permission_controller()->SetOverrideForDevTools(
      kTestOrigin, PermissionType::GEOLOCATION,
      blink::mojom::PermissionStatus::DENIED);

  base::MockCallback<PermissionStatusCallback> geo_callback;
  permission_controller()->SubscribePermissionStatusChange(
      PermissionType::GEOLOCATION, nullptr, nullptr, kUrl, geo_callback.Get());

  base::MockCallback<PermissionStatusCallback> sync_callback;
  permission_controller()->SubscribePermissionStatusChange(
      PermissionType::BACKGROUND_SYNC, nullptr, nullptr, kUrl,
      sync_callback.Get());

  // Geolocation should change status, so subscriber is updated.
  EXPECT_CALL(geo_callback, Run(blink::mojom::PermissionStatus::ASK));
  EXPECT_CALL(sync_callback, Run).Times(0);
  permission_controller()->SetOverrideForDevTools(
      kTestOrigin, PermissionType::GEOLOCATION,
      blink::mojom::PermissionStatus::ASK);

  // Callbacks should not be called again because permission status has not
  // changed.
  permission_controller()->SetOverrideForDevTools(
      kTestOrigin, PermissionType::BACKGROUND_SYNC, sync_status);
  permission_controller()->SetOverrideForDevTools(
      kTestOrigin, PermissionType::GEOLOCATION,
      blink::mojom::PermissionStatus::ASK);
}

TEST_F(PermissionControllerImplTest,
       PermissionsCannotBeOverriddenIfNotOverridable) {
  url::Origin kTestOrigin = url::Origin::Create(GURL(kTestUrl));
  EXPECT_EQ(OverrideStatus::kOverrideSet,
            permission_controller()->SetOverrideForDevTools(
                kTestOrigin, PermissionType::GEOLOCATION,
                blink::mojom::PermissionStatus::DENIED));

  // Delegate will be called, but prevents override from being set.
  EXPECT_CALL(*mock_manager(), IsPermissionOverridableByDevTools(
                                   PermissionType::GEOLOCATION, testing::_))
      .WillOnce(testing::Return(false));
  EXPECT_EQ(OverrideStatus::kOverrideNotSet,
            permission_controller()->SetOverrideForDevTools(
                kTestOrigin, PermissionType::GEOLOCATION,
                blink::mojom::PermissionStatus::ASK));

  blink::mojom::PermissionStatus status = GetPermissionStatusForWorker(
      PermissionType::GEOLOCATION, /*render_process_host=*/nullptr,
      kTestOrigin);
  EXPECT_EQ(blink::mojom::PermissionStatus::DENIED, status);
}

TEST_F(PermissionControllerImplTest,
       GrantPermissionsReturnsStatusesBeingSetIfOverridable) {
  GURL kUrl(kTestUrl);
  url::Origin kTestOrigin = url::Origin::Create(kUrl);
  permission_controller()->SetOverrideForDevTools(
      kTestOrigin, PermissionType::GEOLOCATION,
      blink::mojom::PermissionStatus::DENIED);
  permission_controller()->SetOverrideForDevTools(
      kTestOrigin, PermissionType::MIDI, blink::mojom::PermissionStatus::ASK);
  permission_controller()->SetOverrideForDevTools(
      kTestOrigin, PermissionType::BACKGROUND_SYNC,
      blink::mojom::PermissionStatus::ASK);
  // Delegate will be called, but prevents override from being set.
  EXPECT_CALL(*mock_manager(), IsPermissionOverridableByDevTools(
                                   PermissionType::GEOLOCATION, testing::_))
      .WillOnce(testing::Return(false));
  EXPECT_CALL(*mock_manager(), IsPermissionOverridableByDevTools(
                                   PermissionType::MIDI, testing::_))
      .WillOnce(testing::Return(true));

  // Since one cannot be overridden, none are overridden.
  auto result = permission_controller()->GrantOverridesForDevTools(
      kTestOrigin, {PermissionType::MIDI, PermissionType::GEOLOCATION,
                    PermissionType::BACKGROUND_SYNC});
  EXPECT_EQ(OverrideStatus::kOverrideNotSet, result);

  // Keep original settings as before.
  EXPECT_EQ(blink::mojom::PermissionStatus::DENIED,
            GetPermissionStatusForWorker(PermissionType::GEOLOCATION,
                                         /*render_process_host=*/nullptr,
                                         kTestOrigin));
  EXPECT_EQ(
      blink::mojom::PermissionStatus::ASK,
      GetPermissionStatusForWorker(
          PermissionType::MIDI, /*render_process_host=*/nullptr, kTestOrigin));
  EXPECT_EQ(blink::mojom::PermissionStatus::ASK,
            GetPermissionStatusForWorker(PermissionType::BACKGROUND_SYNC,
                                         /*render_process_host=*/nullptr,
                                         kTestOrigin));

  EXPECT_CALL(*mock_manager(), IsPermissionOverridableByDevTools(
                                   PermissionType::GEOLOCATION, testing::_))
      .WillOnce(testing::Return(true));
  EXPECT_CALL(*mock_manager(), IsPermissionOverridableByDevTools(
                                   PermissionType::MIDI, testing::_))
      .WillOnce(testing::Return(true));
  EXPECT_CALL(*mock_manager(), IsPermissionOverridableByDevTools(
                                   PermissionType::BACKGROUND_SYNC, testing::_))
      .WillOnce(testing::Return(true));
  // If all can be set, overrides will be stored.
  result = permission_controller()->GrantOverridesForDevTools(
      kTestOrigin, {PermissionType::MIDI, PermissionType::GEOLOCATION,
                    PermissionType::BACKGROUND_SYNC});
  EXPECT_EQ(OverrideStatus::kOverrideSet, result);
  EXPECT_EQ(blink::mojom::PermissionStatus::GRANTED,
            GetPermissionStatusForWorker(PermissionType::GEOLOCATION,
                                         /*render_process_host=*/nullptr,
                                         kTestOrigin));
  EXPECT_EQ(
      blink::mojom::PermissionStatus::GRANTED,
      GetPermissionStatusForWorker(
          PermissionType::MIDI, /*render_process_host=*/nullptr, kTestOrigin));
  EXPECT_EQ(blink::mojom::PermissionStatus::GRANTED,
            GetPermissionStatusForWorker(PermissionType::BACKGROUND_SYNC,
                                         /*render_process_host=*/nullptr,
                                         kTestOrigin));
}

}  // namespace content
