Commit eac9f8b3 authored by Christian Dullweber's avatar Christian Dullweber Committed by Commit Bot

Set kCookieControlsMode when kBlockThirdParty cookie is set by extension

An extension can use the privacy.websites.ThirdPartyCookiesAllowed
extension api to set the kBlockThirdPartyCookies preference.
kCookieControlsMode needs to be set to the corresponding value if
kBlockThirdPartyCookies is controlled by extension.

Bug: 1065392
Change-Id: Ib450349cb33251b3eccc06ff2dcc18a0899a028e
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2127034
Commit-Queue: Christian Dullweber <dullweber@chromium.org>
Reviewed-by: default avatarKen Rockot <rockot@google.com>
Cr-Commit-Position: refs/heads/master@{#755106}
parent 2d688ae4
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
#include "chrome/browser/net/prediction_options.h" #include "chrome/browser/net/prediction_options.h"
#include "chrome/common/pref_names.h" #include "chrome/common/pref_names.h"
#include "components/autofill/core/common/autofill_prefs.h" #include "components/autofill/core/common/autofill_prefs.h"
#include "components/content_settings/core/browser/cookie_settings.h"
#include "components/content_settings/core/common/pref_names.h" #include "components/content_settings/core/common/pref_names.h"
#include "components/data_reduction_proxy/core/common/data_reduction_proxy_pref_names.h" #include "components/data_reduction_proxy/core/common/data_reduction_proxy_pref_names.h"
#include "components/embedder_support/pref_names.h" #include "components/embedder_support/pref_names.h"
...@@ -817,6 +818,23 @@ ExtensionFunction::ResponseAction SetPreferenceFunction::Run() { ...@@ -817,6 +818,23 @@ ExtensionFunction::ResponseAction SetPreferenceFunction::Run() {
scope, base::Value(false)); scope, base::Value(false));
} }
// Whenever an extension takes control of the |kBlockThirdPartyCookies|
// preference, we must also set |kCookieControlsMode|.
// See crbug.com/1065392 for more background.
//
// kCookieControlsMode offers an additional setting to only block third-party
// cookies in incognito mode that can't be selected by extensions.
// Instead they can use the preference api in incognito mode directly if they
// are permitted to run there.
if (browser_pref == prefs::kBlockThirdPartyCookies) {
preference_api->SetExtensionControlledPref(
extension_id(), prefs::kCookieControlsMode, scope,
base::Value(static_cast<int>(
browser_pref_value->GetBool()
? content_settings::CookieControlsMode::kOn
: content_settings::CookieControlsMode::kOff)));
}
preference_api->SetExtensionControlledPref( preference_api->SetExtensionControlledPref(
extension_id(), browser_pref, scope, extension_id(), browser_pref, scope,
base::Value::FromUniquePtrValue(std::move(browser_pref_value))); base::Value::FromUniquePtrValue(std::move(browser_pref_value)));
...@@ -867,6 +885,15 @@ ExtensionFunction::ResponseAction ClearPreferenceFunction::Run() { ...@@ -867,6 +885,15 @@ ExtensionFunction::ResponseAction ClearPreferenceFunction::Run() {
Error(extensions::preference_api_constants::kPermissionErrorMessage, Error(extensions::preference_api_constants::kPermissionErrorMessage,
pref_key)); pref_key));
// Whenever an extension clears the |kBlockThirdPartyCookies| preference,
// it must also clear |kCookieControlsMode|.
// See crbug.com/1065392 for more background.
if (browser_pref == prefs::kBlockThirdPartyCookies) {
PreferenceAPI::Get(browser_context())
->RemoveExtensionControlledPref(extension_id(),
prefs::kCookieControlsMode, scope);
}
PreferenceAPI::Get(browser_context()) PreferenceAPI::Get(browser_context())
->RemoveExtensionControlledPref(extension_id(), browser_pref, scope); ->RemoveExtensionControlledPref(extension_id(), browser_pref, scope);
......
...@@ -21,6 +21,8 @@ ...@@ -21,6 +21,8 @@
#include "chrome/common/pref_names.h" #include "chrome/common/pref_names.h"
#include "chrome/test/base/ui_test_utils.h" #include "chrome/test/base/ui_test_utils.h"
#include "components/autofill/core/common/autofill_prefs.h" #include "components/autofill/core/common/autofill_prefs.h"
#include "components/content_settings/core/browser/cookie_settings.h"
#include "components/content_settings/core/common/features.h"
#include "components/content_settings/core/common/pref_names.h" #include "components/content_settings/core/common/pref_names.h"
#include "components/embedder_support/pref_names.h" #include "components/embedder_support/pref_names.h"
#include "components/keep_alive_registry/keep_alive_types.h" #include "components/keep_alive_registry/keep_alive_types.h"
...@@ -91,8 +93,9 @@ class ExtensionPreferenceApiTest : public extensions::ExtensionApiTest { ...@@ -91,8 +93,9 @@ class ExtensionPreferenceApiTest : public extensions::ExtensionApiTest {
// Verifies whether the boolean |preference| has the |expected_value| and is // Verifies whether the boolean |preference| has the |expected_value| and is
// |expected_controlled| by an extension. // |expected_controlled| by an extension.
void VerifyPrefValueAndControlledState(const std::string& preference, void VerifyPrefValueAndControlledState(const std::string& preference,
bool expected_value, const base::Value& expected_value,
bool expected_controlled) { bool expected_controlled) {
SCOPED_TRACE(preference); SCOPED_TRACE(preference);
...@@ -100,12 +103,18 @@ class ExtensionPreferenceApiTest : public extensions::ExtensionApiTest { ...@@ -100,12 +103,18 @@ class ExtensionPreferenceApiTest : public extensions::ExtensionApiTest {
const PrefService::Preference* pref = prefs->FindPreference(preference); const PrefService::Preference* pref = prefs->FindPreference(preference);
ASSERT_TRUE(pref); ASSERT_TRUE(pref);
const base::Value* actual_value = pref->GetValue(); const base::Value* actual_value = pref->GetValue();
ASSERT_TRUE(actual_value->is_bool()); EXPECT_EQ(expected_value.type(), actual_value->type());
EXPECT_EQ(expected_value, actual_value->GetBool()); EXPECT_EQ(expected_value, *actual_value);
EXPECT_EQ(expected_controlled, pref->IsExtensionControlled()); EXPECT_EQ(expected_controlled, pref->IsExtensionControlled());
} }
void SetUp() override {
extensions::ExtensionApiTest::SetUp();
feature_list.InitAndEnableFeature(
content_settings::kImprovedCookieControls);
}
void SetUpOnMainThread() override { void SetUpOnMainThread() override {
extensions::ExtensionApiTest::SetUpOnMainThread(); extensions::ExtensionApiTest::SetUpOnMainThread();
...@@ -131,6 +140,7 @@ class ExtensionPreferenceApiTest : public extensions::ExtensionApiTest { ...@@ -131,6 +140,7 @@ class ExtensionPreferenceApiTest : public extensions::ExtensionApiTest {
extensions::ExtensionApiTest::TearDownOnMainThread(); extensions::ExtensionApiTest::TearDownOnMainThread();
} }
base::test::ScopedFeatureList feature_list;
Profile* profile_; Profile* profile_;
std::unique_ptr<ScopedKeepAlive> keep_alive_; std::unique_ptr<ScopedKeepAlive> keep_alive_;
}; };
...@@ -446,10 +456,10 @@ IN_PROC_BROWSER_TEST_F(ExtensionPreferenceApiTest, SafeBrowsing_SetTrue) { ...@@ -446,10 +456,10 @@ IN_PROC_BROWSER_TEST_F(ExtensionPreferenceApiTest, SafeBrowsing_SetTrue) {
// set to TRUE, while |kSafeBrowsingEnhanced| is always FALSE. // set to TRUE, while |kSafeBrowsingEnhanced| is always FALSE.
ASSERT_TRUE(listener_true.WaitUntilSatisfied()); ASSERT_TRUE(listener_true.WaitUntilSatisfied());
VerifyPrefValueAndControlledState(prefs::kSafeBrowsingEnabled, VerifyPrefValueAndControlledState(prefs::kSafeBrowsingEnabled,
/* expected_value */ true, base::Value(true),
/* expected_controlled */ true); /* expected_controlled */ true);
VerifyPrefValueAndControlledState(prefs::kSafeBrowsingEnhanced, VerifyPrefValueAndControlledState(prefs::kSafeBrowsingEnhanced,
/* expected_value */ false, base::Value(false),
/* expected_controlled */ true); /* expected_controlled */ true);
listener_true.Reply("ok"); listener_true.Reply("ok");
...@@ -458,10 +468,10 @@ IN_PROC_BROWSER_TEST_F(ExtensionPreferenceApiTest, SafeBrowsing_SetTrue) { ...@@ -458,10 +468,10 @@ IN_PROC_BROWSER_TEST_F(ExtensionPreferenceApiTest, SafeBrowsing_SetTrue) {
// default values - TRUE and FALSE, respectively. // default values - TRUE and FALSE, respectively.
ASSERT_TRUE(listener_clear.WaitUntilSatisfied()); ASSERT_TRUE(listener_clear.WaitUntilSatisfied());
VerifyPrefValueAndControlledState(prefs::kSafeBrowsingEnabled, VerifyPrefValueAndControlledState(prefs::kSafeBrowsingEnabled,
/* expected_value */ true, base::Value(true),
/* expected_controlled */ false); /* expected_controlled */ false);
VerifyPrefValueAndControlledState(prefs::kSafeBrowsingEnhanced, VerifyPrefValueAndControlledState(prefs::kSafeBrowsingEnhanced,
/* expected_value */ false, base::Value(false),
/* expected_controlled */ false); /* expected_controlled */ false);
listener_clear.Reply("ok"); listener_clear.Reply("ok");
...@@ -470,10 +480,10 @@ IN_PROC_BROWSER_TEST_F(ExtensionPreferenceApiTest, SafeBrowsing_SetTrue) { ...@@ -470,10 +480,10 @@ IN_PROC_BROWSER_TEST_F(ExtensionPreferenceApiTest, SafeBrowsing_SetTrue) {
// set to FALSE, and |kSafeBrowsingEnhanced| is also FALSE. // set to FALSE, and |kSafeBrowsingEnhanced| is also FALSE.
ASSERT_TRUE(listener_false.WaitUntilSatisfied()); ASSERT_TRUE(listener_false.WaitUntilSatisfied());
VerifyPrefValueAndControlledState(prefs::kSafeBrowsingEnabled, VerifyPrefValueAndControlledState(prefs::kSafeBrowsingEnabled,
/* expected_value */ false, base::Value(false),
/* expected_controlled */ true); /* expected_controlled */ true);
VerifyPrefValueAndControlledState(prefs::kSafeBrowsingEnhanced, VerifyPrefValueAndControlledState(prefs::kSafeBrowsingEnhanced,
/* expected_value */ false, base::Value(false),
/* expected_controlled */ true); /* expected_controlled */ true);
listener_false.Reply("ok"); listener_false.Reply("ok");
...@@ -483,9 +493,83 @@ IN_PROC_BROWSER_TEST_F(ExtensionPreferenceApiTest, SafeBrowsing_SetTrue) { ...@@ -483,9 +493,83 @@ IN_PROC_BROWSER_TEST_F(ExtensionPreferenceApiTest, SafeBrowsing_SetTrue) {
ASSERT_TRUE(listener_done.WaitUntilSatisfied()); ASSERT_TRUE(listener_done.WaitUntilSatisfied());
UninstallExtension(extension->id()); UninstallExtension(extension->id());
VerifyPrefValueAndControlledState(prefs::kSafeBrowsingEnabled, VerifyPrefValueAndControlledState(prefs::kSafeBrowsingEnabled,
/* expected_value */ true, base::Value(true),
/* expected_controlled */ false); /* expected_controlled */ false);
VerifyPrefValueAndControlledState(prefs::kSafeBrowsingEnhanced, VerifyPrefValueAndControlledState(prefs::kSafeBrowsingEnhanced,
/* expected_value */ false, base::Value(false),
/* expected_controlled */ false);
}
// Tests the behavior of the ThirdPartyCookies preference API.
// kCookieControlsMode should be enforced to kOn/kOff if kBlockThirdPartyCookies
// is set to true/false by an extension.
IN_PROC_BROWSER_TEST_F(ExtensionPreferenceApiTest, ThirdPartyCookiesAllowed) {
ExtensionTestMessageListener listener_true("set to true",
/* will_reply */ true);
ExtensionTestMessageListener listener_clear("cleared", /* will_reply */ true);
ExtensionTestMessageListener listener_false("set to false",
/* will_reply */ true);
ExtensionTestMessageListener listener_done("done", /* will_reply */ false);
// Verify initial state.
VerifyPrefValueAndControlledState(prefs::kBlockThirdPartyCookies,
base::Value(false),
/* expected_controlled */ false);
VerifyPrefValueAndControlledState(
prefs::kCookieControlsMode,
base::Value(static_cast<int>(
content_settings::CookieControlsMode::kIncognitoOnly)),
/* expected_controlled */ false);
const base::FilePath extension_path =
test_data_dir_.AppendASCII("preference")
.AppendASCII("third_party_cookies_allowed");
const extensions::Extension* extension = LoadExtension(extension_path);
ASSERT_TRUE(extension);
// Step 1. of the test sets the API to TRUE.
ASSERT_TRUE(listener_true.WaitUntilSatisfied());
VerifyPrefValueAndControlledState(prefs::kBlockThirdPartyCookies,
base::Value(false),
/* expected_controlled */ true);
VerifyPrefValueAndControlledState(
prefs::kCookieControlsMode,
base::Value(static_cast<int>(content_settings::CookieControlsMode::kOff)),
/* expected_controlled */ true);
listener_true.Reply("ok");
// Step 2. of the test clears the value.
ASSERT_TRUE(listener_clear.WaitUntilSatisfied());
VerifyPrefValueAndControlledState(prefs::kBlockThirdPartyCookies,
base::Value(false),
/* expected_controlled */ false);
VerifyPrefValueAndControlledState(
prefs::kCookieControlsMode,
base::Value(static_cast<int>(
content_settings::CookieControlsMode::kIncognitoOnly)),
/* expected_controlled */ false);
listener_clear.Reply("ok");
// Step 3. of the test sets the API to FALSE.
ASSERT_TRUE(listener_false.WaitUntilSatisfied());
VerifyPrefValueAndControlledState(prefs::kBlockThirdPartyCookies,
base::Value(true),
/* expected_controlled */ true);
VerifyPrefValueAndControlledState(
prefs::kCookieControlsMode,
base::Value(static_cast<int>(content_settings::CookieControlsMode::kOn)),
/* expected_controlled */ true);
listener_false.Reply("ok");
// Step 4. of the test uninstalls the extension.
ASSERT_TRUE(listener_done.WaitUntilSatisfied());
UninstallExtension(extension->id());
VerifyPrefValueAndControlledState(prefs::kBlockThirdPartyCookies,
base::Value(false),
/* expected_controlled */ false); /* expected_controlled */ false);
VerifyPrefValueAndControlledState(
prefs::kCookieControlsMode,
base::Value(static_cast<int>(
content_settings::CookieControlsMode::kIncognitoOnly)),
/* expected_controlled */ false);
} }
{
"name" : "Preferences API Test Extension (thirdPartyCookiesAllowed)",
"version" : "0.1",
"manifest_version": 2,
"description" : "Preferences API Test Extension (thirdPartyCookiesAllowed)",
"permissions": [ "privacy" ],
"background": {
"page": "test.html"
}
}
<!--
* Copyright 2020 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.
-->
<script src="test.js"></script>
// Copyright 2020 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.
// Content settings API test
// Run with browser_tests
// --gtest_filter=ExtensionPreferenceApiTest.ThirdPartyCookiesAllowed
function setTrue() {
return new Promise((resolve) => {
chrome.privacy.websites.thirdPartyCookiesAllowed.set({ value: true },
() => chrome.test.sendMessage("set to true", resolve))
});
}
function setFalse() {
return new Promise((resolve) => {
chrome.privacy.websites.thirdPartyCookiesAllowed.set({ value: false },
() => chrome.test.sendMessage("set to false", resolve))
});
}
function clearPref() {
return new Promise((resolve) => {
chrome.privacy.websites.thirdPartyCookiesAllowed.clear({},
() => chrome.test.sendMessage("cleared", resolve))
});
}
(async () => {
await setTrue();
await clearPref();
await setFalse();
chrome.test.sendMessage("done");
})();
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment