Commit 7c24679a authored by Nohemi Fernandez's avatar Nohemi Fernandez Committed by Commit Bot

[iOS] Set CHROME_CONNECTED cookie when the user shows sign-in intent.

Following crrev.com/c/2418576 the CHROME_CONNECTED cookie is added when
navigating to accounts.google.com.

Chrome previously only sent domain names to the
ChromeConnectedHeaderHelper (e.g. google.com) meaning that the URL would
never be accounts.google.com. This patch ensures that we send full URLs
instead of domain names to ChromeConnectedHeaderHelper so that we
can benefit from crrev.com/c/2418576.

Bug: 1125631
Change-Id: Ic020cb90cee8764d6d56c72f3143d058d5d5f4f9
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2426488
Commit-Queue: Nohemi Fernandez <fernandex@chromium.org>
Reviewed-by: default avatarJérôme Lebel <jlebel@chromium.org>
Cr-Commit-Position: refs/heads/master@{#811164}
parent c1e26591
...@@ -78,10 +78,9 @@ class AccountConsistencyService : public KeyedService, ...@@ -78,10 +78,9 @@ class AccountConsistencyService : public KeyedService,
// |GetAllCookies| calls on the cookie manager. // |GetAllCookies| calls on the cookie manager.
void SetGaiaCookiesIfDeleted(); void SetGaiaCookiesIfDeleted();
// Enqueues a request to set the CHROME_CONNECTED cookie for |domain|. // Enqueues a request to set the CHROME_CONNECTED cookie for the domain of the
// The cookie is set if it is not already on |domain|. // |url|. The cookie is set if it is not already on the domain.
void SetChromeConnectedCookieWithDomains( void SetChromeConnectedCookieWithUrls(const std::vector<const GURL>& urls);
const std::vector<std::string>& domains);
// 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.
...@@ -96,8 +95,8 @@ class AccountConsistencyService : public KeyedService, ...@@ -96,8 +95,8 @@ class AccountConsistencyService : public KeyedService,
// KeyedService implementation. // KeyedService implementation.
void Shutdown() override; void Shutdown() override;
// Sets the pending CHROME_CONNECTED cookie for the given |domain|. // Sets the pending CHROME_CONNECTED cookie for the given |url|.
void SetChromeConnectedCookieWithDomain(const std::string& domain); void SetChromeConnectedCookieWithUrl(const GURL& url);
// Called when the request to set CHROME_CONNECTED cookie is done. // Called when the request to set CHROME_CONNECTED cookie is done.
void OnChromeConnectedCookieFinished( void OnChromeConnectedCookieFinished(
...@@ -117,11 +116,11 @@ class AccountConsistencyService : public KeyedService, ...@@ -117,11 +116,11 @@ class AccountConsistencyService : public KeyedService,
const std::string& domain, const std::string& domain,
const base::TimeDelta& cookie_refresh_interval); const base::TimeDelta& cookie_refresh_interval);
// Enqueues a request to set the CHROME_CONNECTED cookie for |domain|. // Enqueues a request to set the CHROME_CONNECTED cookie for the |url|'s
// The cookie is set if it is not already on |domain| or if it is too old // domain. The cookie is set if it is not already on domain or if it is too
// compared to the given |cookie_refresh_interval|. // old compared to the given |cookie_refresh_interval|.
void SetChromeConnectedCookieWithDomains( void SetChromeConnectedCookieWithUrls(
const std::vector<std::string>& domains, const std::vector<const GURL>& urls,
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.
......
...@@ -49,8 +49,15 @@ constexpr base::TimeDelta kDelayThresholdToUpdateChromeConnectedCookie = ...@@ -49,8 +49,15 @@ constexpr base::TimeDelta kDelayThresholdToUpdateChromeConnectedCookie =
constexpr base::TimeDelta kDelayThresholdToUpdateGaiaCookie = constexpr base::TimeDelta kDelayThresholdToUpdateGaiaCookie =
base::TimeDelta::FromHours(1); base::TimeDelta::FromHours(1);
const char* kGoogleDomain = "google.com"; const char* kGoogleUrl = "https://google.com";
const char* kYoutubeDomain = "youtube.com"; const char* kYoutubeUrl = "https://youtube.com";
// Returns the registered, organization-identifying host, but no subdomains,
// from the given GURL. Returns an empty string if the GURL is invalid.
static std::string GetDomainFromUrl(const GURL& url) {
return net::registry_controlled_domains::GetDomainAndRegistry(
url, net::registry_controlled_domains::EXCLUDE_PRIVATE_REGISTRIES);
}
// WebStatePolicyDecider that monitors the HTTP headers on Gaia responses, // WebStatePolicyDecider that monitors the HTTP headers on Gaia responses,
// reacting on the X-Chrome-Manage-Accounts header and notifying its delegate. // reacting on the X-Chrome-Manage-Accounts header and notifying its delegate.
...@@ -101,13 +108,13 @@ void AccountConsistencyHandler::ShouldAllowResponse( ...@@ -101,13 +108,13 @@ void AccountConsistencyHandler::ShouldAllowResponse(
} }
GURL url = net::GURLWithNSURL(http_response.URL); GURL url = net::GURLWithNSURL(http_response.URL);
// Logged-in user is showing intent to navigate to a Google domain where we // User is showing intent to navigate to a Google-owned domain. Set GAIA and
// will need to set a CHROME_CONNECTED cookie if it is not already set. // CHROME_CONNECTED cookies if the user is signed in or if they are not signed
// in and navigating to a GAIA sign-on (this is filtered in
// ChromeConnectedHelper).
if (signin::IsUrlEligibleForMirrorCookie(url)) { if (signin::IsUrlEligibleForMirrorCookie(url)) {
std::string domain = net::registry_controlled_domains::GetDomainAndRegistry( account_consistency_service_->SetChromeConnectedCookieWithUrls(
url, net::registry_controlled_domains::EXCLUDE_PRIVATE_REGISTRIES); {url, GURL(kGoogleUrl)});
account_consistency_service_->SetChromeConnectedCookieWithDomains(
{domain, kGoogleDomain});
account_consistency_service_->SetGaiaCookiesIfDeleted(); account_consistency_service_->SetGaiaCookiesIfDeleted();
} }
...@@ -298,22 +305,23 @@ void AccountConsistencyService::OnDeleteCookiesFinished( ...@@ -298,22 +305,23 @@ void AccountConsistencyService::OnDeleteCookiesFinished(
} }
} }
void AccountConsistencyService::SetChromeConnectedCookieWithDomains( void AccountConsistencyService::SetChromeConnectedCookieWithUrls(
const std::vector<std::string>& domains) { const std::vector<const GURL>& urls) {
SetChromeConnectedCookieWithDomains( SetChromeConnectedCookieWithUrls(
domains, kDelayThresholdToUpdateChromeConnectedCookie); urls, kDelayThresholdToUpdateChromeConnectedCookie);
} }
void AccountConsistencyService::SetChromeConnectedCookieWithDomains( void AccountConsistencyService::SetChromeConnectedCookieWithUrls(
const std::vector<std::string>& domains, const std::vector<const GURL>& urls,
const base::TimeDelta& cookie_refresh_interval) { const base::TimeDelta& cookie_refresh_interval) {
for (const std::string& domain : domains) { for (const GURL& url : urls) {
const std::string domain = GetDomainFromUrl(url);
if (!ShouldSetChromeConnectedCookieToDomain(domain, if (!ShouldSetChromeConnectedCookieToDomain(domain,
cookie_refresh_interval)) { cookie_refresh_interval)) {
continue; continue;
} }
last_cookie_update_map_[domain] = base::Time::Now(); last_cookie_update_map_[domain] = base::Time::Now();
SetChromeConnectedCookieWithDomain(domain); SetChromeConnectedCookieWithUrl(url);
} }
} }
...@@ -339,9 +347,9 @@ void AccountConsistencyService::Shutdown() { ...@@ -339,9 +347,9 @@ void AccountConsistencyService::Shutdown() {
web_state_handlers_.clear(); web_state_handlers_.clear();
} }
void AccountConsistencyService::SetChromeConnectedCookieWithDomain( void AccountConsistencyService::SetChromeConnectedCookieWithUrl(
const std::string& domain) { const GURL& url) {
const GURL url("https://" + domain); const std::string domain = GetDomainFromUrl(url);
std::string cookie_value = signin::BuildMirrorRequestCookieIfPossible( std::string cookie_value = signin::BuildMirrorRequestCookieIfPossible(
url, identity_manager_->GetPrimaryAccountInfo().gaia, url, identity_manager_->GetPrimaryAccountInfo().gaia,
signin::AccountConsistencyMethod::kMirror, cookie_settings_.get(), signin::AccountConsistencyMethod::kMirror, cookie_settings_.get(),
...@@ -355,7 +363,7 @@ void AccountConsistencyService::SetChromeConnectedCookieWithDomain( ...@@ -355,7 +363,7 @@ void AccountConsistencyService::SetChromeConnectedCookieWithDomain(
net::CanonicalCookie::CreateSanitizedCookie( net::CanonicalCookie::CreateSanitizedCookie(
url, url,
/*name=*/kChromeConnectedCookieName, cookie_value, /*name=*/kChromeConnectedCookieName, cookie_value,
/*domain=*/url.host(), /*domain=*/domain,
/*path=*/std::string(), /*path=*/std::string(),
/*creation_time=*/base::Time::Now(), /*creation_time=*/base::Time::Now(),
// Create expiration date of Now+2y to roughly follow the SAPISID // Create expiration date of Now+2y to roughly follow the SAPISID
...@@ -398,8 +406,8 @@ void AccountConsistencyService::AddChromeConnectedCookies() { ...@@ -398,8 +406,8 @@ void AccountConsistencyService::AddChromeConnectedCookies() {
DCHECK(!browser_state_->IsOffTheRecord()); DCHECK(!browser_state_->IsOffTheRecord());
// These cookie requests are preventive and not a strong signal (unlike // These cookie requests are preventive and not a strong signal (unlike
// navigation to a domain). Don't force update the old cookies in this case. // navigation to a domain). Don't force update the old cookies in this case.
SetChromeConnectedCookieWithDomains({kGoogleDomain, kYoutubeDomain}, SetChromeConnectedCookieWithUrls({GURL(kGoogleUrl), GURL(kYoutubeUrl)},
base::TimeDelta::Max()); base::TimeDelta::Max());
} }
void AccountConsistencyService::ResetInternalState() { void AccountConsistencyService::ResetInternalState() {
......
...@@ -78,8 +78,7 @@ bool ContainsCookie(const std::vector<net::CanonicalCookie>& cookies, ...@@ -78,8 +78,7 @@ bool ContainsCookie(const std::vector<net::CanonicalCookie>& cookies,
const std::string& name, const std::string& name,
const std::string& domain) { const std::string& domain) {
for (const auto& cookie : cookies) { for (const auto& cookie : cookies) {
if (cookie.Name() == if (cookie.Name() == name) {
AccountConsistencyService::kChromeConnectedCookieName) {
if (domain.empty() || cookie.Domain() == domain) if (domain.empty() || cookie.Domain() == domain)
return true; return true;
} }
...@@ -289,8 +288,8 @@ class AccountConsistencyServiceTest : public PlatformTest { ...@@ -289,8 +288,8 @@ class AccountConsistencyServiceTest : public PlatformTest {
// 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.
void SimulateSetChromeConnectedCookieForGoogleDomain() { void SimulateSetChromeConnectedCookieForGoogleDomain() {
account_consistency_service_->SetChromeConnectedCookieWithDomains( account_consistency_service_->SetChromeConnectedCookieWithUrls(
{kGoogleDomain}); {GURL("https://google.com")});
WaitUntilAllCookieRequestsAreApplied(); WaitUntilAllCookieRequestsAreApplied();
} }
...@@ -624,8 +623,9 @@ TEST_F(AccountConsistencyServiceTest, DeleteChromeConnectedCookiesAfterSet) { ...@@ -624,8 +623,9 @@ TEST_F(AccountConsistencyServiceTest, DeleteChromeConnectedCookiesAfterSet) {
// |kGoogleDomain| or |kYouTubeDomain| otherwise they will not be reset since // |kGoogleDomain| or |kYouTubeDomain| otherwise they will not be reset since
// it is before the update time. Add multiple URLs to test for race conditions // it is before the update time. Add multiple URLs to test for race conditions
// with remove call. // with remove call.
account_consistency_service_->SetChromeConnectedCookieWithDomains( account_consistency_service_->SetChromeConnectedCookieWithUrls(
{"google.ca", "google.fr", kCountryGoogleDomain}); {GURL("https://google.ca"), GURL("https://google.fr"),
GURL("https://google.de")});
SimulateGaiaCookieManagerServiceLogout(); SimulateGaiaCookieManagerServiceLogout();
WaitUntilAllCookieRequestsAreApplied(); WaitUntilAllCookieRequestsAreApplied();
...@@ -641,12 +641,44 @@ TEST_F(AccountConsistencyServiceTest, SetChromeConnectedCookiesAfterDelete) { ...@@ -641,12 +641,44 @@ TEST_F(AccountConsistencyServiceTest, SetChromeConnectedCookiesAfterDelete) {
// |kGoogleDomain| or |kYouTubeDomain| otherwise they will not be reset since // |kGoogleDomain| or |kYouTubeDomain| otherwise they will not be reset since
// it is before the update time. Add multiple URLs to test for race conditions // it is before the update time. Add multiple URLs to test for race conditions
// with remove call. // with remove call.
account_consistency_service_->SetChromeConnectedCookieWithDomains( account_consistency_service_->SetChromeConnectedCookieWithUrls(
{"google.ca", "google.fr", kCountryGoogleDomain}); {GURL("https://google.ca"), GURL("https://google.fr"),
GURL("https://google.de")});
SimulateGaiaCookieManagerServiceLogout(); SimulateGaiaCookieManagerServiceLogout();
account_consistency_service_->SetChromeConnectedCookieWithDomains( account_consistency_service_->SetChromeConnectedCookieWithUrls(
{"google.ca"}); {GURL("https://google.ca")});
WaitUntilAllCookieRequestsAreApplied(); WaitUntilAllCookieRequestsAreApplied();
CheckDomainHasChromeConnectedCookie("google.ca"); CheckDomainHasChromeConnectedCookie("google.ca");
} }
// Ensures that CHROME_CONNECTED cookies are only set on GAIA urls when the user
// is signed out for |kMobileIdentityConsistency| experiment.
TEST_F(AccountConsistencyServiceTest,
SetMiceChromeConnectedCookiesSignedOutUser) {
base::test::ScopedFeatureList feature_list;
feature_list.InitAndEnableFeature(signin::kMobileIdentityConsistency);
id delegate =
[OCMockObject mockForProtocol:@protocol(ManageAccountsDelegate)];
NSDictionary* headers = [NSDictionary dictionary];
NSHTTPURLResponse* responseGoogle = [[NSHTTPURLResponse alloc]
initWithURL:[NSURL URLWithString:@"https://google.com/"]
statusCode:200
HTTPVersion:@"HTTP/1.1"
headerFields:headers];
account_consistency_service_->SetWebStateHandler(&web_state_, delegate);
EXPECT_TRUE(web_state_.ShouldAllowResponse(responseGoogle,
/* for_main_frame = */ true));
CheckNoChromeConnectedCookies();
NSHTTPURLResponse* responseGaia = [[NSHTTPURLResponse alloc]
initWithURL:[NSURL URLWithString:@"https://accounts.google.com/"]
statusCode:200
HTTPVersion:@"HTTP/1.1"
headerFields:headers];
EXPECT_TRUE(web_state_.ShouldAllowResponse(responseGaia,
/* for_main_frame = */ true));
CheckDomainHasChromeConnectedCookie("google.com");
}
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