| Index: chrome/browser/chromeos/login/login_utils.cc
|
| diff --git a/chrome/browser/chromeos/login/login_utils.cc b/chrome/browser/chromeos/login/login_utils.cc
|
| index 9f51de2fc3f352f3bb6098d10002937c4fed589c..44f127d93931f0d2721d2c0d9b6fc6cdb67c77e4 100644
|
| --- a/chrome/browser/chromeos/login/login_utils.cc
|
| +++ b/chrome/browser/chromeos/login/login_utils.cc
|
| @@ -39,8 +39,9 @@
|
| #include "chrome/browser/chromeos/input_method/input_method_util.h"
|
| #include "chrome/browser/chromeos/login/language_switch_menu.h"
|
| #include "chrome/browser/chromeos/login/login_display_host.h"
|
| +#include "chrome/browser/chromeos/login/oauth1_login_verifier.h"
|
| #include "chrome/browser/chromeos/login/oauth1_token_fetcher.h"
|
| -#include "chrome/browser/chromeos/login/oauth_login_verifier.h"
|
| +#include "chrome/browser/chromeos/login/oauth_login_manager.h"
|
| #include "chrome/browser/chromeos/login/parallel_authenticator.h"
|
| #include "chrome/browser/chromeos/login/policy_oauth_fetcher.h"
|
| #include "chrome/browser/chromeos/login/profile_auth_data.h"
|
| @@ -82,6 +83,7 @@
|
| #include "content/public/browser/notification_service.h"
|
| #include "content/public/common/content_switches.h"
|
| #include "google_apis/gaia/gaia_auth_consumer.h"
|
| +#include "google_apis/gaia/gaia_constants.h"
|
| #include "google_apis/gaia/gaia_urls.h"
|
| #include "googleurl/src/gurl.h"
|
| #include "media/base/media_switches.h"
|
| @@ -180,7 +182,8 @@ class JobRestartRequest
|
| class LoginUtilsImpl
|
| : public LoginUtils,
|
| public OAuth1TokenFetcher::Delegate,
|
| - public OAuthLoginVerifier::Delegate,
|
| + public OAuth1LoginVerifier::Delegate,
|
| + public OAuthLoginManager::Delegate,
|
| public net::NetworkChangeNotifier::ConnectionTypeObserver,
|
| public content::NotificationObserver,
|
| public base::SupportsWeakPtr<LoginUtilsImpl> {
|
| @@ -188,6 +191,8 @@ class LoginUtilsImpl
|
| LoginUtilsImpl()
|
| : pending_requests_(false),
|
| using_oauth_(false),
|
| + force_oauth2_(CommandLine::ForCurrentProcess()->HasSwitch(
|
| + ::switches::kForceOAuth2)),
|
| has_web_auth_cookies_(false),
|
| delegate_(NULL),
|
| job_restart_request_(NULL),
|
| @@ -227,9 +232,6 @@ class LoginUtilsImpl
|
| virtual void PrewarmAuthentication() OVERRIDE;
|
| virtual void RestoreAuthenticationSession(Profile* profile) OVERRIDE;
|
| virtual void StartTokenServices(Profile* user_profile) OVERRIDE;
|
| - virtual void StartSignedInServices(
|
| - Profile* profile,
|
| - const GaiaAuthConsumer::ClientLoginResult& credentials) OVERRIDE;
|
| virtual void StopBackgroundFetchers() OVERRIDE;
|
| virtual void InitRlzDelayed(Profile* user_profile) OVERRIDE;
|
| virtual void CompleteProfileCreate(Profile* user_profile) OVERRIDE;
|
| @@ -239,12 +241,16 @@ class LoginUtilsImpl
|
| const std::string& secret) OVERRIDE;
|
| void OnOAuth1AccessTokenFetchFailed() OVERRIDE;
|
|
|
| - // OAuthLoginVerifier::Delegate overrides.
|
| - virtual void OnOAuthVerificationSucceeded(const std::string& user_name,
|
| - const std::string& sid,
|
| - const std::string& lsid,
|
| - const std::string& auth) OVERRIDE;
|
| - virtual void OnOAuthVerificationFailed(const std::string& user_name) OVERRIDE;
|
| + // OAuth1LoginVerifier::Delegate overrides.
|
| + virtual void OnOAuth1VerificationSucceeded(const std::string& user_name,
|
| + const std::string& sid,
|
| + const std::string& lsid,
|
| + const std::string& auth) OVERRIDE;
|
| + virtual void OnOAuth1VerificationFailed(
|
| + const std::string& user_name) OVERRIDE;
|
| +
|
| + // OAuthLoginManager::Delegate overrides.
|
| + virtual void OnCompletedAuthentication(Profile* user_profile) OVERRIDE;
|
|
|
| // net::NetworkChangeNotifier::ConnectionTypeObserver overrides.
|
| virtual void OnConnectionTypeChanged(
|
| @@ -287,9 +293,9 @@ class LoginUtilsImpl
|
| const std::string& secret);
|
|
|
| // Fetch user credentials (sid/lsid) given OAuth1 access |token| and |secret|.
|
| - void FetchCredentials(Profile* user_profile,
|
| - const std::string& token,
|
| - const std::string& secret);
|
| + void FetchCredentialsWithOAuth1(Profile* user_profile,
|
| + const std::string& token,
|
| + const std::string& secret);
|
|
|
| // Fetch enterprise policy OAuth2 given OAuth1 access |token| and |secret|.
|
| void FetchPolicyToken(Profile* offrecord_profile,
|
| @@ -299,6 +305,11 @@ class LoginUtilsImpl
|
| // Check user's profile for kApplicationLocale setting.
|
| void RespectLocalePreference(Profile* pref);
|
|
|
| + // Returns true if the OAuth2 refresh token and its previously checked value
|
| + // (during token-to-cookies exchange) is known to be valid.
|
| + bool IsOAuth2RefreshTokenValid(Profile* user_profile,
|
| + const std::string& oauth2_refresh_token);
|
| +
|
| // Initializes basic preferences for newly created profile.
|
| void InitProfilePreferences(Profile* user_profile);
|
|
|
| @@ -309,15 +320,30 @@ class LoginUtilsImpl
|
| // Finalized profile preparation.
|
| void FinalizePrepareProfile(Profile* user_profile);
|
|
|
| - // Restores GAIA auth cookies for the created profile.
|
| - void RestoreAuthCookies(Profile* user_profile);
|
| + // Restores GAIA auth cookies for the created user profile from OAuth1 token.
|
| + void RestoreCookiesFromOAuth1Token(Profile* user_profile);
|
| +
|
| + // Restores GAIA auth cookies for the created user profile from OAuth2 token.
|
| + void RestoreAuthSession(Profile* user_profile);
|
| +
|
| + // Removed deprecated OAuth1 token and secret form preference store.
|
| + void RemoveOAuth1Tokens(Profile* user_profile);
|
|
|
| // Initializes RLZ. If |disabled| is true, RLZ pings are disabled.
|
| void InitRlz(Profile* user_profile, bool disabled);
|
|
|
| + // Initializes and starts TokenSerivice credentials with GAIA credentials.
|
| + void PrepareTokenService(
|
| + Profile* profile,
|
| + const GaiaAuthConsumer::ClientLoginResult& credentials);
|
| +
|
| + // Starts signing related services. Initiates TokenService token retreival.
|
| + void StartSignedInServices(Profile* profile);
|
| +
|
| std::string password_;
|
| bool pending_requests_;
|
| bool using_oauth_;
|
| + bool force_oauth2_;
|
| // True if the authenrication profile's cookie jar should contain
|
| // authentication cookies from the authentication extension log in flow.
|
| bool has_web_auth_cookies_;
|
| @@ -325,7 +351,9 @@ class LoginUtilsImpl
|
| scoped_refptr<Authenticator> authenticator_;
|
| scoped_ptr<PolicyOAuthFetcher> policy_oauth_fetcher_;
|
| scoped_ptr<OAuth1TokenFetcher> oauth1_token_fetcher_;
|
| - scoped_ptr<OAuthLoginVerifier> oauth_login_verifier_;
|
| + scoped_ptr<OAuth1LoginVerifier> oauth1_login_verifier_;
|
| +
|
| + scoped_ptr<OAuthLoginManager> login_manager_;
|
|
|
| // Delegate to be fired when the profile will be prepared.
|
| LoginUtils::Delegate* delegate_;
|
| @@ -492,6 +520,23 @@ void LoginUtilsImpl::DelegateDeleted(LoginUtils::Delegate* delegate) {
|
| delegate_ = NULL;
|
| }
|
|
|
| +bool LoginUtilsImpl::IsOAuth2RefreshTokenValid(
|
| + Profile* user_profile,
|
| + const std::string& oauth2_refresh_token) {
|
| + // Do we have a token?
|
| + if (oauth2_refresh_token.empty())
|
| + return false;
|
| +
|
| + // Did previous token-to-cookie exchange fail?
|
| + if (UserManager::Get()->IsUserLoggedIn() &&
|
| + UserManager::Get()->GetLoggedInUser()->oauth_token_status() !=
|
| + User::OAUTH2_TOKEN_STATUS_VALID) {
|
| + return false;
|
| + }
|
| +
|
| + return true;
|
| +}
|
| +
|
| void LoginUtilsImpl::InitProfilePreferences(Profile* user_profile) {
|
| if (UserManager::Get()->IsCurrentUserNew())
|
| SetFirstLoginPrefs(user_profile->GetPrefs());
|
| @@ -521,7 +566,6 @@ void LoginUtilsImpl::OnProfileCreated(
|
| Profile* user_profile,
|
| Profile::CreateStatus status) {
|
| CHECK(user_profile);
|
| -
|
| if (delegate_)
|
| delegate_->OnProfileCreated(user_profile);
|
|
|
| @@ -542,14 +586,18 @@ void LoginUtilsImpl::OnProfileCreated(
|
| btl->AddLoginTimeMarker("UserProfileGotten", false);
|
|
|
| if (using_oauth_) {
|
| - // Reuse the access token fetched by the PolicyOAuthFetcher, if it was
|
| - // used to fetch policies before Profile creation.
|
| - if (policy_oauth_fetcher_.get() &&
|
| - !policy_oauth_fetcher_->oauth1_token().empty()) {
|
| - VLOG(1) << "Resuming profile creation after fetching policy token";
|
| - StoreOAuth1AccessToken(user_profile,
|
| - policy_oauth_fetcher_->oauth1_token(),
|
| - policy_oauth_fetcher_->oauth1_secret());
|
| + if (!force_oauth2_) {
|
| + // Reuse the access token fetched by the PolicyOAuthFetcher, if it was
|
| + // used to fetch policies before Profile creation.
|
| + if (policy_oauth_fetcher_.get() &&
|
| + !policy_oauth_fetcher_->oauth1_token().empty()) {
|
| + VLOG(1) << "Resuming profile creation after fetching policy token";
|
| + StoreOAuth1AccessToken(user_profile,
|
| + policy_oauth_fetcher_->oauth1_token(),
|
| + policy_oauth_fetcher_->oauth1_secret());
|
| + }
|
| + } else {
|
| + // TODO(mnissler): Figure out what to do here in OAuth2 case.
|
| }
|
|
|
| // Transfer proxy authentication cache, cookies (optionally) and server
|
| @@ -570,7 +618,16 @@ void LoginUtilsImpl::OnProfileCreated(
|
| FinalizePrepareProfile(user_profile);
|
| }
|
|
|
| -void LoginUtilsImpl::RestoreAuthCookies(Profile* user_profile) {
|
| +void LoginUtilsImpl::CompleteProfileCreate(Profile* user_profile) {
|
| + if (force_oauth2_)
|
| + RestoreAuthSession(user_profile);
|
| + else
|
| + RestoreCookiesFromOAuth1Token(user_profile);
|
| +
|
| + FinalizePrepareProfile(user_profile);
|
| +}
|
| +
|
| +void LoginUtilsImpl::RestoreCookiesFromOAuth1Token(Profile* user_profile) {
|
| std::string oauth1_token;
|
| std::string oauth1_secret;
|
| if (ReadOAuth1AccessToken(user_profile, &oauth1_token, &oauth1_secret) ||
|
| @@ -596,9 +653,31 @@ void LoginUtilsImpl::RestoreAuthCookies(Profile* user_profile) {
|
| }
|
| }
|
|
|
| -void LoginUtilsImpl::CompleteProfileCreate(Profile* user_profile) {
|
| - RestoreAuthCookies(user_profile);
|
| - FinalizePrepareProfile(user_profile);
|
| +void LoginUtilsImpl::RemoveOAuth1Tokens(Profile* user_profile) {
|
| + PrefServiceSyncable* prefs = user_profile->GetPrefs();
|
| + prefs->RegisterStringPref(prefs::kOAuth1Token,
|
| + "",
|
| + PrefServiceSyncable::UNSYNCABLE_PREF);
|
| + prefs->RegisterStringPref(prefs::kOAuth1Secret,
|
| + "",
|
| + PrefServiceSyncable::UNSYNCABLE_PREF);
|
| + prefs->ClearPref(prefs::kOAuth1Token);
|
| + prefs->ClearPref(prefs::kOAuth1Secret);
|
| + prefs->UnregisterPreference(prefs::kOAuth1Token);
|
| + prefs->UnregisterPreference(prefs::kOAuth1Secret);
|
| +}
|
| +
|
| +void LoginUtilsImpl::RestoreAuthSession(Profile* user_profile) {
|
| + // Remove legacy OAuth1 token if we have one. If it's valid, we should already
|
| + // have OAuth2 refresh token in TokenService that could be used to retreive
|
| + // all other tokens and credentials.
|
| + RemoveOAuth1Tokens(user_profile);
|
| + login_manager_.reset(
|
| + new OAuthLoginManager(this,
|
| + user_profile,
|
| + authenticator_->authentication_profile(),
|
| + has_web_auth_cookies_));
|
| + login_manager_->RestoreOAuth2Tokens();
|
| }
|
|
|
| void LoginUtilsImpl::FinalizePrepareProfile(Profile* user_profile) {
|
| @@ -688,9 +767,16 @@ void LoginUtilsImpl::StartTokenServices(Profile* user_profile) {
|
| oauth1_token, oauth1_secret);
|
| }
|
|
|
| -void LoginUtilsImpl::StartSignedInServices(
|
| +void LoginUtilsImpl::PrepareTokenService(
|
| Profile* user_profile,
|
| const GaiaAuthConsumer::ClientLoginResult& credentials) {
|
| + TokenService* token_service =
|
| + TokenServiceFactory::GetForProfile(user_profile);
|
| + token_service->UpdateCredentials(credentials);
|
| + StartSignedInServices(user_profile);
|
| +}
|
| +
|
| +void LoginUtilsImpl::StartSignedInServices(Profile* user_profile) {
|
| // Fetch/Create the SigninManager - this will cause the TokenService to load
|
| // tokens for the currently signed-in user if the SigninManager hasn't already
|
| // been initialized.
|
| @@ -724,7 +810,6 @@ void LoginUtilsImpl::StartSignedInServices(
|
| password_.clear();
|
| TokenService* token_service =
|
| TokenServiceFactory::GetForProfile(user_profile);
|
| - token_service->UpdateCredentials(credentials);
|
| if (token_service->AreCredentialsValid())
|
| token_service->StartFetchingTokens();
|
| }
|
| @@ -1047,7 +1132,7 @@ void LoginUtilsImpl::KickStartAuthentication(Profile* user_profile) {
|
| void LoginUtilsImpl::StopBackgroundFetchers() {
|
| policy_oauth_fetcher_.reset();
|
| oauth1_token_fetcher_.reset();
|
| - oauth_login_verifier_.reset();
|
| + oauth1_login_verifier_.reset();
|
| }
|
|
|
| void LoginUtilsImpl::FetchSecondaryTokens(Profile* offrecord_profile,
|
| @@ -1064,7 +1149,7 @@ bool LoginUtilsImpl::ReadOAuth1AccessToken(Profile* user_profile,
|
| // Skip reading oauth token if user does not have a valid status.
|
| if (UserManager::Get()->IsUserLoggedIn() &&
|
| UserManager::Get()->GetLoggedInUser()->oauth_token_status() !=
|
| - User::OAUTH_TOKEN_STATUS_VALID) {
|
| + User::OAUTH1_TOKEN_STATUS_VALID) {
|
| return false;
|
| }
|
|
|
| @@ -1078,6 +1163,7 @@ bool LoginUtilsImpl::ReadOAuth1AccessToken(Profile* user_profile,
|
| CrosLibrary::Get()->GetCertLibrary()->DecryptToken(encoded_token);
|
| std::string decoded_secret =
|
| CrosLibrary::Get()->GetCertLibrary()->DecryptToken(encoded_secret);
|
| +
|
| if (!decoded_token.length() || !decoded_secret.length())
|
| return false;
|
|
|
| @@ -1094,6 +1180,7 @@ void LoginUtilsImpl::StoreOAuth1AccessToken(Profile* user_profile,
|
| CrosLibrary::Get()->GetCertLibrary()->EncryptToken(token);
|
| std::string encrypted_secret =
|
| CrosLibrary::Get()->GetCertLibrary()->EncryptToken(secret);
|
| +
|
| PrefService* pref_service = user_profile->GetPrefs();
|
| User* user = UserManager::Get()->GetLoggedInUser();
|
| if (!encrypted_token.empty() && !encrypted_secret.empty()) {
|
| @@ -1103,13 +1190,13 @@ void LoginUtilsImpl::StoreOAuth1AccessToken(Profile* user_profile,
|
| // ...then record the presence of valid OAuth token for this account in
|
| // local state as well.
|
| UserManager::Get()->SaveUserOAuthStatus(
|
| - user->email(), User::OAUTH_TOKEN_STATUS_VALID);
|
| + user->email(), User::OAUTH1_TOKEN_STATUS_VALID);
|
| } else {
|
| LOG(WARNING) << "Failed to get OAuth1 token/secret encrypted.";
|
| // Set the OAuth status invalid so that the user will go through full
|
| // GAIA login next time.
|
| UserManager::Get()->SaveUserOAuthStatus(
|
| - user->email(), User::OAUTH_TOKEN_STATUS_INVALID);
|
| + user->email(), User::OAUTH1_TOKEN_STATUS_INVALID);
|
| }
|
| }
|
|
|
| @@ -1118,18 +1205,18 @@ void LoginUtilsImpl::VerifyOAuth1AccessToken(Profile* user_profile,
|
| const std::string& secret) {
|
| // Kick off verification of OAuth1 access token (via OAuthLogin), this should
|
| // let us fetch credentials that will be used to initialize sync engine.
|
| - FetchCredentials(user_profile, token, secret);
|
| + FetchCredentialsWithOAuth1(user_profile, token, secret);
|
|
|
| FetchSecondaryTokens(user_profile->GetOffTheRecordProfile(), token, secret);
|
| }
|
|
|
| -void LoginUtilsImpl::FetchCredentials(Profile* user_profile,
|
| - const std::string& token,
|
| - const std::string& secret) {
|
| - oauth_login_verifier_.reset(new OAuthLoginVerifier(
|
| +void LoginUtilsImpl::FetchCredentialsWithOAuth1(Profile* user_profile,
|
| + const std::string& token,
|
| + const std::string& secret) {
|
| + oauth1_login_verifier_.reset(new OAuth1LoginVerifier(
|
| this, user_profile, token, secret,
|
| UserManager::Get()->GetLoggedInUser()->email()));
|
| - oauth_login_verifier_->StartOAuthVerification();
|
| + oauth1_login_verifier_->StartOAuthVerification();
|
| }
|
|
|
|
|
| @@ -1171,9 +1258,9 @@ void LoginUtilsImpl::FetchPolicyToken(Profile* offrecord_profile,
|
| authenticator_ = NULL;
|
| }
|
|
|
| -void LoginUtilsImpl::OnOAuthVerificationFailed(const std::string& user_name) {
|
| +void LoginUtilsImpl::OnOAuth1VerificationFailed(const std::string& user_name) {
|
| UserManager::Get()->SaveUserOAuthStatus(user_name,
|
| - User::OAUTH_TOKEN_STATUS_INVALID);
|
| + User::OAUTH1_TOKEN_STATUS_INVALID);
|
| }
|
|
|
| void LoginUtilsImpl::OnOAuth1AccessTokenAvailable(const std::string& token,
|
| @@ -1194,25 +1281,28 @@ void LoginUtilsImpl::OnOAuth1AccessTokenFetchFailed() {
|
| EmptyString());
|
| }
|
|
|
| -void LoginUtilsImpl::OnOAuthVerificationSucceeded(
|
| +void LoginUtilsImpl::OnOAuth1VerificationSucceeded(
|
| const std::string& user_name, const std::string& sid,
|
| const std::string& lsid, const std::string& auth) {
|
| // Kick off sync engine.
|
| GaiaAuthConsumer::ClientLoginResult credentials(sid, lsid, auth,
|
| std::string());
|
| - StartSignedInServices(ProfileManager::GetDefaultProfile(), credentials);
|
| + PrepareTokenService(ProfileManager::GetDefaultProfile(), credentials);
|
| }
|
|
|
| +void LoginUtilsImpl::OnCompletedAuthentication(Profile* user_profile) {
|
| + StartSignedInServices(user_profile);
|
| +}
|
|
|
| void LoginUtilsImpl::OnConnectionTypeChanged(
|
| net::NetworkChangeNotifier::ConnectionType type) {
|
| if (type != net::NetworkChangeNotifier::CONNECTION_NONE &&
|
| UserManager::Get()->IsUserLoggedIn()) {
|
| - if (oauth_login_verifier_.get() &&
|
| - !oauth_login_verifier_->is_done()) {
|
| + if (oauth1_login_verifier_.get() &&
|
| + !oauth1_login_verifier_->is_done()) {
|
| // If we come online for the first time after successful offline login,
|
| // we need to kick off OAuth token verification process again.
|
| - oauth_login_verifier_->ContinueVerification();
|
| + oauth1_login_verifier_->ContinueVerification();
|
| } else if (should_restore_auth_session_) {
|
| should_restore_auth_session_ = false;
|
| Profile* user_profile = ProfileManager::GetDefaultProfile();
|
|
|