Commit e1c54d4a authored by Nohemi Fernandez's avatar Nohemi Fernandez Committed by Chromium LUCI CQ

[iOS] Restore GAIA cookies when the user shows sign-in intent.

Chrome will re-generate missing GAIA cookies when the user takes an
explicit action that requires user sign-in. For example, if the user
clicks on the "Sign in" button in google.com or "Your Data on Maps"
in the iOS Maps app.

Bug: 1157475
Change-Id: I8c6011959cd90c2ff5b651a831c9570baf559f3e
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2587066
Commit-Queue: Nohemi Fernandez <fernandex@chromium.org>
Reviewed-by: default avatarJérôme Lebel <jlebel@chromium.org>
Cr-Commit-Position: refs/heads/master@{#837610}
parent 2a0c0690
...@@ -70,6 +70,9 @@ class AccountConsistencyService : public KeyedService, ...@@ -70,6 +70,9 @@ 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);
// Adds the callback to the list to call when Gaia cookies are restored.
void AddCookieRestoreCallback(base::OnceClosure cookies_restored_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). Calls callback if Gaia cookies were restored. // cookies if needed). Calls callback if Gaia cookies were restored.
...@@ -86,6 +89,9 @@ class AccountConsistencyService : public KeyedService, ...@@ -86,6 +89,9 @@ class AccountConsistencyService : public KeyedService,
// set. Calls callback once all cookies were removed. // set. Calls callback once all cookies were removed.
void RemoveAllChromeConnectedCookies(base::OnceClosure callback); void RemoveAllChromeConnectedCookies(base::OnceClosure callback);
// Adds CHROME_CONNECTED cookies on all the main Google domains.
void AddChromeConnectedCookies();
// 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.
void OnBrowsingDataRemoved(); void OnBrowsingDataRemoved();
...@@ -127,9 +133,6 @@ class AccountConsistencyService : public KeyedService, ...@@ -127,9 +133,6 @@ class AccountConsistencyService : public KeyedService,
const std::vector<const GURL>& urls, 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.
void AddChromeConnectedCookies();
// Triggers a Gaia cookie update on the Google domain. Calls // Triggers a Gaia cookie update on the Google domain. Calls
// |cookies_restored_callback| if the Gaia cookies were restored. // |cookies_restored_callback| if the Gaia cookies were restored.
void TriggerGaiaCookieChangeIfDeleted( void TriggerGaiaCookieChangeIfDeleted(
...@@ -172,6 +175,9 @@ class AccountConsistencyService : public KeyedService, ...@@ -172,6 +175,9 @@ class AccountConsistencyService : public KeyedService,
// Last time Gaia cookie was updated for the Google domain. // Last time Gaia cookie was updated for the Google domain.
base::Time last_gaia_cookie_verification_time_; base::Time last_gaia_cookie_verification_time_;
// List of callbacks to be called following GAIA cookie restoration.
std::vector<base::OnceClosure> gaia_cookies_restored_callbacks_;
// Handlers reacting on GAIA responses with the X-Chrome-Manage-Accounts // Handlers reacting on GAIA responses with the X-Chrome-Manage-Accounts
// header set. // header set.
std::map<web::WebState*, std::unique_ptr<web::WebStatePolicyDecider>> std::map<web::WebState*, std::unique_ptr<web::WebStatePolicyDecider>>
......
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#include "components/signin/ios/browser/features.h" #include "components/signin/ios/browser/features.h"
#include "components/signin/public/base/account_consistency_method.h" #include "components/signin/public/base/account_consistency_method.h"
#include "components/signin/public/identity_manager/accounts_cookie_mutator.h" #include "components/signin/public/identity_manager/accounts_cookie_mutator.h"
#include "components/signin/public/identity_manager/accounts_in_cookie_jar_info.h"
#include "google_apis/gaia/gaia_urls.h" #include "google_apis/gaia/gaia_urls.h"
#include "ios/web/common/web_view_creation_util.h" #include "ios/web/common/web_view_creation_util.h"
#include "ios/web/public/browser_state.h" #include "ios/web/public/browser_state.h"
...@@ -122,6 +123,9 @@ class AccountConsistencyHandler : public web::WebStatePolicyDecider, ...@@ -122,6 +123,9 @@ class AccountConsistencyHandler : public web::WebStatePolicyDecider,
web::PageLoadCompletionStatus load_completion_status) override; web::PageLoadCompletionStatus load_completion_status) override;
// web::WebStatePolicyDecider override. // web::WebStatePolicyDecider override.
WebStatePolicyDecider::PolicyDecision ShouldAllowRequest(
NSURLRequest* request,
const web::WebStatePolicyDecider::RequestInfo& request_info) override;
// Decides on navigation corresponding to |response| whether the navigation // Decides on navigation corresponding to |response| whether the navigation
// should continue and updates authentication cookies on Google domains. // should continue and updates authentication cookies on Google domains.
void ShouldAllowResponse( void ShouldAllowResponse(
...@@ -133,11 +137,15 @@ class AccountConsistencyHandler : public web::WebStatePolicyDecider, ...@@ -133,11 +137,15 @@ class AccountConsistencyHandler : public web::WebStatePolicyDecider,
// Marks that GAIA cookies have been restored. // Marks that GAIA cookies have been restored.
void MarkGaiaCookiesRestored(); void MarkGaiaCookiesRestored();
// Loads |url| in the current tab.
void NavigateToURL(GURL url);
bool show_consistency_promo_ = false; bool show_consistency_promo_ = false;
bool gaia_cookies_restored_ = false; bool gaia_cookies_restored_ = false;
AccountConsistencyService* account_consistency_service_; // Weak. AccountConsistencyService* account_consistency_service_; // Weak.
AccountReconcilor* account_reconcilor_; // Weak. AccountReconcilor* account_reconcilor_; // Weak.
signin::IdentityManager* identity_manager_; signin::IdentityManager* identity_manager_;
web::WebState* web_state_;
__weak id<ManageAccountsDelegate> delegate_; __weak id<ManageAccountsDelegate> delegate_;
base::WeakPtrFactory<AccountConsistencyHandler> weak_ptr_factory_; base::WeakPtrFactory<AccountConsistencyHandler> weak_ptr_factory_;
}; };
...@@ -153,11 +161,30 @@ AccountConsistencyHandler::AccountConsistencyHandler( ...@@ -153,11 +161,30 @@ AccountConsistencyHandler::AccountConsistencyHandler(
account_consistency_service_(service), account_consistency_service_(service),
account_reconcilor_(account_reconcilor), account_reconcilor_(account_reconcilor),
identity_manager_(identity_manager), identity_manager_(identity_manager),
web_state_(web_state),
delegate_(delegate), delegate_(delegate),
weak_ptr_factory_(this) { weak_ptr_factory_(this) {
web_state->AddObserver(this); web_state->AddObserver(this);
} }
web::WebStatePolicyDecider::PolicyDecision
AccountConsistencyHandler::ShouldAllowRequest(
NSURLRequest* request,
const web::WebStatePolicyDecider::RequestInfo& request_info) {
GURL url = net::GURLWithNSURL(request.URL);
if (base::FeatureList::IsEnabled(signin::kRestoreGaiaCookiesOnUserAction) &&
signin::IsUrlEligibleForMirrorCookie(url) &&
identity_manager_->HasPrimaryAccount()) {
// CHROME_CONNECTED cookies are added asynchronously on google.com and
// youtube.com domains when Chrome detects that the user is signed-in. By
// continuing to fulfill the navigation once the cookie request is sent,
// Chrome adopts a best-effort strategy for signing the user into the web if
// necessary.
account_consistency_service_->AddChromeConnectedCookies();
}
return PolicyDecision::Allow();
}
void AccountConsistencyHandler::ShouldAllowResponse( void AccountConsistencyHandler::ShouldAllowResponse(
NSURLResponse* response, NSURLResponse* response,
bool for_main_frame, bool for_main_frame,
...@@ -235,6 +262,23 @@ void AccountConsistencyHandler::ShouldAllowResponse( ...@@ -235,6 +262,23 @@ void AccountConsistencyHandler::ShouldAllowResponse(
if (identity_manager_->HasPrimaryAccount()) { if (identity_manager_->HasPrimaryAccount()) {
LogIOSGaiaCookiesState(GaiaCookieStateOnSignedInNavigation:: LogIOSGaiaCookiesState(GaiaCookieStateOnSignedInNavigation::
kGaiaCookieAbsentOnAddSessionNavigation); kGaiaCookieAbsentOnAddSessionNavigation);
if (base::FeatureList::IsEnabled(
signin::kRestoreGaiaCookiesOnUserAction)) {
// Reset boolean that tracks displaying the sign-in notification
// infobar. This ensures that only the most recent navigation will
// trigger an infobar.
gaia_cookies_restored_ = false;
GURL continue_url = GURL(params.continue_url);
DLOG_IF(ERROR,
!params.continue_url.empty() && !continue_url.is_valid())
<< "Invalid continuation URL: \"" << continue_url << "\"";
identity_manager_->GetAccountsCookieMutator()
->ForceTriggerOnCookieChange();
account_consistency_service_->AddCookieRestoreCallback(
base::BindOnce(&AccountConsistencyHandler::NavigateToURL,
weak_ptr_factory_.GetWeakPtr(), continue_url));
return;
}
} }
if (params.show_consistency_promo) { if (params.show_consistency_promo) {
show_consistency_promo_ = true; show_consistency_promo_ = true;
...@@ -270,6 +314,13 @@ void AccountConsistencyHandler::MarkGaiaCookiesRestored() { ...@@ -270,6 +314,13 @@ void AccountConsistencyHandler::MarkGaiaCookiesRestored() {
gaia_cookies_restored_ = true; gaia_cookies_restored_ = true;
} }
void AccountConsistencyHandler::NavigateToURL(GURL url) {
gaia_cookies_restored_ = true;
web_state_->OpenURL(web::WebState::OpenURLParams(
url, web::Referrer(), WindowOpenDisposition::CURRENT_TAB,
ui::PAGE_TRANSITION_AUTO_TOPLEVEL, false));
}
void AccountConsistencyHandler::PageLoaded( void AccountConsistencyHandler::PageLoaded(
web::WebState* web_state, web::WebState* web_state,
web::PageLoadCompletionStatus load_completion_status) { web::PageLoadCompletionStatus load_completion_status) {
...@@ -362,6 +413,12 @@ void AccountConsistencyService::RemoveWebStateHandler( ...@@ -362,6 +413,12 @@ void AccountConsistencyService::RemoveWebStateHandler(
web_state_handlers_.erase(web_state); web_state_handlers_.erase(web_state);
} }
void AccountConsistencyService::AddCookieRestoreCallback(
base::OnceClosure cookies_restored_callback) {
gaia_cookies_restored_callbacks_.push_back(
std::move(cookies_restored_callback));
}
void AccountConsistencyService::SetGaiaCookiesIfDeleted( void AccountConsistencyService::SetGaiaCookiesIfDeleted(
base::OnceClosure cookies_restored_callback) { base::OnceClosure cookies_restored_callback) {
// We currently enforce a time threshold to update the Gaia cookie // We currently enforce a time threshold to update the Gaia cookie
...@@ -407,9 +464,7 @@ void AccountConsistencyService::TriggerGaiaCookieChangeIfDeleted( ...@@ -407,9 +464,7 @@ void AccountConsistencyService::TriggerGaiaCookieChangeIfDeleted(
// Re-generate cookie to ensure that the user is properly signed in. // Re-generate cookie to ensure that the user is properly signed in.
identity_manager_->GetAccountsCookieMutator()->ForceTriggerOnCookieChange(); identity_manager_->GetAccountsCookieMutator()->ForceTriggerOnCookieChange();
if (!cookies_restored_callback.is_null()) { AddCookieRestoreCallback(std::move(cookies_restored_callback));
std::move(cookies_restored_callback).Run();
}
} }
void AccountConsistencyService::RemoveAllChromeConnectedCookies( void AccountConsistencyService::RemoveAllChromeConnectedCookies(
...@@ -582,4 +637,15 @@ void AccountConsistencyService::OnAccountsInCookieUpdated( ...@@ -582,4 +637,15 @@ void AccountConsistencyService::OnAccountsInCookieUpdated(
const signin::AccountsInCookieJarInfo& accounts_in_cookie_jar_info, const signin::AccountsInCookieJarInfo& accounts_in_cookie_jar_info,
const GoogleServiceAuthError& error) { const GoogleServiceAuthError& error) {
AddChromeConnectedCookies(); AddChromeConnectedCookies();
// If signed-in accounts have been recently restored through GAIA cookie
// restoration then run the relevant callback to finish the update process.
if (accounts_in_cookie_jar_info.signed_in_accounts.size() > 0 &&
!gaia_cookies_restored_callbacks_.empty()) {
std::vector<base::OnceClosure> callbacks;
std::swap(gaia_cookies_restored_callbacks_, callbacks);
for (base::OnceClosure& callback : callbacks) {
std::move(callback).Run();
}
}
} }
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