Commit 9c1e7e35 authored by sauski's avatar sauski Committed by Chromium LUCI CQ

Privacy Sandbox: Implement Conversion Measurement settings functions

Replace the stub functions for conversion measurement on the
PrivacySettingsSandbox class with implementations that respect both
the privacy sandbox preferences and cookie content settings.

Bug: 1152336
Change-Id: I1d7baed13f9830f95f389d26d80629cec17e2988
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2569653Reviewed-by: default avatarChristian Dullweber <dullweber@chromium.org>
Reviewed-by: default avatarMartin Šrámek <msramek@chromium.org>
Commit-Queue: Theodore Olsauskas-Warren <sauski@google.com>
Cr-Commit-Position: refs/heads/master@{#834647}
parent f11e7ff7
......@@ -61,25 +61,10 @@ PrivacySandboxSettings::PrivacySandboxSettings(
bool PrivacySandboxSettings::IsFlocAllowed(
const GURL& url,
const base::Optional<url::Origin>& top_frame_origin) const {
if (!base::FeatureList::IsEnabled(features::kPrivacySandboxSettings)) {
// Simply respect cookie settings if the UI is not available. An empty site
// for cookies is provided so the context is always as a third party.
return cookie_settings_->IsCookieAccessAllowed(url, GURL(),
top_frame_origin);
}
if (!pref_service_->GetBoolean(prefs::kPrivacySandboxApisEnabled))
return false;
// TODO (crbug.com/1155504): Bypassing CookieSettings to access content
// settings directly ignores allowlisted schemes and the storage access API.
// These should be taken into account here.
ContentSettingsForOneType cookie_settings;
cookie_settings_->GetCookieSettings(&cookie_settings);
return !HasNonDefaultBlockSetting(
cookie_settings, url,
top_frame_origin ? top_frame_origin->GetURL() : GURL());
return IsPrivacySandboxAllowed(url, top_frame_origin, cookie_settings);
}
base::Time PrivacySandboxSettings::FlocDataAccessibleSince() const {
......@@ -91,16 +76,50 @@ base::Time PrivacySandboxSettings::FlocDataAccessibleSince() const {
bool PrivacySandboxSettings::IsConversionMeasurementAllowed(
const url::Origin& top_frame_origin,
const url::Origin& reporting_origin) const {
// Simply respect the 3P cookie setting.
// TODO(crbug.com/1152336): Respect privacy sandbox settings.
return !cookie_settings_->ShouldBlockThirdPartyCookies();
ContentSettingsForOneType cookie_settings;
cookie_settings_->GetCookieSettings(&cookie_settings);
return IsPrivacySandboxAllowed(reporting_origin.GetURL(), top_frame_origin,
cookie_settings);
}
bool PrivacySandboxSettings::ShouldSendConversionReport(
const url::Origin& impression_origin,
const url::Origin& conversion_origin,
const url::Origin& reporting_origin) const {
// Simply respect the 3P cookie setting.
// TODO(crbug.com/1152336): Respect privacy sandbox settings.
return !cookie_settings_->ShouldBlockThirdPartyCookies();
// Re-using the |cookie_settings| allows this function to be faster
// than simply calling IsConversionMeasurementAllowed() twice
ContentSettingsForOneType cookie_settings;
cookie_settings_->GetCookieSettings(&cookie_settings);
// The |reporting_origin| needs to have been accessible in both impression
// and conversion contexts. These are both checked when they occur, but
// user settings may have changed between then and when the conversion report
// is sent.
return IsPrivacySandboxAllowed(reporting_origin.GetURL(), impression_origin,
cookie_settings) &&
IsPrivacySandboxAllowed(reporting_origin.GetURL(), reporting_origin,
cookie_settings);
}
bool PrivacySandboxSettings::IsPrivacySandboxAllowed(
const GURL& url,
const base::Optional<url::Origin>& top_frame_origin,
const ContentSettingsForOneType& cookie_settings) const {
if (!base::FeatureList::IsEnabled(features::kPrivacySandboxSettings)) {
// Simply respect cookie settings if the UI is not available. An empty site
// for cookies is provided so the context is always as a third party.
return cookie_settings_->IsCookieAccessAllowed(url, GURL(),
top_frame_origin);
}
if (!pref_service_->GetBoolean(prefs::kPrivacySandboxApisEnabled))
return false;
// TODO (crbug.com/1155504): Bypassing the CookieSettings class to access
// content settings directly ignores allowlisted schemes and the storage
// access API. These should be taken into account here.
return !HasNonDefaultBlockSetting(
cookie_settings, url,
top_frame_origin ? top_frame_origin->GetURL() : GURL());
}
......@@ -60,6 +60,17 @@ class PrivacySandboxSettings : public KeyedService {
const url::Origin& conversion_origin,
const url::Origin& reporting_origin) const;
protected:
// Determines based on the current features, preferences and provided
// |cookie_settings| whether Privacy Sandbox APIs are generally allowable for
// |url| on |top_frame_origin|. Individual APIs may perform additional checks
// for allowability (such as incognito) ontop of this. |cookie_settings| is
// provided as a parameter to allow callers to cache it between calls.
bool IsPrivacySandboxAllowed(
const GURL& url,
const base::Optional<url::Origin>& top_frame_origin,
const ContentSettingsForOneType& cookie_settings) const;
private:
content_settings::CookieSettings* cookie_settings_;
PrefService* pref_service_;
......
......@@ -4,6 +4,7 @@
#include "chrome/browser/privacy_sandbox/privacy_sandbox_settings.h"
#include "base/test/gtest_util.h"
#include "base/test/scoped_feature_list.h"
#include "chrome/browser/content_settings/cookie_settings_factory.h"
#include "chrome/browser/content_settings/host_content_settings_map_factory.h"
......@@ -111,10 +112,12 @@ class PrivacySandboxSettingsTest : public testing::Test {
}
base::test::ScopedFeatureList* feature_list() { return &feature_list_; }
protected:
std::unique_ptr<PrivacySandboxSettings> privacy_sandbox_settings_;
private:
content::BrowserTaskEnvironment browser_task_environment_;
TestingProfile profile_;
std::unique_ptr<PrivacySandboxSettings> privacy_sandbox_settings_;
base::test::ScopedFeatureList feature_list_;
};
......@@ -132,6 +135,14 @@ TEST_F(PrivacySandboxSettingsTest, CookieSettingAppliesWhenUiDisabled) {
GURL("https://embedded.com"),
url::Origin::Create(GURL("https://test.com"))));
EXPECT_TRUE(privacy_sandbox_settings()->IsConversionMeasurementAllowed(
url::Origin::Create(GURL("https://test.com")),
url::Origin::Create(GURL("https://embedded.com"))));
EXPECT_TRUE(privacy_sandbox_settings()->ShouldSendConversionReport(
url::Origin::Create(GURL("https://test.com")),
url::Origin::Create(GURL("https://another-test.com")),
url::Origin::Create(GURL("https://embedded.com"))));
SetupTestState(
/*privacy_sandbox_available=*/false,
/*privacy_sandbox_enabled=*/false,
......@@ -139,15 +150,24 @@ TEST_F(PrivacySandboxSettingsTest, CookieSettingAppliesWhenUiDisabled) {
/*user_cookie_exceptions=*/
{{"https://embedded.com", "https://test.com",
ContentSetting::CONTENT_SETTING_ALLOW},
{"https://another-embedded.com", "*",
{"https://another-test.com", "*",
ContentSetting::CONTENT_SETTING_BLOCK}},
/*managed_cookie_setting=*/kNoSetting,
/*managed_cookie_exceptions=*/{});
EXPECT_TRUE(privacy_sandbox_settings()->IsFlocAllowed(
GURL("https://embedded.com"),
url::Origin::Create(GURL("https://test.com"))));
EXPECT_FALSE(privacy_sandbox_settings()->IsFlocAllowed(
GURL("https://another-embedded.com"), base::nullopt));
GURL("https://another-test.com"), base::nullopt));
EXPECT_TRUE(privacy_sandbox_settings()->IsConversionMeasurementAllowed(
url::Origin::Create(GURL("https://test.com")),
url::Origin::Create(GURL("https://embedded.com"))));
EXPECT_FALSE(privacy_sandbox_settings()->ShouldSendConversionReport(
url::Origin::Create(GURL("https://test.com")),
url::Origin::Create(GURL("https://another-test.com")),
url::Origin::Create(GURL("https://embedded.com"))));
SetupTestState(
/*privacy_sandbox_available=*/false,
......@@ -159,11 +179,20 @@ TEST_F(PrivacySandboxSettingsTest, CookieSettingAppliesWhenUiDisabled) {
/*managed_cookie_setting=*/kNoSetting,
{{"https://embedded.com", "https://test.com",
ContentSetting::CONTENT_SETTING_BLOCK}});
EXPECT_FALSE(privacy_sandbox_settings()->IsFlocAllowed(
GURL("https://embedded.com"),
url::Origin::Create(GURL("https://test.com"))));
EXPECT_TRUE(privacy_sandbox_settings()->IsFlocAllowed(
GURL("https://embedded.com"), base::nullopt));
EXPECT_FALSE(privacy_sandbox_settings()->IsConversionMeasurementAllowed(
url::Origin::Create(GURL("https://test.com")),
url::Origin::Create(GURL("https://embedded.com"))));
EXPECT_FALSE(privacy_sandbox_settings()->ShouldSendConversionReport(
url::Origin::Create(GURL("https://test.com")),
url::Origin::Create(GURL("https://another-test.com")),
url::Origin::Create(GURL("https://embedded.com"))));
}
TEST_F(PrivacySandboxSettingsTest, PreferenceOverridesDefaultContentSetting) {
......@@ -176,10 +205,19 @@ TEST_F(PrivacySandboxSettingsTest, PreferenceOverridesDefaultContentSetting) {
/*user_cookie_exceptions=*/{},
/*managed_cookie_setting=*/kNoSetting,
/*managed_cookie_exceptions=*/{});
EXPECT_TRUE(privacy_sandbox_settings()->IsFlocAllowed(
GURL("https://embedded.com"),
url::Origin::Create(GURL("https://test.com"))));
EXPECT_TRUE(privacy_sandbox_settings()->IsConversionMeasurementAllowed(
url::Origin::Create(GURL("https://test.com")),
url::Origin::Create(GURL("https://embedded.com"))));
EXPECT_TRUE(privacy_sandbox_settings()->ShouldSendConversionReport(
url::Origin::Create(GURL("https://test.com")),
url::Origin::Create(GURL("https://another-test.com")),
url::Origin::Create(GURL("https://embedded.com"))));
// An allow exception should not override the preference value.
SetupTestState(
/*privacy_sandbox_available=*/true,
......@@ -187,12 +225,23 @@ TEST_F(PrivacySandboxSettingsTest, PreferenceOverridesDefaultContentSetting) {
/*default_cookie_setting=*/ContentSetting::CONTENT_SETTING_ALLOW,
/*user_cookie_exceptions=*/
{{"https://embedded.com", "https://test.com",
ContentSetting::CONTENT_SETTING_ALLOW},
{"https://embedded.com", "https://another-test.com",
ContentSetting::CONTENT_SETTING_ALLOW}},
/*managed_cookie_setting=*/kNoSetting,
/*managed_cookie_exceptions=*/{});
EXPECT_FALSE(privacy_sandbox_settings()->IsFlocAllowed(
GURL("https://embedded.com"),
url::Origin::Create(GURL("https://test.com"))));
EXPECT_FALSE(privacy_sandbox_settings()->IsConversionMeasurementAllowed(
url::Origin::Create(GURL("https://test.com")),
url::Origin::Create(GURL("https://embedded.com"))));
EXPECT_FALSE(privacy_sandbox_settings()->ShouldSendConversionReport(
url::Origin::Create(GURL("https://test.com")),
url::Origin::Create(GURL("https://another-test.com")),
url::Origin::Create(GURL("https://embedded.com"))));
}
TEST_F(PrivacySandboxSettingsTest, CookieBlockExceptionsApply) {
......@@ -207,10 +256,19 @@ TEST_F(PrivacySandboxSettingsTest, CookieBlockExceptionsApply) {
ContentSetting::CONTENT_SETTING_BLOCK}},
/*managed_cookie_setting=*/kNoSetting,
/*managed_cookie_exceptions=*/{});
EXPECT_FALSE(privacy_sandbox_settings()->IsFlocAllowed(
GURL("https://embedded.com"),
url::Origin::Create(GURL("https://test.com"))));
EXPECT_FALSE(privacy_sandbox_settings()->IsConversionMeasurementAllowed(
url::Origin::Create(GURL("https://test.com")),
url::Origin::Create(GURL("https://embedded.com"))));
EXPECT_FALSE(privacy_sandbox_settings()->ShouldSendConversionReport(
url::Origin::Create(GURL("https://test.com")),
url::Origin::Create(GURL("https://another-test.com")),
url::Origin::Create(GURL("https://embedded.com"))));
// User created exceptions should not apply if a managed default coookie
// setting exists. What the managed default setting actually is should *not*
// affect whether APIs are enabled. The cookie managed state is reflected in
......@@ -221,12 +279,22 @@ TEST_F(PrivacySandboxSettingsTest, CookieBlockExceptionsApply) {
/*default_cookie_setting=*/ContentSetting::CONTENT_SETTING_ALLOW,
/*user_cookie_exceptions=*/
{{"https://embedded.com", "https://test.com",
ContentSetting::CONTENT_SETTING_BLOCK},
{"https://embedded.com", "https://another-test.com",
ContentSetting::CONTENT_SETTING_BLOCK}},
/*managed_cookie_setting=*/ContentSetting::CONTENT_SETTING_BLOCK,
/*managed_cookie_exceptions=*/{});
EXPECT_TRUE(privacy_sandbox_settings()->IsFlocAllowed(
GURL("https://embedded.com"),
url::Origin::Create(GURL("https://test.com"))));
EXPECT_TRUE(privacy_sandbox_settings()->IsConversionMeasurementAllowed(
url::Origin::Create(GURL("https://test.com")),
url::Origin::Create(GURL("https://embedded.com"))));
EXPECT_TRUE(privacy_sandbox_settings()->ShouldSendConversionReport(
url::Origin::Create(GURL("https://test.com")),
url::Origin::Create(GURL("https://another-test.com")),
url::Origin::Create(GURL("https://embedded.com"))));
// Managed content setting exceptions should override both the privacy
// sandbox pref and any user settings.
......@@ -236,10 +304,13 @@ TEST_F(PrivacySandboxSettingsTest, CookieBlockExceptionsApply) {
/*default_cookie_setting=*/ContentSetting::CONTENT_SETTING_ALLOW,
/*user_cookie_exceptions=*/
{{"https://embedded.com", "https://test.com",
ContentSetting::CONTENT_SETTING_ALLOW},
{"https://embedded.com", "https://another-test.com",
ContentSetting::CONTENT_SETTING_ALLOW}},
/*managed_cookie_setting=*/ContentSetting::CONTENT_SETTING_ALLOW,
{{"https://embedded.com", "https://test.com",
ContentSetting::CONTENT_SETTING_BLOCK}});
EXPECT_FALSE(privacy_sandbox_settings()->IsFlocAllowed(
GURL("https://embedded.com"),
url::Origin::Create(GURL("https://test.com"))));
......@@ -247,6 +318,21 @@ TEST_F(PrivacySandboxSettingsTest, CookieBlockExceptionsApply) {
GURL("https://unrelated.com"),
url::Origin::Create(GURL("https://unrelated.com"))));
EXPECT_FALSE(privacy_sandbox_settings()->IsConversionMeasurementAllowed(
url::Origin::Create(GURL("https://test.com")),
url::Origin::Create(GURL("https://embedded.com"))));
EXPECT_FALSE(privacy_sandbox_settings()->ShouldSendConversionReport(
url::Origin::Create(GURL("https://test.com")),
url::Origin::Create(GURL("https://another-test.com")),
url::Origin::Create(GURL("https://embedded.com"))));
EXPECT_TRUE(privacy_sandbox_settings()->IsConversionMeasurementAllowed(
url::Origin::Create(GURL("https://unrelated-a.com")),
url::Origin::Create(GURL("https://unrelated-b.com"))));
EXPECT_TRUE(privacy_sandbox_settings()->ShouldSendConversionReport(
url::Origin::Create(GURL("https://unrelated-c.com")),
url::Origin::Create(GURL("https://unrelated-d.com")),
url::Origin::Create(GURL("https://unrelated-e.com"))));
// A less specific block exception should not override a more specific allow
// exception. The effective content setting in this scenario is still allow,
// even though a block exception exists.
......@@ -257,7 +343,11 @@ TEST_F(PrivacySandboxSettingsTest, CookieBlockExceptionsApply) {
/*user_cookie_exceptions=*/
{{"https://embedded.com", "https://test.com",
ContentSetting::CONTENT_SETTING_ALLOW},
{"https://embedded.com", "https://another-test.com",
ContentSetting::CONTENT_SETTING_ALLOW},
{"https://[*.]embedded.com", "https://[*.]test.com",
ContentSetting::CONTENT_SETTING_BLOCK},
{"https://[*.]embedded.com", "https://[*.]another-test.com",
ContentSetting::CONTENT_SETTING_BLOCK}},
/*managed_cookie_setting=*/kNoSetting,
/*managed_cookie_exceptions=*/{});
......@@ -265,8 +355,8 @@ TEST_F(PrivacySandboxSettingsTest, CookieBlockExceptionsApply) {
GURL("https://embedded.com"),
url::Origin::Create(GURL("https://test.com"))));
// Exceptions which specify a top frame origin should not match against an
// empty top frame.
// Exceptions which specify a top frame origin should not match against other
// top frame origins, or an empty origin.
SetupTestState(
/*privacy_sandbox_available=*/true,
/*privacy_sandbox_enabled=*/true,
......@@ -278,9 +368,18 @@ TEST_F(PrivacySandboxSettingsTest, CookieBlockExceptionsApply) {
/*managed_cookie_exceptions=*/
{{"https://embedded.com", "https://test.com",
ContentSetting::CONTENT_SETTING_BLOCK}});
EXPECT_TRUE(privacy_sandbox_settings()->IsFlocAllowed(
GURL("https://embedded.com"), base::nullopt));
EXPECT_TRUE(privacy_sandbox_settings()->IsConversionMeasurementAllowed(
url::Origin::Create(GURL("https://another-test.com")),
url::Origin::Create(GURL("https://embedded.com"))));
EXPECT_TRUE(privacy_sandbox_settings()->ShouldSendConversionReport(
url::Origin::Create(GURL("https://another-test.com")),
url::Origin::Create(GURL("https://yet-another-test.com")),
url::Origin::Create(GURL("https://embedded.com"))));
// Exceptions which specify a wildcard top frame origin should match both
// empty top frames and non empty top frames.
SetupTestState(
......@@ -291,15 +390,24 @@ TEST_F(PrivacySandboxSettingsTest, CookieBlockExceptionsApply) {
{{"https://embedded.com", "*", ContentSetting::CONTENT_SETTING_BLOCK}},
/*managed_cookie_setting=*/kNoSetting,
/*managed_cookie_exceptions=*/{});
EXPECT_FALSE(privacy_sandbox_settings()->IsFlocAllowed(
GURL("https://embedded.com"), base::nullopt));
EXPECT_FALSE(privacy_sandbox_settings()->IsFlocAllowed(
GURL("https://embedded.com"),
url::Origin::Create(GURL("https://test.com"))));
EXPECT_FALSE(privacy_sandbox_settings()->IsConversionMeasurementAllowed(
url::Origin::Create(GURL("https://test.com")),
url::Origin::Create(GURL("https://embedded.com"))));
EXPECT_FALSE(privacy_sandbox_settings()->ShouldSendConversionReport(
url::Origin::Create(GURL("https://test.com")),
url::Origin::Create(GURL("https://another-test.com")),
url::Origin::Create(GURL("https://embedded.com"))));
}
TEST_F(PrivacySandboxSettingsTest, FlocAlwaysThirdParty) {
// Check that when the UI is not enabled, all FLoC requests are considered
TEST_F(PrivacySandboxSettingsTest, ThirdPartyByDefault) {
// Check that when the UI is not enabled, all requests are considered
// as third party requests.
profile()->GetTestingPrefService()->SetUserPref(
prefs::kCookieControlsMode,
......@@ -312,9 +420,18 @@ TEST_F(PrivacySandboxSettingsTest, FlocAlwaysThirdParty) {
/*user_cookie_exceptions=*/{},
/*managed_cookie_setting=*/kNoSetting,
/*managed_cookie_exceptions=*/{});
EXPECT_FALSE(privacy_sandbox_settings()->IsFlocAllowed(
GURL("https://embedded.com"),
url::Origin::Create(GURL("https://embedded.com"))));
EXPECT_FALSE(privacy_sandbox_settings()->IsFlocAllowed(
GURL("https://embedded.com"), base::nullopt));
EXPECT_FALSE(privacy_sandbox_settings()->IsConversionMeasurementAllowed(
url::Origin::Create(GURL("https://embedded.com")),
url::Origin::Create(GURL("https://embedded.com"))));
EXPECT_FALSE(privacy_sandbox_settings()->ShouldSendConversionReport(
url::Origin::Create(GURL("https://embedded.com")),
url::Origin::Create(GURL("https://embedded.com")),
url::Origin::Create(GURL("https://embedded.com"))));
}
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