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

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

Issue 11649055: OAuth2 sign-in flow for ChromeOS (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: clang fix 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/oauth2_login_manager.cc
diff --git a/chrome/browser/chromeos/login/oauth2_login_manager.cc b/chrome/browser/chromeos/login/oauth2_login_manager.cc
new file mode 100644
index 0000000000000000000000000000000000000000..dae59a3ab311e62603f12013b8788af1a25d838e
--- /dev/null
+++ b/chrome/browser/chromeos/login/oauth2_login_manager.cc
@@ -0,0 +1,245 @@
+// Copyright (c) 2013 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.
+
+#include "chrome/browser/chromeos/login/oauth2_login_manager.h"
+
+#include "base/string_util.h"
+#include "chrome/browser/browser_process.h"
+#include "chrome/browser/chromeos/login/user_manager.h"
+#include "chrome/browser/policy/browser_policy_connector.h"
+#include "chrome/browser/prefs/pref_service.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/signin/token_service.h"
+#include "chrome/browser/signin/token_service_factory.h"
+#include "chrome/common/chrome_notification_types.h"
+#include "chrome/common/pref_names.h"
+#include "content/public/browser/notification_service.h"
+#include "google_apis/gaia/gaia_constants.h"
+#include "net/url_request/url_request_context_getter.h"
+
+namespace chromeos {
+
+OAuth2LoginManager::OAuth2LoginManager(OAuthLoginManager::Delegate* delegate)
+ : OAuthLoginManager(delegate),
+ loading_reported_(false) {
+}
+
+OAuth2LoginManager::~OAuth2LoginManager() {
+}
+
+void OAuth2LoginManager::RestoreSession(
+ Profile* user_profile,
+ net::URLRequestContextGetter* auth_request_context,
+ bool restore_from_auth_cookies) {
+ user_profile_ = user_profile;
+ auth_request_context_ = auth_request_context;
+ state_ = OAuthLoginManager::SESSION_RESTORE_IN_PROGRESS;
+
+ // TODO(zelidrag): Remove eventually the next line in some future milestone.
+ RemoveLegacyTokens();
+
+ // Reuse the access token fetched by the OAuth2PolicyFetcher, if it was
+ // used to fetch policies before Profile creation.
+ if (oauth2_policy_fetcher_.get() &&
+ oauth2_policy_fetcher_->has_oauth2_tokens()) {
+ VLOG(1) << "Resuming profile creation after fetching policy token";
+ refresh_token_ = oauth2_policy_fetcher_->oauth2_tokens().refresh_token;
+ restore_from_auth_cookies = false;
+ }
+ restore_from_auth_cookies_ = restore_from_auth_cookies;
+ ContinueSessionRestore();
+}
+
+void OAuth2LoginManager::ContinueSessionRestore() {
+ if (restore_from_auth_cookies_) {
+ FetchOAuth2Tokens();
+ return;
+ }
+
+ // Did we already fetch the refresh token (either policy or db)?
+ if (!refresh_token_.empty()) {
+ // TODO(zelidrag): Figure out where to stick that refresh_token_ into.
+ // We probalby need bit more than that.
+ }
+ LoadAndVerifyOAuth2Tokens();
+}
+
+void OAuth2LoginManager::RestorePolicyTokens(
+ net::URLRequestContextGetter* auth_request_context) {
+ oauth2_policy_fetcher_.reset(
+ new OAuth2PolicyFetcher(auth_request_context,
+ g_browser_process->system_request_context()));
+ oauth2_policy_fetcher_->Start();
+}
+
+void OAuth2LoginManager::Stop() {
+ oauth2_token_fetcher_.reset();
+ login_verifier_.reset();
+}
+
+TokenService* OAuth2LoginManager::SetupTokenService() {
+ TokenService* token_service =
+ TokenServiceFactory::GetForProfile(user_profile_);
+ if (registrar_.IsEmpty()) {
+ registrar_.Add(this,
+ chrome::NOTIFICATION_TOKEN_LOADING_FINISHED,
+ content::Source<TokenService>(token_service));
+ registrar_.Add(this,
+ chrome::NOTIFICATION_TOKEN_AVAILABLE,
+ content::Source<TokenService>(token_service));
+ }
+ return token_service;
+}
+
+void OAuth2LoginManager::RemoveLegacyTokens() {
+ 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 OAuth2LoginManager::LoadAndVerifyOAuth2Tokens() {
+ // If we have no cookies, try to load saved OAuth2 token from TokenService.
+ TokenService* token_service = SetupTokenService();
+ token_service->Initialize(GaiaConstants::kChromeSource, user_profile_);
+ token_service->LoadTokensFromDB();
+}
+
+void OAuth2LoginManager::FetchOAuth2Tokens() {
+ DCHECK(auth_request_context_.get());
+ // If we have authenticated cookie jar, get OAuth1 token first, then fetch
+ // SID/LSID cookies through OAuthLogin call.
+ oauth2_token_fetcher_.reset(
+ new OAuth2TokenFetcher(this, auth_request_context_));
+ oauth2_token_fetcher_->Start();
+}
+
+void OAuth2LoginManager::OnOAuth2TokensAvailable(
+ const GaiaAuthConsumer::ClientOAuthResult& oauth2_tokens) {
+ LOG(INFO) << "OAuth2 tokens fetched";
+ TokenService* token_service = SetupTokenService();
+ token_service->UpdateCredentialsWithOAuth2(oauth2_tokens);
+}
+
+void OAuth2LoginManager::OnOAuth2TokensFetchFailed() {
+ LOG(ERROR) << "OAuth2 tokens fetch failed!";
+ state_ = OAuthLoginManager::SESSION_RESTORE_DONE;
+ UserManager::Get()->SaveUserOAuthStatus(
+ UserManager::Get()->GetLoggedInUser()->email(),
+ User::OAUTH2_TOKEN_STATUS_INVALID);
+}
+
+void OAuth2LoginManager::Observe(
+ int type,
+ const content::NotificationSource& source,
+ const content::NotificationDetails& details) {
+ TokenService* token_service =
+ TokenServiceFactory::GetForProfile(user_profile_);
+ switch (type) {
+ case chrome::NOTIFICATION_TOKEN_LOADING_FINISHED: {
+ refresh_token_ = token_service->GetOAuth2LoginRefreshToken();
+ gaia_token_.clear();
+ // TODO(zelidrag): Figure out why just getting GaiaConstants::kGaiaService
+ // token does not do the trick here.
+ RestoreSessionCookies();
+ break;
+ }
+ case chrome::NOTIFICATION_TOKEN_AVAILABLE: {
+ // This path should kick on only when we mint a new OAuth2 refresh
+ // token for user cookies. Otherwise, wait for all tokens to load above.
+ if (!restore_from_auth_cookies_)
+ return;
+
+ TokenService::TokenAvailableDetails* token_details =
+ content::Details<TokenService::TokenAvailableDetails>(
+ details).ptr();
+ if (token_details->service() ==
+ GaiaConstants::kGaiaOAuth2LoginRefreshToken) {
+ DCHECK(!login_verifier_.get());
+ refresh_token_ = token_details->token();
+ gaia_token_.clear();
+ RestoreSessionCookies();
+ }
+ break;
+ }
+ default:
+ NOTREACHED();
+ break;
+ }
+}
+
+void OAuth2LoginManager::RestoreSessionCookies() {
+ if (refresh_token_.empty()) {
+ LOG(ERROR) << "OAuth2 refresh token is empty!";
+ state_ = OAuthLoginManager::SESSION_RESTORE_DONE;
+ UserManager::Get()->SaveUserOAuthStatus(
+ UserManager::Get()->GetLoggedInUser()->email(),
+ User::OAUTH2_TOKEN_STATUS_INVALID);
+ return;
+ }
+
+ DCHECK(!login_verifier_.get());
+ login_verifier_.reset(
+ new OAuth2LoginVerifier(this,
+ g_browser_process->system_request_context(),
+ user_profile_->GetRequestContext()));
+ login_verifier_->VerifyTokens(refresh_token_, gaia_token_);
+ FetchPolicyTokens();
+}
+
+void OAuth2LoginManager::FetchPolicyTokens() {
+ DCHECK(!refresh_token_.empty());
+ if (!oauth2_policy_fetcher_.get() || oauth2_policy_fetcher_->failed()) {
+ // Trigger OAuth2 token fetch for user policy.
+ oauth2_policy_fetcher_.reset(
+ new OAuth2PolicyFetcher(g_browser_process->system_request_context(),
+ refresh_token_));
+ oauth2_policy_fetcher_->Start();
+ }
+}
+void OAuth2LoginManager::OnOAuthLoginSuccess(
+ const GaiaAuthConsumer::ClientLoginResult& gaia_credentials) {
+ LOG(INFO) << "OAuth2 refresh token successfully exchanged for GAIA token.";
+ StartTokenService(gaia_credentials);
+}
+
+void OAuth2LoginManager::OnOAuthLoginFailure() {
+ LOG(ERROR) << "OAuth2 refresh token verification failed!";
+ state_ = OAuthLoginManager::SESSION_RESTORE_DONE;
+ UserManager::Get()->SaveUserOAuthStatus(
+ UserManager::Get()->GetLoggedInUser()->email(),
+ User::OAUTH2_TOKEN_STATUS_INVALID);
+}
+
+void OAuth2LoginManager::OnSessionMergeSuccess() {
+ LOG(INFO) << "OAuth2 refresh and/or GAIA token verification succeeded.";
+ state_ = OAuthLoginManager::SESSION_RESTORE_DONE;
+ UserManager::Get()->SaveUserOAuthStatus(
+ UserManager::Get()->GetLoggedInUser()->email(),
+ User::OAUTH2_TOKEN_STATUS_VALID);
+}
+
+void OAuth2LoginManager::OnSessionMergeFailure() {
+ LOG(ERROR) << "OAuth2 refresh and GAIA token verification failed!";
+ state_ = OAuthLoginManager::SESSION_RESTORE_DONE;
+ UserManager::Get()->SaveUserOAuthStatus(
+ UserManager::Get()->GetLoggedInUser()->email(),
+ User::OAUTH2_TOKEN_STATUS_INVALID);
+}
+
+void OAuth2LoginManager::StartTokenService(
+ const GaiaAuthConsumer::ClientLoginResult& gaia_credentials) {
+ TokenService* token_service = SetupTokenService();
+ token_service->UpdateCredentials(gaia_credentials);
+ CompleteAuthentication();
+}
+
+} // namespace chromeos

Powered by Google App Engine
This is Rietveld 408576698