123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263 |
- // Copyright 2018 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/session_cleanup_cookie_store.h"
- #include "base/bind.h"
- #include "base/files/file_util.h"
- #include "base/files/scoped_temp_dir.h"
- #include "base/memory/ref_counted.h"
- #include "base/run_loop.h"
- #include "base/task/sequenced_task_runner.h"
- #include "base/task/thread_pool.h"
- #include "base/task/thread_pool/thread_pool_instance.h"
- #include "base/test/task_environment.h"
- #include "base/time/time.h"
- #include "net/log/net_log_capture_mode.h"
- #include "net/log/test_net_log.h"
- #include "net/log/test_net_log_util.h"
- #include "testing/gtest/include/gtest/gtest.h"
- #include "url/gurl.h"
- namespace network {
- namespace {
- using CanonicalCookieVector =
- std::vector<std::unique_ptr<net::CanonicalCookie>>;
- const base::FilePath::CharType kTestCookiesFilename[] =
- FILE_PATH_LITERAL("Cookies");
- class SessionCleanupCookieStoreTest : public testing::Test {
- public:
- SessionCleanupCookieStoreTest() {}
- void OnLoaded(base::RunLoop* run_loop,
- CanonicalCookieVector* cookies_out,
- CanonicalCookieVector cookies) {
- cookies_out->swap(cookies);
- run_loop->Quit();
- }
- CanonicalCookieVector Load() {
- base::RunLoop run_loop;
- CanonicalCookieVector cookies;
- store_->Load(base::BindOnce(&SessionCleanupCookieStoreTest::OnLoaded,
- base::Unretained(this), &run_loop, &cookies),
- net::NetLogWithSource::Make(net::NetLogSourceType::NONE));
- run_loop.Run();
- return cookies;
- }
- protected:
- CanonicalCookieVector CreateAndLoad() {
- auto sqlite_store = base::MakeRefCounted<net::SQLitePersistentCookieStore>(
- temp_dir_.GetPath().Append(kTestCookiesFilename),
- base::ThreadPool::CreateSequencedTaskRunner({base::MayBlock()}),
- background_task_runner_, true, nullptr);
- store_ =
- base::MakeRefCounted<SessionCleanupCookieStore>(sqlite_store.get());
- return Load();
- }
- // Adds a persistent cookie to store_.
- void AddCookie(const std::string& name,
- const std::string& value,
- const std::string& domain,
- const std::string& path,
- base::Time creation) {
- store_->AddCookie(*net::CanonicalCookie::CreateUnsafeCookieForTesting(
- name, value, domain, path, creation, creation, base::Time(),
- base::Time(), false, false, net::CookieSameSite::NO_RESTRICTION,
- net::COOKIE_PRIORITY_DEFAULT, false));
- }
- void DestroyStore() {
- store_ = nullptr;
- // Ensure that |store_|'s destructor has run by flushing ThreadPool.
- base::ThreadPoolInstance::Get()->FlushForTesting();
- }
- void SetUp() override { ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); }
- void TearDown() override { DestroyStore(); }
- base::test::TaskEnvironment task_environment_;
- const scoped_refptr<base::SequencedTaskRunner> background_task_runner_ =
- base::ThreadPool::CreateSequencedTaskRunner({base::MayBlock()});
- base::ScopedTempDir temp_dir_;
- scoped_refptr<SessionCleanupCookieStore> store_;
- net::RecordingNetLogObserver net_log_observer_;
- };
- TEST_F(SessionCleanupCookieStoreTest, TestPersistence) {
- CanonicalCookieVector cookies = CreateAndLoad();
- ASSERT_EQ(0u, cookies.size());
- base::Time t = base::Time::Now();
- AddCookie("A", "B", "foo.com", "/", t);
- t += base::Days(10);
- AddCookie("A", "B", "persistent.com", "/", t);
- // Replace the store, which forces the current store to flush data to
- // disk. Then, after reloading the store, confirm that the data was flushed by
- // making sure it loads successfully. This ensures that all pending commits
- // are made to the store before allowing it to be closed.
- DestroyStore();
- // Reload and test for persistence.
- cookies = CreateAndLoad();
- EXPECT_EQ(2u, cookies.size());
- bool found_foo_cookie = false;
- bool found_persistent_cookie = false;
- for (const auto& cookie : cookies) {
- if (cookie->Domain() == "foo.com")
- found_foo_cookie = true;
- else if (cookie->Domain() == "persistent.com")
- found_persistent_cookie = true;
- }
- EXPECT_TRUE(found_foo_cookie);
- EXPECT_TRUE(found_persistent_cookie);
- // Now delete the cookies and check persistence again.
- store_->DeleteCookie(*cookies[0]);
- store_->DeleteCookie(*cookies[1]);
- DestroyStore();
- // Reload and check if the cookies have been removed.
- cookies = CreateAndLoad();
- EXPECT_EQ(0u, cookies.size());
- cookies.clear();
- }
- TEST_F(SessionCleanupCookieStoreTest, TestNetLogIncludeCookies) {
- CanonicalCookieVector cookies = CreateAndLoad();
- base::Time t = base::Time::Now();
- AddCookie("A", "B", "nonpersistent.com", "/", t);
- // Cookies from "nonpersistent.com" should be deleted.
- store_->DeleteSessionCookies(
- base::BindRepeating([](const std::string& domain, bool is_https) {
- return domain == "nonpersistent.com";
- }));
- DestroyStore();
- auto entries = net_log_observer_.GetEntries();
- size_t pos = net::ExpectLogContainsSomewhere(
- entries, 0, net::NetLogEventType::COOKIE_PERSISTENT_STORE_ORIGIN_FILTERED,
- net::NetLogEventPhase::NONE);
- EXPECT_EQ("nonpersistent.com",
- net::GetStringValueFromParams(entries[pos], "origin"));
- EXPECT_FALSE(net::GetBooleanValueFromParams(entries[pos], "is_https"));
- pos = net::ExpectLogContainsSomewhere(
- entries, pos, net::NetLogEventType::COOKIE_PERSISTENT_STORE_CLOSED,
- net::NetLogEventPhase::NONE);
- EXPECT_EQ("SessionCleanupCookieStore",
- net::GetStringValueFromParams(entries[pos], "type"));
- }
- TEST_F(SessionCleanupCookieStoreTest, TestNetLogDoNotIncludeCookies) {
- CanonicalCookieVector cookies = CreateAndLoad();
- base::Time t = base::Time::Now();
- AddCookie("A", "B", "nonpersistent.com", "/", t);
- net_log_observer_.SetObserverCaptureMode(net::NetLogCaptureMode::kDefault);
- // Cookies from "nonpersistent.com" should be deleted.
- store_->DeleteSessionCookies(
- base::BindRepeating([](const std::string& domain, bool is_https) {
- return domain == "nonpersistent.com";
- }));
- DestroyStore();
- auto entries = net_log_observer_.GetEntries();
- size_t pos = net::ExpectLogContainsSomewhere(
- entries, 0, net::NetLogEventType::COOKIE_PERSISTENT_STORE_ORIGIN_FILTERED,
- net::NetLogEventPhase::NONE);
- EXPECT_FALSE(net::GetOptionalStringValueFromParams(entries[pos], "origin"));
- EXPECT_FALSE(
- net::GetOptionalBooleanValueFromParams(entries[pos], "is_https"));
- pos = net::ExpectLogContainsSomewhere(
- entries, pos, net::NetLogEventType::COOKIE_PERSISTENT_STORE_CLOSED,
- net::NetLogEventPhase::NONE);
- EXPECT_EQ("SessionCleanupCookieStore",
- net::GetStringValueFromParams(entries[pos], "type"));
- }
- TEST_F(SessionCleanupCookieStoreTest, TestDeleteSessionCookies) {
- CanonicalCookieVector cookies = CreateAndLoad();
- ASSERT_EQ(0u, cookies.size());
- base::Time t = base::Time::Now();
- AddCookie("A", "B", "foo.com", "/", t);
- t += base::Days(10);
- AddCookie("A", "B", "persistent.com", "/", t);
- t += base::Days(10);
- AddCookie("A", "B", "nonpersistent.com", "/", t);
- // Replace the store, which forces the current store to flush data to
- // disk. Then, after reloading the store, confirm that the data was flushed by
- // making sure it loads successfully. This ensures that all pending commits
- // are made to the store before allowing it to be closed.
- DestroyStore();
- // Reload and test for persistence.
- cookies = CreateAndLoad();
- EXPECT_EQ(3u, cookies.size());
- t += base::Days(10);
- AddCookie("A", "B", "nonpersistent.com", "/second", t);
- // Cookies from "nonpersistent.com" should be deleted.
- store_->DeleteSessionCookies(
- base::BindRepeating([](const std::string& domain, bool is_https) {
- return domain == "nonpersistent.com";
- }));
- task_environment_.RunUntilIdle();
- DestroyStore();
- cookies = CreateAndLoad();
- EXPECT_EQ(2u, cookies.size());
- for (const auto& cookie : cookies) {
- EXPECT_NE("nonpersistent.com", cookie->Domain());
- }
- cookies.clear();
- }
- TEST_F(SessionCleanupCookieStoreTest, ForceKeepSessionState) {
- CanonicalCookieVector cookies = CreateAndLoad();
- ASSERT_EQ(0u, cookies.size());
- base::Time t = base::Time::Now();
- AddCookie("A", "B", "foo.com", "/", t);
- // Recreate |store_|, and call DeleteSessionCookies with a function that that
- // makes "nonpersistent.com" session only, but then instruct the store to
- // forcibly keep all cookies.
- // Reload and test for persistence
- DestroyStore();
- cookies = CreateAndLoad();
- EXPECT_EQ(1u, cookies.size());
- t += base::Days(10);
- AddCookie("A", "B", "persistent.com", "/", t);
- t += base::Days(10);
- AddCookie("A", "B", "nonpersistent.com", "/", t);
- store_->SetForceKeepSessionState();
- // Cookies from "nonpersistent.com" should NOT be deleted.
- store_->DeleteSessionCookies(
- base::BindRepeating([](const std::string& domain, bool is_https) {
- return domain == "nonpersistent.com";
- }));
- task_environment_.RunUntilIdle();
- DestroyStore();
- cookies = CreateAndLoad();
- EXPECT_EQ(3u, cookies.size());
- cookies.clear();
- }
- } // namespace
- } // namespace network
|