| OLD | NEW |
| 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/chromeos/login/oauth2_login_manager.h" | 5 #include "chrome/browser/chromeos/login/oauth2_login_manager.h" |
| 6 | 6 |
| 7 #include "base/command_line.h" | 7 #include "base/command_line.h" |
| 8 #include "base/metrics/histogram.h" | 8 #include "base/metrics/histogram.h" |
| 9 #include "base/prefs/pref_service.h" | 9 #include "base/prefs/pref_service.h" |
| 10 #include "base/strings/string_util.h" | 10 #include "base/strings/string_util.h" |
| 11 #include "chrome/browser/browser_process.h" | 11 #include "chrome/browser/browser_process.h" |
| 12 #include "chrome/browser/profiles/profile.h" | 12 #include "chrome/browser/profiles/profile.h" |
| 13 #include "chrome/browser/signin/profile_oauth2_token_service.h" | 13 #include "chrome/browser/signin/profile_oauth2_token_service.h" |
| 14 #include "chrome/browser/signin/profile_oauth2_token_service_factory.h" | 14 #include "chrome/browser/signin/profile_oauth2_token_service_factory.h" |
| 15 #include "chrome/browser/signin/token_service.h" | |
| 16 #include "chrome/browser/signin/token_service_factory.h" | |
| 17 #include "chrome/common/chrome_switches.h" | 15 #include "chrome/common/chrome_switches.h" |
| 18 #include "google_apis/gaia/gaia_constants.h" | 16 #include "google_apis/gaia/gaia_constants.h" |
| 17 #include "google_apis/gaia/gaia_urls.h" |
| 19 #include "net/url_request/url_request_context_getter.h" | 18 #include "net/url_request/url_request_context_getter.h" |
| 20 | 19 |
| 21 namespace chromeos { | 20 namespace chromeos { |
| 22 | 21 |
| 22 static const char kServiceScopeGetUserInfo[] = |
| 23 "https://www.googleapis.com/auth/userinfo.email"; |
| 24 static const int kMaxRetries = 5; |
| 25 |
| 23 OAuth2LoginManager::OAuth2LoginManager(Profile* user_profile) | 26 OAuth2LoginManager::OAuth2LoginManager(Profile* user_profile) |
| 24 : user_profile_(user_profile), | 27 : user_profile_(user_profile), |
| 25 restore_strategy_(RESTORE_FROM_COOKIE_JAR), | 28 restore_strategy_(RESTORE_FROM_COOKIE_JAR), |
| 26 state_(SESSION_RESTORE_NOT_STARTED), | 29 state_(SESSION_RESTORE_NOT_STARTED), |
| 27 loading_reported_(false) { | 30 loading_reported_(false) { |
| 28 ProfileOAuth2TokenServiceFactory::GetForProfile(user_profile_)-> | 31 GetTokenService()->AddObserver(this); |
| 29 AddObserver(this); | |
| 30 } | 32 } |
| 31 | 33 |
| 32 OAuth2LoginManager::~OAuth2LoginManager() { | 34 OAuth2LoginManager::~OAuth2LoginManager() { |
| 33 } | 35 } |
| 34 | 36 |
| 35 void OAuth2LoginManager::AddObserver(OAuth2LoginManager::Observer* observer) { | 37 void OAuth2LoginManager::AddObserver(OAuth2LoginManager::Observer* observer) { |
| 36 observer_list_.AddObserver(observer); | 38 observer_list_.AddObserver(observer); |
| 37 } | 39 } |
| 38 | 40 |
| 39 void OAuth2LoginManager::RemoveObserver( | 41 void OAuth2LoginManager::RemoveObserver( |
| (...skipping 20 matching lines...) Expand all Loading... |
| 60 if (restore_strategy_ == RESTORE_FROM_COOKIE_JAR || | 62 if (restore_strategy_ == RESTORE_FROM_COOKIE_JAR || |
| 61 restore_strategy_ == RESTORE_FROM_AUTH_CODE) { | 63 restore_strategy_ == RESTORE_FROM_AUTH_CODE) { |
| 62 FetchOAuth2Tokens(); | 64 FetchOAuth2Tokens(); |
| 63 return; | 65 return; |
| 64 } | 66 } |
| 65 | 67 |
| 66 // Save passed OAuth2 refresh token. | 68 // Save passed OAuth2 refresh token. |
| 67 if (restore_strategy_ == RESTORE_FROM_PASSED_OAUTH2_REFRESH_TOKEN) { | 69 if (restore_strategy_ == RESTORE_FROM_PASSED_OAUTH2_REFRESH_TOKEN) { |
| 68 DCHECK(!refresh_token_.empty()); | 70 DCHECK(!refresh_token_.empty()); |
| 69 restore_strategy_ = RESTORE_FROM_SAVED_OAUTH2_REFRESH_TOKEN; | 71 restore_strategy_ = RESTORE_FROM_SAVED_OAUTH2_REFRESH_TOKEN; |
| 70 GaiaAuthConsumer::ClientOAuthResult oauth2_tokens; | 72 GetAccountIdOfRefreshToken(refresh_token_); |
| 71 oauth2_tokens.refresh_token = refresh_token_; | |
| 72 StoreOAuth2Tokens(oauth2_tokens); | |
| 73 return; | 73 return; |
| 74 } | 74 } |
| 75 | 75 |
| 76 DCHECK(restore_strategy_ == RESTORE_FROM_SAVED_OAUTH2_REFRESH_TOKEN); | 76 DCHECK(restore_strategy_ == RESTORE_FROM_SAVED_OAUTH2_REFRESH_TOKEN); |
| 77 LoadAndVerifyOAuth2Tokens(); | 77 GetTokenService()->LoadCredentials(); |
| 78 } | 78 } |
| 79 | 79 |
| 80 void OAuth2LoginManager::Stop() { | 80 void OAuth2LoginManager::Stop() { |
| 81 oauth2_token_fetcher_.reset(); | 81 oauth2_token_fetcher_.reset(); |
| 82 login_verifier_.reset(); | 82 login_verifier_.reset(); |
| 83 } | 83 } |
| 84 | 84 |
| 85 bool OAuth2LoginManager::ShouldBlockTabLoading() { | 85 bool OAuth2LoginManager::ShouldBlockTabLoading() { |
| 86 return state_ == SESSION_RESTORE_PREPARING || | 86 return state_ == SESSION_RESTORE_PREPARING || |
| 87 state_ == SESSION_RESTORE_IN_PROGRESS; | 87 state_ == SESSION_RESTORE_IN_PROGRESS; |
| 88 } | 88 } |
| 89 | 89 |
| 90 void OAuth2LoginManager::OnRefreshTokenAvailable( | 90 void OAuth2LoginManager::OnRefreshTokenAvailable( |
| 91 const std::string& account_id) { | 91 const std::string& account_id) { |
| 92 if (state_ == SESSION_RESTORE_NOT_STARTED) | 92 if (state_ == SESSION_RESTORE_NOT_STARTED) |
| 93 return; | 93 return; |
| 94 | 94 |
| 95 // TODO(fgorski): Once ProfileOAuth2TokenService supports multi-login, make | 95 // TODO(fgorski): Once ProfileOAuth2TokenService supports multi-login, make |
| 96 // sure to restore session cookies in the context of the correct account_id. | 96 // sure to restore session cookies in the context of the correct account_id. |
| 97 LOG(INFO) << "OnRefreshTokenAvailable"; | 97 LOG(INFO) << "OnRefreshTokenAvailable"; |
| 98 RestoreSessionCookies(); | 98 RestoreSessionCookies(); |
| 99 } | 99 } |
| 100 | 100 |
| 101 TokenService* OAuth2LoginManager::SetupTokenService() { | 101 ProfileOAuth2TokenService* OAuth2LoginManager::GetTokenService() { |
| 102 TokenService* token_service = | 102 ProfileOAuth2TokenService* token_service = |
| 103 TokenServiceFactory::GetForProfile(user_profile_); | 103 ProfileOAuth2TokenServiceFactory::GetForProfile(user_profile_); |
| 104 return token_service; | 104 return token_service; |
| 105 } | 105 } |
| 106 | 106 |
| 107 void OAuth2LoginManager::StoreOAuth2Tokens( | 107 void OAuth2LoginManager::GetAccountIdOfRefreshToken( |
| 108 const GaiaAuthConsumer::ClientOAuthResult& oauth2_tokens) { | 108 const std::string& refresh_token) { |
| 109 TokenService* token_service = SetupTokenService(); | 109 gaia::OAuthClientInfo client_info; |
| 110 token_service->UpdateCredentialsWithOAuth2(oauth2_tokens); | 110 GaiaUrls* gaia_urls = GaiaUrls::GetInstance(); |
| 111 client_info.client_id = gaia_urls->oauth2_chrome_client_id(); |
| 112 client_info.client_secret = gaia_urls->oauth2_chrome_client_secret(); |
| 113 |
| 114 account_id_fetcher_.reset(new gaia::GaiaOAuthClient( |
| 115 auth_request_context_.get())); |
| 116 account_id_fetcher_->RefreshToken(client_info, refresh_token, |
| 117 std::vector<std::string>(1, kServiceScopeGetUserInfo), kMaxRetries, |
| 118 this); |
| 119 } |
| 120 |
| 121 void OAuth2LoginManager::OnRefreshTokenResponse( |
| 122 const std::string& access_token, |
| 123 int expires_in_seconds) { |
| 124 account_id_fetcher_->GetUserEmail(access_token, kMaxRetries, this); |
| 125 } |
| 126 |
| 127 void OAuth2LoginManager::OnGetUserEmailResponse( |
| 128 const std::string& user_email) { |
| 129 DCHECK(!refresh_token_.empty()); |
| 130 account_id_fetcher_.reset(); |
| 131 GetTokenService()->UpdateCredentials(user_email, refresh_token_); |
| 111 | 132 |
| 112 FOR_EACH_OBSERVER(Observer, observer_list_, | 133 FOR_EACH_OBSERVER(Observer, observer_list_, |
| 113 OnNewRefreshTokenAvaiable(user_profile_)); | 134 OnNewRefreshTokenAvaiable(user_profile_)); |
| 114 } | 135 } |
| 115 | 136 |
| 116 void OAuth2LoginManager::LoadAndVerifyOAuth2Tokens() { | 137 void OAuth2LoginManager::OnOAuthError() { |
| 117 // If we have no cookies, try to load saved OAuth2 token from TokenService. | 138 account_id_fetcher_.reset(); |
| 118 TokenService* token_service = SetupTokenService(); | 139 LOG(ERROR) << "Account id fetch failed!"; |
| 119 token_service->Initialize(GaiaConstants::kChromeSource, user_profile_); | 140 SetSessionRestoreState(OAuth2LoginManager::SESSION_RESTORE_FAILED); |
| 120 token_service->LoadTokensFromDB(); | 141 } |
| 142 |
| 143 void OAuth2LoginManager::OnNetworkError(int response_code) { |
| 144 account_id_fetcher_.reset(); |
| 145 LOG(ERROR) << "Account id fetch failed! response_code=" << response_code; |
| 146 SetSessionRestoreState(OAuth2LoginManager::SESSION_RESTORE_FAILED); |
| 121 } | 147 } |
| 122 | 148 |
| 123 void OAuth2LoginManager::FetchOAuth2Tokens() { | 149 void OAuth2LoginManager::FetchOAuth2Tokens() { |
| 124 DCHECK(auth_request_context_.get()); | 150 DCHECK(auth_request_context_.get()); |
| 125 // If we have authenticated cookie jar, get OAuth1 token first, then fetch | 151 // If we have authenticated cookie jar, get OAuth1 token first, then fetch |
| 126 // SID/LSID cookies through OAuthLogin call. | 152 // SID/LSID cookies through OAuthLogin call. |
| 127 if (restore_strategy_ == RESTORE_FROM_COOKIE_JAR) { | 153 if (restore_strategy_ == RESTORE_FROM_COOKIE_JAR) { |
| 128 oauth2_token_fetcher_.reset( | 154 oauth2_token_fetcher_.reset( |
| 129 new OAuth2TokenFetcher(this, auth_request_context_.get())); | 155 new OAuth2TokenFetcher(this, auth_request_context_.get())); |
| 130 oauth2_token_fetcher_->StartExchangeFromCookies(); | 156 oauth2_token_fetcher_->StartExchangeFromCookies(); |
| 131 } else if (restore_strategy_ == RESTORE_FROM_AUTH_CODE) { | 157 } else if (restore_strategy_ == RESTORE_FROM_AUTH_CODE) { |
| 132 DCHECK(!auth_code_.empty()); | 158 DCHECK(!auth_code_.empty()); |
| 133 oauth2_token_fetcher_.reset( | 159 oauth2_token_fetcher_.reset( |
| 134 new OAuth2TokenFetcher(this, | 160 new OAuth2TokenFetcher(this, |
| 135 g_browser_process->system_request_context())); | 161 g_browser_process->system_request_context())); |
| 136 oauth2_token_fetcher_->StartExchangeFromAuthCode(auth_code_); | 162 oauth2_token_fetcher_->StartExchangeFromAuthCode(auth_code_); |
| 137 } else { | 163 } else { |
| 138 NOTREACHED(); | 164 NOTREACHED(); |
| 139 SetSessionRestoreState(OAuth2LoginManager::SESSION_RESTORE_FAILED); | 165 SetSessionRestoreState(OAuth2LoginManager::SESSION_RESTORE_FAILED); |
| 140 } | 166 } |
| 141 } | 167 } |
| 142 | 168 |
| 143 void OAuth2LoginManager::OnOAuth2TokensAvailable( | 169 void OAuth2LoginManager::OnOAuth2TokensAvailable( |
| 144 const GaiaAuthConsumer::ClientOAuthResult& oauth2_tokens) { | 170 const GaiaAuthConsumer::ClientOAuthResult& oauth2_tokens) { |
| 145 LOG(INFO) << "OAuth2 tokens fetched"; | 171 LOG(INFO) << "OAuth2 tokens fetched"; |
| 146 StoreOAuth2Tokens(oauth2_tokens); | 172 DCHECK(refresh_token_.empty()); |
| 173 refresh_token_.assign(oauth2_tokens.refresh_token); |
| 174 GetAccountIdOfRefreshToken(refresh_token_); |
| 147 } | 175 } |
| 148 | 176 |
| 149 void OAuth2LoginManager::OnOAuth2TokensFetchFailed() { | 177 void OAuth2LoginManager::OnOAuth2TokensFetchFailed() { |
| 150 LOG(ERROR) << "OAuth2 tokens fetch failed!"; | 178 LOG(ERROR) << "OAuth2 tokens fetch failed!"; |
| 151 UMA_HISTOGRAM_ENUMERATION("OAuth2Login.SessionRestore", | 179 UMA_HISTOGRAM_ENUMERATION("OAuth2Login.SessionRestore", |
| 152 SESSION_RESTORE_TOKEN_FETCH_FAILED, | 180 SESSION_RESTORE_TOKEN_FETCH_FAILED, |
| 153 SESSION_RESTORE_COUNT); | 181 SESSION_RESTORE_COUNT); |
| 154 SetSessionRestoreState(OAuth2LoginManager::SESSION_RESTORE_FAILED); | 182 SetSessionRestoreState(OAuth2LoginManager::SESSION_RESTORE_FAILED); |
| 155 } | 183 } |
| 156 | 184 |
| 157 void OAuth2LoginManager::RestoreSessionCookies() { | 185 void OAuth2LoginManager::RestoreSessionCookies() { |
| 158 DCHECK(!login_verifier_.get()); | 186 DCHECK(!login_verifier_.get()); |
| 159 SetSessionRestoreState(SESSION_RESTORE_IN_PROGRESS); | 187 SetSessionRestoreState(SESSION_RESTORE_IN_PROGRESS); |
| 160 login_verifier_.reset( | 188 login_verifier_.reset( |
| 161 new OAuth2LoginVerifier(this, | 189 new OAuth2LoginVerifier(this, |
| 162 g_browser_process->system_request_context(), | 190 g_browser_process->system_request_context(), |
| 163 user_profile_->GetRequestContext())); | 191 user_profile_->GetRequestContext())); |
| 164 login_verifier_->VerifyProfileTokens(user_profile_); | 192 login_verifier_->VerifyProfileTokens(user_profile_); |
| 165 } | 193 } |
| 166 | 194 |
| 167 void OAuth2LoginManager::Shutdown() { | 195 void OAuth2LoginManager::Shutdown() { |
| 168 ProfileOAuth2TokenServiceFactory::GetForProfile(user_profile_)-> | 196 GetTokenService()->RemoveObserver(this); |
| 169 RemoveObserver(this); | |
| 170 login_verifier_.reset(); | 197 login_verifier_.reset(); |
| 171 oauth2_token_fetcher_.reset(); | 198 oauth2_token_fetcher_.reset(); |
| 172 } | 199 } |
| 173 | 200 |
| 174 void OAuth2LoginManager::OnOAuthLoginSuccess( | 201 void OAuth2LoginManager::OnOAuthLoginSuccess( |
| 175 const GaiaAuthConsumer::ClientLoginResult& gaia_credentials) { | 202 const GaiaAuthConsumer::ClientLoginResult& gaia_credentials) { |
| 176 LOG(INFO) << "OAuth2 refresh token successfully exchanged for GAIA token."; | 203 LOG(INFO) << "OAuth2 refresh token successfully exchanged for GAIA token."; |
| 177 StartTokenService(gaia_credentials); | 204 |
| 205 FOR_EACH_OBSERVER(Observer, observer_list_, |
| 206 OnSessionAuthenticated(user_profile_)); |
| 178 } | 207 } |
| 179 | 208 |
| 180 void OAuth2LoginManager::OnOAuthLoginFailure(bool connection_error) { | 209 void OAuth2LoginManager::OnOAuthLoginFailure(bool connection_error) { |
| 181 LOG(ERROR) << "OAuth2 refresh token verification failed!" | 210 LOG(ERROR) << "OAuth2 refresh token verification failed!" |
| 182 << " connection_error: " << connection_error; | 211 << " connection_error: " << connection_error; |
| 183 UMA_HISTOGRAM_ENUMERATION("OAuth2Login.SessionRestore", | 212 UMA_HISTOGRAM_ENUMERATION("OAuth2Login.SessionRestore", |
| 184 SESSION_RESTORE_OAUTHLOGIN_FAILED, | 213 SESSION_RESTORE_OAUTHLOGIN_FAILED, |
| 185 SESSION_RESTORE_COUNT); | 214 SESSION_RESTORE_COUNT); |
| 186 SetSessionRestoreState(connection_error ? | 215 SetSessionRestoreState(connection_error ? |
| 187 OAuth2LoginManager::SESSION_RESTORE_CONNECTION_FAILED : | 216 OAuth2LoginManager::SESSION_RESTORE_CONNECTION_FAILED : |
| (...skipping 12 matching lines...) Expand all Loading... |
| 200 LOG(ERROR) << "OAuth2 refresh and GAIA token verification failed!" | 229 LOG(ERROR) << "OAuth2 refresh and GAIA token verification failed!" |
| 201 << " connection_error: " << connection_error; | 230 << " connection_error: " << connection_error; |
| 202 UMA_HISTOGRAM_ENUMERATION("OAuth2Login.SessionRestore", | 231 UMA_HISTOGRAM_ENUMERATION("OAuth2Login.SessionRestore", |
| 203 SESSION_RESTORE_MERGE_SESSION_FAILED, | 232 SESSION_RESTORE_MERGE_SESSION_FAILED, |
| 204 SESSION_RESTORE_COUNT); | 233 SESSION_RESTORE_COUNT); |
| 205 SetSessionRestoreState(connection_error ? | 234 SetSessionRestoreState(connection_error ? |
| 206 OAuth2LoginManager::SESSION_RESTORE_CONNECTION_FAILED : | 235 OAuth2LoginManager::SESSION_RESTORE_CONNECTION_FAILED : |
| 207 OAuth2LoginManager::SESSION_RESTORE_FAILED); | 236 OAuth2LoginManager::SESSION_RESTORE_FAILED); |
| 208 } | 237 } |
| 209 | 238 |
| 210 void OAuth2LoginManager::StartTokenService( | |
| 211 const GaiaAuthConsumer::ClientLoginResult& gaia_credentials) { | |
| 212 TokenService* token_service = SetupTokenService(); | |
| 213 token_service->UpdateCredentials(gaia_credentials); | |
| 214 | |
| 215 FOR_EACH_OBSERVER(Observer, observer_list_, | |
| 216 OnSessionAuthenticated(user_profile_)); | |
| 217 | |
| 218 if (token_service->AreCredentialsValid()) | |
| 219 token_service->StartFetchingTokens(); | |
| 220 } | |
| 221 | |
| 222 void OAuth2LoginManager::SetSessionRestoreState( | 239 void OAuth2LoginManager::SetSessionRestoreState( |
| 223 OAuth2LoginManager::SessionRestoreState state) { | 240 OAuth2LoginManager::SessionRestoreState state) { |
| 224 if (state_ == state) | 241 if (state_ == state) |
| 225 return; | 242 return; |
| 226 | 243 |
| 227 state_ = state; | 244 state_ = state; |
| 228 if (state == OAuth2LoginManager::SESSION_RESTORE_FAILED) { | 245 if (state == OAuth2LoginManager::SESSION_RESTORE_FAILED) { |
| 229 UMA_HISTOGRAM_TIMES("OAuth2Login.SessionRestoreTimeToFailure", | 246 UMA_HISTOGRAM_TIMES("OAuth2Login.SessionRestoreTimeToFailure", |
| 230 base::Time::Now() - session_restore_start_); | 247 base::Time::Now() - session_restore_start_); |
| 231 } else if (state == OAuth2LoginManager::SESSION_RESTORE_DONE) { | 248 } else if (state == OAuth2LoginManager::SESSION_RESTORE_DONE) { |
| 232 UMA_HISTOGRAM_TIMES("OAuth2Login.SessionRestoreTimeToSuccess", | 249 UMA_HISTOGRAM_TIMES("OAuth2Login.SessionRestoreTimeToSuccess", |
| 233 base::Time::Now() - session_restore_start_); | 250 base::Time::Now() - session_restore_start_); |
| 234 } | 251 } |
| 235 | 252 |
| 236 FOR_EACH_OBSERVER(Observer, observer_list_, | 253 FOR_EACH_OBSERVER(Observer, observer_list_, |
| 237 OnSessionRestoreStateChanged(user_profile_, state_)); | 254 OnSessionRestoreStateChanged(user_profile_, state_)); |
| 238 } | 255 } |
| 239 | 256 |
| 240 void OAuth2LoginManager::SetSessionRestoreStartForTesting( | 257 void OAuth2LoginManager::SetSessionRestoreStartForTesting( |
| 241 const base::Time& time) { | 258 const base::Time& time) { |
| 242 session_restore_start_ = time; | 259 session_restore_start_ = time; |
| 243 } | 260 } |
| 244 | 261 |
| 245 } // namespace chromeos | 262 } // namespace chromeos |
| OLD | NEW |