1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584 |
- // Copyright 2017 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.
- #include "services/network/restricted_cookie_manager.h"
- #include <set>
- #include "base/bind.h"
- #include "base/callback_helpers.h"
- #include "base/memory/raw_ptr.h"
- #include "base/run_loop.h"
- #include "base/test/bind.h"
- #include "base/test/scoped_feature_list.h"
- #include "base/test/task_environment.h"
- #include "base/time/time.h"
- #include "mojo/public/cpp/bindings/pending_remote.h"
- #include "mojo/public/cpp/bindings/receiver.h"
- #include "mojo/public/cpp/bindings/receiver_set.h"
- #include "mojo/public/cpp/bindings/remote.h"
- #include "mojo/public/cpp/system/functions.h"
- #include "net/base/features.h"
- #include "net/base/isolation_info.h"
- #include "net/base/network_isolation_key.h"
- #include "net/base/schemeful_site.h"
- #include "net/cookies/canonical_cookie_test_helpers.h"
- #include "net/cookies/cookie_constants.h"
- #include "net/cookies/cookie_inclusion_status.h"
- #include "net/cookies/cookie_monster.h"
- #include "net/cookies/cookie_partition_key.h"
- #include "net/cookies/cookie_store.h"
- #include "net/cookies/cookie_store_test_callbacks.h"
- #include "net/cookies/cookie_util.h"
- #include "net/cookies/first_party_set_metadata.h"
- #include "net/cookies/same_party_context.h"
- #include "net/cookies/site_for_cookies.h"
- #include "net/cookies/test_cookie_access_delegate.h"
- #include "services/network/cookie_access_delegate_impl.h"
- #include "services/network/cookie_settings.h"
- #include "services/network/first_party_sets/first_party_sets_access_delegate.h"
- #include "services/network/public/mojom/cookie_access_observer.mojom.h"
- #include "services/network/public/mojom/cookie_manager.mojom.h"
- #include "services/network/public/mojom/first_party_sets.mojom.h"
- #include "services/network/test/test_network_context_client.h"
- #include "testing/gmock/include/gmock/gmock-matchers.h"
- #include "testing/gtest/include/gtest/gtest.h"
- #include "url/origin.h"
- #include "url/url_util.h"
- namespace net {
- bool operator==(const net::SiteForCookies& a, const net::SiteForCookies& b) {
- return a.IsEquivalent(b);
- }
- } // namespace net
- namespace network {
- namespace {
- net::FirstPartySetMetadata ComputeFirstPartySetMetadataSync(
- const url::Origin& origin,
- const net::CookieStore* cookie_store,
- const net::IsolationInfo& isolation_info) {
- base::RunLoop run_loop;
- net::FirstPartySetMetadata first_party_set_metadata;
- RestrictedCookieManager::ComputeFirstPartySetMetadata(
- origin, cookie_store, isolation_info,
- base::BindLambdaForTesting([&](net::FirstPartySetMetadata metadata) {
- first_party_set_metadata = std::move(metadata);
- run_loop.Quit();
- }));
- run_loop.Run();
- return first_party_set_metadata;
- }
- } // namespace
- class RecordingCookieObserver : public network::mojom::CookieAccessObserver {
- public:
- struct CookieOp {
- mojom::CookieAccessDetails::Type type;
- GURL url;
- net::SiteForCookies site_for_cookies;
- mojom::CookieOrLinePtr cookie_or_line;
- net::CookieInclusionStatus status;
- friend void PrintTo(const CookieOp& op, std::ostream* os) {
- *os << "{type=" << op.type << ", url=" << op.url
- << ", site_for_cookies=" << op.site_for_cookies.RepresentativeUrl()
- << ", cookie_or_line=(" << CookieOrLineToString(op.cookie_or_line)
- << ", " << static_cast<int>(op.cookie_or_line->which()) << ")"
- << ", status=" << op.status.GetDebugString() << "}";
- }
- static std::string CookieOrLineToString(
- const mojom::CookieOrLinePtr& cookie_or_line) {
- switch (cookie_or_line->which()) {
- case mojom::CookieOrLine::Tag::kCookie:
- return net::CanonicalCookie::BuildCookieLine(
- {cookie_or_line->get_cookie()});
- case mojom::CookieOrLine::Tag::kCookieString:
- return cookie_or_line->get_cookie_string();
- }
- }
- };
- RecordingCookieObserver() : run_loop_(std::make_unique<base::RunLoop>()) {}
- ~RecordingCookieObserver() override = default;
- std::vector<CookieOp>& recorded_activity() { return recorded_activity_; }
- mojo::PendingRemote<mojom::CookieAccessObserver> GetRemote() {
- mojo::PendingRemote<mojom::CookieAccessObserver> remote;
- receivers_.Add(this, remote.InitWithNewPipeAndPassReceiver());
- return remote;
- }
- void WaitForCallback() {
- run_loop_->Run();
- run_loop_ = std::make_unique<base::RunLoop>();
- }
- void OnCookiesAccessed(mojom::CookieAccessDetailsPtr details) override {
- for (const auto& cookie_and_access_result : details->cookie_list) {
- CookieOp op;
- op.type = details->type;
- op.url = details->url;
- op.site_for_cookies = details->site_for_cookies;
- op.cookie_or_line = std::move(cookie_and_access_result->cookie_or_line);
- op.status = cookie_and_access_result->access_result.status;
- recorded_activity_.push_back(std::move(op));
- }
- run_loop_->QuitClosure().Run();
- }
- void Clone(
- mojo::PendingReceiver<mojom::CookieAccessObserver> observer) override {
- receivers_.Add(this, std::move(observer));
- }
- private:
- std::vector<CookieOp> recorded_activity_;
- mojo::ReceiverSet<mojom::CookieAccessObserver> receivers_;
- std::unique_ptr<base::RunLoop> run_loop_;
- };
- // Synchronous proxies to a wrapped RestrictedCookieManager's methods.
- class RestrictedCookieManagerSync {
- public:
- // Caller must guarantee that |*cookie_service| outlives the
- // SynchronousCookieManager.
- explicit RestrictedCookieManagerSync(
- mojom::RestrictedCookieManager* cookie_service)
- : cookie_service_(cookie_service) {}
- RestrictedCookieManagerSync(const RestrictedCookieManagerSync&) = delete;
- RestrictedCookieManagerSync& operator=(const RestrictedCookieManagerSync&) =
- delete;
- ~RestrictedCookieManagerSync() = default;
- // Wraps GetAllForUrl() but discards CookieAccessResult from returned cookies.
- std::vector<net::CanonicalCookie> GetAllForUrl(
- const GURL& url,
- const net::SiteForCookies& site_for_cookies,
- const url::Origin& top_frame_origin,
- mojom::CookieManagerGetOptionsPtr options,
- bool partitioned_cookies_runtime_feature_enabled) {
- base::RunLoop run_loop;
- std::vector<net::CanonicalCookie> result;
- cookie_service_->GetAllForUrl(
- url, site_for_cookies, top_frame_origin, std::move(options),
- partitioned_cookies_runtime_feature_enabled,
- base::BindLambdaForTesting(
- [&run_loop, &result](const std::vector<net::CookieWithAccessResult>&
- backend_result) {
- result = net::cookie_util::StripAccessResults(backend_result);
- run_loop.Quit();
- }));
- run_loop.Run();
- return result;
- }
- bool SetCanonicalCookie(const net::CanonicalCookie& cookie,
- const GURL& url,
- const net::SiteForCookies& site_for_cookies,
- const url::Origin& top_frame_origin,
- absl::optional<net::CookieInclusionStatus>
- cookie_inclusion_status = absl::nullopt) {
- base::RunLoop run_loop;
- bool result = false;
- net::CookieInclusionStatus status;
- if (cookie_inclusion_status.has_value()) {
- status = cookie_inclusion_status.value();
- }
- cookie_service_->SetCanonicalCookie(
- cookie, url, site_for_cookies, top_frame_origin, status,
- base::BindLambdaForTesting([&run_loop, &result](bool backend_result) {
- result = backend_result;
- run_loop.Quit();
- }));
- run_loop.Run();
- return result;
- }
- void SetCookieFromString(const GURL& url,
- const net::SiteForCookies& site_for_cookies,
- const url::Origin& top_frame_origin,
- const std::string& cookie,
- bool partitioned_cookies_runtime_feature_enabled) {
- base::RunLoop run_loop;
- cookie_service_->SetCookieFromString(
- url, site_for_cookies, top_frame_origin, cookie,
- partitioned_cookies_runtime_feature_enabled,
- base::BindLambdaForTesting(
- [&run_loop](bool site_for_cookies_ok, bool top_frame_origin_ok) {
- run_loop.Quit();
- }));
- run_loop.Run();
- }
- void AddChangeListener(
- const GURL& url,
- const net::SiteForCookies& site_for_cookies,
- const url::Origin& top_frame_origin,
- mojo::PendingRemote<mojom::CookieChangeListener> listener) {
- base::RunLoop run_loop;
- cookie_service_->AddChangeListener(url, site_for_cookies, top_frame_origin,
- std::move(listener),
- run_loop.QuitClosure());
- run_loop.Run();
- }
- private:
- raw_ptr<mojom::RestrictedCookieManager> cookie_service_;
- };
- namespace {
- // Stashes the cookie changes it receives, for testing.
- class TestCookieChangeListener : public network::mojom::CookieChangeListener {
- public:
- explicit TestCookieChangeListener(
- mojo::PendingReceiver<network::mojom::CookieChangeListener> receiver)
- : receiver_(this, std::move(receiver)) {}
- ~TestCookieChangeListener() override = default;
- // Spin in a run loop until a change is received.
- void WaitForChange() {
- base::RunLoop loop;
- run_loop_ = &loop;
- loop.Run();
- run_loop_ = nullptr;
- }
- // Changes received by this listener.
- const std::vector<net::CookieChangeInfo>& observed_changes() const {
- return observed_changes_;
- }
- // network::mojom::CookieChangeListener
- void OnCookieChange(const net::CookieChangeInfo& change) override {
- observed_changes_.emplace_back(change);
- if (run_loop_) // Set in WaitForChange().
- run_loop_->Quit();
- }
- private:
- std::vector<net::CookieChangeInfo> observed_changes_;
- mojo::Receiver<network::mojom::CookieChangeListener> receiver_;
- // If not null, will be stopped when a cookie change notification is received.
- raw_ptr<base::RunLoop> run_loop_ = nullptr;
- };
- } // namespace
- class RestrictedCookieManagerTest
- : public testing::TestWithParam<mojom::RestrictedCookieManagerRole> {
- public:
- RestrictedCookieManagerTest()
- : cookie_monster_(/*store=*/nullptr,
- /*net_log=*/nullptr,
- kFirstPartySetsEnabled),
- isolation_info_(kDefaultIsolationInfo),
- service_(std::make_unique<RestrictedCookieManager>(
- GetParam(),
- &cookie_monster_,
- cookie_settings_,
- kDefaultOrigin,
- isolation_info_,
- recording_client_.GetRemote(),
- kFirstPartySetsEnabled,
- ComputeFirstPartySetMetadataSync(kDefaultOrigin,
- &cookie_monster_,
- isolation_info_))),
- receiver_(service_.get(),
- service_remote_.BindNewPipeAndPassReceiver()) {
- sync_service_ =
- std::make_unique<RestrictedCookieManagerSync>(service_remote_.get());
- }
- ~RestrictedCookieManagerTest() override = default;
- void SetUp() override {
- mojo::SetDefaultProcessErrorHandler(base::BindRepeating(
- &RestrictedCookieManagerTest::OnBadMessage, base::Unretained(this)));
- }
- void TearDown() override {
- mojo::SetDefaultProcessErrorHandler(base::NullCallback());
- }
- // Set a canonical cookie directly into the store.
- // Default to be a cross-site, cross-party cookie context.
- bool SetCanonicalCookie(
- const net::CanonicalCookie& cookie,
- std::string source_scheme,
- bool can_modify_httponly,
- const net::CookieOptions::SameSiteCookieContext::ContextType
- same_site_cookie_context_type = net::CookieOptions::
- SameSiteCookieContext::ContextType::CROSS_SITE,
- const net::SamePartyContext::Type same_party_context_type =
- net::SamePartyContext::Type::kCrossParty) {
- net::ResultSavingCookieCallback<net::CookieAccessResult> callback;
- net::CookieOptions options;
- if (can_modify_httponly)
- options.set_include_httponly();
- net::CookieOptions::SameSiteCookieContext same_site_cookie_context(
- same_site_cookie_context_type, same_site_cookie_context_type);
- options.set_same_site_cookie_context(same_site_cookie_context);
- options.set_same_party_context(
- net::SamePartyContext(same_party_context_type));
- cookie_monster_.SetCanonicalCookieAsync(
- std::make_unique<net::CanonicalCookie>(cookie),
- net::cookie_util::SimulatedCookieSource(cookie, source_scheme), options,
- callback.MakeCallback());
- callback.WaitUntilDone();
- return callback.result().status.IsInclude();
- }
- // Simplified helper for SetCanonicalCookie.
- //
- // Creates a CanonicalCookie that is secure (unless overriden), not http-only,
- // and has SameSite=None. Crashes if the creation fails.
- void SetSessionCookie(const char* name,
- const char* value,
- const char* domain,
- const char* path,
- bool secure = true) {
- ASSERT_TRUE(SetCanonicalCookie(
- *net::CanonicalCookie::CreateUnsafeCookieForTesting(
- name, value, domain, path, base::Time(), base::Time(), base::Time(),
- base::Time(),
- /*secure=*/secure,
- /*httponly=*/false, net::CookieSameSite::NO_RESTRICTION,
- net::COOKIE_PRIORITY_DEFAULT, /*same_party=*/false),
- "https", /*can_modify_httponly=*/true));
- }
- // Like above, but makes an http-only cookie.
- void SetHttpOnlySessionCookie(const char* name,
- const char* value,
- const char* domain,
- const char* path) {
- CHECK(SetCanonicalCookie(
- *net::CanonicalCookie::CreateUnsafeCookieForTesting(
- name, value, domain, path, base::Time(), base::Time(), base::Time(),
- base::Time(),
- /*secure=*/true,
- /*httponly=*/true, net::CookieSameSite::NO_RESTRICTION,
- net::COOKIE_PRIORITY_DEFAULT, /*same_party=*/false),
- "https", /*can_modify_httponly=*/true));
- }
- std::unique_ptr<TestCookieChangeListener> CreateCookieChangeListener(
- const GURL& url,
- const net::SiteForCookies& site_for_cookies,
- const url::Origin& top_frame_origin) {
- mojo::PendingRemote<network::mojom::CookieChangeListener> listener_remote;
- mojo::PendingReceiver<network::mojom::CookieChangeListener> receiver =
- listener_remote.InitWithNewPipeAndPassReceiver();
- sync_service_->AddChangeListener(url, site_for_cookies, top_frame_origin,
- std::move(listener_remote));
- return std::make_unique<TestCookieChangeListener>(std::move(receiver));
- }
- void ExpectBadMessage() { expecting_bad_message_ = true; }
- bool received_bad_message() { return received_bad_message_; }
- mojom::RestrictedCookieManager* backend() { return service_remote_.get(); }
- protected:
- void OnBadMessage(const std::string& reason) {
- EXPECT_TRUE(expecting_bad_message_) << "Unexpected bad message: " << reason;
- received_bad_message_ = true;
- }
- std::vector<RecordingCookieObserver::CookieOp>& recorded_activity() {
- return recording_client_.recorded_activity();
- }
- void WaitForCallback() { return recording_client_.WaitForCallback(); }
- const GURL kDefaultUrl{"https://example.com/"};
- const GURL kDefaultUrlWithPath{"https://example.com/test/"};
- const GURL kOtherUrl{"https://notexample.com/"};
- const GURL kOtherUrlWithPath{"https://notexample.com/test/"};
- const url::Origin kDefaultOrigin = url::Origin::Create(kDefaultUrl);
- const url::Origin kOtherOrigin = url::Origin::Create(kOtherUrl);
- const net::SiteForCookies kDefaultSiteForCookies =
- net::SiteForCookies::FromUrl(kDefaultUrl);
- const net::SiteForCookies kOtherSiteForCookies =
- net::SiteForCookies::FromUrl(kOtherUrl);
- const net::IsolationInfo kDefaultIsolationInfo =
- net::IsolationInfo::CreateForInternalRequest(kDefaultOrigin);
- // IsolationInfo that replaces the default SiteForCookies with a blank one.
- const net::IsolationInfo kOtherIsolationInfo =
- net::IsolationInfo::Create(net::IsolationInfo::RequestType::kOther,
- kDefaultOrigin,
- kDefaultOrigin,
- net::SiteForCookies());
- const bool kFirstPartySetsEnabled = true;
- base::test::SingleThreadTaskEnvironment task_environment_{
- base::test::SingleThreadTaskEnvironment::MainThreadType::IO};
- net::CookieMonster cookie_monster_;
- CookieSettings cookie_settings_;
- net::IsolationInfo isolation_info_;
- RecordingCookieObserver recording_client_;
- std::unique_ptr<RestrictedCookieManager> service_;
- mojo::Remote<mojom::RestrictedCookieManager> service_remote_;
- mojo::Receiver<mojom::RestrictedCookieManager> receiver_;
- std::unique_ptr<RestrictedCookieManagerSync> sync_service_;
- bool expecting_bad_message_ = false;
- bool received_bad_message_ = false;
- };
- namespace {
- mojom::FirstPartySetsAccessDelegateParamsPtr
- CreateFirstPartySetsAccessDelegateParams() {
- auto params = mojom::FirstPartySetsAccessDelegateParams::New();
- params->enabled = true;
- return params;
- }
- } // namespace
- class SamePartyEnabledRestrictedCookieManagerTest
- : public RestrictedCookieManagerTest {
- public:
- SamePartyEnabledRestrictedCookieManagerTest()
- : first_party_sets_manager_(/*enabled=*/true),
- first_party_sets_access_delegate_(
- first_party_sets_access_delegate_remote_
- .BindNewPipeAndPassReceiver(),
- CreateFirstPartySetsAccessDelegateParams(),
- &first_party_sets_manager_) {
- network::mojom::PublicFirstPartySetsPtr public_sets =
- network::mojom::PublicFirstPartySets::New();
- public_sets->sets = {
- {net::SchemefulSite(GURL("https://example.com")),
- net::FirstPartySetEntry(
- net::SchemefulSite(GURL("https://example.com")),
- net::SiteType::kPrimary, absl::nullopt)},
- {net::SchemefulSite(GURL("https://member1.com")),
- net::FirstPartySetEntry(
- net::SchemefulSite(GURL("https://example.com")),
- net::SiteType::kAssociated, 0)},
- };
- first_party_sets_manager_.SetCompleteSets(std::move(public_sets));
- first_party_sets_access_delegate_remote_->NotifyReady(
- mojom::FirstPartySetsReadyEvent::New());
- auto cookie_access_delegate = std::make_unique<CookieAccessDelegateImpl>(
- mojom::CookieAccessDelegateType::USE_CONTENT_SETTINGS,
- &first_party_sets_access_delegate_, &cookie_settings_);
- cookie_monster_.SetCookieAccessDelegate(std::move(cookie_access_delegate));
- }
- ~SamePartyEnabledRestrictedCookieManagerTest() override = default;
- // Set a canonical cookie directly into the store, has both SameSite=lax and
- // SameParty.
- void SetSamePartyCookie(const char* name,
- const char* value,
- const char* domain,
- const char* path,
- bool secure = true) {
- CHECK(SetCanonicalCookie(
- *net::CanonicalCookie::CreateUnsafeCookieForTesting(
- name, value, domain, path, base::Time(), base::Time(), base::Time(),
- base::Time(),
- /*secure=*/secure,
- /*httponly=*/false, net::CookieSameSite::NO_RESTRICTION,
- net::COOKIE_PRIORITY_DEFAULT, /*same_party=*/true),
- "https", /*can_modify_httponly=*/true,
- net::CookieOptions::SameSiteCookieContext::ContextType::SAME_SITE_LAX,
- net::SamePartyContext::Type::kSameParty));
- }
- private:
- base::test::ScopedFeatureList feature_list_;
- FirstPartySetsManager first_party_sets_manager_;
- mojo::Remote<mojom::FirstPartySetsAccessDelegate>
- first_party_sets_access_delegate_remote_;
- FirstPartySetsAccessDelegate first_party_sets_access_delegate_;
- };
- INSTANTIATE_TEST_SUITE_P(
- SameParty,
- SamePartyEnabledRestrictedCookieManagerTest,
- testing::Values(mojom::RestrictedCookieManagerRole::SCRIPT,
- mojom::RestrictedCookieManagerRole::NETWORK));
- namespace {
- using testing::ElementsAre;
- using testing::IsEmpty;
- using testing::Not;
- using testing::UnorderedElementsAre;
- MATCHER_P5(MatchesCookieOp,
- type,
- url,
- site_for_cookies,
- cookie_or_line,
- status,
- "") {
- return testing::ExplainMatchResult(
- testing::AllOf(
- testing::Field(&RecordingCookieObserver::CookieOp::type, type),
- testing::Field(&RecordingCookieObserver::CookieOp::url, url),
- testing::Field(&RecordingCookieObserver::CookieOp::site_for_cookies,
- site_for_cookies),
- testing::Field(&RecordingCookieObserver::CookieOp::cookie_or_line,
- cookie_or_line),
- testing::Field(&RecordingCookieObserver::CookieOp::status, status)),
- arg, result_listener);
- }
- MATCHER_P2(CookieOrLine, string, type, "") {
- return type == arg->which() &&
- testing::ExplainMatchResult(
- string,
- RecordingCookieObserver::CookieOp::CookieOrLineToString(arg),
- result_listener);
- }
- } // anonymous namespace
- // Test the case when `origin` differs from `isolation_info.frame_origin`.
- // RestrictedCookieManager only works for the bound origin and doesn't care
- // about the IsolationInfo's frame_origin. Technically this should only happen
- // when role == mojom::RestrictedCookieManagerRole::NETWORK. Otherwise, it
- // should trigger a CHECK in the RestrictedCookieManager constructor (which is
- // bypassed here due to constructing it properly, then using an origin
- // override).
- TEST_P(RestrictedCookieManagerTest,
- GetAllForUrlFromMismatchingIsolationInfoFrameOrigin) {
- service_->OverrideOriginForTesting(kOtherOrigin);
- // Override isolation_info to make it explicit that its frame_origin is
- // different from the origin.
- service_->OverrideIsolationInfoForTesting(kDefaultIsolationInfo);
- SetSessionCookie("new-name", "new-value", kOtherUrl.host().c_str(), "/");
- // Fetch cookies from the wrong origin (IsolationInfo's frame_origin) should
- // result in a bad message.
- {
- auto options = mojom::CookieManagerGetOptions::New();
- options->name = "new-name";
- options->match_type = mojom::CookieMatchType::EQUALS;
- ExpectBadMessage();
- std::vector<net::CanonicalCookie> cookies = sync_service_->GetAllForUrl(
- kDefaultUrl, kDefaultSiteForCookies, kDefaultOrigin, std::move(options),
- /*partitioned_cookies_runtime_feature_enabled=*/false);
- EXPECT_TRUE(received_bad_message());
- }
- // Fetch cookies from the correct origin value which RestrictedCookieManager
- // is bound to should work.
- {
- auto options = mojom::CookieManagerGetOptions::New();
- options->name = "new-name";
- options->match_type = mojom::CookieMatchType::EQUALS;
- std::vector<net::CanonicalCookie> cookies = sync_service_->GetAllForUrl(
- kOtherUrl, kDefaultSiteForCookies, kDefaultOrigin, std::move(options),
- /*partitioned_cookies_runtime_feature_enabled=*/false);
- ASSERT_THAT(cookies, testing::SizeIs(1));
- EXPECT_EQ("new-name", cookies[0].Name());
- EXPECT_EQ("new-value", cookies[0].Value());
- }
- }
- TEST_P(RestrictedCookieManagerTest, GetAllForUrlBlankFilter) {
- SetSessionCookie("cookie-name", "cookie-value", "example.com", "/");
- SetSessionCookie("cookie-name-2", "cookie-value-2", "example.com", "/");
- SetSessionCookie("other-cookie-name", "other-cookie-value", "not-example.com",
- "/");
- auto options = mojom::CookieManagerGetOptions::New();
- options->name = "";
- options->match_type = mojom::CookieMatchType::STARTS_WITH;
- EXPECT_THAT(
- sync_service_->GetAllForUrl(
- kDefaultUrlWithPath, kDefaultSiteForCookies, kDefaultOrigin,
- std::move(options),
- /*partitioned_cookies_runtime_feature_enabled=*/false),
- UnorderedElementsAre(
- net::MatchesCookieNameValue("cookie-name", "cookie-value"),
- net::MatchesCookieNameValue("cookie-name-2", "cookie-value-2")));
- // Can also use the document.cookie-style API to get the same info.
- std::string cookies_out;
- EXPECT_TRUE(backend()->GetCookiesString(
- kDefaultUrlWithPath, kDefaultSiteForCookies, kDefaultOrigin,
- /*partitioned_cookies_runtime_feature_enabled=*/false, &cookies_out));
- EXPECT_EQ("cookie-name=cookie-value; cookie-name-2=cookie-value-2",
- cookies_out);
- }
- TEST_P(RestrictedCookieManagerTest, GetAllForUrlEmptyFilter) {
- SetSessionCookie("cookie-name", "cookie-value", "example.com", "/");
- auto options = mojom::CookieManagerGetOptions::New();
- options->name = "";
- options->match_type = mojom::CookieMatchType::EQUALS;
- EXPECT_THAT(sync_service_->GetAllForUrl(
- kDefaultUrlWithPath, kDefaultSiteForCookies, kDefaultOrigin,
- std::move(options),
- /*partitioned_cookies_runtime_feature_enabled=*/false),
- IsEmpty());
- }
- TEST_P(RestrictedCookieManagerTest, GetAllForUrlEqualsMatch) {
- SetSessionCookie("cookie-name", "cookie-value", "example.com", "/");
- SetSessionCookie("cookie-name-2", "cookie-value-2", "example.com", "/");
- auto options = mojom::CookieManagerGetOptions::New();
- options->name = "cookie-name";
- options->match_type = mojom::CookieMatchType::EQUALS;
- EXPECT_THAT(
- sync_service_->GetAllForUrl(
- kDefaultUrlWithPath, kDefaultSiteForCookies, kDefaultOrigin,
- std::move(options),
- /*partitioned_cookies_runtime_feature_enabled=*/false),
- ElementsAre(net::MatchesCookieNameValue("cookie-name", "cookie-value")));
- }
- TEST_P(RestrictedCookieManagerTest, GetAllForUrlStartsWithMatch) {
- SetSessionCookie("cookie-name", "cookie-value", "example.com", "/");
- SetSessionCookie("cookie-name-2", "cookie-value-2", "example.com", "/");
- SetSessionCookie("cookie-name-2b", "cookie-value-2b", "example.com", "/");
- SetSessionCookie("cookie-name-3b", "cookie-value-3b", "example.com", "/");
- auto options = mojom::CookieManagerGetOptions::New();
- options->name = "cookie-name-2";
- options->match_type = mojom::CookieMatchType::STARTS_WITH;
- EXPECT_THAT(
- sync_service_->GetAllForUrl(
- kDefaultUrlWithPath, kDefaultSiteForCookies, kDefaultOrigin,
- std::move(options),
- /*partitioned_cookies_runtime_feature_enabled=*/false),
- UnorderedElementsAre(
- net::MatchesCookieNameValue("cookie-name-2", "cookie-value-2"),
- net::MatchesCookieNameValue("cookie-name-2b", "cookie-value-2b")));
- }
- TEST_P(RestrictedCookieManagerTest, GetAllForUrlHttpOnly) {
- SetSessionCookie("cookie-name", "cookie-value", "example.com", "/");
- SetHttpOnlySessionCookie("cookie-name-http", "cookie-value-2", "example.com",
- "/");
- auto options = mojom::CookieManagerGetOptions::New();
- options->name = "cookie-name";
- options->match_type = mojom::CookieMatchType::STARTS_WITH;
- std::vector<net::CanonicalCookie> cookies = sync_service_->GetAllForUrl(
- kDefaultUrlWithPath, kDefaultSiteForCookies, kDefaultOrigin,
- std::move(options),
- /*partitioned_cookies_runtime_feature_enabled=*/false);
- if (GetParam() == mojom::RestrictedCookieManagerRole::SCRIPT) {
- EXPECT_THAT(cookies, UnorderedElementsAre(net::MatchesCookieNameValue(
- "cookie-name", "cookie-value")));
- } else {
- EXPECT_THAT(
- cookies,
- UnorderedElementsAre(
- net::MatchesCookieNameValue("cookie-name", "cookie-value"),
- net::MatchesCookieNameValue("cookie-name-http", "cookie-value-2")));
- }
- }
- TEST_P(RestrictedCookieManagerTest, GetAllForUrlFromWrongOrigin) {
- SetSessionCookie("cookie-name", "cookie-value", "example.com", "/");
- SetSessionCookie("cookie-name-2", "cookie-value-2", "example.com", "/");
- SetSessionCookie("other-cookie-name", "other-cookie-value", "notexample.com",
- "/");
- auto options = mojom::CookieManagerGetOptions::New();
- options->name = "";
- options->match_type = mojom::CookieMatchType::STARTS_WITH;
- ExpectBadMessage();
- EXPECT_THAT(sync_service_->GetAllForUrl(
- kOtherUrlWithPath, kDefaultSiteForCookies, kDefaultOrigin,
- std::move(options),
- /*partitioned_cookies_runtime_feature_enabled=*/false),
- IsEmpty());
- EXPECT_TRUE(received_bad_message());
- }
- TEST_P(RestrictedCookieManagerTest, GetAllForUrlFromOpaqueOrigin) {
- SetSessionCookie("cookie-name", "cookie-value", "example.com", "/");
- url::Origin opaque_origin;
- ASSERT_TRUE(opaque_origin.opaque());
- service_->OverrideOriginForTesting(opaque_origin);
- auto options = mojom::CookieManagerGetOptions::New();
- options->name = "";
- options->match_type = mojom::CookieMatchType::STARTS_WITH;
- ExpectBadMessage();
- EXPECT_THAT(sync_service_->GetAllForUrl(
- kDefaultUrlWithPath, kDefaultSiteForCookies, kDefaultOrigin,
- std::move(options),
- /*partitioned_cookies_runtime_feature_enabled=*/false),
- IsEmpty());
- EXPECT_TRUE(received_bad_message());
- }
- TEST_P(RestrictedCookieManagerTest, GetCookieStringFromWrongOrigin) {
- SetSessionCookie("cookie-name", "cookie-value", "example.com", "/");
- SetSessionCookie("cookie-name-2", "cookie-value-2", "example.com", "/");
- SetSessionCookie("other-cookie-name", "other-cookie-value", "notexample.com",
- "/");
- ExpectBadMessage();
- std::string cookies_out;
- EXPECT_TRUE(backend()->GetCookiesString(
- kOtherUrlWithPath, kDefaultSiteForCookies, kDefaultOrigin,
- /*partitioned_cookies_runtime_feature_enabled=*/false, &cookies_out));
- EXPECT_TRUE(received_bad_message());
- EXPECT_THAT(cookies_out, IsEmpty());
- }
- TEST_P(RestrictedCookieManagerTest, GetAllForUrlPolicy) {
- service_->OverrideIsolationInfoForTesting(kOtherIsolationInfo);
- SetSessionCookie("cookie-name", "cookie-value", "example.com", "/");
- // With default policy, should be able to get all cookies, even third-party.
- {
- auto options = mojom::CookieManagerGetOptions::New();
- options->name = "cookie-name";
- options->match_type = mojom::CookieMatchType::STARTS_WITH;
- EXPECT_THAT(sync_service_->GetAllForUrl(
- kDefaultUrlWithPath, net::SiteForCookies(), kDefaultOrigin,
- std::move(options),
- /*partitioned_cookies_runtime_feature_enabled=*/false),
- ElementsAre(net::MatchesCookieNameValue("cookie-name",
- "cookie-value")));
- }
- WaitForCallback();
- EXPECT_THAT(recorded_activity(),
- ElementsAre(MatchesCookieOp(
- mojom::CookieAccessDetails::Type::kRead,
- "https://example.com/test/", net::SiteForCookies(),
- CookieOrLine("cookie-name=cookie-value",
- mojom::CookieOrLine::Tag::kCookie),
- net::IsInclude())));
- // Disabing getting third-party cookies works correctly.
- cookie_settings_.set_block_third_party_cookies(true);
- {
- auto options = mojom::CookieManagerGetOptions::New();
- options->name = "cookie-name";
- options->match_type = mojom::CookieMatchType::STARTS_WITH;
- EXPECT_THAT(sync_service_->GetAllForUrl(
- kDefaultUrlWithPath, net::SiteForCookies(), kDefaultOrigin,
- std::move(options),
- /*partitioned_cookies_runtime_feature_enabled=*/false),
- IsEmpty());
- }
- WaitForCallback();
- EXPECT_THAT(
- recorded_activity(),
- ElementsAre(
- testing::_,
- MatchesCookieOp(
- mojom::CookieAccessDetails::Type::kRead,
- "https://example.com/test/", net::SiteForCookies(),
- CookieOrLine("cookie-name=cookie-value",
- mojom::CookieOrLine::Tag::kCookie),
- net::CookieInclusionStatus::MakeFromReasonsForTesting(
- {net::CookieInclusionStatus::EXCLUDE_USER_PREFERENCES},
- {}))));
- }
- TEST_P(RestrictedCookieManagerTest, FilteredCookieAccessEvents) {
- service_->OverrideIsolationInfoForTesting(kOtherIsolationInfo);
- const char* kCookieName = "cookie-name";
- const char* kCookieValue = "cookie-value";
- const char* kCookieSite = "example.com";
- std::string cookie_name_field =
- std::string(kCookieName) + std::string("=") + std::string(kCookieValue);
- service_->OverrideIsolationInfoForTesting(kOtherIsolationInfo);
- SetSessionCookie(kCookieName, kCookieValue, kCookieSite, "/");
- // With default policy, should be able to get all cookies, even third-party.
- {
- auto options = mojom::CookieManagerGetOptions::New();
- options->name = kCookieName;
- options->match_type = mojom::CookieMatchType::STARTS_WITH;
- EXPECT_THAT(
- sync_service_->GetAllForUrl(
- kDefaultUrlWithPath, net::SiteForCookies(), kDefaultOrigin,
- std::move(options),
- /*partitioned_cookies_runtime_feature_enabled=*/false),
- ElementsAre(net::MatchesCookieNameValue(kCookieName, kCookieValue)));
- WaitForCallback();
- EXPECT_THAT(
- recorded_activity(),
- ElementsAre(MatchesCookieOp(
- mojom::CookieAccessDetails::Type::kRead, kDefaultUrlWithPath,
- net::SiteForCookies(),
- CookieOrLine(cookie_name_field, mojom::CookieOrLine::Tag::kCookie),
- net::CookieInclusionStatus())));
- }
- {
- auto options = mojom::CookieManagerGetOptions::New();
- options->name = kCookieName;
- options->match_type = mojom::CookieMatchType::STARTS_WITH;
- EXPECT_THAT(
- sync_service_->GetAllForUrl(
- kDefaultUrlWithPath, net::SiteForCookies(), kDefaultOrigin,
- std::move(options),
- /*partitioned_cookies_runtime_feature_enabled=*/false),
- ElementsAre(net::MatchesCookieNameValue(kCookieName, kCookieValue)));
- // A second cookie access should not generate a notification.
- EXPECT_THAT(
- recorded_activity(),
- ElementsAre(MatchesCookieOp(
- mojom::CookieAccessDetails::Type::kRead, kDefaultUrlWithPath,
- net::SiteForCookies(),
- CookieOrLine(cookie_name_field, mojom::CookieOrLine::Tag::kCookie),
- net::CookieInclusionStatus())));
- }
- // Change the cookie with a new value so that a cookie access
- // event is possible, then block the cookie access.
- const char* kNewCookieValue = "new-cookie-value";
- cookie_name_field = std::string(kCookieName) + std::string("=") +
- std::string(kNewCookieValue);
- SetSessionCookie(kCookieName, kNewCookieValue, kCookieSite, "/");
- cookie_settings_.set_block_third_party_cookies(true);
- {
- auto options = mojom::CookieManagerGetOptions::New();
- options->name = kCookieName;
- options->match_type = mojom::CookieMatchType::STARTS_WITH;
- EXPECT_THAT(sync_service_->GetAllForUrl(
- kDefaultUrlWithPath, net::SiteForCookies(), kDefaultOrigin,
- std::move(options),
- /*partitioned_cookies_runtime_feature_enabled=*/false),
- IsEmpty());
- WaitForCallback();
- // A change in access result (allowed -> blocked) should generate a new
- // notification.
- EXPECT_EQ(recorded_activity().size(), 2ul);
- }
- // Allow the cookie access.
- cookie_settings_.set_block_third_party_cookies(false);
- {
- auto options = mojom::CookieManagerGetOptions::New();
- options->name = kCookieName;
- options->match_type = mojom::CookieMatchType::STARTS_WITH;
- EXPECT_THAT(
- sync_service_->GetAllForUrl(
- kDefaultUrlWithPath, net::SiteForCookies(), kDefaultOrigin,
- std::move(options),
- /*partitioned_cookies_runtime_feature_enabled=*/false),
- ElementsAre(net::MatchesCookieNameValue(kCookieName, kNewCookieValue)));
- WaitForCallback();
- // A change in access result (blocked -> allowed) should generate a new
- // notification.
- EXPECT_THAT(recorded_activity(),
- ElementsAre(testing::_, testing::_,
- MatchesCookieOp(
- mojom::CookieAccessDetails::Type::kRead,
- kDefaultUrlWithPath, net::SiteForCookies(),
- CookieOrLine(cookie_name_field,
- mojom::CookieOrLine::Tag::kCookie),
- net::CookieInclusionStatus())));
- }
- }
- TEST_P(RestrictedCookieManagerTest, GetAllForUrlPolicyWarnActual) {
- service_->OverrideIsolationInfoForTesting(kOtherIsolationInfo);
- // Activate legacy semantics to be able to inject a bad cookie.
- auto cookie_access_delegate =
- std::make_unique<net::TestCookieAccessDelegate>();
- cookie_access_delegate->SetExpectationForCookieDomain(
- "example.com", net::CookieAccessSemantics::LEGACY);
- cookie_monster_.SetCookieAccessDelegate(std::move(cookie_access_delegate));
- SetSessionCookie("cookie-name", "cookie-value", "example.com", "/",
- /*secure=*/false);
- // Now test get using (default) nonlegacy semantics.
- cookie_monster_.SetCookieAccessDelegate(nullptr);
- {
- auto options = mojom::CookieManagerGetOptions::New();
- options->name = "cookie-name";
- options->match_type = mojom::CookieMatchType::STARTS_WITH;
- EXPECT_THAT(sync_service_->GetAllForUrl(
- kDefaultUrlWithPath, net::SiteForCookies(), kDefaultOrigin,
- std::move(options),
- /*partitioned_cookies_runtime_feature_enabled=*/false),
- IsEmpty());
- }
- WaitForCallback();
- EXPECT_THAT(recorded_activity(),
- ElementsAre(MatchesCookieOp(
- mojom::CookieAccessDetails::Type::kRead,
- "https://example.com/test/", net::SiteForCookies(),
- CookieOrLine("cookie-name=cookie-value",
- mojom::CookieOrLine::Tag::kCookie),
- net::HasExactlyExclusionReasonsForTesting(
- std::vector<net::CookieInclusionStatus::ExclusionReason>{
- net::CookieInclusionStatus::
- EXCLUDE_SAMESITE_NONE_INSECURE}))));
- }
- TEST_P(SamePartyEnabledRestrictedCookieManagerTest, GetAllForUrlSameParty) {
- SetSamePartyCookie("cookie-name", "cookie-value", "example.com", "/");
- // Same Party
- {
- auto options = mojom::CookieManagerGetOptions::New();
- options->name = "cookie-name";
- options->match_type = mojom::CookieMatchType::STARTS_WITH;
- EXPECT_THAT(sync_service_->GetAllForUrl(
- kDefaultUrlWithPath, kDefaultSiteForCookies, kDefaultOrigin,
- std::move(options),
- /*partitioned_cookies_runtime_feature_enabled=*/false),
- ElementsAre(net::MatchesCookieNameValue("cookie-name",
- "cookie-value")));
- WaitForCallback();
- }
- // Same Party. `party_context` contains fps site.
- service_->OverrideIsolationInfoForTesting(net::IsolationInfo::Create(
- net::IsolationInfo::RequestType::kOther, kDefaultOrigin, kDefaultOrigin,
- net::SiteForCookies(),
- std::set<net::SchemefulSite>{
- net::SchemefulSite(GURL("https://member1.com"))}));
- {
- auto options = mojom::CookieManagerGetOptions::New();
- options->name = "cookie-name";
- options->match_type = mojom::CookieMatchType::STARTS_WITH;
- EXPECT_THAT(sync_service_->GetAllForUrl(
- kDefaultUrlWithPath, net::SiteForCookies(), kDefaultOrigin,
- std::move(options),
- /*partitioned_cookies_runtime_feature_enabled=*/false),
- ElementsAre(net::MatchesCookieNameValue("cookie-name",
- "cookie-value")));
- WaitForCallback();
- }
- {
- // Should still be blocked when third-party cookie blocking is enabled.
- cookie_settings_.set_block_third_party_cookies(true);
- auto options = mojom::CookieManagerGetOptions::New();
- options->name = "cookie-name";
- options->match_type = mojom::CookieMatchType::STARTS_WITH;
- EXPECT_THAT(sync_service_->GetAllForUrl(
- kDefaultUrlWithPath, net::SiteForCookies(), kDefaultOrigin,
- std::move(options),
- /*partitioned_cookies_runtime_feature_enabled=*/false),
- IsEmpty());
- WaitForCallback();
- // This checks that the cookie access is not double-reported due the
- // warning reason and EXCLUDE_USER_PREFERENCES.
- std::vector<net::CookieInclusionStatus::WarningReason> expected_warnings = {
- net::CookieInclusionStatus::WARN_TREATED_AS_SAMEPARTY,
- };
- EXPECT_THAT(
- recorded_activity(),
- ElementsAre(
- testing::_, testing::_,
- MatchesCookieOp(
- mojom::CookieAccessDetails::Type::kRead, kDefaultUrlWithPath,
- net::SiteForCookies(),
- CookieOrLine("cookie-name=cookie-value",
- mojom::CookieOrLine::Tag::kCookie),
- net::CookieInclusionStatus::MakeFromReasonsForTesting(
- {net::CookieInclusionStatus::EXCLUDE_USER_PREFERENCES},
- expected_warnings))));
- cookie_settings_.set_block_third_party_cookies(false);
- }
- // Cross Party
- {
- // `party_context` contains cross-party site.
- service_->OverrideIsolationInfoForTesting(net::IsolationInfo::Create(
- net::IsolationInfo::RequestType::kOther, kDefaultOrigin, kDefaultOrigin,
- net::SiteForCookies(),
- std::set<net::SchemefulSite>{
- net::SchemefulSite(GURL("https://nonexample.com"))}));
- auto options = mojom::CookieManagerGetOptions::New();
- options->name = "cookie-name";
- options->match_type = mojom::CookieMatchType::STARTS_WITH;
- EXPECT_THAT(sync_service_->GetAllForUrl(
- kDefaultUrlWithPath, net::SiteForCookies(), kDefaultOrigin,
- std::move(options),
- /*partitioned_cookies_runtime_feature_enabled=*/false),
- IsEmpty());
- WaitForCallback();
- EXPECT_THAT(
- recorded_activity(),
- ElementsAre(
- testing::_, testing::_, testing::_,
- MatchesCookieOp(
- testing::_ /* type */, testing::_ /* url */,
- testing::_ /* site_for_cookies */,
- testing::_ /* cookie_or_line */,
- net::HasExactlyExclusionReasonsForTesting(
- std::vector<net::CookieInclusionStatus::ExclusionReason>{
- net::CookieInclusionStatus::
- EXCLUDE_SAMEPARTY_CROSS_PARTY_CONTEXT}))));
- }
- }
- TEST_P(RestrictedCookieManagerTest, SetCanonicalCookie) {
- EXPECT_TRUE(sync_service_->SetCanonicalCookie(
- *net::CanonicalCookie::CreateUnsafeCookieForTesting(
- "new-name", "new-value", "example.com", "/", base::Time(),
- base::Time(), base::Time(), base::Time(), /*secure=*/true,
- /*httponly=*/false, net::CookieSameSite::NO_RESTRICTION,
- net::COOKIE_PRIORITY_DEFAULT, /*same_party=*/false),
- kDefaultUrlWithPath, kDefaultSiteForCookies, kDefaultOrigin));
- auto options = mojom::CookieManagerGetOptions::New();
- options->name = "new-name";
- options->match_type = mojom::CookieMatchType::EQUALS;
- EXPECT_THAT(
- sync_service_->GetAllForUrl(
- kDefaultUrlWithPath, kDefaultSiteForCookies, kDefaultOrigin,
- std::move(options),
- /*partitioned_cookies_runtime_feature_enabled=*/false),
- ElementsAre(net::MatchesCookieNameValue("new-name", "new-value")));
- }
- TEST_P(RestrictedCookieManagerTest, SetCanonicalCookieHttpOnly) {
- EXPECT_EQ(GetParam() == mojom::RestrictedCookieManagerRole::NETWORK,
- sync_service_->SetCanonicalCookie(
- *net::CanonicalCookie::CreateUnsafeCookieForTesting(
- "new-name", "new-value", "example.com", "/", base::Time(),
- base::Time(), base::Time(), base::Time(), /*secure=*/true,
- /*httponly=*/true, net::CookieSameSite::NO_RESTRICTION,
- net::COOKIE_PRIORITY_DEFAULT, /*same_party=*/false),
- kDefaultUrlWithPath, kDefaultSiteForCookies, kDefaultOrigin));
- auto options = mojom::CookieManagerGetOptions::New();
- options->name = "new-name";
- options->match_type = mojom::CookieMatchType::EQUALS;
- std::vector<net::CanonicalCookie> cookies = sync_service_->GetAllForUrl(
- kDefaultUrlWithPath, kDefaultSiteForCookies, kDefaultOrigin,
- std::move(options),
- /*partitioned_cookies_runtime_feature_enabled=*/false);
- if (GetParam() == mojom::RestrictedCookieManagerRole::SCRIPT) {
- EXPECT_THAT(cookies, IsEmpty());
- } else {
- EXPECT_THAT(cookies, ElementsAre(net::MatchesCookieNameValue("new-name",
- "new-value")));
- }
- }
- TEST_P(RestrictedCookieManagerTest, SetCookieFromString) {
- bool site_for_cookies_ok = false;
- bool top_frame_origin_ok = false;
- EXPECT_TRUE(backend()->SetCookieFromString(
- kDefaultUrlWithPath, kDefaultSiteForCookies, kDefaultOrigin,
- "new-name=new-value;path=/",
- /*partitioned_cookies_runtime_feature_enabled=*/false,
- &site_for_cookies_ok, &top_frame_origin_ok));
- EXPECT_TRUE(site_for_cookies_ok);
- EXPECT_TRUE(top_frame_origin_ok);
- auto options = mojom::CookieManagerGetOptions::New();
- options->name = "new-name";
- options->match_type = mojom::CookieMatchType::EQUALS;
- EXPECT_THAT(
- sync_service_->GetAllForUrl(
- kDefaultUrlWithPath, kDefaultSiteForCookies, kDefaultOrigin,
- std::move(options),
- /*partitioned_cookies_runtime_feature_enabled=*/false),
- ElementsAre(net::MatchesCookieNameValue("new-name", "new-value")));
- }
- TEST_P(RestrictedCookieManagerTest, BadSetCookieFromString) {
- bool site_for_cookies_ok = true;
- bool top_frame_origin_ok = true;
- // Purposely set an invalid cookie to return early before the DCHECK fails.
- EXPECT_TRUE(backend()->SetCookieFromString(
- kDefaultUrlWithPath, net::SiteForCookies(),
- url::Origin::Create(GURL("https://not-example.com")),
- "__Host-invalid=host_prefix_with_domain; Domain=example.com",
- /*partitioned_cookies_runtime_feature_enabled=*/false,
- &site_for_cookies_ok, &top_frame_origin_ok));
- EXPECT_FALSE(site_for_cookies_ok);
- EXPECT_FALSE(top_frame_origin_ok);
- }
- TEST_P(RestrictedCookieManagerTest, SetCanonicalCookieFromWrongOrigin) {
- ExpectBadMessage();
- EXPECT_FALSE(sync_service_->SetCanonicalCookie(
- *net::CanonicalCookie::CreateUnsafeCookieForTesting(
- "new-name", "new-value", "not-example.com", "/", base::Time(),
- base::Time(), base::Time(), base::Time(), /*secure=*/true,
- /*httponly=*/false, net::CookieSameSite::NO_RESTRICTION,
- net::COOKIE_PRIORITY_DEFAULT, /*same_party=*/false),
- kOtherUrlWithPath, kDefaultSiteForCookies, kDefaultOrigin));
- ASSERT_TRUE(received_bad_message());
- }
- TEST_P(RestrictedCookieManagerTest, SetCanonicalCookieFromOpaqueOrigin) {
- url::Origin opaque_origin;
- ASSERT_TRUE(opaque_origin.opaque());
- service_->OverrideOriginForTesting(opaque_origin);
- ExpectBadMessage();
- EXPECT_FALSE(sync_service_->SetCanonicalCookie(
- *net::CanonicalCookie::CreateUnsafeCookieForTesting(
- "new-name", "new-value", "not-example.com", "/", base::Time(),
- base::Time(), base::Time(), base::Time(), /*secure=*/true,
- /*httponly=*/false, net::CookieSameSite::NO_RESTRICTION,
- net::COOKIE_PRIORITY_DEFAULT, /*same_party=*/false),
- kDefaultUrlWithPath, kDefaultSiteForCookies, kDefaultOrigin));
- ASSERT_TRUE(received_bad_message());
- }
- TEST_P(RestrictedCookieManagerTest, SetCanonicalCookieWithMismatchingDomain) {
- ExpectBadMessage();
- EXPECT_FALSE(sync_service_->SetCanonicalCookie(
- *net::CanonicalCookie::CreateUnsafeCookieForTesting(
- "new-name", "new-value", "not-example.com", "/", base::Time(),
- base::Time(), base::Time(), base::Time(), /*secure=*/true,
- /*httponly=*/false, net::CookieSameSite::NO_RESTRICTION,
- net::COOKIE_PRIORITY_DEFAULT, /*same_party=*/false),
- kDefaultUrlWithPath, kDefaultSiteForCookies, kDefaultOrigin));
- ASSERT_TRUE(received_bad_message());
- }
- TEST_P(RestrictedCookieManagerTest, SetCookieFromStringWrongOrigin) {
- ExpectBadMessage();
- bool site_for_cookies_ok = false;
- bool top_frame_origin_ok = false;
- EXPECT_TRUE(backend()->SetCookieFromString(
- kOtherUrlWithPath, kDefaultSiteForCookies, kDefaultOrigin,
- "new-name=new-value;path=/",
- /*partitioned_cookies_runtime_feature_enabled=*/false,
- &site_for_cookies_ok, &top_frame_origin_ok));
- ASSERT_TRUE(received_bad_message());
- }
- TEST_P(RestrictedCookieManagerTest, SetCanonicalCookiePolicy) {
- service_->OverrideIsolationInfoForTesting(kOtherIsolationInfo);
- {
- // With default settings object, setting a third-party cookie is OK.
- auto cookie = net::CanonicalCookie::Create(
- kDefaultUrl, "A=B; SameSite=none; Secure", base::Time::Now(),
- absl::nullopt /* server_time */,
- absl::nullopt /* cookie_partition_key */);
- EXPECT_TRUE(sync_service_->SetCanonicalCookie(
- *cookie, kDefaultUrl, net::SiteForCookies(), kDefaultOrigin));
- }
- WaitForCallback();
- EXPECT_THAT(recorded_activity(),
- ElementsAre(MatchesCookieOp(
- mojom::CookieAccessDetails::Type::kChange,
- "https://example.com/", net::SiteForCookies(),
- CookieOrLine("A=B", mojom::CookieOrLine::Tag::kCookie),
- net::IsInclude())));
- {
- // Not if third-party cookies are disabled, though.
- cookie_settings_.set_block_third_party_cookies(true);
- auto cookie = net::CanonicalCookie::Create(
- kDefaultUrl, "A2=B2; SameSite=none; Secure", base::Time::Now(),
- absl::nullopt /* server_time */,
- absl::nullopt /* cookie_partition_key */);
- EXPECT_FALSE(sync_service_->SetCanonicalCookie(
- *cookie, kDefaultUrl, net::SiteForCookies(), kDefaultOrigin));
- }
- WaitForCallback();
- EXPECT_THAT(
- recorded_activity(),
- ElementsAre(
- testing::_,
- MatchesCookieOp(
- mojom::CookieAccessDetails::Type::kChange, "https://example.com/",
- net::SiteForCookies(),
- CookieOrLine("A2=B2", mojom::CookieOrLine::Tag::kCookie),
- net::HasExactlyExclusionReasonsForTesting(
- std::vector<net::CookieInclusionStatus::ExclusionReason>{
- net::CookieInclusionStatus::EXCLUDE_USER_PREFERENCES}))));
- // Read back, in first-party context
- auto options = mojom::CookieManagerGetOptions::New();
- options->name = "A";
- options->match_type = mojom::CookieMatchType::STARTS_WITH;
- service_->OverrideIsolationInfoForTesting(kDefaultIsolationInfo);
- EXPECT_THAT(sync_service_->GetAllForUrl(
- kDefaultUrlWithPath, kDefaultSiteForCookies, kDefaultOrigin,
- std::move(options),
- /*partitioned_cookies_runtime_feature_enabled=*/false),
- ElementsAre(net::MatchesCookieNameValue("A", "B")));
- WaitForCallback();
- EXPECT_THAT(
- recorded_activity(),
- ElementsAre(
- testing::_, testing::_,
- MatchesCookieOp(
- mojom::CookieAccessDetails::Type::kRead,
- "https://example.com/test/",
- net::SiteForCookies::FromUrl(GURL("https://example.com/")),
- CookieOrLine("A=B", mojom::CookieOrLine::Tag::kCookie),
- net::IsInclude())));
- }
- TEST_P(RestrictedCookieManagerTest, SetCanonicalCookiePolicyWarnActual) {
- service_->OverrideIsolationInfoForTesting(kOtherIsolationInfo);
- auto cookie = net::CanonicalCookie::Create(
- kDefaultUrl, "A=B", base::Time::Now(), absl::nullopt /* server_time */,
- absl::nullopt /* cookie_partition_key */);
- EXPECT_FALSE(sync_service_->SetCanonicalCookie(
- *cookie, kDefaultUrl, net::SiteForCookies(), kDefaultOrigin));
- EXPECT_THAT(recorded_activity(),
- ElementsAre(MatchesCookieOp(
- mojom::CookieAccessDetails::Type::kChange,
- "https://example.com/", net::SiteForCookies(),
- CookieOrLine("A=B", mojom::CookieOrLine::Tag::kCookie),
- net::HasExactlyExclusionReasonsForTesting(
- std::vector<net::CookieInclusionStatus::ExclusionReason>{
- net::CookieInclusionStatus::
- EXCLUDE_SAMESITE_UNSPECIFIED_TREATED_AS_LAX}))));
- }
- TEST_P(SamePartyEnabledRestrictedCookieManagerTest,
- SetCookieFromString_SameParty_ReportsInvalid) {
- // Invalid. Should be reported.
- sync_service_->SetCookieFromString(
- kDefaultUrlWithPath, net::SiteForCookies(), kDefaultOrigin,
- "name=value;SameParty",
- /*partitioned_cookies_runtime_feature_enabled=*/false);
- WaitForCallback();
- EXPECT_THAT(
- recorded_activity(),
- ElementsAre(MatchesCookieOp(
- mojom::CookieAccessDetails::Type::kChange, kDefaultUrlWithPath,
- net::SiteForCookies(),
- CookieOrLine("name=value;SameParty",
- mojom::CookieOrLine::Tag::kCookieString),
- net::HasExactlyExclusionReasonsForTesting(
- std::vector<net::CookieInclusionStatus::ExclusionReason>{
- net::CookieInclusionStatus::EXCLUDE_INVALID_SAMEPARTY}))));
- }
- TEST_P(SamePartyEnabledRestrictedCookieManagerTest,
- SetCanonicalCookieSameParty) {
- // Same Party. `party_context` contains fps site.
- {
- service_->OverrideIsolationInfoForTesting(net::IsolationInfo::Create(
- net::IsolationInfo::RequestType::kOther, kDefaultOrigin,
- url::Origin::Create(GURL("https://member1.com")), net::SiteForCookies(),
- std::set<net::SchemefulSite>{
- net::SchemefulSite(GURL("https://member1.com"))}));
- // Need to override origin as well since the access is from member1.com.
- service_->OverrideOriginForTesting(
- url::Origin::Create(GURL("https://member1.com")));
- EXPECT_TRUE(sync_service_->SetCanonicalCookie(
- *net::CanonicalCookie::CreateUnsafeCookieForTesting(
- "new-name", "new-value", "member1.com", "/", base::Time(),
- base::Time(), base::Time(), base::Time(), /*secure=*/true,
- /*httponly=*/false, net::CookieSameSite::LAX_MODE,
- net::COOKIE_PRIORITY_DEFAULT, /*same_party=*/true),
- GURL("https://member1.com/test/"), net::SiteForCookies(),
- kDefaultOrigin));
- auto options = mojom::CookieManagerGetOptions::New();
- options->name = "new-name";
- options->match_type = mojom::CookieMatchType::EQUALS;
- EXPECT_THAT(
- sync_service_->GetAllForUrl(
- GURL("https://member1.com/test/"), net::SiteForCookies(),
- kDefaultOrigin, std::move(options),
- /*partitioned_cookies_runtime_feature_enabled=*/false),
- ElementsAre(net::MatchesCookieNameValue("new-name", "new-value")));
- }
- // Cross Party
- {
- service_->OverrideIsolationInfoForTesting(net::IsolationInfo::Create(
- net::IsolationInfo::RequestType::kOther, kDefaultOrigin, kDefaultOrigin,
- net::SiteForCookies(),
- std::set<net::SchemefulSite>{
- net::SchemefulSite(GURL("https://not-example.com"))}));
- // Need to restore the origin value since the previous Same Party test case
- // changed it to member1.com.
- service_->OverrideOriginForTesting(kDefaultOrigin);
- EXPECT_FALSE(sync_service_->SetCanonicalCookie(
- *net::CanonicalCookie::CreateUnsafeCookieForTesting(
- "new-name", "new-value", "example.com", "/", base::Time(),
- base::Time(), base::Time(), base::Time(), /*secure=*/true,
- /*httponly=*/false, net::CookieSameSite::NO_RESTRICTION,
- net::COOKIE_PRIORITY_DEFAULT, /*same_party=*/true),
- kDefaultUrlWithPath, net::SiteForCookies(), kDefaultOrigin));
- EXPECT_THAT(
- recorded_activity(),
- ElementsAre(
- testing::_, testing::_,
- MatchesCookieOp(
- mojom::CookieAccessDetails::Type::kChange,
- "https://example.com/test/", net::SiteForCookies(),
- CookieOrLine("new-name=new-value",
- mojom::CookieOrLine::Tag::kCookie),
- net::HasExactlyExclusionReasonsForTesting(
- std::vector<net::CookieInclusionStatus::ExclusionReason>{
- net::CookieInclusionStatus::
- EXCLUDE_SAMEPARTY_CROSS_PARTY_CONTEXT}))));
- }
- }
- TEST_P(RestrictedCookieManagerTest, SetCanonicalCookieWithInclusionStatus) {
- ExpectBadMessage();
- net::CookieInclusionStatus status_exclude(
- net::CookieInclusionStatus::ExclusionReason::EXCLUDE_USER_PREFERENCES);
- // In this instance cookie should be OK but due to the status having
- // an exclusion reason, the result should be false and a BadMessage should
- // be received.
- EXPECT_FALSE(sync_service_->SetCanonicalCookie(
- *net::CanonicalCookie::CreateUnsafeCookieForTesting(
- "new-name", "new-value", "example.com", "/", base::Time(),
- base::Time(), base::Time(), base::Time(), /*secure=*/true,
- /*httponly=*/false, net::CookieSameSite::LAX_MODE,
- net::COOKIE_PRIORITY_DEFAULT, /*same_party=*/false),
- kDefaultUrlWithPath, kDefaultSiteForCookies, kDefaultOrigin,
- status_exclude));
- ASSERT_TRUE(received_bad_message());
- // In this instance the cookie should be OK and the status only
- // has a warning so the result should be true.
- net::CookieInclusionStatus status_warning(
- net::CookieInclusionStatus::WARN_ATTRIBUTE_VALUE_EXCEEDS_MAX_SIZE);
- EXPECT_TRUE(sync_service_->SetCanonicalCookie(
- *net::CanonicalCookie::CreateUnsafeCookieForTesting(
- "new-name", "new-value", "example.com", "/", base::Time(),
- base::Time(), base::Time(), base::Time(), /*secure=*/true,
- /*httponly=*/false, net::CookieSameSite::LAX_MODE,
- net::COOKIE_PRIORITY_DEFAULT, /*same_party=*/false),
- kDefaultUrlWithPath, kDefaultSiteForCookies, kDefaultOrigin,
- status_warning));
- WaitForCallback();
- EXPECT_THAT(
- recorded_activity(),
- ElementsAre(MatchesCookieOp(
- mojom::CookieAccessDetails::Type::kChange, kDefaultUrlWithPath,
- kDefaultSiteForCookies,
- CookieOrLine("new-name=new-value", mojom::CookieOrLine::Tag::kCookie),
- net::CookieInclusionStatus::MakeFromReasonsForTesting(
- {}, {net::CookieInclusionStatus::
- WARN_ATTRIBUTE_VALUE_EXCEEDS_MAX_SIZE}))));
- }
- TEST_P(RestrictedCookieManagerTest, CookiesEnabledFor) {
- service_->OverrideIsolationInfoForTesting(kOtherIsolationInfo);
- // Default, third-party access is OK.
- bool result = false;
- EXPECT_TRUE(backend()->CookiesEnabledFor(kDefaultUrl, net::SiteForCookies(),
- kDefaultOrigin, &result));
- EXPECT_TRUE(result);
- // Third-party cookies disabled.
- cookie_settings_.set_block_third_party_cookies(true);
- EXPECT_TRUE(backend()->CookiesEnabledFor(kDefaultUrl, net::SiteForCookies(),
- kDefaultOrigin, &result));
- EXPECT_FALSE(result);
- // First-party ones still OK.
- service_->OverrideIsolationInfoForTesting(kDefaultIsolationInfo);
- EXPECT_TRUE(backend()->CookiesEnabledFor(kDefaultUrl, kDefaultSiteForCookies,
- kDefaultOrigin, &result));
- EXPECT_TRUE(result);
- }
- // Test that special chrome:// scheme always attaches SameSite cookies when the
- // requested origin is secure.
- TEST_P(RestrictedCookieManagerTest, SameSiteCookiesSpecialScheme) {
- url::ScopedSchemeRegistryForTests scoped_registry;
- cookie_settings_.set_secure_origin_cookies_allowed_schemes({"chrome"});
- url::AddStandardScheme("chrome", url::SchemeType::SCHEME_WITH_HOST);
- GURL extension_url("chrome-extension://abcdefghijklmnopqrstuvwxyz");
- GURL chrome_url("chrome://whatever");
- GURL http_url("http://example.com/test");
- GURL https_url("https://example.com/test");
- auto http_origin = url::Origin::Create(http_url);
- auto https_origin = url::Origin::Create(https_url);
- auto chrome_origin = url::Origin::Create(chrome_url);
- net::SiteForCookies chrome_site_for_cookies =
- net::SiteForCookies::FromUrl(chrome_url);
- // Test if site_for_cookies is chrome, then SameSite cookies can be
- // set and gotten if the origin is secure.
- service_->OverrideIsolationInfoForTesting(net::IsolationInfo::Create(
- net::IsolationInfo::RequestType::kOther, chrome_origin, https_origin,
- chrome_site_for_cookies));
- service_->OverrideOriginForTesting(https_origin);
- EXPECT_TRUE(sync_service_->SetCanonicalCookie(
- *net::CanonicalCookie::CreateUnsafeCookieForTesting(
- "strict-cookie", "1", "example.com", "/", base::Time(), base::Time(),
- base::Time(), base::Time(), /*secure=*/false,
- /*httponly=*/false, net::CookieSameSite::STRICT_MODE,
- net::COOKIE_PRIORITY_DEFAULT, /*same_party=*/false),
- https_url, chrome_site_for_cookies, chrome_origin));
- EXPECT_TRUE(sync_service_->SetCanonicalCookie(
- *net::CanonicalCookie::CreateUnsafeCookieForTesting(
- "lax-cookie", "1", "example.com", "/", base::Time(), base::Time(),
- base::Time(), base::Time(), /*secure=*/false,
- /*httponly=*/false, net::CookieSameSite::LAX_MODE,
- net::COOKIE_PRIORITY_DEFAULT, /*same_party=*/false),
- https_url, chrome_site_for_cookies, chrome_origin));
- auto options = mojom::CookieManagerGetOptions::New();
- options->name = "";
- options->match_type = mojom::CookieMatchType::STARTS_WITH;
- EXPECT_THAT(
- sync_service_->GetAllForUrl(
- https_url, chrome_site_for_cookies, chrome_origin, std::move(options),
- /*partitioned_cookies_runtime_feature_enabled=*/false),
- testing::SizeIs(2));
- // Test if site_for_cookies is chrome, then SameSite cookies cannot be
- // set and gotten if the origin is not secure.
- service_->OverrideIsolationInfoForTesting(net::IsolationInfo::Create(
- net::IsolationInfo::RequestType::kOther, chrome_origin, http_origin,
- chrome_site_for_cookies));
- service_->OverrideOriginForTesting(http_origin);
- EXPECT_FALSE(sync_service_->SetCanonicalCookie(
- *net::CanonicalCookie::CreateUnsafeCookieForTesting(
- "strict-cookie", "2", "example.com", "/", base::Time(), base::Time(),
- base::Time(), base::Time(), /*secure=*/false,
- /*httponly=*/false, net::CookieSameSite::STRICT_MODE,
- net::COOKIE_PRIORITY_DEFAULT, /*same_party=*/false),
- http_url, chrome_site_for_cookies, chrome_origin));
- EXPECT_FALSE(sync_service_->SetCanonicalCookie(
- *net::CanonicalCookie::CreateUnsafeCookieForTesting(
- "lax-cookie", "2", "example.com", "/", base::Time(), base::Time(),
- base::Time(), base::Time(), /*secure=*/false,
- /*httponly=*/false, net::CookieSameSite::LAX_MODE,
- net::COOKIE_PRIORITY_DEFAULT, /*same_party=*/false),
- http_url, chrome_site_for_cookies, chrome_origin));
- options = mojom::CookieManagerGetOptions::New();
- options->name = "";
- options->match_type = mojom::CookieMatchType::STARTS_WITH;
- EXPECT_THAT(
- sync_service_->GetAllForUrl(
- http_url, chrome_site_for_cookies, chrome_origin, std::move(options),
- /*partitioned_cookies_runtime_feature_enabled=*/false),
- IsEmpty());
- }
- TEST_P(RestrictedCookieManagerTest, ChangeDispatch) {
- auto listener = CreateCookieChangeListener(
- kDefaultUrlWithPath, kDefaultSiteForCookies, kDefaultOrigin);
- ASSERT_THAT(listener->observed_changes(), testing::SizeIs(0));
- SetSessionCookie("cookie-name", "cookie-value", "example.com", "/");
- listener->WaitForChange();
- ASSERT_THAT(listener->observed_changes(), testing::SizeIs(1));
- EXPECT_EQ(net::CookieChangeCause::INSERTED,
- listener->observed_changes()[0].cause);
- EXPECT_THAT(listener->observed_changes()[0].cookie,
- net::MatchesCookieNameValue("cookie-name", "cookie-value"));
- }
- TEST_P(RestrictedCookieManagerTest, ChangeSettings) {
- service_->OverrideIsolationInfoForTesting(kOtherIsolationInfo);
- auto listener = CreateCookieChangeListener(
- kDefaultUrlWithPath, net::SiteForCookies(), kDefaultOrigin);
- EXPECT_THAT(listener->observed_changes(), IsEmpty());
- cookie_settings_.set_block_third_party_cookies(true);
- SetSessionCookie("cookie-name", "cookie-value", "example.com", "/");
- base::RunLoop().RunUntilIdle();
- EXPECT_THAT(listener->observed_changes(), IsEmpty());
- }
- TEST_P(RestrictedCookieManagerTest, AddChangeListenerFromWrongOrigin) {
- mojo::PendingRemote<network::mojom::CookieChangeListener> bad_listener_remote;
- mojo::PendingReceiver<network::mojom::CookieChangeListener> bad_receiver =
- bad_listener_remote.InitWithNewPipeAndPassReceiver();
- ExpectBadMessage();
- sync_service_->AddChangeListener(kOtherUrlWithPath, kDefaultSiteForCookies,
- kDefaultOrigin,
- std::move(bad_listener_remote));
- EXPECT_TRUE(received_bad_message());
- TestCookieChangeListener bad_listener(std::move(bad_receiver));
- mojo::PendingRemote<network::mojom::CookieChangeListener>
- good_listener_remote;
- mojo::PendingReceiver<network::mojom::CookieChangeListener> good_receiver =
- good_listener_remote.InitWithNewPipeAndPassReceiver();
- sync_service_->AddChangeListener(kDefaultUrlWithPath, kDefaultSiteForCookies,
- kDefaultOrigin,
- std::move(good_listener_remote));
- TestCookieChangeListener good_listener(std::move(good_receiver));
- ASSERT_THAT(bad_listener.observed_changes(), IsEmpty());
- ASSERT_THAT(good_listener.observed_changes(), IsEmpty());
- SetSessionCookie("other-cookie-name", "other-cookie-value", "not-example.com",
- "/");
- SetSessionCookie("cookie-name", "cookie-value", "example.com", "/");
- good_listener.WaitForChange();
- EXPECT_THAT(bad_listener.observed_changes(), IsEmpty());
- ASSERT_THAT(good_listener.observed_changes(), testing::SizeIs(1));
- EXPECT_EQ(net::CookieChangeCause::INSERTED,
- good_listener.observed_changes()[0].cause);
- EXPECT_THAT(good_listener.observed_changes()[0].cookie,
- net::MatchesCookieNameValue("cookie-name", "cookie-value"));
- }
- TEST_P(RestrictedCookieManagerTest, AddChangeListenerFromOpaqueOrigin) {
- url::Origin opaque_origin;
- ASSERT_TRUE(opaque_origin.opaque());
- service_->OverrideOriginForTesting(opaque_origin);
- mojo::PendingRemote<network::mojom::CookieChangeListener> bad_listener_remote;
- mojo::PendingReceiver<network::mojom::CookieChangeListener> bad_receiver =
- bad_listener_remote.InitWithNewPipeAndPassReceiver();
- ExpectBadMessage();
- sync_service_->AddChangeListener(kDefaultUrlWithPath, kDefaultSiteForCookies,
- kDefaultOrigin,
- std::move(bad_listener_remote));
- EXPECT_TRUE(received_bad_message());
- TestCookieChangeListener bad_listener(std::move(bad_receiver));
- ASSERT_THAT(bad_listener.observed_changes(), IsEmpty());
- }
- TEST_P(SamePartyEnabledRestrictedCookieManagerTest,
- AddChangeListenerSameParty) {
- // Same Party. `party_context` contains fps site.
- {
- service_->OverrideIsolationInfoForTesting(net::IsolationInfo::Create(
- net::IsolationInfo::RequestType::kOther, kDefaultOrigin, kDefaultOrigin,
- net::SiteForCookies(),
- std::set<net::SchemefulSite>{
- net::SchemefulSite(GURL("https://member1.com"))}));
- auto listener = CreateCookieChangeListener(
- kDefaultUrlWithPath, net::SiteForCookies(), kDefaultOrigin);
- ASSERT_THAT(listener->observed_changes(), IsEmpty());
- SetSamePartyCookie("cookie-name", "cookie-value", "example.com", "/");
- listener->WaitForChange();
- ASSERT_THAT(listener->observed_changes(), testing::SizeIs(1));
- EXPECT_EQ(net::CookieChangeCause::INSERTED,
- listener->observed_changes()[0].cause);
- EXPECT_THAT(listener->observed_changes()[0].cookie,
- net::MatchesCookieNameValue("cookie-name", "cookie-value"));
- }
- // Cross Party.
- {
- service_->OverrideIsolationInfoForTesting(net::IsolationInfo::Create(
- net::IsolationInfo::RequestType::kOther, kDefaultOrigin, kDefaultOrigin,
- net::SiteForCookies(),
- std::set<net::SchemefulSite>{
- net::SchemefulSite(GURL("https://not-example.com"))}));
- auto listener = CreateCookieChangeListener(
- kDefaultUrlWithPath, net::SiteForCookies(), kDefaultOrigin);
- EXPECT_THAT(listener->observed_changes(), IsEmpty());
- SetSamePartyCookie("cookie-name", "cookie-value", "example.com", "/");
- EXPECT_THAT(listener->observed_changes(), IsEmpty());
- }
- }
- // Test that the Change listener receives the access semantics, and that they
- // are taken into account when deciding when to dispatch the change.
- TEST_P(RestrictedCookieManagerTest, ChangeNotificationIncludesAccessSemantics) {
- auto cookie_access_delegate =
- std::make_unique<net::TestCookieAccessDelegate>();
- cookie_access_delegate->SetExpectationForCookieDomain(
- "example.com", net::CookieAccessSemantics::LEGACY);
- cookie_monster_.SetCookieAccessDelegate(std::move(cookie_access_delegate));
- // Use a cross-site site_for_cookies.
- service_->OverrideIsolationInfoForTesting(kOtherIsolationInfo);
- auto listener = CreateCookieChangeListener(
- kDefaultUrlWithPath, net::SiteForCookies(), kDefaultOrigin);
- ASSERT_THAT(listener->observed_changes(), IsEmpty());
- auto cookie = net::CanonicalCookie::Create(
- kDefaultUrl, "cookie_with_no_samesite=unspecified", base::Time::Now(),
- absl::nullopt, absl::nullopt /* cookie_partition_key */);
- // Set cookie directly into the CookieMonster, using all-inclusive options.
- net::ResultSavingCookieCallback<net::CookieAccessResult> callback;
- cookie_monster_.SetCanonicalCookieAsync(
- std::move(cookie), kDefaultUrl, net::CookieOptions::MakeAllInclusive(),
- callback.MakeCallback());
- callback.WaitUntilDone();
- ASSERT_TRUE(callback.result().status.IsInclude());
- // The listener only receives the change because the cookie is legacy.
- listener->WaitForChange();
- ASSERT_THAT(listener->observed_changes(), testing::SizeIs(1));
- EXPECT_EQ(net::CookieAccessSemantics::LEGACY,
- listener->observed_changes()[0].access_result.access_semantics);
- }
- TEST_P(RestrictedCookieManagerTest, NoChangeNotificationForNonlegacyCookie) {
- auto cookie_access_delegate =
- std::make_unique<net::TestCookieAccessDelegate>();
- cookie_access_delegate->SetExpectationForCookieDomain(
- "example.com", net::CookieAccessSemantics::NONLEGACY);
- cookie_monster_.SetCookieAccessDelegate(std::move(cookie_access_delegate));
- // Use a cross-site site_for_cookies.
- service_->OverrideIsolationInfoForTesting(kOtherIsolationInfo);
- auto listener = CreateCookieChangeListener(
- kDefaultUrlWithPath, net::SiteForCookies(), kDefaultOrigin);
- ASSERT_THAT(listener->observed_changes(), testing::SizeIs(0));
- auto unspecified_cookie = net::CanonicalCookie::Create(
- kDefaultUrl, "cookie_with_no_samesite=unspecified", base::Time::Now(),
- absl::nullopt, absl::nullopt /* cookie_partition_key */);
- auto samesite_none_cookie = net::CanonicalCookie::Create(
- kDefaultUrl, "samesite_none_cookie=none; SameSite=None; Secure",
- base::Time::Now(), absl::nullopt,
- absl::nullopt /* cookie_partition_key */);
- // Set cookies directly into the CookieMonster, using all-inclusive options.
- net::ResultSavingCookieCallback<net::CookieAccessResult> callback1;
- cookie_monster_.SetCanonicalCookieAsync(
- std::move(unspecified_cookie), kDefaultUrl,
- net::CookieOptions::MakeAllInclusive(), callback1.MakeCallback());
- callback1.WaitUntilDone();
- ASSERT_TRUE(callback1.result().status.IsInclude());
- // Listener doesn't receive notification because cookie is not included for
- // request URL for being unspecified and treated as lax.
- base::RunLoop().RunUntilIdle();
- ASSERT_THAT(listener->observed_changes(), testing::SizeIs(0));
- net::ResultSavingCookieCallback<net::CookieAccessResult> callback2;
- cookie_monster_.SetCanonicalCookieAsync(
- std::move(samesite_none_cookie), kDefaultUrl,
- net::CookieOptions::MakeAllInclusive(), callback2.MakeCallback());
- callback2.WaitUntilDone();
- ASSERT_TRUE(callback2.result().status.IsInclude());
- // Listener only receives notification about the SameSite=None cookie.
- listener->WaitForChange();
- ASSERT_THAT(listener->observed_changes(), testing::SizeIs(1));
- EXPECT_EQ("samesite_none_cookie",
- listener->observed_changes()[0].cookie.Name());
- EXPECT_EQ(net::CookieAccessSemantics::NONLEGACY,
- listener->observed_changes()[0].access_result.access_semantics);
- }
- INSTANTIATE_TEST_SUITE_P(
- All,
- RestrictedCookieManagerTest,
- ::testing::Values(mojom::RestrictedCookieManagerRole::SCRIPT,
- mojom::RestrictedCookieManagerRole::NETWORK));
- class PartitionedCookiesRestrictedCookieManagerTest
- : public RestrictedCookieManagerTest {
- public:
- PartitionedCookiesRestrictedCookieManagerTest() {
- feature_list_.InitAndEnableFeature(net::features::kPartitionedCookies);
- }
- ~PartitionedCookiesRestrictedCookieManagerTest() override = default;
- private:
- base::test::ScopedFeatureList feature_list_;
- };
- // Test Partitioned cookie behavior when feature is disabled.
- TEST_P(RestrictedCookieManagerTest, PartitionedCookies) {
- const GURL kCookieURL("https://example.com");
- const GURL kTopFrameURL("https://foo.com");
- const net::SiteForCookies kSiteForCookies =
- net::SiteForCookies::FromUrl(kTopFrameURL);
- const url::Origin kTopFrameOrigin = url::Origin::Create(kTopFrameURL);
- const net::IsolationInfo kIsolationInfo =
- net::IsolationInfo::CreateForInternalRequest(kTopFrameOrigin);
- service_->OverrideIsolationInfoForTesting(kIsolationInfo);
- // Set partitioned_cookies_runtime_feature_enabled to true to make sure it
- // does not override the net feature.
- sync_service_->SetCookieFromString(
- kCookieURL, kSiteForCookies, kTopFrameOrigin,
- "__Host-foo=bar; Secure; SameSite=None; Path=/; Partitioned",
- /*partitioned_cookies_runtime_feature_enabled=*/true);
- { // Test request from the same top-level site.
- auto options = mojom::CookieManagerGetOptions::New();
- options->name = "";
- options->match_type = mojom::CookieMatchType::STARTS_WITH;
- net::CookieList cookies = sync_service_->GetAllForUrl(
- kCookieURL, kSiteForCookies, kTopFrameOrigin, std::move(options),
- /*partitioned_cookies_runtime_feature_enabled=*/true);
- ASSERT_EQ(1u, cookies.size());
- EXPECT_FALSE(cookies[0].IsPartitioned());
- EXPECT_EQ("__Host-foo", cookies[0].Name());
- auto listener = CreateCookieChangeListener(kCookieURL, kSiteForCookies,
- kTopFrameOrigin);
- // Update partitioned cookie Max-Age: None -> 7200.
- EXPECT_TRUE(SetCanonicalCookie(
- *net::CanonicalCookie::Create(
- kCookieURL,
- "__Host-foo=bar; Secure; SameSite=None; Path=/; Partitioned; "
- "Max-Age=7200",
- base::Time::Now(), absl::nullopt /* server_time */,
- net::CookiePartitionKey::FromNetworkIsolationKey(
- kIsolationInfo.network_isolation_key())),
- "https", false /* can_modify_httponly */));
- // If Partitioned cookies are disabled, the change listener should see the
- // change to the cookie on this top-level site.
- listener->WaitForChange();
- ASSERT_THAT(listener->observed_changes(), testing::SizeIs(1));
- }
- { // Test request from another top-level site.
- const GURL kOtherTopFrameURL("https://bar.com");
- const net::SiteForCookies kOtherSiteForCookies =
- net::SiteForCookies::FromUrl(kOtherTopFrameURL);
- const url::Origin kOtherTopFrameOrigin =
- url::Origin::Create(kOtherTopFrameURL);
- const net::IsolationInfo kOtherIsolationInfo =
- net::IsolationInfo::CreateForInternalRequest(kOtherTopFrameOrigin);
- service_->OverrideIsolationInfoForTesting(kOtherIsolationInfo);
- auto options = mojom::CookieManagerGetOptions::New();
- options->name = "";
- options->match_type = mojom::CookieMatchType::STARTS_WITH;
- net::CookieList cookies = sync_service_->GetAllForUrl(
- kCookieURL, kOtherSiteForCookies, kOtherTopFrameOrigin,
- std::move(options),
- /*partitioned_cookies_runtime_feature_enabled=*/true);
- ASSERT_EQ(1u, cookies.size());
- EXPECT_FALSE(cookies[0].IsPartitioned());
- EXPECT_EQ("__Host-foo", cookies[0].Name());
- auto listener = CreateCookieChangeListener(kCookieURL, kOtherSiteForCookies,
- kOtherTopFrameOrigin);
- // Update partitioned cookie Max-Age: 7200 -> 3600.
- EXPECT_TRUE(SetCanonicalCookie(
- *net::CanonicalCookie::Create(
- kCookieURL,
- "__Host-foo=bar; Secure; SameSite=None; Path=/; Partitioned; "
- "Max-Age=3600",
- base::Time::Now(), absl::nullopt /* server_time */,
- net::CookiePartitionKey::FromNetworkIsolationKey(
- kIsolationInfo.network_isolation_key())),
- "https", false /* can_modify_httponly */));
- // If Partitioned cookies are disabled, the change listener should see the
- // change to the cookie on the other top-level site as well.
- listener->WaitForChange();
- ASSERT_THAT(listener->observed_changes(), testing::SizeIs(1));
- }
- }
- TEST_P(RestrictedCookieManagerTest, PartitionKeyFromScript) {
- const GURL kCookieURL("https://example.com");
- const GURL kTopFrameURL("https://foo.com");
- const net::SiteForCookies kSiteForCookies =
- net::SiteForCookies::FromUrl(kTopFrameURL);
- const url::Origin kTopFrameOrigin = url::Origin::Create(kTopFrameURL);
- const net::IsolationInfo kIsolationInfo =
- net::IsolationInfo::CreateForInternalRequest(kTopFrameOrigin);
- service_->OverrideIsolationInfoForTesting(kIsolationInfo);
- EXPECT_TRUE(sync_service_->SetCanonicalCookie(
- *net::CanonicalCookie::Create(
- kCookieURL,
- "__Host-foo=bar; Secure; SameSite=None; Path=/; Partitioned",
- base::Time::Now(), absl::nullopt /* server_time */,
- net::CookiePartitionKey::FromScript()),
- kCookieURL, kSiteForCookies, kTopFrameOrigin));
- auto options = mojom::CookieManagerGetOptions::New();
- options->name = "";
- options->match_type = mojom::CookieMatchType::STARTS_WITH;
- net::CookieList cookies = sync_service_->GetAllForUrl(
- kCookieURL, kSiteForCookies, kTopFrameOrigin, std::move(options),
- /*partitioned_cookies_runtime_feature_enabled=*/true);
- ASSERT_EQ(1u, cookies.size());
- EXPECT_FALSE(cookies[0].IsPartitioned());
- EXPECT_EQ("__Host-foo", cookies[0].Name());
- }
- // Test Partitioned cookie behavior when feature is enabled.
- TEST_P(PartitionedCookiesRestrictedCookieManagerTest, PartitionedCookies) {
- const GURL kCookieURL("https://example.com");
- const GURL kTopFrameURL("https://sub.foo.com");
- const net::SiteForCookies kSiteForCookies =
- net::SiteForCookies::FromUrl(kTopFrameURL);
- const url::Origin kTopFrameOrigin = url::Origin::Create(kTopFrameURL);
- const net::IsolationInfo kIsolationInfo =
- net::IsolationInfo::CreateForInternalRequest(kTopFrameOrigin);
- service_->OverrideIsolationInfoForTesting(kIsolationInfo);
- sync_service_->SetCookieFromString(
- kCookieURL, kSiteForCookies, kTopFrameOrigin,
- "__Host-foo=bar; Secure; SameSite=None; Path=/; Partitioned",
- /*partitioned_cookies_runtime_feature_enabled=*/true);
- { // Test request from the same top-level site.
- auto options = mojom::CookieManagerGetOptions::New();
- options->name = "";
- options->match_type = mojom::CookieMatchType::STARTS_WITH;
- net::CookieList cookies = sync_service_->GetAllForUrl(
- kCookieURL, kSiteForCookies, kTopFrameOrigin, std::move(options),
- /*partitioned_cookies_runtime_feature_enabled=*/true);
- ASSERT_EQ(1u, cookies.size());
- EXPECT_TRUE(cookies[0].IsPartitioned());
- EXPECT_EQ(
- net::CookiePartitionKey::FromURLForTesting(GURL("https://foo.com")),
- cookies[0].PartitionKey());
- EXPECT_EQ("__Host-foo", cookies[0].Name());
- auto listener = CreateCookieChangeListener(kCookieURL, kSiteForCookies,
- kTopFrameOrigin);
- // Update partitioned cookie Max-Age: None -> 7200.
- EXPECT_TRUE(SetCanonicalCookie(
- *net::CanonicalCookie::Create(
- kCookieURL,
- "__Host-foo=bar; Secure; SameSite=None; Path=/; Partitioned; "
- "Max-Age=7200",
- base::Time::Now(), absl::nullopt /* server_time */,
- net::CookiePartitionKey::FromNetworkIsolationKey(
- kIsolationInfo.network_isolation_key())),
- "https", false /* can_modify_httponly */));
- // If Partitioned cookies are enabled, the change listener should see the
- // change to the cookie on this top-level site.
- listener->WaitForChange();
- ASSERT_THAT(listener->observed_changes(), testing::SizeIs(1));
- }
- { // Test request from another top-level site.
- const GURL kOtherTopFrameURL("https://foo.bar.com");
- const net::SiteForCookies kOtherSiteForCookies =
- net::SiteForCookies::FromUrl(kOtherTopFrameURL);
- const url::Origin kOtherTopFrameOrigin =
- url::Origin::Create(kOtherTopFrameURL);
- const net::IsolationInfo kOtherIsolationInfo =
- net::IsolationInfo::CreateForInternalRequest(kOtherTopFrameOrigin);
- service_->OverrideIsolationInfoForTesting(kOtherIsolationInfo);
- auto options = mojom::CookieManagerGetOptions::New();
- options->name = "";
- options->match_type = mojom::CookieMatchType::STARTS_WITH;
- net::CookieList cookies = sync_service_->GetAllForUrl(
- kCookieURL, kOtherSiteForCookies, kOtherTopFrameOrigin,
- std::move(options),
- /*partitioned_cookies_runtime_feature_enabled=*/true);
- ASSERT_EQ(0u, cookies.size());
- auto listener = CreateCookieChangeListener(kCookieURL, kOtherSiteForCookies,
- kOtherTopFrameOrigin);
- // Set a new listener with the original IsolationInfo, we wait for this
- // listener to receive an event to verify that the second listener was
- // either called or skipped.
- service_->OverrideIsolationInfoForTesting(kIsolationInfo);
- auto second_listener = CreateCookieChangeListener(
- kCookieURL, kSiteForCookies, kTopFrameOrigin);
- // Update partitioned cookie Max-Age: 7200 -> 3600.
- EXPECT_TRUE(SetCanonicalCookie(
- *net::CanonicalCookie::Create(
- kCookieURL,
- "__Host-foo=bar; Secure; SameSite=None; Path=/; Partitioned; "
- "Max-Age=3600",
- base::Time::Now(), absl::nullopt /* server_time */,
- net::CookiePartitionKey::FromNetworkIsolationKey(
- kIsolationInfo.network_isolation_key())),
- "https", false /* can_modify_httponly */));
- // If Partitioned cookies are enabled, the listener should not see cookie
- // change events on this top-level site.
- second_listener->WaitForChange();
- ASSERT_THAT(listener->observed_changes(), testing::SizeIs(0));
- }
- { // Test that a cookie cannot be set with a different partition key than
- // RestrictedCookieManager's.
- service_->OverrideIsolationInfoForTesting(kIsolationInfo);
- ExpectBadMessage();
- EXPECT_FALSE(sync_service_->SetCanonicalCookie(
- *net::CanonicalCookie::Create(
- kCookieURL,
- "__Host-foo=bar; Secure; SameSite=None; Path=/; Partitioned",
- base::Time::Now(), absl::nullopt /* server_time */,
- net::CookiePartitionKey::FromURLForTesting(
- GURL("https://foo.bar.com"))),
- kCookieURL, kSiteForCookies, kTopFrameOrigin));
- }
- }
- TEST_P(PartitionedCookiesRestrictedCookieManagerTest, PartitionKeyFromScript) {
- const GURL kCookieURL("https://example.com");
- const GURL kTopFrameURL("https://foo.com");
- const net::SiteForCookies kSiteForCookies =
- net::SiteForCookies::FromUrl(kTopFrameURL);
- const url::Origin kTopFrameOrigin = url::Origin::Create(kTopFrameURL);
- const net::IsolationInfo kIsolationInfo =
- net::IsolationInfo::CreateForInternalRequest(kTopFrameOrigin);
- service_->OverrideIsolationInfoForTesting(kIsolationInfo);
- EXPECT_TRUE(sync_service_->SetCanonicalCookie(
- *net::CanonicalCookie::Create(
- kCookieURL,
- "__Host-foo=bar; Secure; SameSite=None; Path=/; Partitioned",
- base::Time::Now(), absl::nullopt /* server_time */,
- net::CookiePartitionKey::FromScript()),
- kCookieURL, kSiteForCookies, kTopFrameOrigin));
- auto options = mojom::CookieManagerGetOptions::New();
- options->name = "";
- options->match_type = mojom::CookieMatchType::STARTS_WITH;
- net::CookieList cookies = sync_service_->GetAllForUrl(
- kCookieURL, kSiteForCookies, kTopFrameOrigin, std::move(options),
- /*partitioned_cookies_runtime_feature_enabled=*/true);
- ASSERT_EQ(1u, cookies.size());
- EXPECT_TRUE(cookies[0].IsPartitioned());
- EXPECT_EQ(cookies[0].PartitionKey().value(),
- net::CookiePartitionKey::FromURLForTesting(kTopFrameURL));
- EXPECT_EQ("__Host-foo", cookies[0].Name());
- }
- // Tests the interaction between First-Party Sets and partitioned cookies in
- // RestrictedCookieManager. When FPS are enabled, RestrictedCookieManager
- // should use the same cookie partition key for all sites in
- TEST_P(PartitionedCookiesRestrictedCookieManagerTest,
- PartitionedCookiesAndFirstPartySets) {
- const GURL kOwnerURL("https://owner.com");
- const net::SchemefulSite kOwnerSite(kOwnerURL);
- const url::Origin kOwnerOrigin = url::Origin::Create(kOwnerURL);
- const net::IsolationInfo kOwnerIsolationInfo =
- net::IsolationInfo::CreateForInternalRequest(kOwnerOrigin);
- const net::SiteForCookies kOwnerSiteForCookies =
- net::SiteForCookies::FromUrl(kOwnerURL);
- const GURL kMemberURL("https://member.com");
- const net::SchemefulSite kMemberSite(kMemberURL);
- const url::Origin kMemberOrigin = url::Origin::Create(kMemberURL);
- const net::IsolationInfo kMemberIsolationInfo =
- net::IsolationInfo::CreateForInternalRequest(kMemberOrigin);
- const net::SiteForCookies kMemberSiteForCookies =
- net::SiteForCookies::FromUrl(kMemberURL);
- const GURL kNonMemberURL("https://nonmember.com");
- const url::Origin kNonMemberOrigin = url::Origin::Create(kNonMemberURL);
- const net::IsolationInfo kNonMemberIsolationInfo =
- net::IsolationInfo::CreateForInternalRequest(kNonMemberOrigin);
- const net::SiteForCookies kNonMemberSiteForCookies =
- net::SiteForCookies::FromUrl(kNonMemberURL);
- const GURL kCookieURL("https://example.com");
- auto cookie_access_delegate =
- std::make_unique<net::TestCookieAccessDelegate>();
- cookie_access_delegate->SetFirstPartySets({
- {kOwnerSite, net::FirstPartySetEntry(kOwnerSite, net::SiteType::kPrimary,
- absl::nullopt)},
- {kMemberSite,
- net::FirstPartySetEntry(kOwnerSite, net::SiteType::kAssociated, 0)},
- });
- cookie_monster_.SetCookieAccessDelegate(std::move(cookie_access_delegate));
- // Set https://example.com cookie when the top-frame site is the owner
- // of the set.
- service_->OverrideIsolationInfoForTesting(kOwnerIsolationInfo);
- sync_service_->SetCookieFromString(
- kCookieURL, kOwnerSiteForCookies, kOwnerOrigin,
- "__Host-foo=0; Secure; SameSite=None; Path=/; Partitioned",
- /*partitioned_cookies_runtime_feature_enabled=*/true);
- {
- // Check that its partition key is the set's owner site.
- auto options = mojom::CookieManagerGetOptions::New();
- options->name = "";
- options->match_type = mojom::CookieMatchType::STARTS_WITH;
- net::CookieList cookies = sync_service_->GetAllForUrl(
- kCookieURL, kOwnerSiteForCookies, kOwnerOrigin, std::move(options),
- /*partitioned_cookies_runtime_feature_enabled=*/true);
- ASSERT_EQ(1u, cookies.size());
- EXPECT_TRUE(cookies[0].IsPartitioned());
- EXPECT_EQ(net::CookiePartitionKey::FromURLForTesting(kOwnerURL),
- cookies[0].PartitionKey());
- EXPECT_EQ("__Host-foo", cookies[0].Name());
- auto listener = CreateCookieChangeListener(kCookieURL, kOwnerSiteForCookies,
- kOwnerOrigin);
- // Update partitioned cookie Max-Age: None -> 7200.
- sync_service_->SetCookieFromString(
- kCookieURL, kOwnerSiteForCookies, kOwnerOrigin,
- "__Host-foo=0; Secure; SameSite=None; Path=/; Partitioned; "
- "Max-Age: 7200",
- /*partitioned_cookies_runtime_feature_enabled=*/true);
- listener->WaitForChange();
- ASSERT_THAT(listener->observed_changes(), testing::SizeIs(1));
- }
- {
- // Check that cookie is available to https://example.com when the top-frame
- // site is a site that is a member of the set but not the owner.
- service_->OverrideIsolationInfoForTesting(kMemberIsolationInfo);
- auto options = mojom::CookieManagerGetOptions::New();
- options->name = "";
- options->match_type = mojom::CookieMatchType::STARTS_WITH;
- net::CookieList cookies = sync_service_->GetAllForUrl(
- kCookieURL, kMemberSiteForCookies, kMemberOrigin, std::move(options),
- /*partitioned_cookies_runtime_feature_enabled=*/true);
- ASSERT_EQ(1u, cookies.size());
- EXPECT_TRUE(cookies[0].IsPartitioned());
- EXPECT_EQ(net::CookiePartitionKey::FromURLForTesting(kOwnerURL),
- cookies[0].PartitionKey());
- EXPECT_EQ("__Host-foo", cookies[0].Name());
- auto listener = CreateCookieChangeListener(
- kCookieURL, kMemberSiteForCookies, kMemberOrigin);
- // Update partitioned cookie Max-Age: None -> 7200.
- service_->OverrideIsolationInfoForTesting(kOwnerIsolationInfo);
- sync_service_->SetCookieFromString(
- kCookieURL, kOwnerSiteForCookies, kOwnerOrigin,
- "__Host-foo=0; Secure; SameSite=None; Path=/; Partitioned; "
- "Max-Age: 3600",
- /*partitioned_cookies_runtime_feature_enabled=*/true);
- listener->WaitForChange();
- ASSERT_THAT(listener->observed_changes(), testing::SizeIs(1));
- }
- // Set https://example.com cookie when the top-frame site is a member of
- // the set.
- service_->OverrideIsolationInfoForTesting(kMemberIsolationInfo);
- sync_service_->SetCookieFromString(
- kCookieURL, kMemberSiteForCookies, kMemberOrigin,
- "__Host-bar=1; Secure; SameSite=None; Path=/; Partitioned",
- /*partitioned_cookies_runtime_feature_enabled=*/true);
- {
- // Check that the new cookie's partition key is the set's owner site.
- auto options = mojom::CookieManagerGetOptions::New();
- options->name = "";
- options->match_type = mojom::CookieMatchType::STARTS_WITH;
- net::CookieList cookies = sync_service_->GetAllForUrl(
- kCookieURL, kMemberSiteForCookies, kMemberOrigin, std::move(options),
- /*partitioned_cookies_runtime_feature_enabled=*/true);
- ASSERT_EQ(2u, cookies.size());
- EXPECT_EQ("__Host-foo", cookies[0].Name());
- EXPECT_EQ("__Host-bar", cookies[1].Name());
- for (const auto& cookie : cookies) {
- EXPECT_TRUE(cookie.IsPartitioned());
- EXPECT_EQ(net::CookiePartitionKey::FromURLForTesting(kOwnerURL),
- cookie.PartitionKey());
- }
- }
- {
- // Check that the owner site can also access both cookies.
- service_->OverrideIsolationInfoForTesting(kOwnerIsolationInfo);
- auto options = mojom::CookieManagerGetOptions::New();
- options->name = "";
- options->match_type = mojom::CookieMatchType::STARTS_WITH;
- net::CookieList cookies = sync_service_->GetAllForUrl(
- kCookieURL, kOwnerSiteForCookies, kOwnerOrigin, std::move(options),
- /*partitioned_cookies_runtime_feature_enabled=*/true);
- ASSERT_EQ(2u, cookies.size());
- EXPECT_EQ("__Host-foo", cookies[0].Name());
- EXPECT_EQ("__Host-bar", cookies[1].Name());
- }
- {
- // Check that the cookies are not available to https://example.com when the
- // top-frame site is not a member of the set.
- service_->OverrideIsolationInfoForTesting(kNonMemberIsolationInfo);
- auto options = mojom::CookieManagerGetOptions::New();
- options->name = "";
- options->match_type = mojom::CookieMatchType::STARTS_WITH;
- net::CookieList cookies = sync_service_->GetAllForUrl(
- kCookieURL, kNonMemberSiteForCookies, kNonMemberOrigin,
- std::move(options),
- /*partitioned_cookies_runtime_feature_enabled=*/true);
- ASSERT_EQ(0u, cookies.size());
- auto listener = CreateCookieChangeListener(
- kCookieURL, kNonMemberSiteForCookies, kNonMemberOrigin);
- // Set a new listener with the original IsolationInfo, we wait for this
- // listener to receive an event to verify that the second listener was
- // either called or skipped.
- service_->OverrideIsolationInfoForTesting(kOwnerIsolationInfo);
- auto second_listener = CreateCookieChangeListener(
- kCookieURL, kOwnerSiteForCookies, kOwnerOrigin);
- // Update partitioned cookie __Host-bar's Max-Age: None -> 3600.
- service_->OverrideIsolationInfoForTesting(kOwnerIsolationInfo);
- sync_service_->SetCookieFromString(
- kCookieURL, kOwnerSiteForCookies, kOwnerOrigin,
- "__Host-bar=1; Secure; SameSite=None; Path=/; Partitioned; "
- "Max-Age: 3600",
- /*partitioned_cookies_runtime_feature_enabled=*/true);
- // The listener set on the non-member top-frame site should not be able to
- // observe the change.
- second_listener->WaitForChange();
- ASSERT_THAT(listener->observed_changes(), testing::SizeIs(0));
- }
- }
- TEST_P(PartitionedCookiesRestrictedCookieManagerTest, PartitionKeyWithNonce) {
- const GURL kCookieURL("https://example.com");
- const GURL kTopFrameURL("https://foo.com");
- const net::SiteForCookies kSiteForCookies =
- net::SiteForCookies::FromUrl(kTopFrameURL);
- const url::Origin kTopFrameOrigin = url::Origin::Create(kTopFrameURL);
- const base::UnguessableToken kNonce = base::UnguessableToken::Create();
- const absl::optional<std::set<net::SchemefulSite>> kPartyContextEmpty =
- std::set<net::SchemefulSite>();
- const net::IsolationInfo kNoncedIsolationInfo = net::IsolationInfo::Create(
- net::IsolationInfo::RequestType::kMainFrame, kTopFrameOrigin,
- kTopFrameOrigin, kSiteForCookies, kPartyContextEmpty, &kNonce);
- const absl::optional<net::CookiePartitionKey> kNoncedPartitionKey =
- net::CookiePartitionKey::FromNetworkIsolationKey(
- net::NetworkIsolationKey(net::SchemefulSite(kTopFrameURL),
- net::SchemefulSite(kTopFrameURL), &kNonce));
- const net::IsolationInfo kUnnoncedIsolationInfo =
- net::IsolationInfo::CreateForInternalRequest(kTopFrameOrigin);
- service_->OverrideIsolationInfoForTesting(kNoncedIsolationInfo);
- EXPECT_TRUE(sync_service_->SetCanonicalCookie(
- *net::CanonicalCookie::Create(
- kCookieURL, "__Host-foo=bar; Secure; SameSite=None; Path=/;",
- base::Time::Now(), absl::nullopt /* server_time */,
- net::CookiePartitionKey::FromScript()),
- kCookieURL, kSiteForCookies, kTopFrameOrigin));
- {
- auto options = mojom::CookieManagerGetOptions::New();
- options->name = "";
- options->match_type = mojom::CookieMatchType::STARTS_WITH;
- net::CookieList cookies = sync_service_->GetAllForUrl(
- kCookieURL, kSiteForCookies, kTopFrameOrigin, std::move(options),
- /*partitioned_cookies_runtime_feature_enabled=*/true);
- ASSERT_EQ(1u, cookies.size());
- EXPECT_TRUE(cookies[0].IsPartitioned());
- EXPECT_EQ(cookies[0].PartitionKey().value(), kNoncedPartitionKey);
- EXPECT_EQ("__Host-foo", cookies[0].Name());
- }
- { // Test that an unnonced partition cannot see the cookies or observe
- // changes to them.
- service_->OverrideIsolationInfoForTesting(kUnnoncedIsolationInfo);
- auto options = mojom::CookieManagerGetOptions::New();
- options->name = "";
- options->match_type = mojom::CookieMatchType::STARTS_WITH;
- net::CookieList cookies = sync_service_->GetAllForUrl(
- kCookieURL, kSiteForCookies, kTopFrameOrigin, std::move(options),
- /*partitioned_cookies_runtime_feature_enabled=*/true);
- ASSERT_EQ(0u, cookies.size());
- auto listener = CreateCookieChangeListener(kCookieURL, kSiteForCookies,
- kTopFrameOrigin);
- service_->OverrideIsolationInfoForTesting(kNoncedIsolationInfo);
- auto second_listener = CreateCookieChangeListener(
- kCookieURL, kSiteForCookies, kTopFrameOrigin);
- // Update partitioned cookie Max-Age: None -> 7200.
- EXPECT_TRUE(SetCanonicalCookie(
- *net::CanonicalCookie::Create(
- kCookieURL,
- "__Host-foo=bar; Secure; SameSite=None; Path=/; Max-Age=7200",
- base::Time::Now(), absl::nullopt /* server_time */,
- kNoncedPartitionKey),
- "https", false /* can_modify_httponly */));
- second_listener->WaitForChange();
- ASSERT_THAT(listener->observed_changes(), testing::SizeIs(0));
- }
- { // Test that the nonced partition cannot observe changes to the unnonced
- // partition and unpartitioned cookies.
- // Set an unpartitioned cookie.
- service_->OverrideIsolationInfoForTesting(kUnnoncedIsolationInfo);
- EXPECT_TRUE(SetCanonicalCookie(
- *net::CanonicalCookie::Create(
- kCookieURL,
- "__Host-unpartitioned=123; Secure; SameSite=None; Path=/;",
- base::Time::Now(), absl::nullopt /* server_time */, absl::nullopt),
- "https", false /* can_modify_httponly */));
- // Set a partitioned cookie in the unnonced partition.
- EXPECT_TRUE(sync_service_->SetCanonicalCookie(
- *net::CanonicalCookie::Create(
- kCookieURL,
- "__Host-bar=baz; Secure; SameSite=None; Path=/; Partitioned;",
- base::Time::Now(), absl::nullopt /* server_time */,
- net::CookiePartitionKey::FromScript()),
- kCookieURL, kSiteForCookies, kTopFrameOrigin));
- service_->OverrideIsolationInfoForTesting(kNoncedIsolationInfo);
- auto options = mojom::CookieManagerGetOptions::New();
- options->name = "";
- options->match_type = mojom::CookieMatchType::STARTS_WITH;
- // Should only be able to see the nonced partitioned cookie only.
- net::CookieList cookies = sync_service_->GetAllForUrl(
- kCookieURL, kSiteForCookies, kTopFrameOrigin, std::move(options),
- /*partitioned_cookies_runtime_feature_enabled=*/true);
- ASSERT_EQ(1u, cookies.size());
- ASSERT_EQ("__Host-foo", cookies[0].Name());
- // Create a listener in the nonced partition.
- auto listener = CreateCookieChangeListener(kCookieURL, kSiteForCookies,
- kTopFrameOrigin);
- // Create a second listener in an unnonced partition.
- service_->OverrideIsolationInfoForTesting(kUnnoncedIsolationInfo);
- auto second_listener = CreateCookieChangeListener(
- kCookieURL, kSiteForCookies, kTopFrameOrigin);
- // Update unpartitioned cookie Max-Age: None -> 7200.
- EXPECT_TRUE(SetCanonicalCookie(
- *net::CanonicalCookie::Create(
- kCookieURL,
- "__Host-unpartitioned=123; Secure; SameSite=None; Path=/; "
- "Max-Age=7200",
- base::Time::Now(), absl::nullopt /* server_time */, absl::nullopt),
- "https", false /* can_modify_httponly */));
- // Test that the nonced partition cannot observe the change.
- second_listener->WaitForChange();
- ASSERT_THAT(listener->observed_changes(), testing::SizeIs(0));
- // Update unnonced partitioned cookie Max-Age: None -> 7200.
- EXPECT_TRUE(SetCanonicalCookie(
- *net::CanonicalCookie::Create(
- kCookieURL,
- "__Host-bar=baz; Secure; SameSite=None; Path=/; Partitioned; "
- "Max-Age=7200",
- base::Time::Now(), absl::nullopt /* server_time */, absl::nullopt),
- "https", false /* can_modify_httponly */));
- // Test that the nonced partition cannot observe the change.
- second_listener->WaitForChange();
- ASSERT_THAT(listener->observed_changes(), testing::SizeIs(0));
- }
- }
- TEST_P(PartitionedCookiesRestrictedCookieManagerTest, RuntimeEnabledFeature) {
- const GURL kCookieURL("https://example.com");
- const GURL kTopFrameURL("https://sub.foo.com");
- const net::SiteForCookies kSiteForCookies =
- net::SiteForCookies::FromUrl(kTopFrameURL);
- const url::Origin kTopFrameOrigin = url::Origin::Create(kTopFrameURL);
- const net::IsolationInfo kIsolationInfo =
- net::IsolationInfo::CreateForInternalRequest(kTopFrameOrigin);
- service_->OverrideIsolationInfoForTesting(kIsolationInfo);
- // Setting a partitioned cookie when the RuntimeEnabledFeature is disabled
- // should result in an unpartitioned cookie.
- sync_service_->SetCookieFromString(
- kCookieURL, kSiteForCookies, kTopFrameOrigin,
- "__Host-foo=bar; Secure; SameSite=None; Path=/; Partitioned",
- /*partitioned_cookies_runtime_feature_enabled=*/false);
- auto options = mojom::CookieManagerGetOptions::New();
- options->name = "";
- options->match_type = mojom::CookieMatchType::STARTS_WITH;
- net::CookieList cookies = sync_service_->GetAllForUrl(
- kCookieURL, kSiteForCookies, kTopFrameOrigin, std::move(options),
- /*partitioned_cookies_runtime_feature_enabled=*/true);
- ASSERT_EQ(1u, cookies.size());
- EXPECT_EQ("__Host-foo", cookies[0].Name());
- EXPECT_FALSE(cookies[0].IsPartitioned());
- // Should be able to access both partitioned and unpartitioned cookie when the
- // RuntimeEnabledFeature is on.
- sync_service_->SetCookieFromString(
- kCookieURL, kSiteForCookies, kTopFrameOrigin,
- "__Host-bar=baz; Secure; SameSite=None; Path=/; Partitioned",
- /*partitioned_cookies_runtime_feature_enabled=*/true);
- options = mojom::CookieManagerGetOptions::New();
- options->name = "";
- options->match_type = mojom::CookieMatchType::STARTS_WITH;
- cookies = sync_service_->GetAllForUrl(
- kCookieURL, kSiteForCookies, kTopFrameOrigin, std::move(options),
- /*partitioned_cookies_runtime_feature_enabled=*/true);
- ASSERT_EQ(2u, cookies.size());
- EXPECT_FALSE(cookies[0].IsPartitioned());
- EXPECT_TRUE(cookies[1].IsPartitioned());
- // Should only be able to read the unpartitioned cookie when the feature is
- // off.
- options = mojom::CookieManagerGetOptions::New();
- options->name = "";
- options->match_type = mojom::CookieMatchType::STARTS_WITH;
- cookies = sync_service_->GetAllForUrl(
- kCookieURL, kSiteForCookies, kTopFrameOrigin, std::move(options),
- /*partitioned_cookies_runtime_feature_enabled=*/false);
- ASSERT_EQ(1u, cookies.size());
- EXPECT_EQ("__Host-foo", cookies[0].Name());
- }
- TEST_P(PartitionedCookiesRestrictedCookieManagerTest,
- RuntimeEnabledFeature_NoncedPartitionKey) {
- const GURL kCookieURL("https://example.com");
- const GURL kTopFrameURL("https://sub.foo.com");
- const net::SiteForCookies kSiteForCookies =
- net::SiteForCookies::FromUrl(kTopFrameURL);
- const url::Origin kTopFrameOrigin = url::Origin::Create(kTopFrameURL);
- const base::UnguessableToken kNonce = base::UnguessableToken::Create();
- const net::IsolationInfo kNoncedIsolationInfo = net::IsolationInfo::Create(
- net::IsolationInfo::RequestType::kOther, kTopFrameOrigin, kTopFrameOrigin,
- net::SiteForCookies::FromOrigin(kTopFrameOrigin),
- /*party_context=*/std::set<net::SchemefulSite>(), &kNonce);
- service_->OverrideIsolationInfoForTesting(kNoncedIsolationInfo);
- // Should be able to set and read a partitioned cookie with a nonce when the
- // runtime enabled feature is off.
- sync_service_->SetCookieFromString(
- kCookieURL, kSiteForCookies, kTopFrameOrigin,
- "__Host-foo=bar; Secure; SameSite=None; Path=/; Partitioned",
- /*partitioned_cookies_runtime_feature_enabled=*/false);
- auto options = mojom::CookieManagerGetOptions::New();
- options->name = "";
- options->match_type = mojom::CookieMatchType::STARTS_WITH;
- net::CookieList cookies = sync_service_->GetAllForUrl(
- kCookieURL, kSiteForCookies, kTopFrameOrigin, std::move(options),
- /*partitioned_cookies_runtime_feature_enabled=*/false);
- ASSERT_EQ(1u, cookies.size());
- EXPECT_EQ("__Host-foo", cookies[0].Name());
- EXPECT_TRUE(cookies[0].IsPartitioned());
- }
- TEST_P(PartitionedCookiesRestrictedCookieManagerTest,
- RuntimeEnabledFeature_BypassOriginTrial) {
- base::test::ScopedFeatureList feature_list;
- feature_list.InitWithFeatures(
- {net::features::kPartitionedCookies,
- net::features::kPartitionedCookiesBypassOriginTrial},
- {});
- const GURL kCookieURL("https://example.com");
- const GURL kTopFrameURL("https://sub.foo.com");
- const net::SiteForCookies kSiteForCookies =
- net::SiteForCookies::FromUrl(kTopFrameURL);
- const url::Origin kTopFrameOrigin = url::Origin::Create(kTopFrameURL);
- const net::IsolationInfo kIsolationInfo =
- net::IsolationInfo::CreateForInternalRequest(kTopFrameOrigin);
- service_->OverrideIsolationInfoForTesting(kIsolationInfo);
- // Setting a partitioned cookie when the RuntimeEnabledFeature is disabled but
- // the "bypass origin trial" feature is enabled should result in a partitioned
- // cookie.
- sync_service_->SetCookieFromString(
- kCookieURL, kSiteForCookies, kTopFrameOrigin,
- "__Host-foo=bar; Secure; SameSite=None; Path=/; Partitioned",
- /*partitioned_cookies_runtime_feature_enabled=*/false);
- auto options = mojom::CookieManagerGetOptions::New();
- options->name = "";
- options->match_type = mojom::CookieMatchType::STARTS_WITH;
- auto cookies = sync_service_->GetAllForUrl(
- kCookieURL, kSiteForCookies, kTopFrameOrigin, std::move(options),
- /*partitioned_cookies_runtime_feature_enabled=*/true);
- ASSERT_EQ(1u, cookies.size());
- EXPECT_TRUE(cookies[0].IsPartitioned());
- }
- TEST_P(PartitionedCookiesRestrictedCookieManagerTest,
- ConvertPartitionedCookiesToUnpartitioned) {
- const GURL kCookieURL("https://example.com");
- const GURL kTopFrameURL("https://sub.foo.com");
- const net::SiteForCookies kSiteForCookies =
- net::SiteForCookies::FromUrl(kTopFrameURL);
- const url::Origin kTopFrameOrigin = url::Origin::Create(kTopFrameURL);
- const net::IsolationInfo kIsolationInfo =
- net::IsolationInfo::CreateForInternalRequest(kTopFrameOrigin);
- service_->OverrideIsolationInfoForTesting(kIsolationInfo);
- sync_service_->SetCookieFromString(
- kCookieURL, kSiteForCookies, kTopFrameOrigin,
- "__Host-foo=bar; Secure; SameSite=None; Path=/; Partitioned",
- /*partitioned_cookies_runtime_feature_enabled=*/true);
- auto options = mojom::CookieManagerGetOptions::New();
- options->name = "";
- options->match_type = mojom::CookieMatchType::STARTS_WITH;
- auto cookies = sync_service_->GetAllForUrl(
- kCookieURL, kSiteForCookies, kTopFrameOrigin, std::move(options),
- /*partitioned_cookies_runtime_feature_enabled=*/true);
- ASSERT_EQ(1u, cookies.size());
- EXPECT_TRUE(cookies[0].IsPartitioned());
- service_->ConvertPartitionedCookiesToUnpartitioned(kCookieURL);
- // The partitioned cookie should now be unpartitioned.
- options = mojom::CookieManagerGetOptions::New();
- options->name = "";
- options->match_type = mojom::CookieMatchType::STARTS_WITH;
- cookies = sync_service_->GetAllForUrl(
- kCookieURL, kSiteForCookies, kTopFrameOrigin, std::move(options),
- /*partitioned_cookies_runtime_feature_enabled=*/true);
- ASSERT_EQ(1u, cookies.size());
- EXPECT_FALSE(cookies[0].IsPartitioned());
- }
- TEST_P(PartitionedCookiesRestrictedCookieManagerTest,
- ConvertPartitionedCookiesToUnpartitioned_BypassOriginTrial) {
- base::test::ScopedFeatureList feature_list;
- feature_list.InitWithFeatures(
- {net::features::kPartitionedCookies,
- net::features::kPartitionedCookiesBypassOriginTrial},
- {});
- const GURL kCookieURL("https://example.com");
- const GURL kTopFrameURL("https://sub.foo.com");
- const net::SiteForCookies kSiteForCookies =
- net::SiteForCookies::FromUrl(kTopFrameURL);
- const url::Origin kTopFrameOrigin = url::Origin::Create(kTopFrameURL);
- const net::IsolationInfo kIsolationInfo =
- net::IsolationInfo::CreateForInternalRequest(kTopFrameOrigin);
- service_->OverrideIsolationInfoForTesting(kIsolationInfo);
- sync_service_->SetCookieFromString(
- kCookieURL, kSiteForCookies, kTopFrameOrigin,
- "__Host-foo=bar; Secure; SameSite=None; Path=/; Partitioned",
- /*partitioned_cookies_runtime_feature_enabled=*/false);
- auto options = mojom::CookieManagerGetOptions::New();
- options->name = "";
- options->match_type = mojom::CookieMatchType::STARTS_WITH;
- auto cookies = sync_service_->GetAllForUrl(
- kCookieURL, kSiteForCookies, kTopFrameOrigin, std::move(options),
- /*partitioned_cookies_runtime_feature_enabled=*/true);
- ASSERT_EQ(1u, cookies.size());
- EXPECT_TRUE(cookies[0].IsPartitioned());
- service_->ConvertPartitionedCookiesToUnpartitioned(kCookieURL);
- // The partitioned cookie should remain partitioned if the origin trial bypass
- // is enabled.
- options = mojom::CookieManagerGetOptions::New();
- options->name = "";
- options->match_type = mojom::CookieMatchType::STARTS_WITH;
- cookies = sync_service_->GetAllForUrl(
- kCookieURL, kSiteForCookies, kTopFrameOrigin, std::move(options),
- /*partitioned_cookies_runtime_feature_enabled=*/true);
- ASSERT_EQ(1u, cookies.size());
- EXPECT_TRUE(cookies[0].IsPartitioned());
- }
- INSTANTIATE_TEST_SUITE_P(
- PartitionedCookies,
- PartitionedCookiesRestrictedCookieManagerTest,
- ::testing::Values(mojom::RestrictedCookieManagerRole::SCRIPT,
- mojom::RestrictedCookieManagerRole::NETWORK));
- } // namespace network
|