Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(37)

Unified Diff: chrome/browser/chromeos/login/login_utils.cc

Issue 11649055: OAuth2 sign-in flow for ChromeOS (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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();

Powered by Google App Engine
This is Rietveld 408576698