session_cleanup_cookie_store_unittest.cc 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263
  1. // Copyright 2018 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "services/network/session_cleanup_cookie_store.h"
  5. #include "base/bind.h"
  6. #include "base/files/file_util.h"
  7. #include "base/files/scoped_temp_dir.h"
  8. #include "base/memory/ref_counted.h"
  9. #include "base/run_loop.h"
  10. #include "base/task/sequenced_task_runner.h"
  11. #include "base/task/thread_pool.h"
  12. #include "base/task/thread_pool/thread_pool_instance.h"
  13. #include "base/test/task_environment.h"
  14. #include "base/time/time.h"
  15. #include "net/log/net_log_capture_mode.h"
  16. #include "net/log/test_net_log.h"
  17. #include "net/log/test_net_log_util.h"
  18. #include "testing/gtest/include/gtest/gtest.h"
  19. #include "url/gurl.h"
  20. namespace network {
  21. namespace {
  22. using CanonicalCookieVector =
  23. std::vector<std::unique_ptr<net::CanonicalCookie>>;
  24. const base::FilePath::CharType kTestCookiesFilename[] =
  25. FILE_PATH_LITERAL("Cookies");
  26. class SessionCleanupCookieStoreTest : public testing::Test {
  27. public:
  28. SessionCleanupCookieStoreTest() {}
  29. void OnLoaded(base::RunLoop* run_loop,
  30. CanonicalCookieVector* cookies_out,
  31. CanonicalCookieVector cookies) {
  32. cookies_out->swap(cookies);
  33. run_loop->Quit();
  34. }
  35. CanonicalCookieVector Load() {
  36. base::RunLoop run_loop;
  37. CanonicalCookieVector cookies;
  38. store_->Load(base::BindOnce(&SessionCleanupCookieStoreTest::OnLoaded,
  39. base::Unretained(this), &run_loop, &cookies),
  40. net::NetLogWithSource::Make(net::NetLogSourceType::NONE));
  41. run_loop.Run();
  42. return cookies;
  43. }
  44. protected:
  45. CanonicalCookieVector CreateAndLoad() {
  46. auto sqlite_store = base::MakeRefCounted<net::SQLitePersistentCookieStore>(
  47. temp_dir_.GetPath().Append(kTestCookiesFilename),
  48. base::ThreadPool::CreateSequencedTaskRunner({base::MayBlock()}),
  49. background_task_runner_, true, nullptr);
  50. store_ =
  51. base::MakeRefCounted<SessionCleanupCookieStore>(sqlite_store.get());
  52. return Load();
  53. }
  54. // Adds a persistent cookie to store_.
  55. void AddCookie(const std::string& name,
  56. const std::string& value,
  57. const std::string& domain,
  58. const std::string& path,
  59. base::Time creation) {
  60. store_->AddCookie(*net::CanonicalCookie::CreateUnsafeCookieForTesting(
  61. name, value, domain, path, creation, creation, base::Time(),
  62. base::Time(), false, false, net::CookieSameSite::NO_RESTRICTION,
  63. net::COOKIE_PRIORITY_DEFAULT, false));
  64. }
  65. void DestroyStore() {
  66. store_ = nullptr;
  67. // Ensure that |store_|'s destructor has run by flushing ThreadPool.
  68. base::ThreadPoolInstance::Get()->FlushForTesting();
  69. }
  70. void SetUp() override { ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); }
  71. void TearDown() override { DestroyStore(); }
  72. base::test::TaskEnvironment task_environment_;
  73. const scoped_refptr<base::SequencedTaskRunner> background_task_runner_ =
  74. base::ThreadPool::CreateSequencedTaskRunner({base::MayBlock()});
  75. base::ScopedTempDir temp_dir_;
  76. scoped_refptr<SessionCleanupCookieStore> store_;
  77. net::RecordingNetLogObserver net_log_observer_;
  78. };
  79. TEST_F(SessionCleanupCookieStoreTest, TestPersistence) {
  80. CanonicalCookieVector cookies = CreateAndLoad();
  81. ASSERT_EQ(0u, cookies.size());
  82. base::Time t = base::Time::Now();
  83. AddCookie("A", "B", "foo.com", "/", t);
  84. t += base::Days(10);
  85. AddCookie("A", "B", "persistent.com", "/", t);
  86. // Replace the store, which forces the current store to flush data to
  87. // disk. Then, after reloading the store, confirm that the data was flushed by
  88. // making sure it loads successfully. This ensures that all pending commits
  89. // are made to the store before allowing it to be closed.
  90. DestroyStore();
  91. // Reload and test for persistence.
  92. cookies = CreateAndLoad();
  93. EXPECT_EQ(2u, cookies.size());
  94. bool found_foo_cookie = false;
  95. bool found_persistent_cookie = false;
  96. for (const auto& cookie : cookies) {
  97. if (cookie->Domain() == "foo.com")
  98. found_foo_cookie = true;
  99. else if (cookie->Domain() == "persistent.com")
  100. found_persistent_cookie = true;
  101. }
  102. EXPECT_TRUE(found_foo_cookie);
  103. EXPECT_TRUE(found_persistent_cookie);
  104. // Now delete the cookies and check persistence again.
  105. store_->DeleteCookie(*cookies[0]);
  106. store_->DeleteCookie(*cookies[1]);
  107. DestroyStore();
  108. // Reload and check if the cookies have been removed.
  109. cookies = CreateAndLoad();
  110. EXPECT_EQ(0u, cookies.size());
  111. cookies.clear();
  112. }
  113. TEST_F(SessionCleanupCookieStoreTest, TestNetLogIncludeCookies) {
  114. CanonicalCookieVector cookies = CreateAndLoad();
  115. base::Time t = base::Time::Now();
  116. AddCookie("A", "B", "nonpersistent.com", "/", t);
  117. // Cookies from "nonpersistent.com" should be deleted.
  118. store_->DeleteSessionCookies(
  119. base::BindRepeating([](const std::string& domain, bool is_https) {
  120. return domain == "nonpersistent.com";
  121. }));
  122. DestroyStore();
  123. auto entries = net_log_observer_.GetEntries();
  124. size_t pos = net::ExpectLogContainsSomewhere(
  125. entries, 0, net::NetLogEventType::COOKIE_PERSISTENT_STORE_ORIGIN_FILTERED,
  126. net::NetLogEventPhase::NONE);
  127. EXPECT_EQ("nonpersistent.com",
  128. net::GetStringValueFromParams(entries[pos], "origin"));
  129. EXPECT_FALSE(net::GetBooleanValueFromParams(entries[pos], "is_https"));
  130. pos = net::ExpectLogContainsSomewhere(
  131. entries, pos, net::NetLogEventType::COOKIE_PERSISTENT_STORE_CLOSED,
  132. net::NetLogEventPhase::NONE);
  133. EXPECT_EQ("SessionCleanupCookieStore",
  134. net::GetStringValueFromParams(entries[pos], "type"));
  135. }
  136. TEST_F(SessionCleanupCookieStoreTest, TestNetLogDoNotIncludeCookies) {
  137. CanonicalCookieVector cookies = CreateAndLoad();
  138. base::Time t = base::Time::Now();
  139. AddCookie("A", "B", "nonpersistent.com", "/", t);
  140. net_log_observer_.SetObserverCaptureMode(net::NetLogCaptureMode::kDefault);
  141. // Cookies from "nonpersistent.com" should be deleted.
  142. store_->DeleteSessionCookies(
  143. base::BindRepeating([](const std::string& domain, bool is_https) {
  144. return domain == "nonpersistent.com";
  145. }));
  146. DestroyStore();
  147. auto entries = net_log_observer_.GetEntries();
  148. size_t pos = net::ExpectLogContainsSomewhere(
  149. entries, 0, net::NetLogEventType::COOKIE_PERSISTENT_STORE_ORIGIN_FILTERED,
  150. net::NetLogEventPhase::NONE);
  151. EXPECT_FALSE(net::GetOptionalStringValueFromParams(entries[pos], "origin"));
  152. EXPECT_FALSE(
  153. net::GetOptionalBooleanValueFromParams(entries[pos], "is_https"));
  154. pos = net::ExpectLogContainsSomewhere(
  155. entries, pos, net::NetLogEventType::COOKIE_PERSISTENT_STORE_CLOSED,
  156. net::NetLogEventPhase::NONE);
  157. EXPECT_EQ("SessionCleanupCookieStore",
  158. net::GetStringValueFromParams(entries[pos], "type"));
  159. }
  160. TEST_F(SessionCleanupCookieStoreTest, TestDeleteSessionCookies) {
  161. CanonicalCookieVector cookies = CreateAndLoad();
  162. ASSERT_EQ(0u, cookies.size());
  163. base::Time t = base::Time::Now();
  164. AddCookie("A", "B", "foo.com", "/", t);
  165. t += base::Days(10);
  166. AddCookie("A", "B", "persistent.com", "/", t);
  167. t += base::Days(10);
  168. AddCookie("A", "B", "nonpersistent.com", "/", t);
  169. // Replace the store, which forces the current store to flush data to
  170. // disk. Then, after reloading the store, confirm that the data was flushed by
  171. // making sure it loads successfully. This ensures that all pending commits
  172. // are made to the store before allowing it to be closed.
  173. DestroyStore();
  174. // Reload and test for persistence.
  175. cookies = CreateAndLoad();
  176. EXPECT_EQ(3u, cookies.size());
  177. t += base::Days(10);
  178. AddCookie("A", "B", "nonpersistent.com", "/second", t);
  179. // Cookies from "nonpersistent.com" should be deleted.
  180. store_->DeleteSessionCookies(
  181. base::BindRepeating([](const std::string& domain, bool is_https) {
  182. return domain == "nonpersistent.com";
  183. }));
  184. task_environment_.RunUntilIdle();
  185. DestroyStore();
  186. cookies = CreateAndLoad();
  187. EXPECT_EQ(2u, cookies.size());
  188. for (const auto& cookie : cookies) {
  189. EXPECT_NE("nonpersistent.com", cookie->Domain());
  190. }
  191. cookies.clear();
  192. }
  193. TEST_F(SessionCleanupCookieStoreTest, ForceKeepSessionState) {
  194. CanonicalCookieVector cookies = CreateAndLoad();
  195. ASSERT_EQ(0u, cookies.size());
  196. base::Time t = base::Time::Now();
  197. AddCookie("A", "B", "foo.com", "/", t);
  198. // Recreate |store_|, and call DeleteSessionCookies with a function that that
  199. // makes "nonpersistent.com" session only, but then instruct the store to
  200. // forcibly keep all cookies.
  201. // Reload and test for persistence
  202. DestroyStore();
  203. cookies = CreateAndLoad();
  204. EXPECT_EQ(1u, cookies.size());
  205. t += base::Days(10);
  206. AddCookie("A", "B", "persistent.com", "/", t);
  207. t += base::Days(10);
  208. AddCookie("A", "B", "nonpersistent.com", "/", t);
  209. store_->SetForceKeepSessionState();
  210. // Cookies from "nonpersistent.com" should NOT be deleted.
  211. store_->DeleteSessionCookies(
  212. base::BindRepeating([](const std::string& domain, bool is_https) {
  213. return domain == "nonpersistent.com";
  214. }));
  215. task_environment_.RunUntilIdle();
  216. DestroyStore();
  217. cookies = CreateAndLoad();
  218. EXPECT_EQ(3u, cookies.size());
  219. cookies.clear();
  220. }
  221. } // namespace
  222. } // namespace network