/* Any copyright is dedicated to the Public Domain. * http://creativecommons.org/publicdomain/zero/1.0/ */ "use strict"; const { UrlClassifierTestUtils } = ChromeUtils.importESModule( "resource://testing-common/UrlClassifierTestUtils.sys.mjs" ); Services.cookies.QueryInterface(Ci.nsICookieService); function restore_prefs() { Services.prefs.clearUserPref("network.cookie.cookieBehavior"); Services.prefs.clearUserPref( "network.cookieJarSettings.unblocked_for_testing" ); Services.prefs.clearUserPref( "network.cookie.rejectForeignWithExceptions.enabled" ); } registerCleanupFunction(restore_prefs); async function fake_profile_change() { await new Promise(resolve => { Services.obs.addObserver(function waitForDBClose() { Services.obs.removeObserver(waitForDBClose, "cookie-db-closed"); resolve(); }, "cookie-db-closed"); Services.cookies .QueryInterface(Ci.nsIObserver) .observe(null, "profile-before-change", null); }); await new Promise(resolve => { Services.obs.addObserver(function waitForDBOpen() { Services.obs.removeObserver(waitForDBOpen, "cookie-db-read"); resolve(); }, "cookie-db-read"); Services.cookies .QueryInterface(Ci.nsIObserver) .observe(null, "profile-do-change", ""); }); } async function test_cookie_settings({ cookiesEnabled, thirdPartyCookiesEnabled, rejectTrackers, cookieJarSettingsLocked, }) { let firstPartyURI = NetUtil.newURI("https://example.com/"); let thirdPartyURI = NetUtil.newURI("https://example.org/"); let channel = NetUtil.newChannel({ uri: firstPartyURI, loadUsingSystemPrincipal: true, }); channel.QueryInterface( Ci.nsIHttpChannelInternal ).forceAllowThirdPartyCookie = true; Services.cookies.removeAll(); Services.cookies.setCookieStringFromHttp( firstPartyURI, "key=value; SameSite=None; Secure;", channel ); Services.cookies.setCookieStringFromHttp( thirdPartyURI, "key=value; SameSite=None; Secure;", channel ); let expectedFirstPartyCookies = 1; let expectedThirdPartyCookies = 1; if (!cookiesEnabled) { expectedFirstPartyCookies = 0; } if (!cookiesEnabled || !thirdPartyCookiesEnabled) { expectedThirdPartyCookies = 0; } is( Services.cookies.countCookiesFromHost(firstPartyURI.host), expectedFirstPartyCookies, "Number of first-party cookies should match expected" ); is( Services.cookies.countCookiesFromHost(thirdPartyURI.host), expectedThirdPartyCookies, "Number of third-party cookies should match expected" ); // Add a cookie so we can check if it persists past the end of the session // but, first remove existing cookies set by this host to put us in a known state Services.cookies.removeAll(); Services.cookies.setCookieStringFromHttp( firstPartyURI, "key=value; max-age=1000; SameSite=None; Secure;", channel ); await fake_profile_change(); // Now check if the cookie persisted or not let expectedCookieCount = 1; if (!cookiesEnabled) { expectedCookieCount = 0; } is( Services.cookies.countCookiesFromHost(firstPartyURI.host), expectedCookieCount, "Number of cookies was not what expected after restarting session" ); is( Services.prefs.prefIsLocked("network.cookie.cookieBehavior"), cookieJarSettingsLocked, "Cookie behavior pref lock status should be what is expected" ); let tab = await BrowserTestUtils.openNewForegroundTab( gBrowser, "about:preferences" ); BrowserTestUtils.removeTab(tab); if (rejectTrackers) { tab = await BrowserTestUtils.addTab( gBrowser, "http://example.net/browser/browser/components/enterprisepolicies/tests/browser/page.html" ); let browser = gBrowser.getBrowserForTab(tab); await BrowserTestUtils.browserLoaded(browser); await SpecialPowers.spawn(tab.linkedBrowser, [], async function () { // Load the script twice { let src = content.document.createElement("script"); let p = new content.Promise((resolve, reject) => { src.onload = resolve; src.onerror = reject; }); content.document.body.appendChild(src); src.src = "https://tracking.example.org/browser/browser/components/enterprisepolicies/tests/browser/subResources.sjs?what=script"; await p; } { let src = content.document.createElement("script"); let p = new content.Promise(resolve => { src.onload = resolve; }); content.document.body.appendChild(src); src.src = "https://tracking.example.org/browser/browser/components/enterprisepolicies/tests/browser/subResources.sjs?what=script"; await p; } }); BrowserTestUtils.removeTab(tab); await fetch( "https://tracking.example.org/browser/browser/components/enterprisepolicies/tests/browser/subResources.sjs?result&what=script" ) .then(r => r.text()) .then(text => { is(text, "0", '"Reject Tracker" pref should match what is expected'); }); } } add_task(async function prepare_tracker_tables() { await UrlClassifierTestUtils.addTestTrackers(); }); add_task(async function test_initial_state() { Services.prefs.setBoolPref( "network.cookieJarSettings.unblocked_for_testing", true ); Services.prefs.setBoolPref( "network.cookie.rejectForeignWithExceptions.enabled", false ); await test_cookie_settings({ cookiesEnabled: true, thirdPartyCookiesEnabled: true, cookieJarSettingsLocked: false, }); restore_prefs(); }); add_task(async function test_undefined_unlocked() { Services.prefs.setIntPref("network.cookie.cookieBehavior", 3); Services.prefs.setBoolPref( "network.cookieJarSettings.unblocked_for_testing", true ); Services.prefs.setBoolPref( "network.cookie.rejectForeignWithExceptions.enabled", false ); await setupPolicyEngineWithJson({ policies: { Cookies: {}, }, }); is( Services.prefs.getIntPref("network.cookie.cookieBehavior", undefined), 3, "An empty cookie policy should not have changed the cookieBehavior preference" ); restore_prefs(); }); add_task(async function test_disabled() { Services.prefs.setBoolPref( "network.cookieJarSettings.unblocked_for_testing", true ); Services.prefs.setBoolPref( "network.cookie.rejectForeignWithExceptions.enabled", false ); await setupPolicyEngineWithJson({ policies: { Cookies: { Default: false, }, }, }); await test_cookie_settings({ cookiesEnabled: false, thirdPartyCookiesEnabled: true, cookieJarSettingsLocked: false, }); restore_prefs(); }); add_task(async function test_third_party_disabled() { Services.prefs.setBoolPref( "network.cookieJarSettings.unblocked_for_testing", true ); Services.prefs.setBoolPref( "network.cookie.rejectForeignWithExceptions.enabled", false ); await setupPolicyEngineWithJson({ policies: { Cookies: { AcceptThirdParty: "never", }, }, }); await test_cookie_settings({ cookiesEnabled: true, thirdPartyCookiesEnabled: false, cookieJarSettingsLocked: false, }); restore_prefs(); }); add_task(async function test_disabled_and_third_party_disabled() { Services.prefs.setBoolPref( "network.cookieJarSettings.unblocked_for_testing", true ); Services.prefs.setBoolPref( "network.cookie.rejectForeignWithExceptions.enabled", false ); await setupPolicyEngineWithJson({ policies: { Cookies: { Default: false, AcceptThirdParty: "never", }, }, }); await test_cookie_settings({ cookiesEnabled: false, thirdPartyCookiesEnabled: false, cookieJarSettingsLocked: false, }); restore_prefs(); }); add_task(async function test_disabled_and_third_party_disabled_locked() { Services.prefs.setBoolPref( "network.cookieJarSettings.unblocked_for_testing", true ); Services.prefs.setBoolPref( "network.cookie.rejectForeignWithExceptions.enabled", false ); await setupPolicyEngineWithJson({ policies: { Cookies: { Default: false, AcceptThirdParty: "never", Locked: true, }, }, }); await test_cookie_settings({ cookiesEnabled: false, thirdPartyCookiesEnabled: false, cookieJarSettingsLocked: true, }); restore_prefs(); }); add_task(async function test_undefined_locked() { Services.prefs.setBoolPref( "network.cookieJarSettings.unblocked_for_testing", true ); Services.prefs.setBoolPref( "network.cookie.rejectForeignWithExceptions.enabled", false ); await setupPolicyEngineWithJson({ policies: { Cookies: { Locked: true, }, }, }); await test_cookie_settings({ cookiesEnabled: true, thirdPartyCookiesEnabled: true, cookieJarSettingsLocked: true, }); restore_prefs(); }); add_task(async function test_cookie_reject_trackers() { Services.prefs.setBoolPref( "network.cookieJarSettings.unblocked_for_testing", true ); Services.prefs.setBoolPref( "network.cookie.rejectForeignWithExceptions.enabled", false ); await setupPolicyEngineWithJson({ policies: { Cookies: { RejectTracker: true, }, }, }); await test_cookie_settings({ cookiesEnabled: true, thirdPartyCookiesEnabled: true, rejectTrackers: true, cookieJarSettingsLocked: false, }); restore_prefs(); }); add_task(async function prepare_tracker_tables() { await UrlClassifierTestUtils.cleanupTestTrackers(); });