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 {
static const bool has_exact_change_cause = false;
static const bool has_exact_change_ordering = false;
static const int creation_time_granularity_in_ms = 1000;
static const bool supports_cookie_access_semantics = false;
base::test::SingleThreadTaskEnvironment task_environment_;
};
......
......@@ -387,7 +387,7 @@ void CookieMonster::SetForceKeepSessionState() {
void CookieMonster::SetAllCookiesAsync(const CookieList& list,
SetCookiesCallback callback) {
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 object.
&CookieMonster::SetAllCookies, base::Unretained(this), list,
......@@ -404,7 +404,7 @@ void CookieMonster::SetCanonicalCookieAsync(
std::string domain = cookie->Domain();
DoCookieCallbackForHostOrDomain(
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 object.
&CookieMonster::SetCanonicalCookie, base::Unretained(this),
......@@ -429,17 +429,28 @@ void CookieMonster::GetCookieListWithOptionsAsync(
void CookieMonster::GetAllCookiesAsync(GetAllCookiesCallback callback) {
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 object.
&CookieMonster::GetAllCookies, base::Unretained(this),
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,
DeleteCallback callback) {
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 object.
&CookieMonster::DeleteCanonicalCookie, base::Unretained(this), cookie,
......@@ -450,7 +461,7 @@ void CookieMonster::DeleteAllCreatedInTimeRangeAsync(
const TimeRange& creation_range,
DeleteCallback callback) {
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 object.
&CookieMonster::DeleteAllCreatedInTimeRange, base::Unretained(this),
......@@ -460,7 +471,7 @@ void CookieMonster::DeleteAllCreatedInTimeRangeAsync(
void CookieMonster::DeleteAllMatchingInfoAsync(CookieDeletionInfo delete_info,
DeleteCallback callback) {
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 object.
&CookieMonster::DeleteAllMatchingInfo, base::Unretained(this),
......@@ -470,7 +481,7 @@ void CookieMonster::DeleteAllMatchingInfoAsync(CookieDeletionInfo delete_info,
void CookieMonster::DeleteSessionCookiesAsync(
CookieStore::DeleteCallback callback) {
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 object.
&CookieMonster::DeleteSessionCookies, base::Unretained(this),
......@@ -593,6 +604,17 @@ void CookieMonster::GetAllCookies(GetAllCookiesCallback callback) {
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,
const CookieOptions& options,
GetCookieListCallback callback) {
......
......@@ -165,6 +165,8 @@ class NET_EXPORT CookieMonster : public CookieStore {
const CookieOptions& options,
GetCookieListCallback callback) override;
void GetAllCookiesAsync(GetAllCookiesCallback callback) override;
void GetAllCookiesWithAccessSemanticsAsync(
GetAllCookiesWithAccessSemanticsCallback callback) override;
void DeleteCanonicalCookieAsync(const CanonicalCookie& cookie,
DeleteCallback callback) override;
void DeleteAllCreatedInTimeRangeAsync(
......@@ -358,6 +360,10 @@ class NET_EXPORT CookieMonster : public CookieStore {
void GetAllCookies(GetAllCookiesCallback callback);
void AttachAccessSemanticsListForCookieList(
GetAllCookiesWithAccessSemanticsCallback callback,
const CookieList& cookie_list);
void GetCookieListWithOptions(const GURL& url,
const CookieOptions& options,
GetCookieListCallback callback);
......
......@@ -92,6 +92,7 @@ struct CookieMonsterTestTraits {
static const bool has_exact_change_cause = true;
static const bool has_exact_change_ordering = true;
static const int creation_time_granularity_in_ms = 0;
static const bool supports_cookie_access_semantics = true;
};
INSTANTIATE_TYPED_TEST_SUITE_P(CookieMonster,
......
......@@ -11,6 +11,24 @@ namespace net {
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) {
DeleteAllCreatedInTimeRangeAsync(CookieDeletionInfo::TimeRange(),
std::move(callback));
......
......@@ -49,6 +49,10 @@ class NET_EXPORT CookieStore {
const CookieStatusList& excluded_list)>;
using GetAllCookiesCallback =
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 =
base::OnceCallback<void(CanonicalCookie::CookieInclusionStatus status)>;
using DeleteCallback = base::OnceCallback<void(uint32_t num_deleted)>;
......@@ -83,6 +87,18 @@ class NET_EXPORT CookieStore {
// longest path, then by earliest creation date.
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
// query on this CookieStore. Invokes |callback| with 1 if a cookie was
// deleted, 0 otherwise.
......
......@@ -80,4 +80,21 @@ void GetAllCookiesCallback::Run(const CookieList& cookies) {
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
......@@ -13,6 +13,7 @@
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
#include "net/cookies/canonical_cookie.h"
#include "net/cookies/cookie_constants.h"
#include "net/cookies/cookie_store.h"
namespace base {
......@@ -151,6 +152,36 @@ class GetAllCookiesCallback : public CookieCallback {
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
#endif // NET_COOKIES_COOKIE_STORE_TEST_CALLBACKS_H_
......@@ -24,6 +24,7 @@
#include "net/cookies/cookie_store.h"
#include "net/cookies/cookie_store_test_callbacks.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 "url/gurl.h"
......@@ -101,6 +102,11 @@ const char kValidCookieLine[] = "A=B; path=/";
// // Time to wait between two cookie insertions to ensure that cookies have
// // different creation times.
// 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>
......@@ -1661,6 +1667,58 @@ TYPED_TEST_P(CookieStoreTest, GetAllCookiesAsync) {
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) {
CookieStore* cs = this->GetCookieStore();
......@@ -1756,6 +1814,7 @@ REGISTER_TYPED_TEST_SUITE_P(CookieStoreTest,
EmptyName,
CookieOrdering,
GetAllCookiesAsync,
GetAllCookiesWithAccessSemanticsAsync,
DeleteCanonicalCookieAsync,
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