Commit b24f0041 authored by Nohemi Fernandez's avatar Nohemi Fernandez Committed by Commit Bot

[iOS] Use canonical DeleteCookies API from CookieManager.

This allows us to outsource all cookie tracking efforts to the dedicated
Chrome implementation rather than re-implementing the cookie request
queue.

Bug: 1102794
Change-Id: I284888a796acd60cfc696598e53e7debc726b6c2
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2346664
Commit-Queue: Nohemi Fernandez <fernandex@chromium.org>
Reviewed-by: default avatarMihai Sardarescu <msarda@chromium.org>
Cr-Commit-Position: refs/heads/master@{#803045}
parent cd8566c8
...@@ -10,7 +10,6 @@ ...@@ -10,7 +10,6 @@
#include <string> #include <string>
#include "base/callback.h" #include "base/callback.h"
#include "base/containers/circular_deque.h"
#include "base/macros.h" #include "base/macros.h"
#include "base/memory/ref_counted.h" #include "base/memory/ref_counted.h"
#include "base/time/time.h" #include "base/time/time.h"
...@@ -71,10 +70,6 @@ class AccountConsistencyService : public KeyedService, ...@@ -71,10 +70,6 @@ class AccountConsistencyService : public KeyedService,
// Removes the handler associated with |web_state|. // Removes the handler associated with |web_state|.
void RemoveWebStateHandler(web::WebState* web_state); void RemoveWebStateHandler(web::WebState* web_state);
// Removes CHROME_CONNECTED cookies on all the Google domains where it was
// set. Calls callback once all cookies were removed.
void RemoveChromeConnectedCookies(base::OnceClosure callback);
// Checks for the presence of Gaia cookies and if they have been deleted // Checks for the presence of Gaia cookies and if they have been deleted
// notifies the AccountReconcilor (the class responsible for rebuilding Gaia // notifies the AccountReconcilor (the class responsible for rebuilding Gaia
// cookies if needed). // cookies if needed).
...@@ -85,12 +80,12 @@ class AccountConsistencyService : public KeyedService, ...@@ -85,12 +80,12 @@ class AccountConsistencyService : public KeyedService,
// Enqueues a request to set the CHROME_CONNECTED cookie for |domain|. // Enqueues a request to set the CHROME_CONNECTED cookie for |domain|.
// The cookie is set if it is not already on |domain|. // The cookie is set if it is not already on |domain|.
void SetChromeConnectedCookieWithDomain(const std::string& domain); void SetChromeConnectedCookieWithDomains(
const std::vector<std::string>& domains);
// Enqueues a request to remove the CHROME_CONNECTED cookie to |domain|. // Removes CHROME_CONNECTED cookies on all the Google domains where it was
// Does nothing if the cookie is not set on |domain|. // set. Calls callback once all cookies were removed.
void RemoveChromeConnectedCookieFromDomain(const std::string& domain, void RemoveAllChromeConnectedCookies(base::OnceClosure callback);
base::OnceClosure callback);
// Notifies the AccountConsistencyService that browsing data has been removed // Notifies the AccountConsistencyService that browsing data has been removed
// for any time period. // for any time period.
...@@ -99,47 +94,24 @@ class AccountConsistencyService : public KeyedService, ...@@ -99,47 +94,24 @@ class AccountConsistencyService : public KeyedService,
private: private:
friend class AccountConsistencyServiceTest; friend class AccountConsistencyServiceTest;
// The type of a cookie request.
enum CookieRequestType {
ADD_CHROME_CONNECTED_COOKIE,
REMOVE_CHROME_CONNECTED_COOKIE
};
// A CHROME_CONNECTED cookie request to be applied by the
// AccountConsistencyService.
struct CookieRequest {
static CookieRequest CreateAddCookieRequest(const std::string& domain);
static CookieRequest CreateRemoveCookieRequest(const std::string& domain,
base::OnceClosure callback);
CookieRequest();
~CookieRequest();
// Movable, not copyable.
CookieRequest(CookieRequest&&);
CookieRequest& operator=(CookieRequest&&) = default;
CookieRequest(const CookieRequest&) = delete;
CookieRequest& operator=(const CookieRequest&) = delete;
CookieRequestType request_type;
std::string domain;
base::OnceClosure callback;
};
// Loads the domains with a CHROME_CONNECTED cookie from the prefs. // Loads the domains with a CHROME_CONNECTED cookie from the prefs.
void LoadFromPrefs(); void LoadFromPrefs();
// KeyedService implementation. // KeyedService implementation.
void Shutdown() override; void Shutdown() override;
// Applies the pending CHROME_CONNECTED cookie requests one by one. // Sets the pending CHROME_CONNECTED cookie for the given |domain|.
void ApplyCookieRequests(); void SetChromeConnectedCookieWithDomain(const std::string& domain);
// Called when the request to set CHROME_CONNECTED cookie is done. // Called when the request to set CHROME_CONNECTED cookie is done.
void FinishedSetChromeConnectedCookie( void OnChromeConnectedCookieFinished(
const std::string& domain,
net::CookieAccessResult cookie_access_result); net::CookieAccessResult cookie_access_result);
// Called when the current CHROME_CONNECTED cookie request is done. // Called when cookie deletion is completed with the number of cookies that
void FinishedApplyingChromeConnectedCookieRequest(bool success); // were removed from the cookie store.
void OnDeleteCookiesFinished(base::OnceClosure callback,
uint32_t num_cookies_deleted);
// Returns whether the CHROME_CONNECTED cookie should be added to |domain|. // Returns whether the CHROME_CONNECTED cookie should be added to |domain|.
// If the cookie is not already on |domain|, it will return true. If the // If the cookie is not already on |domain|, it will return true. If the
...@@ -152,8 +124,8 @@ class AccountConsistencyService : public KeyedService, ...@@ -152,8 +124,8 @@ class AccountConsistencyService : public KeyedService,
// Enqueues a request to set the CHROME_CONNECTED cookie for |domain|. // Enqueues a request to set the CHROME_CONNECTED cookie for |domain|.
// The cookie is set if it is not already on |domain| or if it is too old // The cookie is set if it is not already on |domain| or if it is too old
// compared to the given |cookie_refresh_interval|. // compared to the given |cookie_refresh_interval|.
void SetChromeConnectedCookieWithDomain( void SetChromeConnectedCookieWithDomains(
const std::string& domain, const std::vector<std::string>& domains,
const base::TimeDelta& cookie_refresh_interval); const base::TimeDelta& cookie_refresh_interval);
// Adds CHROME_CONNECTED cookies on all the main Google domains. // Adds CHROME_CONNECTED cookies on all the main Google domains.
...@@ -167,6 +139,9 @@ class AccountConsistencyService : public KeyedService, ...@@ -167,6 +139,9 @@ class AccountConsistencyService : public KeyedService,
// Records whether Gaia cookies were present on navigation in UMA histogram. // Records whether Gaia cookies were present on navigation in UMA histogram.
static void LogIOSGaiaCookiesPresentOnNavigation(bool is_present); static void LogIOSGaiaCookiesPresentOnNavigation(bool is_present);
// Clears all pending cookie requests and cached domains.
void ResetInternalState();
// IdentityManager::Observer implementation. // IdentityManager::Observer implementation.
void OnPrimaryAccountSet(const CoreAccountInfo& account_info) override; void OnPrimaryAccountSet(const CoreAccountInfo& account_info) override;
void OnPrimaryAccountCleared( void OnPrimaryAccountCleared(
...@@ -189,10 +164,9 @@ class AccountConsistencyService : public KeyedService, ...@@ -189,10 +164,9 @@ class AccountConsistencyService : public KeyedService,
// signout events. // signout events.
signin::IdentityManager* identity_manager_; signin::IdentityManager* identity_manager_;
// Whether a CHROME_CONNECTED cookie request is currently being applied. // The number of cookie manager requests that are being processed.
bool applying_cookie_requests_; // Used for testing purposes only.
// The queue of CHROME_CONNECTED cookie requests to be applied. int64_t active_cookie_manager_requests_for_testing_;
base::circular_deque<CookieRequest> cookie_requests_;
// The map between domains where a CHROME_CONNECTED cookie is present and // The map between domains where a CHROME_CONNECTED cookie is present and
// the time when the cookie was last updated. // the time when the cookie was last updated.
std::map<std::string, base::Time> last_cookie_update_map_; std::map<std::string, base::Time> last_cookie_update_map_;
......
...@@ -202,7 +202,8 @@ class AccountConsistencyServiceTest : public PlatformTest { ...@@ -202,7 +202,8 @@ class AccountConsistencyServiceTest : public PlatformTest {
// Spinning the runloop is needed to ensure that the cookie manager requests // Spinning the runloop is needed to ensure that the cookie manager requests
// are executed. // are executed.
base::RunLoop().RunUntilIdle(); base::RunLoop().RunUntilIdle();
EXPECT_TRUE(account_consistency_service_->cookie_requests_.empty()); EXPECT_EQ(0, account_consistency_service_
->active_cookie_manager_requests_for_testing_);
} }
void SignIn() { void SignIn() {
...@@ -234,6 +235,16 @@ class AccountConsistencyServiceTest : public PlatformTest { ...@@ -234,6 +235,16 @@ class AccountConsistencyServiceTest : public PlatformTest {
return cookies_out; return cookies_out;
} }
// Returns time the CHROME_CONNECTED cookie was last updated for |domain|.
base::Time GetCookieLastUpdateTime(const std::string& domain) {
return account_consistency_service_->last_cookie_update_map_[domain];
}
// Returns time the Gaia cookie was last updated for Google domains.
base::Time GetGaiaLastUpdateTime() {
return account_consistency_service_->last_gaia_cookie_verification_time_;
}
void CheckDomainHasChromeConnectedCookie(const std::string& domain) { void CheckDomainHasChromeConnectedCookie(const std::string& domain) {
EXPECT_TRUE( EXPECT_TRUE(
ContainsCookie(GetCookiesInCookieJar(), ContainsCookie(GetCookiesInCookieJar(),
...@@ -264,28 +275,23 @@ class AccountConsistencyServiceTest : public PlatformTest { ...@@ -264,28 +275,23 @@ class AccountConsistencyServiceTest : public PlatformTest {
// the cookies once the sign-out is done. // the cookies once the sign-out is done.
void SimulateGaiaCookieManagerServiceLogout() { void SimulateGaiaCookieManagerServiceLogout() {
base::RunLoop run_loop; base::RunLoop run_loop;
account_consistency_service_->RemoveChromeConnectedCookies( account_consistency_service_->RemoveAllChromeConnectedCookies(
run_loop.QuitClosure()); run_loop.QuitClosure());
run_loop.Run(); run_loop.Run();
} }
// Simulates setting the CHROME_CONNECTED cookie for the Google domain at the // Simulates setting the CHROME_CONNECTED cookie for the Google domain at the
// designated time interval. Returns the time at which the cookie was updated. // designated time interval. Returns the time at which the cookie was updated.
base::Time SimulateSetChromeConnectedCookie() { void SimulateSetChromeConnectedCookieForGoogleDomain() {
account_consistency_service_->SetChromeConnectedCookieWithDomain( account_consistency_service_->SetChromeConnectedCookieWithDomains(
kGoogleDomain); {kGoogleDomain});
WaitUntilAllCookieRequestsAreApplied(); WaitUntilAllCookieRequestsAreApplied();
return account_consistency_service_->last_cookie_update_map_[kGoogleDomain];
} }
// Simulates updating the Gaia cookie on the Google domain at the designated // Simulates updating the Gaia cookie on the Google domain at the designated
// time interval. Returns the time at which the cookie was updated. // time interval. Returns the time at which the cookie was updated.
base::Time SimulateUpdateGaiaCookie() { void SimulateUpdateGaiaCookie() {
account_consistency_service_->SetGaiaCookiesIfDeleted(); account_consistency_service_->SetGaiaCookiesIfDeleted();
WaitUntilAllCookieRequestsAreApplied();
return account_consistency_service_->last_gaia_cookie_verification_time_;
} }
void CheckGoogleDomainHasGaiaCookie() { void CheckGoogleDomainHasGaiaCookie() {
...@@ -489,44 +495,82 @@ TEST_F(AccountConsistencyServiceTest, DomainsClearedOnBrowsingDataRemoved) { ...@@ -489,44 +495,82 @@ TEST_F(AccountConsistencyServiceTest, DomainsClearedOnBrowsingDataRemoved) {
TEST_F(AccountConsistencyServiceTest, SetChromeConnectedCookieNotUpdateTime) { TEST_F(AccountConsistencyServiceTest, SetChromeConnectedCookieNotUpdateTime) {
SignIn(); SignIn();
base::Time first_cookie_update = SimulateSetChromeConnectedCookie();
// The second update will not send a cookie request, since this call is made const base::Time signin_time = base::Time::Now();
// before update time. // Advance clock before 24-hour CHROME_CONNECTED update time.
base::Time second_cookie_update = SimulateSetChromeConnectedCookie(); task_environment_.FastForwardBy(base::TimeDelta::FromHours(2));
EXPECT_EQ(first_cookie_update, second_cookie_update); SimulateSetChromeConnectedCookieForGoogleDomain();
EXPECT_EQ(signin_time, GetCookieLastUpdateTime(kGoogleDomain));
} }
TEST_F(AccountConsistencyServiceTest, SetChromeConnectedCookieAtUpdateTime) { TEST_F(AccountConsistencyServiceTest, SetChromeConnectedCookieAtUpdateTime) {
SignIn(); SignIn();
base::Time first_cookie_update = SimulateSetChromeConnectedCookie();
// Advance clock past 24-hour CHROME_CONNECTED update time. // Advance clock past 24-hour CHROME_CONNECTED update time.
task_environment_.FastForwardBy(base::TimeDelta::FromDays(2)); task_environment_.FastForwardBy(base::TimeDelta::FromDays(2));
const base::Time second_cookie_update_time = base::Time::Now();
SimulateSetChromeConnectedCookieForGoogleDomain();
// The second update will not send a cookie request, since CHROME_CONNECTED EXPECT_EQ(second_cookie_update_time, GetCookieLastUpdateTime(kGoogleDomain));
// has already been set.
base::Time second_cookie_update = SimulateSetChromeConnectedCookie();
EXPECT_GT(second_cookie_update, first_cookie_update);
} }
TEST_F(AccountConsistencyServiceTest, SetGaiaCookieUpdateNotUpdateTime) { TEST_F(AccountConsistencyServiceTest, SetGaiaCookieUpdateNotUpdateTime) {
base::Time first_gaia_cookie_update = SimulateUpdateGaiaCookie(); SimulateUpdateGaiaCookie();
// The second update will not send a cookie request, since this call is made // Advance clock past one-hour Gaia update time.
// before update time. const base::Time first_update_time = base::Time::Now();
base::Time second_gaia_cookie_update = SimulateUpdateGaiaCookie(); task_environment_.FastForwardBy(base::TimeDelta::FromMinutes(1));
EXPECT_EQ(first_gaia_cookie_update, second_gaia_cookie_update); SimulateUpdateGaiaCookie();
EXPECT_EQ(first_update_time, GetGaiaLastUpdateTime());
} }
TEST_F(AccountConsistencyServiceTest, SetGaiaCookieUpdateAtUpdateTime) { TEST_F(AccountConsistencyServiceTest, SetGaiaCookieUpdateAtUpdateTime) {
base::Time first_gaia_cookie_update = SimulateUpdateGaiaCookie(); SimulateUpdateGaiaCookie();
// Advance clock past one-hour Gaia update time. // Advance clock past one-hour Gaia update time.
task_environment_.FastForwardBy(base::TimeDelta::FromHours(2)); task_environment_.FastForwardBy(base::TimeDelta::FromHours(2));
const base::Time second_update_time = base::Time::Now();
SimulateUpdateGaiaCookie();
EXPECT_EQ(second_update_time, GetGaiaLastUpdateTime());
}
// Ensures that set and remove cookie operations are handled in the order
// they are called resulting in no cookies.
TEST_F(AccountConsistencyServiceTest, DeleteChromeConnectedCookiesAfterSet) {
SignIn();
// URLs must pass IsGoogleDomainURL and not duplicate sign-in domains
// |kGoogleDomain| or |kYouTubeDomain| otherwise they will not be reset since
// it is before the update time. Add multiple URLs to test for race conditions
// with remove call.
account_consistency_service_->SetChromeConnectedCookieWithDomains(
{"google.ca", "google.fr", kCountryGoogleDomain});
account_consistency_service_->RemoveAllChromeConnectedCookies(
base::OnceClosure());
WaitUntilAllCookieRequestsAreApplied();
CheckNoChromeConnectedCookies();
}
// Ensures that set and remove cookie operations are handled in the order
// they are called resulting in one cookie.
TEST_F(AccountConsistencyServiceTest, SetChromeConnectedCookiesAfterDelete) {
SignIn();
// The second update will send a cookie request, since update time is not // URLs must pass IsGoogleDomainURL and not duplicate sign-in domains
// considered for the call. // |kGoogleDomain| or |kYouTubeDomain| otherwise they will not be reset since
base::Time second_gaia_cookie_update = SimulateUpdateGaiaCookie(); // it is before the update time. Add multiple URLs to test for race conditions
EXPECT_GT(second_gaia_cookie_update, first_gaia_cookie_update); // with remove call.
account_consistency_service_->SetChromeConnectedCookieWithDomains(
{"google.ca", "google.fr", kCountryGoogleDomain});
account_consistency_service_->RemoveAllChromeConnectedCookies(
base::OnceClosure());
account_consistency_service_->SetChromeConnectedCookieWithDomains(
{"google.ca"});
WaitUntilAllCookieRequestsAreApplied();
CheckDomainHasChromeConnectedCookie("google.ca");
} }
...@@ -86,5 +86,6 @@ std::unique_ptr<GaiaAuthFetcher> IOSChromeSigninClient::CreateGaiaAuthFetcher( ...@@ -86,5 +86,6 @@ std::unique_ptr<GaiaAuthFetcher> IOSChromeSigninClient::CreateGaiaAuthFetcher(
void IOSChromeSigninClient::PreGaiaLogout(base::OnceClosure callback) { void IOSChromeSigninClient::PreGaiaLogout(base::OnceClosure callback) {
AccountConsistencyService* accountConsistencyService = AccountConsistencyService* accountConsistencyService =
ios::AccountConsistencyServiceFactory::GetForBrowserState(browser_state_); ios::AccountConsistencyServiceFactory::GetForBrowserState(browser_state_);
accountConsistencyService->RemoveChromeConnectedCookies(std::move(callback)); accountConsistencyService->RemoveAllChromeConnectedCookies(
std::move(callback));
} }
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