summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authornkostylev <nkostylev@chromium.org>2014-10-24 07:36:01 -0700
committerCommit bot <commit-bot@chromium.org>2014-10-24 14:36:23 +0000
commit07398a38454635dcbebac7898cbaa91969741e60 (patch)
tree9352d97d49a3baf0fe1110af3199414b224f62c0
parentbae68443fb41cf6796942f6e037a6ad6afd1b687 (diff)
downloadchromium_src-07398a38454635dcbebac7898cbaa91969741e60.zip
chromium_src-07398a38454635dcbebac7898cbaa91969741e60.tar.gz
chromium_src-07398a38454635dcbebac7898cbaa91969741e60.tar.bz2
Revert of Revert of Inline sign in extracts gaia id from HTTP header and seeds account tracker (patchset #1 id:1 of https://codereview.chromium.org/671183002/)
Reason for revert: White success page and no way to proceed only reproduces for use_athena=1 builds. This CL fixes that: https://codereview.chromium.org/642693003/ Re-landing. Original issue's description: > Revert of Inline sign in extracts gaia id from HTTP header and seeds account tracker (patchset #46 id:1740001 of https://codereview.chromium.org/473153002/) > > Reason for revert: > This breaks Chrome OS GAIA login. > > After successful GAIA authentication uses sees blank white page and nothing happens. > > Please build chromeos=1 build and check that sign in as new user works fine before relanding this CL. Unfortunately autotests rely on fake gaia server and doesn't check this end-to-end sign in flow. > > Original issue's description: > > Inline login handler extracts gaia id from HTTP header and seeds account tracker > > service during sign in. > > > > BUG=341408 > > > > Committed: https://crrev.com/a8e7c94b1b79a0948d05a1fcfff53391d22ce37a > > Cr-Commit-Position: refs/heads/master@{#300750} > > TBR=guohui@chromium.org,bartfab@chromium.org,xiyuan@chromium.org,achuith@chromium.org,davemoore@chromium.org,rogerta@chromium.org > NOTREECHECKS=true > NOTRY=true > BUG=341408 > > Committed: https://crrev.com/bbaf207927765f4b7c7cae2a4af8db6c4c4a67ce > Cr-Commit-Position: refs/heads/master@{#300873} TBR=guohui@chromium.org,bartfab@chromium.org,xiyuan@chromium.org,achuith@chromium.org,davemoore@chromium.org,rogerta@chromium.org NOTREECHECKS=true NOTRY=true BUG=341408 Review URL: https://codereview.chromium.org/677703002 Cr-Commit-Position: refs/heads/master@{#301099}
-rw-r--r--chrome/app/chromeos_strings.grdp4
-rw-r--r--chrome/browser/chromeos/login/saml/saml_browsertest.cc2
-rw-r--r--chrome/browser/chromeos/login/session/user_session_manager.cc13
-rw-r--r--chrome/browser/chromeos/login/signin/oauth2_login_manager.cc52
-rw-r--r--chrome/browser/chromeos/login/signin/oauth2_login_manager.h18
-rw-r--r--chrome/browser/chromeos/login/signin/oauth2_login_manager_factory.cc2
-rw-r--r--chrome/browser/resources/chromeos/login/login_common.js2
-rw-r--r--chrome/browser/resources/chromeos/login/oobe_screen_oauth_enrollment.js37
-rw-r--r--chrome/browser/resources/chromeos/login/screen_gaia_signin.js68
-rw-r--r--chrome/browser/resources/component_extension_resources.grd1
-rw-r--r--chrome/browser/resources/gaia_auth/background.js16
-rw-r--r--chrome/browser/resources/gaia_auth/main.js91
-rw-r--r--chrome/browser/resources/gaia_auth/success.html2
-rw-r--r--chrome/browser/resources/gaia_auth/success.js16
-rw-r--r--chrome/browser/resources/gaia_auth_host/gaia_auth_host.js95
-rw-r--r--chrome/browser/ui/webui/chromeos/login/enrollment_screen_handler.cc13
-rw-r--r--chrome/browser/ui/webui/chromeos/login/enrollment_screen_handler.h5
-rw-r--r--chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.cc25
-rw-r--r--chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.h12
-rw-r--r--chrome/browser/ui/webui/chromeos/login/inline_login_handler_chromeos.cc20
-rw-r--r--chrome/browser/ui/webui/chromeos/login/signin_screen_handler.cc16
-rw-r--r--chrome/browser/ui/webui/chromeos/login/signin_screen_handler.h5
-rw-r--r--chrome/browser/ui/webui/signin/inline_login_handler_impl.cc62
-rw-r--r--chromeos/login/auth/user_context.cc10
-rw-r--r--chromeos/login/auth/user_context.h3
-rw-r--r--components/signin/core/browser/account_tracker_service.cc40
-rw-r--r--components/signin/core/browser/account_tracker_service.h12
-rw-r--r--components/signin/core/browser/account_tracker_service_unittest.cc22
-rw-r--r--google_apis/gaia/fake_gaia.cc45
-rw-r--r--google_apis/gaia/fake_gaia.h13
-rw-r--r--tools/telemetry/telemetry/core/backends/chrome/chromeos_login_ext/main.js1
31 files changed, 422 insertions, 301 deletions
diff --git a/chrome/app/chromeos_strings.grdp b/chrome/app/chromeos_strings.grdp
index 19ee467..3f938a3 100644
--- a/chrome/app/chromeos_strings.grdp
+++ b/chrome/app/chromeos_strings.grdp
@@ -1436,8 +1436,8 @@ Press any key to continue exploring.
<message name="IDS_LOGIN_CONFIRM_PASSWORD_ERROR_TEXT" desc="Error text to show when the password typed by the user could not be verified.">
Sorry, your password could not be verified. Please try again.
</message>
- <message name="IDS_LOGIN_FATAL_ERROR_NO_EMAIL" desc="Message to show when the authentication could not be completed because the user's e-mail address could not be retrieved.">
- Oops, couldn't sign you in. Sign-in failed because your e-mail address could not be retrieved.
+ <message name="IDS_LOGIN_FATAL_ERROR_NO_ACCOUNT_DETAILS" desc="Message to show when the authentication could not be completed because the user's account details could not be retrieved.">
+ Oops, couldn't sign you in. Sign-in failed because your account details could not be retrieved.
</message>
<message name="IDS_LOGIN_FATAL_ERROR_NO_PASSWORD" desc="Message to show when the authentication could not be completed because the user's password could not be retrieved.">
Something went wrong with signing in.
diff --git a/chrome/browser/chromeos/login/saml/saml_browsertest.cc b/chrome/browser/chromeos/login/saml/saml_browsertest.cc
index a0e34ba..44e8402 100644
--- a/chrome/browser/chromeos/login/saml/saml_browsertest.cc
+++ b/chrome/browser/chromeos/login/saml/saml_browsertest.cc
@@ -575,7 +575,7 @@ IN_PROC_BROWSER_TEST_F(SamlTest, FailToRetrieveAutenticatedUserEmailAddress) {
SetSignFormField("Password", "fake_password");
ExecuteJsInSigninFrame("document.getElementById('Submit').click();");
- EXPECT_EQ(l10n_util::GetStringUTF8(IDS_LOGIN_FATAL_ERROR_NO_EMAIL),
+ EXPECT_EQ(l10n_util::GetStringUTF8(IDS_LOGIN_FATAL_ERROR_NO_ACCOUNT_DETAILS),
WaitForAndGetFatalErrorMessage());
}
diff --git a/chrome/browser/chromeos/login/session/user_session_manager.cc b/chrome/browser/chromeos/login/session/user_session_manager.cc
index 123b80a..374cf3f 100644
--- a/chrome/browser/chromeos/login/session/user_session_manager.cc
+++ b/chrome/browser/chromeos/login/session/user_session_manager.cc
@@ -56,6 +56,7 @@
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/browser/rlz/rlz.h"
+#include "chrome/browser/signin/account_tracker_service_factory.h"
#include "chrome/browser/signin/easy_unlock_service.h"
#include "chrome/browser/signin/signin_manager_factory.h"
#include "chrome/common/chrome_switches.h"
@@ -75,6 +76,7 @@
#include "components/component_updater/component_updater_service.h"
#include "components/policy/core/common/cloud/cloud_policy_constants.h"
#include "components/session_manager/core/session_manager.h"
+#include "components/signin/core/browser/account_tracker_service.h"
#include "components/signin/core/browser/signin_manager_base.h"
#include "components/user_manager/user.h"
#include "components/user_manager/user_manager.h"
@@ -745,6 +747,17 @@ void UserSessionManager::InitProfilePreferences(
profile->GetPrefs()->SetString(prefs::kSupervisedUserId,
supervised_user_sync_id);
} else if (user_manager::UserManager::Get()->IsLoggedInAsRegularUser()) {
+ // Prime the account tracker with this combination of gaia id/display email.
+ // Don't do this unless both email and gaia_id are valid. They may not
+ // be when simply unlocking the profile.
+ if (!user_context.GetGaiaID().empty() &&
+ !user_context.GetUserID().empty()) {
+ AccountTrackerService* account_tracker =
+ AccountTrackerServiceFactory::GetForProfile(profile);
+ account_tracker->SeedAccountInfo(user_context.GetGaiaID(),
+ user_context.GetUserID());
+ }
+
// Make sure that the google service username is properly set (we do this
// on every sign in, not just the first login, to deal with existing
// profiles that might not have it set yet).
diff --git a/chrome/browser/chromeos/login/signin/oauth2_login_manager.cc b/chrome/browser/chromeos/login/signin/oauth2_login_manager.cc
index 97bff3b..8128dda 100644
--- a/chrome/browser/chromeos/login/signin/oauth2_login_manager.cc
+++ b/chrome/browser/chromeos/login/signin/oauth2_login_manager.cc
@@ -13,11 +13,13 @@
#include "base/strings/string_util.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/signin/account_tracker_service_factory.h"
#include "chrome/browser/signin/chrome_signin_client_factory.h"
#include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
#include "chrome/browser/signin/signin_manager_factory.h"
#include "chrome/common/chrome_switches.h"
#include "chromeos/chromeos_switches.h"
+#include "components/signin/core/browser/account_tracker_service.h"
#include "components/signin/core/browser/profile_oauth2_token_service.h"
#include "components/signin/core/browser/signin_client.h"
#include "components/signin/core/browser/signin_manager.h"
@@ -166,53 +168,67 @@ const std::string& OAuth2LoginManager::GetPrimaryAccountId() {
void OAuth2LoginManager::StoreOAuth2Token() {
const std::string& primary_account_id = GetPrimaryAccountId();
if (primary_account_id.empty()) {
- GetAccountIdOfRefreshToken(refresh_token_);
+ GetAccountInfoOfRefreshToken(refresh_token_);
return;
}
- OnGetUserEmailResponse(primary_account_id);
+ UpdateCredentials(primary_account_id);
}
-void OAuth2LoginManager::GetAccountIdOfRefreshToken(
+void OAuth2LoginManager::GetAccountInfoOfRefreshToken(
const std::string& refresh_token) {
gaia::OAuthClientInfo client_info;
GaiaUrls* gaia_urls = GaiaUrls::GetInstance();
client_info.client_id = gaia_urls->oauth2_chrome_client_id();
client_info.client_secret = gaia_urls->oauth2_chrome_client_secret();
- account_id_fetcher_.reset(new gaia::GaiaOAuthClient(
+ account_info_fetcher_.reset(new gaia::GaiaOAuthClient(
auth_request_context_.get()));
- account_id_fetcher_->RefreshToken(client_info, refresh_token,
+ account_info_fetcher_->RefreshToken(client_info, refresh_token,
std::vector<std::string>(1, kServiceScopeGetUserInfo), kMaxRetries,
this);
}
+void OAuth2LoginManager::UpdateCredentials(const std::string& account_id) {
+ DCHECK(!account_id.empty());
+ DCHECK(!refresh_token_.empty());
+ // |account_id| is assumed to be already canonicalized if it's an email.
+ GetTokenService()->UpdateCredentials(account_id, refresh_token_);
+
+ FOR_EACH_OBSERVER(Observer, observer_list_,
+ OnNewRefreshTokenAvaiable(user_profile_));
+}
+
void OAuth2LoginManager::OnRefreshTokenResponse(
const std::string& access_token,
int expires_in_seconds) {
- account_id_fetcher_->GetUserEmail(access_token, kMaxRetries, this);
+ account_info_fetcher_->GetUserInfo(access_token, kMaxRetries, this);
}
-void OAuth2LoginManager::OnGetUserEmailResponse(
- const std::string& user_email) {
- DCHECK(!refresh_token_.empty());
- account_id_fetcher_.reset();
- std::string canonicalized = gaia::CanonicalizeEmail(user_email);
- GetTokenService()->UpdateCredentials(canonicalized, refresh_token_);
+void OAuth2LoginManager::OnGetUserInfoResponse(
+ scoped_ptr<base::DictionaryValue> user_info) {
+ account_info_fetcher_.reset();
- FOR_EACH_OBSERVER(Observer, observer_list_,
- OnNewRefreshTokenAvaiable(user_profile_));
+ std::string gaia_id;
+ std::string email;
+ user_info->GetString("id", &gaia_id);
+ user_info->GetString("email", &email);
+
+ AccountTrackerService* account_tracker =
+ AccountTrackerServiceFactory::GetForProfile(user_profile_);
+ account_tracker->SeedAccountInfo(gaia_id, email);
+ UpdateCredentials(account_tracker->PickAccountIdForAccount(gaia_id, email));
}
void OAuth2LoginManager::OnOAuthError() {
- account_id_fetcher_.reset();
- LOG(ERROR) << "Account id fetch failed!";
+ account_info_fetcher_.reset();
+ LOG(ERROR) << "Account info fetch failed!";
SetSessionRestoreState(OAuth2LoginManager::SESSION_RESTORE_FAILED);
}
void OAuth2LoginManager::OnNetworkError(int response_code) {
- account_id_fetcher_.reset();
- LOG(ERROR) << "Account id fetch failed! response_code=" << response_code;
+ account_info_fetcher_.reset();
+ LOG(ERROR) << "Account info fetch failed! response_code=" << response_code;
SetSessionRestoreState(OAuth2LoginManager::SESSION_RESTORE_FAILED);
}
diff --git a/chrome/browser/chromeos/login/signin/oauth2_login_manager.h b/chrome/browser/chromeos/login/signin/oauth2_login_manager.h
index 9543f5d..ab9ccdf 100644
--- a/chrome/browser/chromeos/login/signin/oauth2_login_manager.h
+++ b/chrome/browser/chromeos/login/signin/oauth2_login_manager.h
@@ -149,8 +149,9 @@ class OAuth2LoginManager : public KeyedService,
// gaia::GaiaOAuthClient::Delegate overrides.
void OnRefreshTokenResponse(const std::string& access_token,
- int expires_in_seconds) override;
- void OnGetUserEmailResponse(const std::string& user_email) override;
+ int expires_in_seconds) override;
+ void OnGetUserInfoResponse(
+ scoped_ptr<base::DictionaryValue> user_info) override;
void OnOAuthError() override;
void OnNetworkError(int response_code) override;
@@ -180,12 +181,15 @@ class OAuth2LoginManager : public KeyedService,
// Records |refresh_token_| to token service. The associated account id is
// assumed to be the primary account id of the user profile. If the primary
- // account id is not present, GetAccountIdOfRefreshToken will be called to
- // retrieve the associated account id.
+ // account id is not present, GetAccountInfoOfRefreshToken will be called to
+ // retrieve the associated account info.
void StoreOAuth2Token();
- // Get the account id corresponding to the specified refresh token.
- void GetAccountIdOfRefreshToken(const std::string& refresh_token);
+ // Get the account info corresponding to the specified refresh token.
+ void GetAccountInfoOfRefreshToken(const std::string& refresh_token);
+
+ // Update the token service and inform listeners of a new refresh token.
+ void UpdateCredentials(const std::string& account_id);
// Attempts to fetch OAuth2 tokens by using pre-authenticated cookie jar from
// provided |auth_profile|.
@@ -230,7 +234,7 @@ class OAuth2LoginManager : public KeyedService,
scoped_ptr<OAuth2TokenFetcher> oauth2_token_fetcher_;
scoped_ptr<OAuth2LoginVerifier> login_verifier_;
- scoped_ptr<gaia::GaiaOAuthClient> account_id_fetcher_;
+ scoped_ptr<gaia::GaiaOAuthClient> account_info_fetcher_;
// OAuth2 refresh token.
std::string refresh_token_;
diff --git a/chrome/browser/chromeos/login/signin/oauth2_login_manager_factory.cc b/chrome/browser/chromeos/login/signin/oauth2_login_manager_factory.cc
index 1d429a0..da71de9 100644
--- a/chrome/browser/chromeos/login/signin/oauth2_login_manager_factory.cc
+++ b/chrome/browser/chromeos/login/signin/oauth2_login_manager_factory.cc
@@ -6,6 +6,7 @@
#include "chrome/browser/chromeos/login/signin/oauth2_login_manager.h"
#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/signin/account_tracker_service_factory.h"
#include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
#include "chrome/browser/signin/signin_manager_factory.h"
#include "chrome/browser/ui/global_error/global_error_service_factory.h"
@@ -17,6 +18,7 @@ OAuth2LoginManagerFactory::OAuth2LoginManagerFactory()
: BrowserContextKeyedServiceFactory(
"OAuth2LoginManager",
BrowserContextDependencyManager::GetInstance()) {
+ DependsOn(AccountTrackerServiceFactory::GetInstance());
DependsOn(GlobalErrorServiceFactory::GetInstance());
DependsOn(SigninManagerFactory::GetInstance());
DependsOn(ProfileOAuth2TokenServiceFactory::GetInstance());
diff --git a/chrome/browser/resources/chromeos/login/login_common.js b/chrome/browser/resources/chromeos/login/login_common.js
index 0366f8c..c25f59b 100644
--- a/chrome/browser/resources/chromeos/login/login_common.js
+++ b/chrome/browser/resources/chromeos/login/login_common.js
@@ -263,7 +263,7 @@ cr.define('cr.ui', function() {
Oobe.loginForTesting = function(username, password) {
Oobe.disableSigninUI();
chrome.send('skipToLoginForTesting', [username]);
- chrome.send('completeLogin', [username, password, false]);
+ chrome.send('completeLogin', ['12345', username, password, false]);
};
/**
diff --git a/chrome/browser/resources/chromeos/login/oobe_screen_oauth_enrollment.js b/chrome/browser/resources/chromeos/login/oobe_screen_oauth_enrollment.js
index 0947594..67e163d 100644
--- a/chrome/browser/resources/chromeos/login/oobe_screen_oauth_enrollment.js
+++ b/chrome/browser/resources/chromeos/login/oobe_screen_oauth_enrollment.js
@@ -16,7 +16,6 @@ login.createScreen('OAuthEnrollmentScreen', 'oauth-enrollment', function() {
'showStep',
'showError',
'showWorking',
- 'setAuthenticatedUserEmail',
'doReload',
],
@@ -206,24 +205,6 @@ login.createScreen('OAuthEnrollmentScreen', 'oauth-enrollment', function() {
this.showStep(STEP_WORKING);
},
- /**
- * Invoked when the authenticated user's e-mail address has been retrieved.
- * This completes SAML authentication.
- * @param {number} attemptToken An opaque token used to correlate this
- * method invocation with the corresponding request to retrieve the
- * user's e-mail address.
- * @param {string} email The authenticated user's e-mail address.
- */
- setAuthenticatedUserEmail: function(attemptToken, email) {
- if (this.attemptToken_ != attemptToken)
- return;
-
- if (!email)
- this.showError(loadTimeData.getString('fatalEnrollmentError'), false);
- else
- chrome.send('oauthEnrollCompleteLogin', [email]);
- },
-
doReload: function() {
$('oauth-enroll-signin-frame').contentWindow.location.href =
this.signInUrl_;
@@ -289,20 +270,10 @@ login.createScreen('OAuthEnrollmentScreen', 'oauth-enrollment', function() {
var msg = m.data;
if (msg.method == 'completeLogin') {
- // A user has successfully authenticated via regular GAIA.
+ // A user has successfully authenticated via regular GAIA or SAML.
chrome.send('oauthEnrollCompleteLogin', [msg.email]);
}
- if (msg.method == 'retrieveAuthenticatedUserEmail') {
- // A user has successfully authenticated via SAML. However, the user's
- // identity is not known. Instead of reporting success immediately,
- // retrieve the user's e-mail address first.
- this.attemptToken_ = msg.attemptToken;
- this.showWorking(null);
- chrome.send('oauthEnrollRetrieveAuthenticatedUserEmail',
- [msg.attemptToken]);
- }
-
if (msg.method == 'authPageLoaded' && this.currentStep_ == STEP_SIGNIN) {
if (msg.isSAML) {
$('oauth-saml-notice-message').textContent = loadTimeData.getStringF(
@@ -318,6 +289,12 @@ login.createScreen('OAuthEnrollmentScreen', 'oauth-enrollment', function() {
loadTimeData.getStringF('insecureURLEnrollmentError', msg.url),
false);
}
+
+ if (msg.method == 'missingGaiaInfo') {
+ this.showError(
+ loadTimeData.getString('fatalEnrollmentError'),
+ false);
+ }
}
};
});
diff --git a/chrome/browser/resources/chromeos/login/screen_gaia_signin.js b/chrome/browser/resources/chromeos/login/screen_gaia_signin.js
index 153663d..ff04403 100644
--- a/chrome/browser/resources/chromeos/login/screen_gaia_signin.js
+++ b/chrome/browser/resources/chromeos/login/screen_gaia_signin.js
@@ -22,7 +22,6 @@ login.createScreen('GaiaSigninScreen', 'gaia-signin', function() {
EXTERNAL_API: [
'loadAuthExtension',
'updateAuthExtension',
- 'setAuthenticatedUserEmail',
'doReload',
'onFrameError',
'updateCancelButtonState'
@@ -94,14 +93,16 @@ login.createScreen('GaiaSigninScreen', 'gaia-signin', function() {
this.gaiaAuthHost_ = new cr.login.GaiaAuthHost($('signin-frame'));
this.gaiaAuthHost_.addEventListener(
'ready', this.onAuthReady_.bind(this));
- this.gaiaAuthHost_.retrieveAuthenticatedUserEmailCallback =
- this.onRetrieveAuthenticatedUserEmail_.bind(this);
this.gaiaAuthHost_.confirmPasswordCallback =
this.onAuthConfirmPassword_.bind(this);
this.gaiaAuthHost_.noPasswordCallback =
this.onAuthNoPassword_.bind(this);
this.gaiaAuthHost_.insecureContentBlockedCallback =
this.onInsecureContentBlocked_.bind(this);
+ this.gaiaAuthHost_.missingGaiaInfoCallback =
+ this.missingGaiaInfo_.bind(this);
+ this.gaiaAuthHost_.samlApiUsedCallback =
+ this.samlApiUsed_.bind(this);
this.gaiaAuthHost_.addEventListener('authFlowChange',
this.onAuthFlowChange_.bind(this));
@@ -338,21 +339,6 @@ login.createScreen('GaiaSigninScreen', 'gaia-signin', function() {
},
/**
- * Sends the authenticated user's e-mail address to the auth extension.
- * @param {number} attemptToken The opaque token provided to
- * onRetrieveAuthenticatedUserEmail_.
- * @param {string} email The authenticated user's e-mail address.
- */
- setAuthenticatedUserEmail: function(attemptToken, email) {
- if (!email) {
- this.showFatalAuthError(
- loadTimeData.getString('fatalErrorMessageNoEmail'));
- } else {
- this.gaiaAuthHost_.setAuthenticatedUserEmail(attemptToken, email);
- }
- },
-
- /**
* Updates [Cancel] button state. Allow cancellation of screen only when
* user pods can be displayed.
*/
@@ -413,27 +399,6 @@ login.createScreen('GaiaSigninScreen', 'gaia-signin', function() {
},
/**
- * Invoked when the user has successfully authenticated via SAML and the
- * auth host needs to retrieve the user's e-mail.
- * @param {number} attemptToken Opaque token to be passed to
- * setAuthenticatedUserEmail along with the e-mail address.
- * @param {boolean} apiUsed Whether the principals API was used during
- * authentication.
- * @private
- */
- onRetrieveAuthenticatedUserEmail_: function(attemptToken, apiUsed) {
- if (apiUsed) {
- // If the principals API was used, report this to the C++ backend so
- // that statistics can be kept. If password scraping was used instead,
- // there is no need to inform the C++ backend at this point: Either
- // onAuthNoPassword_ or onAuthConfirmPassword_ will be called in a
- // moment, both of which imply to the backend that the API was not used.
- chrome.send('usingSAMLAPI');
- }
- chrome.send('retrieveAuthenticatedUserEmail', [attemptToken]);
- },
-
- /**
* Invoked when the user has successfully authenticated via SAML, the
* principals API was not used and the auth host needs the user to confirm
* the scraped password.
@@ -503,6 +468,21 @@ login.createScreen('GaiaSigninScreen', 'gaia-signin', function() {
},
/**
+ * Show fatal auth error when information is missing from GAIA.
+ */
+ missingGaiaInfo_: function() {
+ this.showFatalAuthError(
+ loadTimeData.getString('fatalErrorMessageNoAccountDetails'));
+ },
+
+ /**
+ * Record that SAML API was used during sign-in.
+ */
+ samlApiUsed_: function() {
+ chrome.send('usingSAMLAPI');
+ },
+
+ /**
* Invoked when auth is completed successfully.
* @param {!Object} credentials Credentials of the completed authentication.
* @private
@@ -511,15 +491,19 @@ login.createScreen('GaiaSigninScreen', 'gaia-signin', function() {
if (credentials.useOffline) {
this.email = credentials.email;
chrome.send('authenticateUser',
- [credentials.email, credentials.password]);
+ [credentials.gaiaId,
+ credentials.email,
+ credentials.password]);
} else if (credentials.authCode) {
chrome.send('completeAuthentication',
- [credentials.email,
+ [credentials.gaiaId,
+ credentials.email,
credentials.password,
credentials.authCode]);
} else {
chrome.send('completeLogin',
- [credentials.email,
+ [credentials.gaiaId,
+ credentials.email,
credentials.password,
credentials.usingSAML]);
}
diff --git a/chrome/browser/resources/component_extension_resources.grd b/chrome/browser/resources/component_extension_resources.grd
index 90a8491..12abe4e 100644
--- a/chrome/browser/resources/component_extension_resources.grd
+++ b/chrome/browser/resources/component_extension_resources.grd
@@ -49,7 +49,6 @@
<include name="IDR_GAIA_AUTH_OFFLINE_JS" file="gaia_auth/offline.js" type="BINDATA" />
<include name="IDR_GAIA_AUTH_OFFLINE_CSS" file="gaia_auth/offline.css" type="BINDATA" />
<include name="IDR_GAIA_AUTH_SUCCESS" file="gaia_auth/success.html" allowexternalscript="true" type="BINDATA" />
- <include name="IDR_GAIA_AUTH_SUCCESS_JS" file="gaia_auth/success.js" type="BINDATA" />
<include name="IDR_GAIA_AUTH_UTIL_JS" file="gaia_auth/util.js" type="BINDATA" />
<include name="IDR_GAIA_AUTH_BACKGROUND_JS" file="gaia_auth/background.js" type="BINDATA" />
<include name="IDR_GAIA_AUTH_SAML_INJECTED_JS" file="gaia_auth/saml_injected.js" type="BINDATA" />
diff --git a/chrome/browser/resources/gaia_auth/background.js b/chrome/browser/resources/gaia_auth/background.js
index ffe0b078..db94085 100644
--- a/chrome/browser/resources/gaia_auth/background.js
+++ b/chrome/browser/resources/gaia_auth/background.js
@@ -119,6 +119,10 @@ BackgroundBridge.prototype = {
// 'google-accounts-signin'.
email_: null,
+ // Gaia Id of the newly authenticated user based on the gaia response
+ // header 'google-accounts-signin'.
+ gaiaId_: null,
+
// Session index of the newly authenticated user based on the gaia response
// header 'google-accounts-signin'.
sessionIndex_: null,
@@ -204,7 +208,7 @@ BackgroundBridge.prototype = {
onCompleted: function(details) {
// Only monitors requests in the gaia frame whose parent frame ID must be
// positive.
- if (!this.isDesktopFlow_ || details.parentFrameId <= 0)
+ if (details.parentFrameId <= 0)
return;
if (details.url.lastIndexOf(backgroundBridgeManager.CONTINUE_URL_BASE, 0) ==
@@ -213,11 +217,12 @@ BackgroundBridge.prototype = {
if (details.url.indexOf('ntp=1') >= 0)
skipForNow = true;
- // TOOD(guohui): Show password confirmation UI.
+ // TOOD(guohui): For desktop SAML flow, show password confirmation UI.
var passwords = this.onGetScrapedPasswords_();
var msg = {
'name': 'completeLogin',
'email': this.email_,
+ 'gaiaId': this.gaiaId_,
'password': passwords[0],
'sessionIndex': this.sessionIndex_,
'skipForNow': skipForNow
@@ -262,11 +267,7 @@ BackgroundBridge.prototype = {
onHeadersReceived: function(details) {
var headers = details.responseHeaders;
- if (this.isDesktopFlow_ &&
- this.gaiaUrl_ &&
- details.url.lastIndexOf(this.gaiaUrl_) == 0) {
- // TODO(xiyuan, guohui): CrOS should reuse the logic below for reading the
- // email for SAML users and cut off the /ListAccount call.
+ if (this.gaiaUrl_ && details.url.lastIndexOf(this.gaiaUrl_) == 0) {
for (var i = 0; headers && i < headers.length; ++i) {
if (headers[i].name.toLowerCase() == 'google-accounts-signin') {
var headerValues = headers[i].value.toLowerCase().split(',');
@@ -277,6 +278,7 @@ BackgroundBridge.prototype = {
});
// Remove "" around.
this.email_ = signinDetails['email'].slice(1, -1);
+ this.gaiaId_ = signinDetails['obfuscatedid'].slice(1, -1);
this.sessionIndex_ = signinDetails['sessionindex'];
break;
}
diff --git a/chrome/browser/resources/gaia_auth/main.js b/chrome/browser/resources/gaia_auth/main.js
index ba48c65..b9a57d8 100644
--- a/chrome/browser/resources/gaia_auth/main.js
+++ b/chrome/browser/resources/gaia_auth/main.js
@@ -48,6 +48,7 @@ Authenticator.getInstance = function() {
Authenticator.prototype = {
email_: null,
+ gaiaId_: null,
// Depending on the key type chosen, this will contain the plain text password
// or a credential derived from it along with the information required to
@@ -56,6 +57,9 @@ Authenticator.prototype = {
// when support for key types other than plain text password is added.
passwordBytes_: null,
+ chooseWhatToSync_: false,
+ skipForNow_: false,
+ sessionIndex_: null,
attemptToken_: null,
// Input params from extension initialization URL.
@@ -104,10 +108,6 @@ Authenticator.prototype = {
this.GAIA_URL.indexOf(msg.origin) == 0;
},
- isInternalMessage_: function(msg) {
- return msg.origin == Authenticator.THIS_EXTENSION_ORIGIN;
- },
-
isParentMessage_: function(msg) {
return msg.origin == this.parentPage_;
},
@@ -165,9 +165,9 @@ Authenticator.prototype = {
});
this.supportChannel_.registerMessage(
'switchToFullTab', this.switchToFullTab_.bind(this));
- this.supportChannel_.registerMessage(
- 'completeLogin', this.completeLogin_.bind(this));
}
+ this.supportChannel_.registerMessage(
+ 'completeLogin', this.onCompleteLogin_.bind(this));
this.initSAML_();
this.maybeInitialized_();
}.bind(this));
@@ -198,7 +198,7 @@ Authenticator.prototype = {
/**
* Invoked when the background script sends a message to indicate that the
* current content does not fit in a constrained window.
- * @param {Object=} opt_extraMsg Optional extra info to send.
+ * @param {Object=} msg Extra info to send.
*/
switchToFullTab_: function(msg) {
var parentMsg = {
@@ -220,8 +220,11 @@ Authenticator.prototype = {
this.passwordBytes_,
'usingSAML': this.isSAMLFlow_,
'chooseWhatToSync': this.chooseWhatToSync_ || false,
- 'skipForNow': opt_extraMsg && opt_extraMsg.skipForNow,
- 'sessionIndex': opt_extraMsg && opt_extraMsg.sessionIndex
+ 'skipForNow': (opt_extraMsg && opt_extraMsg.skipForNow) ||
+ this.skipForNow_,
+ 'sessionIndex': (opt_extraMsg && opt_extraMsg.sessionIndex) ||
+ this.sessionIndex_,
+ 'gaiaId': (opt_extraMsg && opt_extraMsg.gaiaId) || this.gaiaId_
};
window.parent.postMessage(msg, this.parentPage_);
this.supportChannel_.send({name: 'resetAuth'});
@@ -268,6 +271,7 @@ Authenticator.prototype = {
// from the GAIA login form are no longer relevant and can be discarded.
this.isSAMLFlow_ = true;
this.email_ = null;
+ this.gaiaId_ = null;
this.passwordBytes_ = null;
}
@@ -316,8 +320,9 @@ Authenticator.prototype = {
console.error('Authenticator.onAPICall_: unsupported key type');
return;
}
+ // Not setting |email_| and |gaiaId_| because this API call will
+ // eventually be followed by onCompleteLogin_() which does set it.
this.apiToken_ = call.token;
- this.email_ = call.user;
this.passwordBytes_ = call.passwordBytes;
} else if (call.method == 'confirm') {
if (call.token != this.apiToken_)
@@ -342,21 +347,34 @@ Authenticator.prototype = {
});
},
- onConfirmLogin_: function() {
- if (!this.isSAMLFlow_) {
- this.completeLogin_();
+ /**
+ * Callback invoked for 'completeLogin' message.
+ * @param {Object=} msg Message sent from background page.
+ */
+ onCompleteLogin_: function(msg) {
+ if (!msg.email || !msg.gaiaId || !msg.sessionIndex) {
+ console.error('Missing fields to complete login.');
+ window.parent.postMessage({method: 'missingGaiaInfo'}, this.parentPage_);
return;
}
- var apiUsed = !!this.passwordBytes_;
+ // Skip SAML extra steps for desktop flow and non-SAML flow.
+ if (!this.isSAMLFlow_ || this.desktopMode_) {
+ this.completeLogin_(msg);
+ return;
+ }
- // Retrieve the e-mail address of the user who just authenticated from GAIA.
- window.parent.postMessage({method: 'retrieveAuthenticatedUserEmail',
- attemptToken: this.attemptToken_,
- apiUsed: apiUsed},
- this.parentPage_);
+ this.email_ = msg.email;
+ this.gaiaId_ = msg.gaiaId;
+ // Password from |msg| is not used because ChromeOS SAML flow
+ // gets password by asking user to confirm.
+ this.skipForNow_ = msg.skipForNow;
+ this.sessionIndex_ = msg.sessionIndex;
- if (!apiUsed) {
+ if (this.passwordBytes_) {
+ window.parent.postMessage({method: 'samlApiUsed'}, this.parentPage_);
+ this.completeLogin_(msg);
+ } else {
this.supportChannel_.sendWithCallback(
{name: 'getScrapedPasswords'},
function(passwords) {
@@ -374,13 +392,6 @@ Authenticator.prototype = {
}
},
- maybeCompleteSAMLLogin_: function() {
- // SAML login is complete when the user's e-mail address has been retrieved
- // from GAIA and the user has successfully confirmed the password.
- if (this.email_ !== null && this.passwordBytes_ !== null)
- this.completeLogin_();
- },
-
onVerifyConfirmedPassword_: function(password) {
this.supportChannel_.sendWithCallback(
{name: 'getScrapedPasswords'},
@@ -388,7 +399,10 @@ Authenticator.prototype = {
for (var i = 0; i < passwords.length; ++i) {
if (passwords[i] == password) {
this.passwordBytes_ = passwords[i];
- this.maybeCompleteSAMLLogin_();
+ // SAML login is complete when the user has successfully
+ // confirmed the password.
+ if (this.passwordBytes_ !== null)
+ this.completeLogin_();
return;
}
}
@@ -401,6 +415,7 @@ Authenticator.prototype = {
onMessage: function(e) {
var msg = e.data;
if (msg.method == 'attemptLogin' && this.isGaiaMessage_(e)) {
+ // At this point GAIA does not yet know the gaiaId, so its not set here.
this.email_ = msg.email;
this.passwordBytes_ = msg.password;
this.attemptToken_ = msg.attemptToken;
@@ -416,27 +431,15 @@ Authenticator.prototype = {
this.maybeInitialized_();
}
this.email_ = null;
+ this.gaiaId_ = null;
+ this.sessionIndex_ = false;
this.passwordBytes_ = null;
this.attemptToken_ = null;
this.isSAMLFlow_ = false;
+ this.skipForNow_ = false;
+ this.chooseWhatToSync_ = false;
if (this.supportChannel_)
this.supportChannel_.send({name: 'resetAuth'});
- } else if (msg.method == 'setAuthenticatedUserEmail' &&
- this.isParentMessage_(e)) {
- if (this.attemptToken_ == msg.attemptToken) {
- this.email_ = msg.email;
- this.maybeCompleteSAMLLogin_();
- }
- } else if (msg.method == 'confirmLogin' && this.isInternalMessage_(e)) {
- // In the desktop mode, Chrome needs to wait for extra info such as
- // session index from the background JS.
- if (this.desktopMode_)
- return;
-
- if (this.attemptToken_ == msg.attemptToken)
- this.onConfirmLogin_();
- else
- console.error('Authenticator.onMessage: unexpected attemptToken!?');
} else if (msg.method == 'verifyConfirmedPassword' &&
this.isParentMessage_(e)) {
this.onVerifyConfirmedPassword_(msg.password);
diff --git a/chrome/browser/resources/gaia_auth/success.html b/chrome/browser/resources/gaia_auth/success.html
index d9c5712..fa5b1e6 100644
--- a/chrome/browser/resources/gaia_auth/success.html
+++ b/chrome/browser/resources/gaia_auth/success.html
@@ -1,8 +1,6 @@
<!DOCTYPE html>
<head>
<meta charset="utf-8">
-<script src="util.js"></script>
-<script src="success.js"></script>
</head>
<html>
<body></body>
diff --git a/chrome/browser/resources/gaia_auth/success.js b/chrome/browser/resources/gaia_auth/success.js
deleted file mode 100644
index 54ed7fa..0000000
--- a/chrome/browser/resources/gaia_auth/success.js
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-function load() {
- var params = getUrlSearchParams(location.search);
- var msg = {
- 'method': 'confirmLogin',
- 'attemptToken': params['attemptToken']
- };
- window.parent.postMessage(msg,
- 'chrome-extension://mfffpogegjflfpflabcdkioaeobkgjik/main.html');
-}
-
-document.addEventListener('DOMContentLoaded', load);
-
diff --git a/chrome/browser/resources/gaia_auth_host/gaia_auth_host.js b/chrome/browser/resources/gaia_auth_host/gaia_auth_host.js
index e835e20..cf870cb 100644
--- a/chrome/browser/resources/gaia_auth_host/gaia_auth_host.js
+++ b/chrome/browser/resources/gaia_auth_host/gaia_auth_host.js
@@ -141,18 +141,6 @@ cr.define('cr.login', function() {
successCallback_: null,
/**
- * Invoked when GAIA indicates login success and SAML was used. At this
- * point, GAIA cookies are present but the identity of the authenticated
- * user is not known. The embedder of GaiaAuthHost should extract the GAIA
- * cookies from the cookie jar, query GAIA for the authenticated user's
- * e-mail address and invoke GaiaAuthHost.setAuthenticatedUserEmail with the
- * result. The argument is an opaque token that should be passed back to
- * GaiaAuthHost.setAuthenticatedUserEmail.
- * @type {function(number)}
- */
- retrieveAuthenticatedUserEmailCallback_: null,
-
- /**
* Invoked when the auth flow needs a user to confirm his/her passwords.
* This could happen when there are more than one passwords scraped during
* SAML flow. The embedder of GaiaAuthHost should show an UI to collect a
@@ -175,22 +163,28 @@ cr.define('cr.login', function() {
/**
* Invoked when the authentication flow had to be aborted because content
* served over an unencrypted connection was detected.
+ */
insecureContentBlockedCallback_: null,
/**
- * The iframe container.
- * @type {HTMLIFrameElement}
+ * Invoked to display an error message to the user when a GAIA error occurs
+ * during authentication.
+ * @type {function()}
*/
- get frame() {
- return this.frame_;
- },
+ missingGaiaInfoCallback_: null,
/**
- * Sets retrieveAuthenticatedUserEmailCallback_.
+ * Invoked to record that the credentials passing API was used.
* @type {function()}
*/
- set retrieveAuthenticatedUserEmailCallback(callback) {
- this.retrieveAuthenticatedUserEmailCallback_ = callback;
+ samlApiUsedCallback_: null,
+
+ /**
+ * The iframe container.
+ * @type {HTMLIFrameElement}
+ */
+ get frame() {
+ return this.frame_;
},
/**
@@ -218,6 +212,22 @@ cr.define('cr.login', function() {
},
/**
+ * Sets missingGaiaInfoCallback_.
+ * @type {function()}
+ */
+ set missingGaiaInfoCallback(callback) {
+ this.missingGaiaInfoCallback_ = callback;
+ },
+
+ /**
+ * Sets samlApiUsedCallback_.
+ * @type {function()}
+ */
+ set samlApiUsedCallback(callback) {
+ this.samlApiUsedCallback_ = callback;
+ },
+
+ /**
* Loads the auth extension.
* @param {AuthMode} authMode Authorization mode.
* @param {Object} data Parameters for the auth extension. See the auth
@@ -286,21 +296,6 @@ cr.define('cr.login', function() {
},
/**
- * Sends the authenticated user's e-mail address to the auth extension.
- * @param {number} attemptToken The opaque token provided to the
- * retrieveAuthenticatedUserEmailCallback_.
- * @param {string} email The authenticated user's e-mail address.
- */
- setAuthenticatedUserEmail: function(attemptToken, email) {
- var msg = {
- method: 'setAuthenticatedUserEmail',
- attemptToken: attemptToken,
- email: email
- };
- this.frame_.contentWindow.postMessage(msg, AUTH_URL_BASE);
- },
-
- /**
* Invoked to process authentication success.
* @param {Object} credentials Credential object to pass to success
* callback.
@@ -346,6 +341,7 @@ cr.define('cr.login', function() {
}
this.onAuthSuccess_({email: msg.email,
password: msg.password,
+ gaiaId: msg.gaiaId,
useOffline: msg.method == 'offlineLogin',
usingSAML: msg.usingSAML || false,
chooseWhatToSync: msg.chooseWhatToSync,
@@ -354,17 +350,6 @@ cr.define('cr.login', function() {
return;
}
- if (msg.method == 'retrieveAuthenticatedUserEmail') {
- if (this.retrieveAuthenticatedUserEmailCallback_) {
- this.retrieveAuthenticatedUserEmailCallback_(msg.attemptToken,
- msg.apiUsed);
- } else {
- console.error(
- 'GaiaAuthHost: Invalid retrieveAuthenticatedUserEmailCallback_.');
- }
- return;
- }
-
if (msg.method == 'confirmPassword') {
if (this.confirmPasswordCallback_)
this.confirmPasswordCallback_(msg.passwordCount);
@@ -402,6 +387,24 @@ cr.define('cr.login', function() {
return;
}
+ if (msg.method == 'missingGaiaInfo') {
+ if (this.missingGaiaInfoCallback_) {
+ this.missingGaiaInfoCallback_();
+ } else {
+ console.error('GaiaAuthHost: Invalid missingGaiaInfoCallback_.');
+ }
+ return;
+ }
+
+ if (msg.method == 'samlApiUsed') {
+ if (this.samlApiUsedCallback_) {
+ this.samlApiUsedCallback_();
+ } else {
+ console.error('GaiaAuthHost: Invalid samlApiUsedCallback_.');
+ }
+ return;
+ }
+
console.error('Unknown message method=' + msg.method);
}
};
diff --git a/chrome/browser/ui/webui/chromeos/login/enrollment_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/enrollment_screen_handler.cc
index 00e9841..1d78088 100644
--- a/chrome/browser/ui/webui/chromeos/login/enrollment_screen_handler.cc
+++ b/chrome/browser/ui/webui/chromeos/login/enrollment_screen_handler.cc
@@ -22,7 +22,6 @@
#include "chrome/browser/chromeos/policy/policy_oauth2_token_fetcher.h"
#include "chrome/browser/extensions/signin/gaia_auth_extension_loader.h"
#include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/ui/webui/chromeos/login/authenticated_user_email_retriever.h"
#include "chrome/browser/ui/webui/chromeos/login/oobe_ui.h"
#include "chrome/grit/generated_resources.h"
#include "chromeos/network/network_state.h"
@@ -148,8 +147,6 @@ EnrollmentScreenHandler::~EnrollmentScreenHandler() {
// EnrollmentScreenHandler, WebUIMessageHandler implementation --
void EnrollmentScreenHandler::RegisterMessages() {
- AddCallback("oauthEnrollRetrieveAuthenticatedUserEmail",
- &EnrollmentScreenHandler::HandleRetrieveAuthenticatedUserEmail);
AddCallback("oauthEnrollClose",
&EnrollmentScreenHandler::HandleClose);
AddCallback("oauthEnrollCompleteLogin",
@@ -519,16 +516,6 @@ void EnrollmentScreenHandler::OnFrameError(
}
// EnrollmentScreenHandler, private -----------------------------
-void EnrollmentScreenHandler::HandleRetrieveAuthenticatedUserEmail(
- double attempt_token) {
- email_retriever_.reset(new AuthenticatedUserEmailRetriever(
- base::Bind(&EnrollmentScreenHandler::CallJS<double, std::string>,
- base::Unretained(this),
- "setAuthenticatedUserEmail",
- attempt_token),
- Profile::FromWebUI(web_ui())->GetRequestContext()));
-}
-
void EnrollmentScreenHandler::HandleClose(const std::string& reason) {
DCHECK(controller_);
diff --git a/chrome/browser/ui/webui/chromeos/login/enrollment_screen_handler.h b/chrome/browser/ui/webui/chromeos/login/enrollment_screen_handler.h
index b8ab5c3..004ddb1 100644
--- a/chrome/browser/ui/webui/chromeos/login/enrollment_screen_handler.h
+++ b/chrome/browser/ui/webui/chromeos/login/enrollment_screen_handler.h
@@ -24,7 +24,6 @@ class PolicyOAuth2TokenFetcher;
namespace chromeos {
-class AuthenticatedUserEmailRetriever;
class ErrorScreensHistogramHelper;
// WebUIMessageHandler implementation which handles events occurring on the
@@ -75,7 +74,6 @@ class EnrollmentScreenHandler
private:
// Handlers for WebUI messages.
- void HandleRetrieveAuthenticatedUserEmail(double attempt_token);
void HandleClose(const std::string& reason);
void HandleCompleteLogin(const std::string& user);
void HandleRetry();
@@ -140,9 +138,6 @@ class EnrollmentScreenHandler
// The callbacks to invoke after browsing data has been cleared.
std::vector<base::Closure> auth_reset_callbacks_;
- // Helper that retrieves the authenticated user's e-mail address.
- scoped_ptr<AuthenticatedUserEmailRetriever> email_retriever_;
-
// Latest enrollment frame error.
net::Error frame_error_;
diff --git a/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.cc
index 4325274..4e4f710 100644
--- a/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.cc
+++ b/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.cc
@@ -267,7 +267,8 @@ void GaiaScreenHandler::DeclareLocalizedValues(
IDS_LOGIN_CONSUMER_MANAGEMENT_ENROLLMENT);
// Strings used by the SAML fatal error dialog.
- builder->Add("fatalErrorMessageNoEmail", IDS_LOGIN_FATAL_ERROR_NO_EMAIL);
+ builder->Add("fatalErrorMessageNoAccountDetails",
+ IDS_LOGIN_FATAL_ERROR_NO_ACCOUNT_DETAILS);
builder->Add("fatalErrorMessageNoPassword",
IDS_LOGIN_FATAL_ERROR_NO_PASSWORD);
builder->Add("fatalErrorMessageVerificationFailed",
@@ -319,23 +320,29 @@ void GaiaScreenHandler::HandleFrameLoadingCompleted(int status) {
}
void GaiaScreenHandler::HandleCompleteAuthentication(
+ const std::string& gaia_id,
const std::string& email,
const std::string& password,
const std::string& auth_code) {
if (!Delegate())
return;
+
+ DCHECK(!email.empty());
+ DCHECK(!gaia_id.empty());
Delegate()->SetDisplayEmail(gaia::SanitizeEmail(email));
UserContext user_context(email);
+ user_context.SetGaiaID(gaia_id);
user_context.SetKey(Key(password));
user_context.SetAuthCode(auth_code);
Delegate()->CompleteLogin(user_context);
}
-void GaiaScreenHandler::HandleCompleteLogin(const std::string& typed_email,
+void GaiaScreenHandler::HandleCompleteLogin(const std::string& gaia_id,
+ const std::string& typed_email,
const std::string& password,
bool using_saml) {
if (!is_enrolling_consumer_management_) {
- DoCompleteLogin(typed_email, password, using_saml);
+ DoCompleteLogin(gaia_id, typed_email, password, using_saml);
return;
}
@@ -354,6 +361,7 @@ void GaiaScreenHandler::HandleCompleteLogin(const std::string& typed_email,
consumer_management_->SetOwner(owner_email,
base::Bind(&GaiaScreenHandler::OnSetOwnerDone,
weak_factory_.GetWeakPtr(),
+ gaia_id,
typed_email,
password,
using_saml));
@@ -417,7 +425,8 @@ void GaiaScreenHandler::HandleGaiaUIReady() {
SubmitLoginFormForTest();
}
-void GaiaScreenHandler::OnSetOwnerDone(const std::string& typed_email,
+void GaiaScreenHandler::OnSetOwnerDone(const std::string& gaia_id,
+ const std::string& typed_email,
const std::string& password,
bool using_saml,
bool success) {
@@ -433,10 +442,11 @@ void GaiaScreenHandler::OnSetOwnerDone(const std::string& typed_email,
// We should continue logging in the user, as there's not much we can do
// here.
}
- DoCompleteLogin(typed_email, password, using_saml);
+ DoCompleteLogin(gaia_id, typed_email, password, using_saml);
}
-void GaiaScreenHandler::DoCompleteLogin(const std::string& typed_email,
+void GaiaScreenHandler::DoCompleteLogin(const std::string& gaia_id,
+ const std::string& typed_email,
const std::string& password,
bool using_saml) {
if (!Delegate())
@@ -445,9 +455,12 @@ void GaiaScreenHandler::DoCompleteLogin(const std::string& typed_email,
if (using_saml && !using_saml_api_)
RecordSAMLScrapingVerificationResultInHistogram(true);
+ DCHECK(!typed_email.empty());
+ DCHECK(!gaia_id.empty());
const std::string sanitized_email = gaia::SanitizeEmail(typed_email);
Delegate()->SetDisplayEmail(sanitized_email);
UserContext user_context(sanitized_email);
+ user_context.SetGaiaID(gaia_id);
user_context.SetKey(Key(password));
user_context.SetAuthFlow(using_saml
? UserContext::AUTH_FLOW_GAIA_WITH_SAML
diff --git a/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.h b/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.h
index 4d5c411..c90428d 100644
--- a/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.h
+++ b/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.h
@@ -100,10 +100,12 @@ class GaiaScreenHandler : public BaseScreenHandler {
// WebUI message handlers.
void HandleFrameLoadingCompleted(int status);
- void HandleCompleteAuthentication(const std::string& email,
+ void HandleCompleteAuthentication(const std::string& gaia_id,
+ const std::string& email,
const std::string& password,
const std::string& auth_code);
- void HandleCompleteLogin(const std::string& typed_email,
+ void HandleCompleteLogin(const std::string& gaia_id,
+ const std::string& typed_email,
const std::string& password,
bool using_saml);
@@ -114,13 +116,15 @@ class GaiaScreenHandler : public BaseScreenHandler {
void HandleGaiaUIReady();
// This is called when ConsumerManagementService::SetOwner() returns.
- void OnSetOwnerDone(const std::string& typed_email,
+ void OnSetOwnerDone(const std::string& gaia_id,
+ const std::string& typed_email,
const std::string& password,
bool using_saml,
bool success);
// Really handles the complete login message.
- void DoCompleteLogin(const std::string& typed_email,
+ void DoCompleteLogin(const std::string& gaia_id,
+ const std::string& typed_email,
const std::string& password,
bool using_saml);
diff --git a/chrome/browser/ui/webui/chromeos/login/inline_login_handler_chromeos.cc b/chrome/browser/ui/webui/chromeos/login/inline_login_handler_chromeos.cc
index a3a722e..12e5ae2 100644
--- a/chrome/browser/ui/webui/chromeos/login/inline_login_handler_chromeos.cc
+++ b/chrome/browser/ui/webui/chromeos/login/inline_login_handler_chromeos.cc
@@ -4,13 +4,17 @@
#include "chrome/browser/ui/webui/chromeos/login/inline_login_handler_chromeos.h"
+#include <string>
+
#include "chrome/browser/chromeos/login/signin/oauth2_token_fetcher.h"
#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/signin/account_tracker_service_factory.h"
#include "chrome/browser/signin/chrome_signin_client_factory.h"
#include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
#include "chrome/browser/signin/signin_manager_factory.h"
#include "chrome/browser/signin/signin_promo.h"
#include "chrome/common/url_constants.h"
+#include "components/signin/core/browser/account_tracker_service.h"
#include "components/signin/core/browser/profile_oauth2_token_service.h"
#include "components/signin/core/browser/signin_client.h"
#include "components/signin/core/browser/signin_manager.h"
@@ -72,10 +76,20 @@ void InlineLoginHandlerChromeOS::CompleteLogin(const base::ListValue* args) {
dict->GetString("sessionIndex", &session_index);
CHECK(!session_index.empty()) << "Session index is empty.";
- std::string account_id;
- dict->GetString("email", &account_id);
- CHECK(!account_id.empty()) << "Account ID is empty.";
+ std::string email;
+ dict->GetString("email", &email);
+ CHECK(!email.empty()) << "Email is empty.";
+
+ std::string gaia_id;
+ dict->GetString("gaiaId", &gaia_id);
+ CHECK(!gaia_id.empty()) << "Gaia ID is empty.";
+
+ AccountTrackerService* account_tracker =
+ AccountTrackerServiceFactory::GetForProfile(profile);
+ account_tracker->SeedAccountInfo(gaia_id, email);
+ const std::string account_id =
+ account_tracker->PickAccountIdForAccount(gaia_id, email);
oauth2_delegate_.reset(new InlineLoginUIOAuth2Delegate(web_ui(), account_id));
net::URLRequestContextGetter* request_context =
content::BrowserContext::GetStoragePartitionForSite(
diff --git a/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.cc
index 4f22f50..463373d 100644
--- a/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.cc
+++ b/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.cc
@@ -8,7 +8,6 @@
#include <vector>
#include "base/bind.h"
-#include "base/bind_helpers.h"
#include "base/debug/trace_event.h"
#include "base/location.h"
#include "base/logging.h"
@@ -47,7 +46,6 @@
#include "chrome/browser/io_thread.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/signin/easy_unlock_service.h"
-#include "chrome/browser/ui/webui/chromeos/login/authenticated_user_email_retriever.h"
#include "chrome/browser/ui/webui/chromeos/login/error_screen_handler.h"
#include "chrome/browser/ui/webui/chromeos/login/l10n_util.h"
#include "chrome/browser/ui/webui/chromeos/login/native_window_delegate.h"
@@ -73,7 +71,6 @@
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/web_contents.h"
#include "google_apis/gaia/gaia_auth_util.h"
-#include "net/url_request/url_request_context_getter.h"
#include "third_party/cros_system_api/dbus/service_constants.h"
#include "ui/base/webui/web_ui_util.h"
@@ -777,8 +774,6 @@ void SigninScreenHandler::RegisterMessages() {
&SigninScreenHandler::HandleUpdateOfflineLogin);
AddCallback("focusPod", &SigninScreenHandler::HandleFocusPod);
AddCallback("hardlockPod", &SigninScreenHandler::HandleHardlockPod);
- AddCallback("retrieveAuthenticatedUserEmail",
- &SigninScreenHandler::HandleRetrieveAuthenticatedUserEmail);
AddCallback("getPublicSessionKeyboardLayouts",
&SigninScreenHandler::HandleGetPublicSessionKeyboardLayouts);
AddCallback("cancelConsumerManagementEnrollment",
@@ -1381,17 +1376,6 @@ void SigninScreenHandler::HandleHardlockPod(const std::string& user_id) {
service->SetHardlockState(EasyUnlockScreenlockStateHandler::USER_HARDLOCK);
}
-void SigninScreenHandler::HandleRetrieveAuthenticatedUserEmail(
- double attempt_token) {
- // TODO(antrim) : move GaiaSigninScreen dependency to GaiaSigninScreen.
- email_retriever_.reset(new AuthenticatedUserEmailRetriever(
- base::Bind(&SigninScreenHandler::CallJS<double, std::string>,
- base::Unretained(this),
- "login.GaiaSigninScreen.setAuthenticatedUserEmail",
- attempt_token),
- Profile::FromWebUI(web_ui())->GetRequestContext()));
-}
-
void SigninScreenHandler::HandleGetPublicSessionKeyboardLayouts(
const std::string& user_id,
const std::string& locale) {
diff --git a/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.h b/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.h
index 74dda85..22277e3 100644
--- a/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.h
+++ b/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.h
@@ -46,7 +46,6 @@ class ListValue;
namespace chromeos {
-class AuthenticatedUserEmailRetriever;
class CaptivePortalWindowProxy;
class CoreOobeActor;
class ErrorScreensHistogramHelper;
@@ -395,7 +394,6 @@ class SigninScreenHandler
void HandleFocusPod(const std::string& user_id);
void HandleHardlockPod(const std::string& user_id);
void HandleLaunchKioskApp(const std::string& app_id, bool diagnostic_mode);
- void HandleRetrieveAuthenticatedUserEmail(double attempt_token);
void HandleGetPublicSessionKeyboardLayouts(const std::string& user_id,
const std::string& locale);
void HandleCancelConsumerManagementEnrollment();
@@ -520,9 +518,6 @@ class SigninScreenHandler
// TODO(ygorshenin@): remove this dependency.
GaiaScreenHandler* gaia_screen_handler_;
- // Helper that retrieves the authenticated user's e-mail address.
- scoped_ptr<AuthenticatedUserEmailRetriever> email_retriever_;
-
// Maximized mode controller delegate.
scoped_ptr<TouchViewControllerDelegate> max_mode_delegate_;
diff --git a/chrome/browser/ui/webui/signin/inline_login_handler_impl.cc b/chrome/browser/ui/webui/signin/inline_login_handler_impl.cc
index a3d56d6..13c59ca 100644
--- a/chrome/browser/ui/webui/signin/inline_login_handler_impl.cc
+++ b/chrome/browser/ui/webui/signin/inline_login_handler_impl.cc
@@ -33,10 +33,10 @@
#include "components/signin/core/browser/account_tracker_service.h"
#include "components/signin/core/browser/profile_oauth2_token_service.h"
#include "components/signin/core/browser/signin_error_controller.h"
-#include "components/signin/core/browser/signin_oauth_helper.h"
#include "components/signin/core/common/profile_management_switches.h"
#include "content/public/browser/storage_partition.h"
#include "content/public/browser/web_ui.h"
+#include "google_apis/gaia/gaia_auth_consumer.h"
#include "google_apis/gaia/gaia_auth_fetcher.h"
#include "google_apis/gaia/gaia_auth_util.h"
#include "google_apis/gaia/gaia_constants.h"
@@ -45,7 +45,7 @@
namespace {
-class InlineSigninHelper : public SigninOAuthHelper::Consumer {
+class InlineSigninHelper : public GaiaAuthConsumer {
public:
InlineSigninHelper(
base::WeakPtr<InlineLoginHandlerImpl> handler,
@@ -53,6 +53,7 @@ class InlineSigninHelper : public SigninOAuthHelper::Consumer {
Profile* profile,
const GURL& current_url,
const std::string& email,
+ const std::string& gaia_id,
const std::string& password,
const std::string& session_index,
const std::string& signin_scoped_device_id,
@@ -60,19 +61,17 @@ class InlineSigninHelper : public SigninOAuthHelper::Consumer {
bool confirm_untrusted_signin);
private:
- // Overriden from SigninOAuthHelper::Consumer.
- void OnSigninOAuthInformationAvailable(
- const std::string& email,
- const std::string& display_email,
- const std::string& refresh_token) override;
- void OnSigninOAuthInformationFailure(
- const GoogleServiceAuthError& error) override;
+ // Overridden from GaiaAuthConsumer.
+ void OnClientOAuthSuccess(const ClientOAuthResult& result) override;
+ void OnClientOAuthFailure(const GoogleServiceAuthError& error)
+ override;
- SigninOAuthHelper signin_oauth_helper_;
+ GaiaAuthFetcher gaia_auth_fetcher_;
base::WeakPtr<InlineLoginHandlerImpl> handler_;
Profile* profile_;
GURL current_url_;
std::string email_;
+ std::string gaia_id_;
std::string password_;
std::string session_index_;
bool choose_what_to_sync_;
@@ -87,29 +86,29 @@ InlineSigninHelper::InlineSigninHelper(
Profile* profile,
const GURL& current_url,
const std::string& email,
+ const std::string& gaia_id,
const std::string& password,
const std::string& session_index,
const std::string& signin_scoped_device_id,
bool choose_what_to_sync,
bool confirm_untrusted_signin)
- : signin_oauth_helper_(getter, session_index, signin_scoped_device_id,
- this),
+ : gaia_auth_fetcher_(this, GaiaConstants::kChromeSource, getter),
handler_(handler),
profile_(profile),
current_url_(current_url),
email_(email),
+ gaia_id_(gaia_id),
password_(password),
session_index_(session_index),
choose_what_to_sync_(choose_what_to_sync),
confirm_untrusted_signin_(confirm_untrusted_signin) {
DCHECK(profile_);
DCHECK(!email_.empty());
+ gaia_auth_fetcher_.StartCookieForOAuthLoginTokenExchangeWithDeviceId(
+ session_index, signin_scoped_device_id);
}
-void InlineSigninHelper::OnSigninOAuthInformationAvailable(
- const std::string& email,
- const std::string& display_email,
- const std::string& refresh_token) {
+void InlineSigninHelper::OnClientOAuthSuccess(const ClientOAuthResult& result) {
content::WebContents* contents = NULL;
Browser* browser = NULL;
if (handler_) {
@@ -121,11 +120,19 @@ void InlineSigninHelper::OnSigninOAuthInformationAvailable(
AboutSigninInternalsFactory::GetForProfile(profile_);
about_signin_internals->OnRefreshTokenReceived("Successful");
+ AccountTrackerService* account_tracker =
+ AccountTrackerServiceFactory::GetForProfile(profile_);
+ std::string account_id =
+ account_tracker->PickAccountIdForAccount(gaia_id_, email_);
+
+ // Prime the account tracker with this combination of gaia id/display email.
+ account_tracker->SeedAccountInfo(gaia_id_, email_);
+
signin::Source source = signin::GetSourceForPromoURL(current_url_);
std::string primary_email =
SigninManagerFactory::GetForProfile(profile_)->GetAuthenticatedUsername();
- if (gaia::AreEmailsSame(email, primary_email) &&
+ if (gaia::AreEmailsSame(email_, primary_email) &&
source == signin::SOURCE_REAUTH &&
switches::IsNewProfileManagement()) {
chrome::SetLocalAuthCredentials(profile_, password_);
@@ -133,14 +140,8 @@ void InlineSigninHelper::OnSigninOAuthInformationAvailable(
if (source == signin::SOURCE_AVATAR_BUBBLE_ADD_ACCOUNT ||
source == signin::SOURCE_REAUTH) {
- // TODO(rogerta): the javascript code will need to pass in the gaia-id
- // of the account instead of the email when chrome uses gaia-id as key.
- DCHECK_EQ(AccountTrackerService::MIGRATION_NOT_STARTED,
- AccountTrackerServiceFactory::GetForProfile(profile_)->
- GetMigrationState());
- const std::string account_id = gaia::CanonicalizeEmail(email);
ProfileOAuth2TokenServiceFactory::GetForProfile(profile_)->
- UpdateCredentials(account_id, refresh_token);
+ UpdateCredentials(account_id, result.refresh_token);
if (signin::IsAutoCloseEnabledInURL(current_url_)) {
// Close the gaia sign in tab via a task to make sure we aren't in the
@@ -192,7 +193,7 @@ void InlineSigninHelper::OnSigninOAuthInformationAvailable(
bool start_signin =
!OneClickSigninHelper::HandleCrossAccountError(
profile_, "",
- email, password_, refresh_token,
+ email_, password_, result.refresh_token,
OneClickSigninHelper::AUTO_ACCEPT_EXPLICIT,
source, start_mode,
base::Bind(&InlineLoginHandlerImpl::SyncStarterCallback,
@@ -202,7 +203,7 @@ void InlineSigninHelper::OnSigninOAuthInformationAvailable(
// OneClickSigninSyncStarter will delete itself once the job is done.
new OneClickSigninSyncStarter(
profile_, browser,
- email, password_, refresh_token,
+ account_id, password_, result.refresh_token,
start_mode,
contents,
confirmation_required,
@@ -214,7 +215,7 @@ void InlineSigninHelper::OnSigninOAuthInformationAvailable(
base::MessageLoop::current()->DeleteSoon(FROM_HERE, this);
}
-void InlineSigninHelper::OnSigninOAuthInformationFailure(
+void InlineSigninHelper::OnClientOAuthFailure(
const GoogleServiceAuthError& error) {
if (handler_)
handler_->HandleLoginError(error.ToString());
@@ -312,6 +313,11 @@ void InlineLoginHandlerImpl::CompleteLogin(const base::ListValue* args) {
dict->GetString("password", &password_string16);
std::string password(base::UTF16ToASCII(password_string16));
+ base::string16 gaia_id_string16;
+ dict->GetString("gaiaId", &gaia_id_string16);
+ DCHECK(!gaia_id_string16.empty());
+ std::string gaia_id = base::UTF16ToASCII(gaia_id_string16);
+
// When doing a SAML sign in, this email check may result in a false
// positive. This happens when the user types one email address in the
// gaia sign in page, but signs in to a different account in the SAML sign in
@@ -390,7 +396,7 @@ void InlineLoginHandlerImpl::CompleteLogin(const base::ListValue* args) {
// InlineSigninHelper will delete itself.
new InlineSigninHelper(GetWeakPtr(), partition->GetURLRequestContext(),
Profile::FromWebUI(web_ui()), current_url,
- email, password, session_index,
+ email, gaia_id, password, session_index,
signin_scoped_device_id, choose_what_to_sync,
confirm_untrusted_signin_);
diff --git a/chromeos/login/auth/user_context.cc b/chromeos/login/auth/user_context.cc
index 31113f1..edeb24e 100644
--- a/chromeos/login/auth/user_context.cc
+++ b/chromeos/login/auth/user_context.cc
@@ -15,6 +15,7 @@ UserContext::UserContext()
UserContext::UserContext(const UserContext& other)
: user_id_(other.user_id_),
+ gaia_id_(other.gaia_id_),
key_(other.key_),
auth_code_(other.auth_code_),
user_id_hash_(other.user_id_hash_),
@@ -48,6 +49,7 @@ UserContext::~UserContext() {
bool UserContext::operator==(const UserContext& context) const {
return context.user_id_ == user_id_ &&
+ context.gaia_id_ == gaia_id_ &&
context.key_ == key_ &&
context.auth_code_ == auth_code_ &&
context.user_id_hash_ == user_id_hash_ &&
@@ -66,6 +68,10 @@ const std::string& UserContext::GetUserID() const {
return user_id_;
}
+const std::string& UserContext::GetGaiaID() const {
+ return gaia_id_;
+}
+
const Key* UserContext::GetKey() const {
return &key_;
}
@@ -111,6 +117,10 @@ void UserContext::SetUserID(const std::string& user_id) {
user_id_ = login::CanonicalizeUserID(user_id);
}
+void UserContext::SetGaiaID(const std::string& gaia_id) {
+ gaia_id_ = gaia_id;
+}
+
void UserContext::SetKey(const Key& key) {
key_ = key;
}
diff --git a/chromeos/login/auth/user_context.h b/chromeos/login/auth/user_context.h
index ff28c96..879e59a 100644
--- a/chromeos/login/auth/user_context.h
+++ b/chromeos/login/auth/user_context.h
@@ -41,6 +41,7 @@ class CHROMEOS_EXPORT UserContext {
bool operator!=(const UserContext& context) const;
const std::string& GetUserID() const;
+ const std::string& GetGaiaID() const;
const Key* GetKey() const;
Key* GetKey();
const std::string& GetAuthCode() const;
@@ -54,6 +55,7 @@ class CHROMEOS_EXPORT UserContext {
bool HasCredentials() const;
void SetUserID(const std::string& user_id);
+ void SetGaiaID(const std::string& gaia_id);
void SetKey(const Key& key);
void SetAuthCode(const std::string& auth_code);
void SetUserIDHash(const std::string& user_id_hash);
@@ -67,6 +69,7 @@ class CHROMEOS_EXPORT UserContext {
private:
std::string user_id_;
+ std::string gaia_id_;
Key key_;
std::string auth_code_;
std::string user_id_hash_;
diff --git a/components/signin/core/browser/account_tracker_service.cc b/components/signin/core/browser/account_tracker_service.cc
index 714c452..0b13386 100644
--- a/components/signin/core/browser/account_tracker_service.cc
+++ b/components/signin/core/browser/account_tracker_service.cc
@@ -5,6 +5,7 @@
#include "components/signin/core/browser/account_tracker_service.h"
#include "base/debug/trace_event.h"
+#include "base/logging.h"
#include "base/prefs/pref_service.h"
#include "base/prefs/scoped_user_pref_update.h"
#include "base/profiler/scoped_profile.h"
@@ -448,3 +449,42 @@ void AccountTrackerService::LoadFromTokenService() {
OnRefreshTokenAvailable(*it);
}
}
+
+std::string AccountTrackerService::PickAccountIdForAccount(
+ const std::string& gaia,
+ const std::string& email) {
+ return PickAccountIdForAccount(pref_service_, gaia, email);
+}
+
+// static
+std::string AccountTrackerService::PickAccountIdForAccount(
+ PrefService* pref_service,
+ const std::string& gaia,
+ const std::string& email) {
+ DCHECK(!gaia.empty());
+ DCHECK(!email.empty());
+ switch(GetMigrationState(pref_service)) {
+ case MIGRATION_NOT_STARTED:
+ case MIGRATION_IN_PROGRESS:
+ return gaia::CanonicalizeEmail(gaia::SanitizeEmail(email));
+ case MIGRATION_DONE:
+ return gaia;
+ default:
+ NOTREACHED();
+ return email;
+ }
+}
+
+void AccountTrackerService::SeedAccountInfo(const std::string& gaia,
+ const std::string& email) {
+ DCHECK(!gaia.empty());
+ DCHECK(!email.empty());
+ const std::string account_id = PickAccountIdForAccount(gaia, email);
+ const bool already_exists = ContainsKey(accounts_, account_id);
+ StartTrackingAccount(account_id);
+ AccountState& state = accounts_[account_id];
+ DCHECK(!already_exists || state.info.gaia == gaia);
+ state.info.gaia = gaia;
+ state.info.email = email;
+ SaveToPrefs(state);
+}
diff --git a/components/signin/core/browser/account_tracker_service.h b/components/signin/core/browser/account_tracker_service.h
index a6f403e..c65ed01 100644
--- a/components/signin/core/browser/account_tracker_service.h
+++ b/components/signin/core/browser/account_tracker_service.h
@@ -79,6 +79,18 @@ class AccountTrackerService : public KeyedService,
// there are still unfininshed fetchers.
virtual bool IsAllUserInfoFetched() const;
+ // Picks the correct account_id for the specified account depending on the
+ // migration state.
+ std::string PickAccountIdForAccount(const std::string& gaia,
+ const std::string& email);
+ static std::string PickAccountIdForAccount(PrefService* pref_service,
+ const std::string& gaia,
+ const std::string& email);
+
+ // Seeds the account whose account_id is given by PickAccountIdForAccount()
+ // with its corresponding gaia id and email address.
+ void SeedAccountInfo(const std::string& gaia, const std::string& email);
+
AccountIdMigrationState GetMigrationState();
static AccountIdMigrationState GetMigrationState(PrefService* pref_service);
diff --git a/components/signin/core/browser/account_tracker_service_unittest.cc b/components/signin/core/browser/account_tracker_service_unittest.cc
index 64b83b0..7a4d327 100644
--- a/components/signin/core/browser/account_tracker_service_unittest.cc
+++ b/components/signin/core/browser/account_tracker_service_unittest.cc
@@ -10,6 +10,7 @@
#include "base/prefs/testing_pref_service.h"
#include "base/strings/stringprintf.h"
#include "components/signin/core/browser/account_tracker_service.h"
+#include "components/signin/core/common/signin_pref_names.h"
#include "google_apis/gaia/fake_oauth2_token_service.h"
#include "google_apis/gaia/gaia_oauth_client.h"
#include "net/http/http_status_code.h"
@@ -198,6 +199,9 @@ class AccountTrackerServiceTest : public testing::Test {
pref_service_.registry()->RegisterListPref(
AccountTrackerService::kAccountInfoPref);
+ pref_service_.registry()->RegisterIntegerPref(
+ prefs::kAccountIdMigrationState,
+ AccountTrackerService::MIGRATION_NOT_STARTED);
account_tracker_.reset(new AccountTrackerService());
account_tracker_->Initialize(fake_oauth2_token_service_.get(),
@@ -505,3 +509,21 @@ TEST_F(AccountTrackerServiceTest, Persistence) {
tracker.Shutdown();
}
}
+
+TEST_F(AccountTrackerServiceTest, SeedAccountInfo) {
+ std::vector<AccountTrackerService::AccountInfo> infos =
+ account_tracker()->GetAccounts();
+ EXPECT_EQ(0u, infos.size());
+
+ const std::string gaia_id = AccountIdToGaiaId("alpha");
+ const std::string email = AccountIdToEmail("alpha");
+ const std::string account_id =
+ account_tracker()->PickAccountIdForAccount(gaia_id, email);
+ account_tracker()->SeedAccountInfo(gaia_id, email);
+
+ infos = account_tracker()->GetAccounts();
+ EXPECT_EQ(1u, infos.size());
+ EXPECT_EQ(account_id, infos[0].account_id);
+ EXPECT_EQ(gaia_id, infos[0].gaia);
+ EXPECT_EQ(email, infos[0].email);
+}
diff --git a/google_apis/gaia/fake_gaia.cc b/google_apis/gaia/fake_gaia.cc
index 9c4836f..b1a3942 100644
--- a/google_apis/gaia/fake_gaia.cc
+++ b/google_apis/gaia/fake_gaia.cc
@@ -51,6 +51,8 @@ const char kTestOAuthLoginSID[] = "fake-oauth-SID-cookie";
const char kTestOAuthLoginLSID[] = "fake-oauth-LSID-cookie";
const char kTestOAuthLoginAuthCode[] = "fake-oauth-auth-code";
+const char kDefaultGaiaId[] ="12345";
+
const base::FilePath::CharType kServiceLogin[] =
FILE_PATH_LITERAL("google_apis/test/service_login.html");
@@ -163,6 +165,30 @@ void FakeGaia::SetMergeSessionParams(
merge_session_params_ = params;
}
+void FakeGaia::MapEmailToGaiaId(const std::string& email,
+ const std::string& gaia_id) {
+ DCHECK(!email.empty());
+ DCHECK(!gaia_id.empty());
+ email_to_gaia_id_map_[email] = gaia_id;
+}
+
+std::string FakeGaia::GetGaiaIdOfEmail(const std::string& email) const {
+ DCHECK(!email.empty());
+ auto it = email_to_gaia_id_map_.find(email);
+ return it == email_to_gaia_id_map_.end() ? std::string(kDefaultGaiaId) :
+ it->second;
+}
+
+void FakeGaia::AddGoogleAccountsSigninHeader(
+ net::test_server::BasicHttpResponse* http_response,
+ const std::string& email) const {
+ DCHECK(!email.empty());
+ http_response->AddCustomHeader("google-accounts-signin",
+ base::StringPrintf(
+ "email=\"%s\", obfuscatedid=\"%s\", sessionindex=0",
+ email.c_str(), GetGaiaIdOfEmail(email).c_str()));
+}
+
void FakeGaia::Initialize() {
GaiaUrls* gaia_urls = GaiaUrls::GetInstance();
// Handles /MergeSession GAIA call.
@@ -415,8 +441,11 @@ void FakeGaia::HandleServiceLoginAuth(const HttpRequest& request,
std::string redirect_url = continue_url;
std::string email;
- if (GetQueryParameter(request.content, "Email", &email) &&
- saml_account_idp_map_.find(email) != saml_account_idp_map_.end()) {
+ const bool is_saml =
+ GetQueryParameter(request.content, "Email", &email) &&
+ saml_account_idp_map_.find(email) != saml_account_idp_map_.end();
+
+ if (is_saml) {
GURL url(saml_account_idp_map_[email]);
url = net::AppendQueryParameter(url, "SAMLRequest", "fake_request");
url = net::AppendQueryParameter(url, "RelayState", continue_url);
@@ -431,8 +460,12 @@ void FakeGaia::HandleServiceLoginAuth(const HttpRequest& request,
http_response->set_code(net::HTTP_TEMPORARY_REDIRECT);
http_response->AddCustomHeader("Location", redirect_url);
- http_response->AddCustomHeader("google-accounts-signin",
- base::StringPrintf("email=\"%s\", sessionindex=0", email.c_str()));
+
+ // SAML sign-ins complete in HandleSSO().
+ if (is_saml)
+ return;
+
+ AddGoogleAccountsSigninHeader(http_response, email);
}
void FakeGaia::HandleSSO(const HttpRequest& request,
@@ -449,6 +482,9 @@ void FakeGaia::HandleSSO(const HttpRequest& request,
http_response->set_code(net::HTTP_TEMPORARY_REDIRECT);
http_response->AddCustomHeader("Location", redirect_url);
http_response->AddCustomHeader("Google-Accounts-SAML", "End");
+
+ if (!merge_session_params_.email.empty())
+ AddGoogleAccountsSigninHeader(http_response, merge_session_params_.email);
}
void FakeGaia::HandleAuthToken(const HttpRequest& request,
@@ -580,3 +616,4 @@ void FakeGaia::HandleGetUserInfo(const HttpRequest& request,
merge_session_params_.email.c_str()));
http_response->set_code(net::HTTP_OK);
}
+
diff --git a/google_apis/gaia/fake_gaia.h b/google_apis/gaia/fake_gaia.h
index 4db3b84..e00a80a 100644
--- a/google_apis/gaia/fake_gaia.h
+++ b/google_apis/gaia/fake_gaia.h
@@ -86,6 +86,11 @@ class FakeGaia {
// Sets the initial value of tokens and cookies.
void SetMergeSessionParams(const MergeSessionParams& params);
+ // Sets the specified |gaia_id| as corresponding to the given |email|
+ // address when setting GAIA response headers. If no mapping is given for
+ // an email address, a default GAIA Id is used.
+ void MapEmailToGaiaId(const std::string& email, const std::string& gaia_id);
+
// Initializes HTTP request handlers. Should be called after switches
// for tweaking GaiaUrls are in place.
void Initialize();
@@ -121,8 +126,15 @@ class FakeGaia {
private:
typedef std::multimap<std::string, AccessTokenInfo> AccessTokenInfoMap;
+ typedef std::map<std::string, std::string> EmailToGaiaIdMap;
typedef std::map<std::string, GURL> SamlAccountIdpMap;
+ std::string GetGaiaIdOfEmail(const std::string& email) const;
+
+ void AddGoogleAccountsSigninHeader(
+ net::test_server::BasicHttpResponse* http_response,
+ const std::string& email) const;
+
// Formats a JSON response with the data in |response_dict|.
void FormatJSONResponse(const base::DictionaryValue& response_dict,
net::test_server::BasicHttpResponse* http_response);
@@ -169,6 +181,7 @@ class FakeGaia {
const;
MergeSessionParams merge_session_params_;
+ EmailToGaiaIdMap email_to_gaia_id_map_;
AccessTokenInfoMap access_token_info_map_;
RequestHandlerMap request_handlers_;
std::string service_login_response_;
diff --git a/tools/telemetry/telemetry/core/backends/chrome/chromeos_login_ext/main.js b/tools/telemetry/telemetry/core/backends/chrome/chromeos_login_ext/main.js
index 7ec6a6c..7d21eb3 100644
--- a/tools/telemetry/telemetry/core/backends/chrome/chromeos_login_ext/main.js
+++ b/tools/telemetry/telemetry/core/backends/chrome/chromeos_login_ext/main.js
@@ -12,6 +12,7 @@ window.parent.postMessage(msg, PARENT_PAGE);
var msg = {
'method': 'completeLogin',
'email': 'test@test.test',
+ 'gaiaId': '12345',
'password': ''
};
window.parent.postMessage(msg, PARENT_PAGE);