Commit 8d1685b9 authored by Lily Chen's avatar Lily Chen Committed by Commit Bot

Add CookieStore method to fetch all cookies with their access semantics

This change adds a CookieStore method,
GetAllCookiesWithAccessSemanticsAsync, which returns a list of all
cookies in the CookieStore along with a list of the
CookieAccessSemantics for each returned cookie. These lists will be in
the same order, so that each cookie in the returned list of cookies has
the access semantics at the same index in the other list.

This is implemented for CookieMonster only, and other CookieStore
implementations will use the default impl which returns UNKNOWN for
all the cookies. A later CL will additionally expose this method
via the CookieManager interface.

Bug: 978172
Change-Id: I8463806f5cc6ce6c8d200bec57bbecba5fe3aec6
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1846071Reviewed-by: default avatarMohammad Refaat <mrefaat@chromium.org>
Reviewed-by: default avatarMaks Orlovich <morlovich@chromium.org>
Commit-Queue: Lily Chen <chlily@chromium.org>
Cr-Commit-Position: refs/heads/master@{#703824}
parent 41ffef1b
...@@ -69,6 +69,7 @@ struct CookieStoreIOSTestTraits { ...@@ -69,6 +69,7 @@ struct CookieStoreIOSTestTraits {
static const bool has_exact_change_cause = false; static const bool has_exact_change_cause = false;
static const bool has_exact_change_ordering = false; static const bool has_exact_change_ordering = false;
static const int creation_time_granularity_in_ms = 1000; static const int creation_time_granularity_in_ms = 1000;
static const bool supports_cookie_access_semantics = false;
base::test::SingleThreadTaskEnvironment task_environment_; base::test::SingleThreadTaskEnvironment task_environment_;
}; };
......
...@@ -387,7 +387,7 @@ void CookieMonster::SetForceKeepSessionState() { ...@@ -387,7 +387,7 @@ void CookieMonster::SetForceKeepSessionState() {
void CookieMonster::SetAllCookiesAsync(const CookieList& list, void CookieMonster::SetAllCookiesAsync(const CookieList& list,
SetCookiesCallback callback) { SetCookiesCallback callback) {
DoCookieCallback(base::BindOnce( DoCookieCallback(base::BindOnce(
// base::Unretained is safe as DoCookieCallbackForURL stores // base::Unretained is safe as DoCookieCallback stores
// the callback on |*this|, so the callback will not outlive // the callback on |*this|, so the callback will not outlive
// the object. // the object.
&CookieMonster::SetAllCookies, base::Unretained(this), list, &CookieMonster::SetAllCookies, base::Unretained(this), list,
...@@ -404,7 +404,7 @@ void CookieMonster::SetCanonicalCookieAsync( ...@@ -404,7 +404,7 @@ void CookieMonster::SetCanonicalCookieAsync(
std::string domain = cookie->Domain(); std::string domain = cookie->Domain();
DoCookieCallbackForHostOrDomain( DoCookieCallbackForHostOrDomain(
base::BindOnce( base::BindOnce(
// base::Unretained is safe as DoCookieCallbackForURL stores // base::Unretained is safe as DoCookieCallbackForHostOrDomain stores
// the callback on |*this|, so the callback will not outlive // the callback on |*this|, so the callback will not outlive
// the object. // the object.
&CookieMonster::SetCanonicalCookie, base::Unretained(this), &CookieMonster::SetCanonicalCookie, base::Unretained(this),
...@@ -429,17 +429,28 @@ void CookieMonster::GetCookieListWithOptionsAsync( ...@@ -429,17 +429,28 @@ void CookieMonster::GetCookieListWithOptionsAsync(
void CookieMonster::GetAllCookiesAsync(GetAllCookiesCallback callback) { void CookieMonster::GetAllCookiesAsync(GetAllCookiesCallback callback) {
DoCookieCallback(base::BindOnce( DoCookieCallback(base::BindOnce(
// base::Unretained is safe as DoCookieCallbackForURL stores // base::Unretained is safe as DoCookieCallback stores
// the callback on |*this|, so the callback will not outlive // the callback on |*this|, so the callback will not outlive
// the object. // the object.
&CookieMonster::GetAllCookies, base::Unretained(this), &CookieMonster::GetAllCookies, base::Unretained(this),
std::move(callback))); std::move(callback)));
} }
void CookieMonster::GetAllCookiesWithAccessSemanticsAsync(
GetAllCookiesWithAccessSemanticsCallback callback) {
DoCookieCallback(base::BindOnce(
// base::Unretained is safe as DoCookieCallback stores
// the callback on |*this|, so the callback will not outlive
// the object.
&CookieMonster::GetAllCookies, base::Unretained(this),
base::BindOnce(&CookieMonster::AttachAccessSemanticsListForCookieList,
base::Unretained(this), std::move(callback))));
}
void CookieMonster::DeleteCanonicalCookieAsync(const CanonicalCookie& cookie, void CookieMonster::DeleteCanonicalCookieAsync(const CanonicalCookie& cookie,
DeleteCallback callback) { DeleteCallback callback) {
DoCookieCallback(base::BindOnce( DoCookieCallback(base::BindOnce(
// base::Unretained is safe as DoCookieCallbackForURL stores // base::Unretained is safe as DoCookieCallback stores
// the callback on |*this|, so the callback will not outlive // the callback on |*this|, so the callback will not outlive
// the object. // the object.
&CookieMonster::DeleteCanonicalCookie, base::Unretained(this), cookie, &CookieMonster::DeleteCanonicalCookie, base::Unretained(this), cookie,
...@@ -450,7 +461,7 @@ void CookieMonster::DeleteAllCreatedInTimeRangeAsync( ...@@ -450,7 +461,7 @@ void CookieMonster::DeleteAllCreatedInTimeRangeAsync(
const TimeRange& creation_range, const TimeRange& creation_range,
DeleteCallback callback) { DeleteCallback callback) {
DoCookieCallback(base::BindOnce( DoCookieCallback(base::BindOnce(
// base::Unretained is safe as DoCookieCallbackForURL stores // base::Unretained is safe as DoCookieCallback stores
// the callback on |*this|, so the callback will not outlive // the callback on |*this|, so the callback will not outlive
// the object. // the object.
&CookieMonster::DeleteAllCreatedInTimeRange, base::Unretained(this), &CookieMonster::DeleteAllCreatedInTimeRange, base::Unretained(this),
...@@ -460,7 +471,7 @@ void CookieMonster::DeleteAllCreatedInTimeRangeAsync( ...@@ -460,7 +471,7 @@ void CookieMonster::DeleteAllCreatedInTimeRangeAsync(
void CookieMonster::DeleteAllMatchingInfoAsync(CookieDeletionInfo delete_info, void CookieMonster::DeleteAllMatchingInfoAsync(CookieDeletionInfo delete_info,
DeleteCallback callback) { DeleteCallback callback) {
DoCookieCallback(base::BindOnce( DoCookieCallback(base::BindOnce(
// base::Unretained is safe as DoCookieCallbackForURL stores // base::Unretained is safe as DoCookieCallback stores
// the callback on |*this|, so the callback will not outlive // the callback on |*this|, so the callback will not outlive
// the object. // the object.
&CookieMonster::DeleteAllMatchingInfo, base::Unretained(this), &CookieMonster::DeleteAllMatchingInfo, base::Unretained(this),
...@@ -470,7 +481,7 @@ void CookieMonster::DeleteAllMatchingInfoAsync(CookieDeletionInfo delete_info, ...@@ -470,7 +481,7 @@ void CookieMonster::DeleteAllMatchingInfoAsync(CookieDeletionInfo delete_info,
void CookieMonster::DeleteSessionCookiesAsync( void CookieMonster::DeleteSessionCookiesAsync(
CookieStore::DeleteCallback callback) { CookieStore::DeleteCallback callback) {
DoCookieCallback(base::BindOnce( DoCookieCallback(base::BindOnce(
// base::Unretained is safe as DoCookieCallbackForURL stores // base::Unretained is safe as DoCookieCallback stores
// the callback on |*this|, so the callback will not outlive // the callback on |*this|, so the callback will not outlive
// the object. // the object.
&CookieMonster::DeleteSessionCookies, base::Unretained(this), &CookieMonster::DeleteSessionCookies, base::Unretained(this),
...@@ -593,6 +604,17 @@ void CookieMonster::GetAllCookies(GetAllCookiesCallback callback) { ...@@ -593,6 +604,17 @@ void CookieMonster::GetAllCookies(GetAllCookiesCallback callback) {
MaybeRunCookieCallback(std::move(callback), cookie_list); MaybeRunCookieCallback(std::move(callback), cookie_list);
} }
void CookieMonster::AttachAccessSemanticsListForCookieList(
GetAllCookiesWithAccessSemanticsCallback callback,
const CookieList& cookie_list) {
std::vector<CookieAccessSemantics> access_semantics_list;
for (const CanonicalCookie& cookie : cookie_list) {
access_semantics_list.push_back(GetAccessSemanticsForCookie(cookie));
}
MaybeRunCookieCallback(std::move(callback), cookie_list,
access_semantics_list);
}
void CookieMonster::GetCookieListWithOptions(const GURL& url, void CookieMonster::GetCookieListWithOptions(const GURL& url,
const CookieOptions& options, const CookieOptions& options,
GetCookieListCallback callback) { GetCookieListCallback callback) {
......
...@@ -165,6 +165,8 @@ class NET_EXPORT CookieMonster : public CookieStore { ...@@ -165,6 +165,8 @@ class NET_EXPORT CookieMonster : public CookieStore {
const CookieOptions& options, const CookieOptions& options,
GetCookieListCallback callback) override; GetCookieListCallback callback) override;
void GetAllCookiesAsync(GetAllCookiesCallback callback) override; void GetAllCookiesAsync(GetAllCookiesCallback callback) override;
void GetAllCookiesWithAccessSemanticsAsync(
GetAllCookiesWithAccessSemanticsCallback callback) override;
void DeleteCanonicalCookieAsync(const CanonicalCookie& cookie, void DeleteCanonicalCookieAsync(const CanonicalCookie& cookie,
DeleteCallback callback) override; DeleteCallback callback) override;
void DeleteAllCreatedInTimeRangeAsync( void DeleteAllCreatedInTimeRangeAsync(
...@@ -358,6 +360,10 @@ class NET_EXPORT CookieMonster : public CookieStore { ...@@ -358,6 +360,10 @@ class NET_EXPORT CookieMonster : public CookieStore {
void GetAllCookies(GetAllCookiesCallback callback); void GetAllCookies(GetAllCookiesCallback callback);
void AttachAccessSemanticsListForCookieList(
GetAllCookiesWithAccessSemanticsCallback callback,
const CookieList& cookie_list);
void GetCookieListWithOptions(const GURL& url, void GetCookieListWithOptions(const GURL& url,
const CookieOptions& options, const CookieOptions& options,
GetCookieListCallback callback); GetCookieListCallback callback);
......
...@@ -92,6 +92,7 @@ struct CookieMonsterTestTraits { ...@@ -92,6 +92,7 @@ struct CookieMonsterTestTraits {
static const bool has_exact_change_cause = true; static const bool has_exact_change_cause = true;
static const bool has_exact_change_ordering = true; static const bool has_exact_change_ordering = true;
static const int creation_time_granularity_in_ms = 0; static const int creation_time_granularity_in_ms = 0;
static const bool supports_cookie_access_semantics = true;
}; };
INSTANTIATE_TYPED_TEST_SUITE_P(CookieMonster, INSTANTIATE_TYPED_TEST_SUITE_P(CookieMonster,
......
...@@ -11,6 +11,24 @@ namespace net { ...@@ -11,6 +11,24 @@ namespace net {
CookieStore::~CookieStore() = default; CookieStore::~CookieStore() = default;
// Default implementation which returns a default vector of UNKNOWN
// CookieAccessSemantics.
void CookieStore::GetAllCookiesWithAccessSemanticsAsync(
GetAllCookiesWithAccessSemanticsCallback callback) {
GetAllCookiesCallback adapted_callback = base::BindOnce(
[](CookieStore::GetAllCookiesWithAccessSemanticsCallback
original_callback,
const CookieList& cookies) {
std::vector<CookieAccessSemantics> default_access_semantics_list;
default_access_semantics_list.assign(cookies.size(),
CookieAccessSemantics::UNKNOWN);
std::move(original_callback)
.Run(cookies, default_access_semantics_list);
},
std::move(callback));
GetAllCookiesAsync(std::move(adapted_callback));
}
void CookieStore::DeleteAllAsync(DeleteCallback callback) { void CookieStore::DeleteAllAsync(DeleteCallback callback) {
DeleteAllCreatedInTimeRangeAsync(CookieDeletionInfo::TimeRange(), DeleteAllCreatedInTimeRangeAsync(CookieDeletionInfo::TimeRange(),
std::move(callback)); std::move(callback));
......
...@@ -49,6 +49,10 @@ class NET_EXPORT CookieStore { ...@@ -49,6 +49,10 @@ class NET_EXPORT CookieStore {
const CookieStatusList& excluded_list)>; const CookieStatusList& excluded_list)>;
using GetAllCookiesCallback = using GetAllCookiesCallback =
base::OnceCallback<void(const CookieList& cookies)>; base::OnceCallback<void(const CookieList& cookies)>;
// |access_semantics_list| is guaranteed to the same length as |cookies|.
using GetAllCookiesWithAccessSemanticsCallback = base::OnceCallback<void(
const CookieList& cookies,
const std::vector<CookieAccessSemantics>& access_semantics_list)>;
using SetCookiesCallback = using SetCookiesCallback =
base::OnceCallback<void(CanonicalCookie::CookieInclusionStatus status)>; base::OnceCallback<void(CanonicalCookie::CookieInclusionStatus status)>;
using DeleteCallback = base::OnceCallback<void(uint32_t num_deleted)>; using DeleteCallback = base::OnceCallback<void(uint32_t num_deleted)>;
...@@ -83,6 +87,18 @@ class NET_EXPORT CookieStore { ...@@ -83,6 +87,18 @@ class NET_EXPORT CookieStore {
// longest path, then by earliest creation date. // longest path, then by earliest creation date.
virtual void GetAllCookiesAsync(GetAllCookiesCallback callback) = 0; virtual void GetAllCookiesAsync(GetAllCookiesCallback callback) = 0;
// Returns all the cookies, for use in management UI, etc. This does not mark
// the cookies as having been accessed. The returned cookies are ordered by
// longest path, then by earliest creation date.
// Additionally returns a vector of CookieAccessSemantics values for the
// returned cookies, which will be the same length as the vector of returned
// cookies. This vector will either contain all CookieAccessSemantics::UNKNOWN
// (if the default implementation is used), or each entry in the
// vector of CookieAccessSemantics will indicate the access semantics
// applicable to the cookie at the same index in the returned CookieList.
virtual void GetAllCookiesWithAccessSemanticsAsync(
GetAllCookiesWithAccessSemanticsCallback callback);
// Deletes one specific cookie. |cookie| must have been returned by a previous // Deletes one specific cookie. |cookie| must have been returned by a previous
// query on this CookieStore. Invokes |callback| with 1 if a cookie was // query on this CookieStore. Invokes |callback| with 1 if a cookie was
// deleted, 0 otherwise. // deleted, 0 otherwise.
......
...@@ -80,4 +80,21 @@ void GetAllCookiesCallback::Run(const CookieList& cookies) { ...@@ -80,4 +80,21 @@ void GetAllCookiesCallback::Run(const CookieList& cookies) {
CallbackEpilogue(); CallbackEpilogue();
} }
GetAllCookiesWithAccessSemanticsCallback::
GetAllCookiesWithAccessSemanticsCallback() = default;
GetAllCookiesWithAccessSemanticsCallback::
GetAllCookiesWithAccessSemanticsCallback(base::Thread* run_in_thread)
: CookieCallback(run_in_thread) {}
GetAllCookiesWithAccessSemanticsCallback::
~GetAllCookiesWithAccessSemanticsCallback() = default;
void GetAllCookiesWithAccessSemanticsCallback::Run(
const CookieList& cookies,
const std::vector<CookieAccessSemantics>& access_semantics_list) {
cookies_ = cookies;
access_semantics_list_ = access_semantics_list;
CallbackEpilogue();
}
} // namespace net } // namespace net
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include "base/run_loop.h" #include "base/run_loop.h"
#include "base/single_thread_task_runner.h" #include "base/single_thread_task_runner.h"
#include "net/cookies/canonical_cookie.h" #include "net/cookies/canonical_cookie.h"
#include "net/cookies/cookie_constants.h"
#include "net/cookies/cookie_store.h" #include "net/cookies/cookie_store.h"
namespace base { namespace base {
...@@ -151,6 +152,36 @@ class GetAllCookiesCallback : public CookieCallback { ...@@ -151,6 +152,36 @@ class GetAllCookiesCallback : public CookieCallback {
CookieList cookies_; CookieList cookies_;
}; };
class GetAllCookiesWithAccessSemanticsCallback : public CookieCallback {
public:
GetAllCookiesWithAccessSemanticsCallback();
explicit GetAllCookiesWithAccessSemanticsCallback(
base::Thread* run_in_thread);
~GetAllCookiesWithAccessSemanticsCallback();
void Run(const CookieList& cookies,
const std::vector<CookieAccessSemantics>& access_semantics_list);
// Makes a callback that will invoke Run. Assumes that |this| will be kept
// alive till the time the callback is used.
base::OnceCallback<void(const CookieList&,
const std::vector<CookieAccessSemantics>&)>
MakeCallback() {
return base::BindOnce(&GetAllCookiesWithAccessSemanticsCallback::Run,
base::Unretained(this));
}
const CookieList& cookies() { return cookies_; }
const std::vector<CookieAccessSemantics>& access_semantics_list() {
return access_semantics_list_;
}
private:
CookieList cookies_;
std::vector<CookieAccessSemantics> access_semantics_list_;
};
} // namespace net } // namespace net
#endif // NET_COOKIES_COOKIE_STORE_TEST_CALLBACKS_H_ #endif // NET_COOKIES_COOKIE_STORE_TEST_CALLBACKS_H_
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#include "net/cookies/cookie_store.h" #include "net/cookies/cookie_store.h"
#include "net/cookies/cookie_store_test_callbacks.h" #include "net/cookies/cookie_store_test_callbacks.h"
#include "net/cookies/cookie_store_test_helpers.h" #include "net/cookies/cookie_store_test_helpers.h"
#include "net/cookies/test_cookie_access_delegate.h"
#include "testing/gtest/include/gtest/gtest.h" #include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h" #include "url/gurl.h"
...@@ -101,6 +102,11 @@ const char kValidCookieLine[] = "A=B; path=/"; ...@@ -101,6 +102,11 @@ const char kValidCookieLine[] = "A=B; path=/";
// // Time to wait between two cookie insertions to ensure that cookies have // // Time to wait between two cookie insertions to ensure that cookies have
// // different creation times. // // different creation times.
// static const int creation_time_granularity_in_ms; // static const int creation_time_granularity_in_ms;
//
// // The cookie store supports setting a CookieAccessDelegate and using it to
// // get the access semantics for each cookie via
// // CookieStore::GetAllCookiesWithAccessSemanticsAsync().
// static const bool supports_cookie_access_semantics;
// }; // };
template <class CookieStoreTestTraits> template <class CookieStoreTestTraits>
...@@ -1661,6 +1667,58 @@ TYPED_TEST_P(CookieStoreTest, GetAllCookiesAsync) { ...@@ -1661,6 +1667,58 @@ TYPED_TEST_P(CookieStoreTest, GetAllCookiesAsync) {
ASSERT_TRUE(++it == cookies.end()); ASSERT_TRUE(++it == cookies.end());
} }
TYPED_TEST_P(CookieStoreTest, GetAllCookiesWithAccessSemanticsAsync) {
CookieStore* cs = this->GetCookieStore();
auto access_delegate = std::make_unique<TestCookieAccessDelegate>();
TestCookieAccessDelegate* test_delegate = access_delegate.get();
// if !supports_cookie_access_semantics, setting a delegate here will do
// nothing.
cs->SetCookieAccessDelegate(std::move(access_delegate));
test_delegate->SetExpectationForCookieDomain("domain1.test",
CookieAccessSemantics::LEGACY);
test_delegate->SetExpectationForCookieDomain(
"domain2.test", CookieAccessSemantics::NONLEGACY);
test_delegate->SetExpectationForCookieDomain("domain3.test",
CookieAccessSemantics::UNKNOWN);
this->CreateAndSetCookie(cs, GURL("http://domain1.test"), "cookie=1",
CookieOptions::MakeAllInclusive());
this->CreateAndSetCookie(cs, GURL("http://domain2.test"), "cookie=1",
CookieOptions::MakeAllInclusive());
this->CreateAndSetCookie(cs, GURL("http://domain3.test"), "cookie=1",
CookieOptions::MakeAllInclusive());
this->CreateAndSetCookie(cs, GURL("http://domain4.test"), "cookie=1",
CookieOptions::MakeAllInclusive());
GetAllCookiesWithAccessSemanticsCallback callback;
cs->GetAllCookiesWithAccessSemanticsAsync(callback.MakeCallback());
callback.WaitUntilDone();
EXPECT_TRUE(callback.was_run());
EXPECT_EQ(callback.cookies().size(), callback.access_semantics_list().size());
EXPECT_EQ(4u, callback.access_semantics_list().size());
EXPECT_EQ("domain1.test", callback.cookies()[0].Domain());
EXPECT_EQ("domain2.test", callback.cookies()[1].Domain());
EXPECT_EQ("domain3.test", callback.cookies()[2].Domain());
EXPECT_EQ("domain4.test", callback.cookies()[3].Domain());
if (!TypeParam::supports_cookie_access_semantics) {
for (CookieAccessSemantics semantics : callback.access_semantics_list()) {
EXPECT_EQ(CookieAccessSemantics::UNKNOWN, semantics);
}
} else {
EXPECT_EQ(CookieAccessSemantics::LEGACY,
callback.access_semantics_list()[0]);
EXPECT_EQ(CookieAccessSemantics::NONLEGACY,
callback.access_semantics_list()[1]);
EXPECT_EQ(CookieAccessSemantics::UNKNOWN,
callback.access_semantics_list()[2]);
EXPECT_EQ(CookieAccessSemantics::UNKNOWN,
callback.access_semantics_list()[3]);
}
}
TYPED_TEST_P(CookieStoreTest, DeleteCanonicalCookieAsync) { TYPED_TEST_P(CookieStoreTest, DeleteCanonicalCookieAsync) {
CookieStore* cs = this->GetCookieStore(); CookieStore* cs = this->GetCookieStore();
...@@ -1756,6 +1814,7 @@ REGISTER_TYPED_TEST_SUITE_P(CookieStoreTest, ...@@ -1756,6 +1814,7 @@ REGISTER_TYPED_TEST_SUITE_P(CookieStoreTest,
EmptyName, EmptyName,
CookieOrdering, CookieOrdering,
GetAllCookiesAsync, GetAllCookiesAsync,
GetAllCookiesWithAccessSemanticsAsync,
DeleteCanonicalCookieAsync, DeleteCanonicalCookieAsync,
DeleteSessionCookie); DeleteSessionCookie);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment