Chromium Code Reviews| Index: chrome/browser/chromeos/login/oauth_login_manager.cc |
| diff --git a/chrome/browser/chromeos/login/oauth_login_manager.cc b/chrome/browser/chromeos/login/oauth_login_manager.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..926f41a56f156e15f156b491653f902493ab86b0 |
| --- /dev/null |
| +++ b/chrome/browser/chromeos/login/oauth_login_manager.cc |
| @@ -0,0 +1,184 @@ |
| +// 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/oauth_login_manager.h" |
| + |
| +#include "base/metrics/histogram.h" |
| +#include "chrome/browser/browser_process.h" |
| +#include "chrome/browser/chromeos/login/user_manager.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 "content/public/browser/notification_observer.h" |
| +#include "content/public/browser/notification_service.h" |
| +#include "google_apis/gaia/gaia_auth_fetcher.h" |
| +#include "google_apis/gaia/gaia_constants.h" |
| + |
| +using content::BrowserThread; |
| + |
| +namespace { |
| + |
| +// OAuth token verification max retry count. |
| +const int kMaxCookieRecoveryAttemptCount = 5; |
| +// OAuth token verification retry delay in milliseconds. |
| +const int kCookieRecoveryRestartDelay = 10000; |
| + |
| +} // namespace |
| + |
| + |
| +namespace chromeos { |
| + |
| +OAuthLoginManager::OAuthLoginManager(Delegate* delegate, |
| + Profile* user_profile, |
| + Profile* auth_profile, |
| + bool has_web_auth_cookies) |
| + : delegate_(delegate), |
| + user_profile_(user_profile), |
| + auth_profile_(auth_profile), |
| + has_web_auth_cookies_(has_web_auth_cookies), |
| + loading_reported_(false), |
| + restore_attempt_count_(0) { |
| +} |
| + |
| + |
| +void OAuthLoginManager::RestoreOAuth2Tokens() { |
| + if (has_web_auth_cookies_) { |
| + FetchOAuth2Tokens(); |
| + return; |
| + } |
| + LoadAndVerifyOAuth2Tokens(); |
| +} |
| + |
| +TokenService* OAuthLoginManager::SetupTokenService() { |
|
xiyuan
2013/01/08 17:41:43
Could SetupTokenService be called multiple times d
zel
2013/01/11 02:42:59
Done.
|
| + TokenService* token_service = |
| + TokenServiceFactory::GetForProfile(user_profile_); |
| + 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)); |
| + registrar_.Add(this, |
| + chrome::NOTIFICATION_TOKEN_REQUEST_FAILED, |
| + content::Source<TokenService>(token_service)); |
| + return token_service; |
| +} |
| + |
| +void OAuthLoginManager::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 OAuthLoginManager::FetchOAuth2Tokens() { |
| + // 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_profile_)); |
| + oauth2_token_fetcher_->Start(); |
| +} |
| + |
| +void OAuthLoginManager::OnOAuth2TokenAvailable( |
| + const GaiaAuthConsumer::ClientLoginResult& gaia_credentials, |
| + const GaiaAuthConsumer::ClientOAuthResult& oauth2_tokens) { |
| + TokenService* token_service = SetupTokenService(); |
| + token_service->UpdateCredentialsWithOAuth2(oauth2_tokens); |
| + token_service->UpdateCredentials(gaia_credentials); |
| + delegate_->OnCompletedAuthentication(user_profile_); |
| +} |
| + |
| +void OAuthLoginManager::OnOAuth2TokenFetchFailed() { |
| + UserManager::Get()->SaveUserOAuthStatus( |
| + UserManager::Get()->GetLoggedInUser()->email(), |
| + User::OAUTH2_TOKEN_STATUS_INVALID); |
| +} |
| + |
| +void OAuthLoginManager::Observe( |
| + int type, |
| + const content::NotificationSource& source, |
| + const content::NotificationDetails& details) OVERRIDE { |
| + TokenService* token_service = |
| + TokenServiceFactory::GetForProfile(user_profile_); |
| + switch (type) { |
| + case chrome::NOTIFICATION_TOKEN_LOADING_FINISHED: { |
| + refresh_token_ = token_service->GetOAuth2LoginRefreshToken(); |
| + ReportTokenLoaded(); |
| + // Have we started restoring GAIA auth cookies yet? |
| + if (!refresh_token_.empty() && !login_verifier_.get()) |
| + RestoreSessionCookies(); |
| + |
| + break; |
| + } |
| + case chrome::NOTIFICATION_TOKEN_REQUEST_FAILED: { |
| + // TODO(zelidrag): Figure out how to recover from transient errors with |
| + // TokenService class - similar to what we do in RetryOnError() here. |
| + TokenService::TokenAvailableDetails* token_details = |
| + content::Details<TokenService::TokenAvailableDetails>( |
| + details).ptr(); |
| + if (token_details->service() == |
| + GaiaConstants::kGaiaOAuth2LoginRefreshToken) { |
| + UserManager::Get()->SaveUserOAuthStatus( |
| + UserManager::Get()->GetLoggedInUser()->email(), |
| + User::OAUTH2_TOKEN_STATUS_INVALID); |
| + } |
| + break; |
| + } |
| + case chrome::NOTIFICATION_TOKEN_AVAILABLE: { |
| + 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(); |
| + RestoreSessionCookies(); |
| + } |
| + |
| + break; |
| + } |
| + default: |
| + NOTREACHED(); |
| + break; |
| + } |
| +} |
| + |
| +void OAuthLoginManager::RestoreSessionCookies() { |
| + VLOG(1) << "Fetched refresh token!"; |
| + DCHECK(!refresh_token_.empty()); |
| + if (!login_verifier_.get()) { |
| + login_verifier_.reset( |
| + new OAuth2LoginVerifier(this, |
| + g_browser_process->system_request_context(), |
| + user_profile_)); |
| + } |
| + login_verifier_->VerifyRefreshToken(refresh_token_); |
| +} |
| + |
| +void OAuthLoginManager::OnOAuth2LoginVerifierSuccess(const std::string& sid, |
| + const std::string& lsid, |
| + const std::string& auth) { |
| + UserManager::Get()->SaveUserOAuthStatus( |
| + UserManager::Get()->GetLoggedInUser()->email(), |
| + User::OAUTH2_TOKEN_STATUS_VALID); |
| +} |
| + |
| +void OAuthLoginManager::OnOAuth2LoginVerifierFaulure() { |
| + UserManager::Get()->SaveUserOAuthStatus( |
| + UserManager::Get()->GetLoggedInUser()->email(), |
| + User::OAUTH2_TOKEN_STATUS_INVALID); |
| +} |
| + |
| +void OAuthLoginManager::ReportTokenLoaded() { |
| + VLOG(1) << "Got OAuth2 refresh token!"; |
| + DCHECK(!loading_reported_); |
| + loading_reported_ = true; |
| + if (refresh_token_.empty()) { |
| + UserManager::Get()->SaveUserOAuthStatus( |
| + UserManager::Get()->GetLoggedInUser()->email(), |
| + User::OAUTH2_TOKEN_STATUS_INVALID); |
| + } |
| +} |
| + |
| +} // namespace chromeos |