Commit 3b7d3215 authored by Roman Sorokin's avatar Roman Sorokin Committed by Commit Bot

Chrome OS: Wait for oauth_code to appear in cookie jar.

If oauth_code is missing from the cookie jar - wait for it and then
continue authentication.

Also not handle missing oauth_code anymore
Also ignore web callbacks after authentication completed

Bug: 1021297, b/146424936
Change-Id: I1f046124477aef996ff4b87fcb377328104cb866
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1972837
Commit-Queue: Roman Sorokin [CET] <rsorokin@chromium.org>
Reviewed-by: default avatarXiyuan Xia <xiyuan@chromium.org>
Cr-Commit-Position: refs/heads/master@{#727161}
parent b979657f
......@@ -242,6 +242,7 @@ cr.define('cr.login', function() {
this.reloadUrl_ = null;
this.trusted_ = true;
this.readyFired_ = false;
this.authCompletedFired_ = false;
this.webview_ = typeof webview == 'string' ? $(webview) : webview;
assert(this.webview_);
this.enableGaiaActionButtons_ = false;
......@@ -466,6 +467,7 @@ cr.define('cr.login', function() {
load(authMode, data) {
this.authMode = authMode;
this.resetStates();
this.authCompletedFired_ = false;
// gaiaUrl parameter is used for testing. Once defined, it is never
// changed.
this.idpOrigin_ = data.gaiaUrl || IDP_ORIGIN;
......@@ -512,6 +514,7 @@ cr.define('cr.login', function() {
*/
reload() {
this.resetStates();
this.authCompletedFired_ = false;
this.webview_.src = this.reloadUrl_;
this.isLoaded_ = true;
}
......@@ -710,6 +713,13 @@ cr.define('cr.login', function() {
* @private
*/
onHeadersReceived_(details) {
if (this.authCompletedFired_) {
// SIGN_IN_HEADER could be sent more thane once. Sometimes already
// after authentication completed. Return here to avoid triggering
// maybeCompleteAuth which shows "create your password screen" because
// scraped passwords are wiped at that point.
return;
}
const currentUrl = details.url;
if (currentUrl.lastIndexOf(this.idpOrigin_, 0) != 0) {
return;
......@@ -774,6 +784,9 @@ cr.define('cr.login', function() {
const msg = e.data;
if (msg.method in messageHandlers) {
if (this.authCompletedFired_) {
console.error(msg.method + ' message sent after auth completed');
}
messageHandlers[msg.method].call(this, msg);
} else if (!IGNORED_MESSAGES_FROM_GAIA.includes(msg.method)) {
console.warn('Unrecognized message from GAIA: ' + msg.method);
......@@ -818,6 +831,9 @@ cr.define('cr.login', function() {
* @private
*/
maybeCompleteAuth_() {
if (this.authCompletedFired_) {
return;
}
const missingGaiaInfo =
!this.email_ || !this.gaiaId_ || !this.sessionIndex_;
if (missingGaiaInfo && !this.skipForNow_) {
......@@ -1010,6 +1026,7 @@ cr.define('cr.login', function() {
}
}));
this.resetStates();
this.authCompletedFired_ = true;
}
/**
......
......@@ -749,6 +749,10 @@ void GaiaScreenHandler::OnPortalDetectionCompleted(
LoadAuthExtension(true /* force */, false /* offline */);
}
void GaiaScreenHandler::OnCookieChange(const net::CookieChangeInfo& change) {
ContinueAuthenticationWhenCookiesAvailable();
}
void GaiaScreenHandler::HandleIdentifierEntered(const std::string& user_email) {
if (LoginDisplayHost::default_host() &&
!LoginDisplayHost::default_host()->IsUserWhitelisted(
......@@ -886,6 +890,28 @@ void GaiaScreenHandler::HandleCompleteAuthentication(
if (!LoginDisplayHost::default_host())
return;
DCHECK(!email.empty());
DCHECK(!gaia_id.empty());
const std::string sanitized_email = gaia::SanitizeEmail(email);
LoginDisplayHost::default_host()->SetDisplayEmail(sanitized_email);
pending_user_context_ = std::make_unique<UserContext>();
std::string error_message;
if (!BuildUserContextForGaiaSignIn(
GetUsertypeFromServicesString(services),
GetAccountId(email, gaia_id, AccountType::GOOGLE), using_saml,
password, SamlPasswordAttributes::FromJs(*password_attributes),
pending_user_context_.get(), &error_message)) {
core_oobe_view_->ShowSignInError(0, error_message, std::string(),
HelpAppLauncher::HELP_CANT_ACCESS_ACCOUNT);
pending_user_context_.reset();
return;
}
ContinueAuthenticationWhenCookiesAvailable();
}
void GaiaScreenHandler::ContinueAuthenticationWhenCookiesAvailable() {
// When the network service is enabled, the webRequest API doesn't expose
// cookie headers. So manually fetch the cookies for the GAIA URL from the
// CookieManager.
......@@ -897,23 +923,24 @@ void GaiaScreenHandler::HandleCompleteAuthentication(
if (!partition)
return;
network::mojom::CookieManager* cookie_manager =
partition->GetCookieManagerForBrowserProcess();
if (!oauth_code_listener_.is_bound()) {
// Set listener before requesting the cookies to avoid race conditions.
cookie_manager->AddCookieChangeListener(
GaiaUrls::GetInstance()->gaia_url(), kOAUTHCodeCookie,
oauth_code_listener_.BindNewPipeAndPassRemote());
}
const net::CookieOptions cookie_options =
net::CookieOptions::MakeAllInclusive();
partition->GetCookieManagerForBrowserProcess()->GetCookieList(
cookie_manager->GetCookieList(
GaiaUrls::GetInstance()->gaia_url(), cookie_options,
base::BindOnce(&GaiaScreenHandler::OnGetCookiesForCompleteAuthentication,
weak_factory_.GetWeakPtr(), gaia_id, email, password,
using_saml, services,
SamlPasswordAttributes::FromJs(*password_attributes)));
weak_factory_.GetWeakPtr()));
}
void GaiaScreenHandler::OnGetCookiesForCompleteAuthentication(
const std::string& gaia_id,
const std::string& email,
const std::string& password,
bool using_saml,
const ::login::StringList& services,
const SamlPasswordAttributes& password_attributes,
const net::CookieStatusList& cookies,
const net::CookieStatusList& excluded_cookies) {
std::string auth_code, gaps_cookie;
......@@ -926,26 +953,18 @@ void GaiaScreenHandler::OnGetCookiesForCompleteAuthentication(
}
if (auth_code.empty()) {
DoCompleteLogin(gaia_id, email, password, using_saml, password_attributes);
// Will try again from onCookieChange.
return;
}
DCHECK(!email.empty());
DCHECK(!gaia_id.empty());
const std::string sanitized_email = gaia::SanitizeEmail(email);
LoginDisplayHost::default_host()->SetDisplayEmail(sanitized_email);
DCHECK(pending_user_context_);
UserContext user_context = *pending_user_context_;
pending_user_context_.reset();
oauth_code_listener_.reset();
UserContext user_context;
std::string error_message;
if (!BuildUserContextForGaiaSignIn(
GetUsertypeFromServicesString(services),
GetAccountId(email, gaia_id, AccountType::GOOGLE), using_saml,
password, auth_code, gaps_cookie, password_attributes, &user_context,
&error_message)) {
core_oobe_view_->ShowSignInError(0, error_message, std::string(),
HelpAppLauncher::HELP_CANT_ACCESS_ACCOUNT);
return;
}
user_context.SetAuthCode(auth_code);
if (!gaps_cookie.empty())
user_context.SetGAPSCookie(gaps_cookie);
LoginDisplayHost::default_host()->CompleteLogin(user_context);
}
......@@ -1130,9 +1149,7 @@ void GaiaScreenHandler::DoCompleteLogin(
if (!BuildUserContextForGaiaSignIn(
user ? user->GetType() : CalculateUserType(account_id),
GetAccountId(typed_email, gaia_id, AccountType::GOOGLE), using_saml,
password, std::string() /* auth_code */,
std::string() /* gaps_cookie */, password_attributes, &user_context,
&error_message)) {
password, password_attributes, &user_context, &error_message)) {
core_oobe_view_->ShowSignInError(0, error_message, std::string(),
HelpAppLauncher::HELP_CANT_ACCESS_ACCOUNT);
return;
......@@ -1505,8 +1522,6 @@ bool GaiaScreenHandler::BuildUserContextForGaiaSignIn(
const AccountId& account_id,
bool using_saml,
const std::string& password,
const std::string& auth_code,
const std::string& gaps_cookie,
const SamlPasswordAttributes& password_attributes,
UserContext* user_context,
std::string* error_message) {
......@@ -1536,15 +1551,11 @@ bool GaiaScreenHandler::BuildUserContextForGaiaSignIn(
user_context->SetKey(key);
user_context->SetPasswordKey(Key(password));
}
if (!auth_code.empty())
user_context->SetAuthCode(auth_code);
user_context->SetAuthFlow(using_saml
? UserContext::AUTH_FLOW_GAIA_WITH_SAML
: UserContext::AUTH_FLOW_GAIA_WITHOUT_SAML);
if (using_saml)
user_context->SetIsUsingSamlPrincipalsApi(using_saml_api_);
if (!gaps_cookie.empty())
user_context->SetGAPSCookie(gaps_cookie);
if (using_saml && ExtractSamlPasswordAttributesEnabled()) {
user_context->SetSamlPasswordAttributes(password_attributes);
}
......
......@@ -22,6 +22,7 @@
#include "components/user_manager/user_type.h"
#include "net/base/net_errors.h"
#include "net/cookies/canonical_cookie.h"
#include "services/network/public/mojom/cookie_manager.mojom.h"
class AccountId;
......@@ -76,6 +77,7 @@ class GaiaView {
class GaiaScreenHandler : public BaseScreenHandler,
public GaiaView,
public NetworkPortalDetector::Observer,
public network::mojom::CookieChangeListener,
public SecurityTokenPinDialogHost {
public:
using TView = GaiaView;
......@@ -189,6 +191,9 @@ class GaiaScreenHandler : public BaseScreenHandler,
const NetworkState* network,
const NetworkPortalDetector::CaptivePortalState& state) override;
// network::mojom::CookieChangeListener:
void OnCookieChange(const net::CookieChangeInfo& change) override;
// WebUI message handlers.
void HandleWebviewLoadAborted(int error_code);
void HandleCompleteAuthentication(
......@@ -198,15 +203,6 @@ class GaiaScreenHandler : public BaseScreenHandler,
bool using_saml,
const ::login::StringList& services,
const base::DictionaryValue* password_attributes);
void OnGetCookiesForCompleteAuthentication(
const std::string& gaia_id,
const std::string& email,
const std::string& password,
bool using_saml,
const ::login::StringList& services,
const SamlPasswordAttributes& password_attributes,
const net::CookieStatusList& cookies,
const net::CookieStatusList& excluded_cookies);
void HandleCompleteLogin(const std::string& gaia_id,
const std::string& typed_email,
const std::string& password,
......@@ -329,12 +325,15 @@ class GaiaScreenHandler : public BaseScreenHandler,
const AccountId& account_id,
bool using_saml,
const std::string& password,
const std::string& auth_code,
const std::string& gaps_cookie,
const SamlPasswordAttributes& password_attributes,
UserContext* user_context,
std::string* error_message);
void ContinueAuthenticationWhenCookiesAvailable();
void OnGetCookiesForCompleteAuthentication(
const net::CookieStatusList& cookies,
const net::CookieStatusList& excluded_cookies);
bool is_security_token_pin_dialog_running() const {
return !security_token_pin_dialog_closed_callback_.is_null();
}
......@@ -450,6 +449,11 @@ class GaiaScreenHandler : public BaseScreenHandler,
std::unique_ptr<SamlChallengeKeyHandler> saml_challenge_key_handler_;
std::unique_ptr<SamlChallengeKeyHandler> saml_challenge_key_handler_for_test_;
// Connection to the CookieManager that signals when the GAIA cookies change.
mojo::Receiver<network::mojom::CookieChangeListener> oauth_code_listener_{
this};
std::unique_ptr<UserContext> pending_user_context_;
base::WeakPtrFactory<GaiaScreenHandler> weak_factory_{this};
DISALLOW_COPY_AND_ASSIGN(GaiaScreenHandler);
......
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