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 VLOG(1) << "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 VLOG(1) << "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 VLOG(1) << "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 : |
188 OAuth2LoginManager::SESSION_RESTORE_FAILED); | 217 OAuth2LoginManager::SESSION_RESTORE_FAILED); |
189 } | 218 } |
190 | 219 |
191 void OAuth2LoginManager::OnSessionMergeSuccess() { | 220 void OAuth2LoginManager::OnSessionMergeSuccess() { |
192 LOG(INFO) << "OAuth2 refresh and/or GAIA token verification succeeded."; | 221 VLOG(1) << "OAuth2 refresh and/or GAIA token verification succeeded."; |
193 UMA_HISTOGRAM_ENUMERATION("OAuth2Login.SessionRestore", | 222 UMA_HISTOGRAM_ENUMERATION("OAuth2Login.SessionRestore", |
194 SESSION_RESTORE_SUCCESS, | 223 SESSION_RESTORE_SUCCESS, |
195 SESSION_RESTORE_COUNT); | 224 SESSION_RESTORE_COUNT); |
196 SetSessionRestoreState(OAuth2LoginManager::SESSION_RESTORE_DONE); | 225 SetSessionRestoreState(OAuth2LoginManager::SESSION_RESTORE_DONE); |
197 } | 226 } |
198 | 227 |
199 void OAuth2LoginManager::OnSessionMergeFailure(bool connection_error) { | 228 void OAuth2LoginManager::OnSessionMergeFailure(bool connection_error) { |
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 |